unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: thomas.wiecki@gmail.com
Cc: 14567@debbugs.gnu.org
Subject: bug#14567: Scrolling of large images
Date: Sat, 08 Jun 2013 17:19:32 +0300	[thread overview]
Message-ID: <83vc5osn0r.fsf@gnu.org> (raw)
In-Reply-To: <83obbjuov4.fsf@gnu.org>

> Date: Thu, 06 Jun 2013 20:32:15 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: 14567@debbugs.gnu.org
> 
> > From: Thomas Wiecki <thomas.wiecki@gmail.com>
> > Date: Thu, 6 Jun 2013 13:16:43 -0400
> > Cc: 14567@debbugs.gnu.org
> > 
> > 1. Download a large image (e.g.
> > http://cdn.urbanislandz.com/wp-content/uploads/2011/10/MMSposter-large.jpg)
> > and save it as /tmp/test.jpg
> > 2. In an emacs buffer type "(insert-image (create-image "/tmp/test.jpg"))"
> > 3. Type some arbitrary lines of text below this line.
> > 4. In first line (containing insert-image), type C-x C-e at end of line to
> > load the image.
> > 5. Image should appear in buffer.
> > 6. Scroll down repeatedly until past the image.
> > 
> > Expected behavior: Scrolls down smoothly even once scrolled past image.
> > Observed behavior: Scrolls down smoothly until end of image is reached. At
> > end of image, the next scroll causes a huge jump in the window so that and
> > only the text is shown but not any of the residual image.
> > 
> > 7. scroll back up
> > 
> > Expected behavior: Scrolls upwards over image.
> > Observed behavior: Jumps over complete image and shows beginning of buffer.
> 
> Perfect, thanks.  I will take a look.

Can you try the changes below and see if they give good results,
including in the real-life use cases where you bumped into this?  Note
that you will have to rebuild Emacs to try this.

Thanks.

=== modified file 'lisp/simple.el'
--- lisp/simple.el	2013-06-05 18:10:27 +0000
+++ lisp/simple.el	2013-06-08 14:14:39 +0000
@@ -4738,20 +4738,35 @@ lines."
 	   (vpos (nth 1 lh))
 	   (ypos (nth 2 lh))
 	   (rbot (nth 3 lh))
+	   (this-lh (window-line-height))
+	   (this-height (nth 0 this-lh))
+	   (this-ypos (nth 2 this-lh))
+	   (fch (frame-char-height))
 	   py vs)
       (when (or (null lh)
-		(>= rbot (frame-char-height))
-		(<= ypos (- (frame-char-height))))
+		(>= rbot fch)
+		(<= ypos (- fch))
+		(null this-lh)
+		(<= this-ypos (- fch)))
 	(unless lh
 	  (let ((wend (pos-visible-in-window-p t nil t)))
 	    (setq rbot (nth 3 wend)
 		  vpos (nth 5 wend))))
+	(unless this-lh
+	  (let ((wstart (pos-visible-in-window-p nil nil t)))
+	    (setq this-ypos (nth 2 wstart)
+		  this-height (nth 4 wstart))))
 	(cond
-	 ;; If last line of window is fully visible, move forward.
-	 ((or (null rbot) (= rbot 0))
+	 ;; If last line of window is fully visible, and vscrolling
+	 ;; more would make this line invisible, move forward.
+	 ((and (or (< (setq vs (window-vscroll nil t)) fch)
+		   (<= this-height fch))
+	       (or (null rbot) (= rbot 0)))
 	  nil)
-	 ;; If cursor is not in the bottom scroll margin, move forward.
-	 ((and (> vpos 0)
+	 ;; If cursor is not in the bottom scroll margin, and the
+	 ;; current line is is not too tall, move forward.
+	 ((and (<= this-height fch)
+	       (> vpos 0)
 	       (< (setq py
 			(or (nth 1 (window-line-height))
 			    (let ((ppos (posn-at-point)))
@@ -4761,9 +4776,10 @@ lines."
 	  nil)
 	 ;; When already vscrolled, we vscroll some more if we can,
 	 ;; or clear vscroll and move forward at end of tall image.
-	 ((> (setq vs (window-vscroll nil t)) 0)
-	  (when (> rbot 0)
-	    (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
+	 ((> vs 0)
+	  (when (or (> rbot 0)
+		    (> this-height fch))
+	    (set-window-vscroll nil (+ vs fch) t)))
 	 ;; If cursor just entered the bottom scroll margin, move forward,
 	 ;; but also vscroll one line so redisplay won't recenter.
 	 ((and (> vpos 0)
@@ -4808,7 +4824,14 @@ lines."
 	       ;; display-based motion doesn't make sense (because each
 	       ;; logical line occupies exactly one screen line).
 	       (not (> (window-hscroll) 0)))
-	  (line-move-visual arg noerror)
+	  (prog1 (line-move-visual arg noerror)
+	    ;; If we moved into a tall line, set vscroll to make
+	    ;; scrolling through tall images more smooth.
+	    (let ((lh (line-pixel-height)))
+	      (if (and (< arg 0)
+		       (< (point) (window-start))
+		       (> lh (frame-char-height)))
+		  (set-window-vscroll nil (- lh (frame-char-height)) t))))
 	(line-move-1 arg noerror to-end)))))
 
 ;; Display-based alternative to line-move-1.

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2013-06-06 16:35:31 +0000
+++ src/xdisp.c	2013-06-08 14:02:28 +0000
@@ -1217,6 +1217,24 @@ line_bottom_y (struct it *it)
   return line_top_y + line_height;
 }
 
+DEFUN ("line-pixel-height", Fline_pixel_height,
+       Sline_pixel_height, 0, 0, 0,
+       doc: /* Return height in pixels of text line in the selected window.
+
+Value is the height in pixels of the line at point.  */)
+  (void)
+{
+  struct it it;
+  struct text_pos pt;
+  struct window *w = XWINDOW (selected_window);
+
+  SET_TEXT_POS (pt, PT, PT_BYTE);
+  start_display (&it, w, pt);
+  it.vpos = it.current_y = 0;
+  last_height = 0;
+  return make_number (line_bottom_y (&it));
+}
+
 /* Subroutine of pos_visible_p below.  Extracts a display string, if
    any, from the display spec given as its argument.  */
 static Lisp_Object
@@ -28665,6 +28683,7 @@ syms_of_xdisp (void)
   defsubr (&Stool_bar_lines_needed);
   defsubr (&Slookup_image_map);
 #endif
+  defsubr (&Sline_pixel_height);
   defsubr (&Sformat_mode_line);
   defsubr (&Sinvisible_p);
   defsubr (&Scurrent_bidi_paragraph_direction);






  reply	other threads:[~2013-06-08 14:19 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-06 12:17 bug#14567: Scrolling of large images Thomas Wiecki
2013-06-06 16:42 ` Eli Zaretskii
2013-06-06 17:16   ` Thomas Wiecki
2013-06-06 17:32     ` Eli Zaretskii
2013-06-08 14:19       ` Eli Zaretskii [this message]
2013-06-08 15:52         ` Thomas Wiecki
2013-06-08 16:49           ` Eli Zaretskii
2013-06-08 17:51             ` Thomas Wiecki
2013-06-08 18:44               ` Eli Zaretskii
2013-06-08 21:39                 ` Thomas Wiecki
2013-06-09  2:42                   ` Eli Zaretskii
2013-06-09  9:27                     ` Vitalie Spinu
2013-06-11 20:14                     ` David Engster
2013-06-15  8:23                       ` Eli Zaretskii
2013-06-15  9:02                         ` David Engster
2013-06-15  9:39                           ` Eli Zaretskii
2013-06-15 10:08                             ` David Engster
2013-06-15 11:13                               ` Thierry Volpiatto
2013-06-15 11:26                                 ` Eli Zaretskii
2013-06-15 12:41                                   ` Eli Zaretskii
2013-06-16  5:33                                     ` Thierry Volpiatto
2013-06-16  6:18                                       ` Thierry Volpiatto
2013-06-16 16:24                                         ` Eli Zaretskii
2013-06-17  4:57                                           ` Thierry Volpiatto
2013-06-17 15:14                                             ` Eli Zaretskii
2013-06-18 11:35                                               ` Thierry Volpiatto
2013-06-18 16:13                                                 ` Eli Zaretskii
2013-06-19  6:43                                                   ` Thierry Volpiatto
2013-07-06  9:02 ` bug#14567: These changes sometimes break plain text navigation Dima Kogan
2013-07-06 11:02   ` Eli Zaretskii
2013-07-06 16:14     ` Dima Kogan
2013-07-06 17:41       ` Eli Zaretskii
2013-07-06 21:51         ` Dima Kogan
2013-07-07  2:48           ` Eli Zaretskii
2013-07-07  4:46             ` Dima Kogan
2013-07-07 15:51               ` Eli Zaretskii
2013-07-07 18:57                 ` Dima Kogan
2013-07-08 17:35                   ` Eli Zaretskii
2013-07-08 23:42                     ` Dima Kogan
2013-07-09 17:00                       ` bug#14598: " Eli Zaretskii
2013-07-10  9:30                         ` Stephen Berman
2013-07-10 16:27                           ` Eli Zaretskii
2013-07-10 21:33                             ` Stephen Berman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=83vc5osn0r.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=14567@debbugs.gnu.org \
    --cc=thomas.wiecki@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).