changeset 90084:befae6bafecb

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-6 Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-48 - miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-51 Update from CVS
author Miles Bader <miles@gnu.org>
date Mon, 24 Jan 2005 22:34:31 +0000
parents 2b2f720892ae (current diff) 4712d3f43248 (diff)
children f8a7a9ba3d08
files etc/NEWS lisp/ChangeLog lisp/calc/calc-store.el lisp/files.el lisp/international/encoded-kb.el lisp/progmodes/gdb-ui.el lisp/simple.el lisp/term/w32-win.el lisp/textmodes/refill.el lispref/ChangeLog lispref/windows.texi man/ChangeLog man/faq.texi src/ChangeLog src/dispextern.h src/indent.c src/macgui.h src/macterm.c src/window.c src/xdisp.c
diffstat 20 files changed, 445 insertions(+), 255 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Mon Jan 24 03:43:01 2005 +0000
+++ b/etc/NEWS	Mon Jan 24 22:34:31 2005 +0000
@@ -2563,6 +2563,13 @@
 * Lisp Changes in Emacs 21.4
 
 +++
+** The line-move, scroll-up, and scroll-down functions will now
+modify the window vscroll to scroll through display rows that are
+taller that the height of the window, for example in the presense of
+large images.  To disable this feature, Lisp code may bind the new
+variable `auto-window-vscroll' to nil.
+
++++
 ** If a buffer sets buffer-save-without-query to non-nil,
 save-some-buffers will always save that buffer without asking
 (if it's modified).
--- a/lisp/ChangeLog	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/ChangeLog	Mon Jan 24 22:34:31 2005 +0000
@@ -1,3 +1,49 @@
+2005-01-24  Jay Belanger  <belanger@truman.edu>
+
+	* calc/calc-store.el (calc-declare-variable): Use calc-var-name to
+	display variable name.
+
+2005-01-24  Kenichi Handa  <handa@m17n.org>
+
+	* international/encoded-kb.el (encoded-kbd-iso2022-single-shift):
+	Fix setting of the element of encoded-kbd-iso2022-invocations.
+
+2005-01-24  Nick Roberts  <nickrob@snap.net.nz>
+
+	* progmodes/gdb-ui.el (gdb-goto-breakpoint, gdb-frames-select)
+	(gdb-threads-select): Change to also accept mouse events.
+	(gdb-mouse-goto-breakpoint, gdb-frames-mouse-select)
+	(gdb-threads-mouse-select): Delete.
+
+2005-01-23  Luc Teirlinck  <teirllm@auburn.edu>
+
+	* files.el (insert-directory): Take care of empty directory,
+	listed without -a switch.
+
+2005-01-23  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* textmodes/refill.el (refill-post-command-function):
+	Add `indent-new-comment-line' and `reindent-then-newline-and-indent'
+	to the list of functions that we should be careful not to undo.
+	(refill-late-fill-paragraph-function): Remove.
+	(refill-saved-state): New var.
+	(refill-mode): Use it to save fill-paragraph-function.
+	Save also the value of auto-fill-function.
+
+	* term/w32-win.el: Simplify code.
+
+2005-01-23  Kim F. Storm  <storm@cua.dk>
+
+	* simple.el (line-move): Adapt to new return value from
+	pos-visible-in-window-p.
+
+	* simple.el (line-move): Fix last change.  Check partial
+	visibility at point rather than at window-start.
+
+2005-01-22  Jason Rumney  <jasonr@gnu.org>
+
+	* term/w32-win.el (xw-defined-colors): Remove debug-message.
+
 2005-01-22  David Kastrup  <dak@gnu.org>
 
 	* progmodes/grep.el: Add alias `find-grep' for `grep-find'.
--- a/lisp/calc/calc-store.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/calc/calc-store.el	Mon Jan 24 22:34:31 2005 +0000
@@ -482,7 +482,7 @@
 			     (setq rp nil)))
 		       (not rp)))))
      (calc-unread-command ?\C-a)
-     (setq decl (read-string (format "Declare: %s  to be: " var)
+     (setq decl (read-string (format "Declare: %s  to be: " (calc-var-name var))
 			     (and rp
 				  (math-format-flat-expr (nth 2 (car dp)) 0))))
      (setq decl (and (string-match "[^ \t]" decl)
--- a/lisp/files.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/files.el	Mon Jan 24 22:34:31 2005 +0000
@@ -4550,45 +4550,54 @@
 	  (when (if (stringp switches)
 		    (string-match "--dired\\>" switches)
 		  (member "--dired" switches))
+	    ;; The following overshoots by one line for an empty
+	    ;; directory listed with "--dired", but without "-a"
+	    ;; switch, where the ls output contains a
+	    ;; "//DIRED-OPTIONS//" line, but no "//DIRED//" line.
+	    ;; We take care of that case later.
 	    (forward-line -2)
             (when (looking-at "//SUBDIRED//")
               (delete-region (point) (progn (forward-line 1) (point)))
               (forward-line -1))
-	    (when (looking-at "//DIRED//")
-	      (let ((end (line-end-position))
-		    (linebeg (point))
-		    error-lines)
-		;; Find all the lines that are error messages,
-		;; and record the bounds of each one.
-		(goto-char beg)
-		(while (< (point) linebeg)
-		  (or (eql (following-char) ?\s)
-		      (push (list (point) (line-end-position)) error-lines))
-		  (forward-line 1))
-		(setq error-lines (nreverse error-lines))
-		;; Now read the numeric positions of file names.
-		(goto-char linebeg)
-		(forward-word 1)
-		(forward-char 3)
-		(while (< (point) end)
-		  (let ((start (insert-directory-adj-pos
+	    (if (looking-at "//DIRED//")
+		(let ((end (line-end-position))
+		      (linebeg (point))
+		      error-lines)
+		  ;; Find all the lines that are error messages,
+		  ;; and record the bounds of each one.
+		  (goto-char beg)
+		  (while (< (point) linebeg)
+		    (or (eql (following-char) ?\s)
+			(push (list (point) (line-end-position)) error-lines))
+		    (forward-line 1))
+		  (setq error-lines (nreverse error-lines))
+		  ;; Now read the numeric positions of file names.
+		  (goto-char linebeg)
+		  (forward-word 1)
+		  (forward-char 3)
+		  (while (< (point) end)
+		    (let ((start (insert-directory-adj-pos
+				  (+ beg (read (current-buffer)))
+				  error-lines))
+			  (end (insert-directory-adj-pos
 				(+ beg (read (current-buffer)))
-				error-lines))
-			(end (insert-directory-adj-pos
-			      (+ beg (read (current-buffer)))
-			      error-lines)))
-		    (if (memq (char-after end) '(?\n ?\ ))
-			;; End is followed by \n or by " -> ".
-			(put-text-property start end 'dired-filename t)
-		      ;; It seems that we can't trust ls's output as to
-		      ;; byte positions of filenames.
-		      (put-text-property beg (point) 'dired-filename nil)
-		      (end-of-line))))
-		(goto-char end)
-		(beginning-of-line)
-		(delete-region (point) (progn (forward-line 1) (point))))
-	      (if (looking-at "//DIRED-OPTIONS//")
-		  (delete-region (point) (progn (forward-line 1) (point))))))
+				error-lines)))
+		      (if (memq (char-after end) '(?\n ?\ ))
+			  ;; End is followed by \n or by " -> ".
+			  (put-text-property start end 'dired-filename t)
+			;; It seems that we can't trust ls's output as to
+			;; byte positions of filenames.
+			(put-text-property beg (point) 'dired-filename nil)
+			(end-of-line))))
+		  (goto-char end)
+		  (beginning-of-line)
+		  (delete-region (point) (progn (forward-line 1) (point))))
+	      ;; Take care of the case where the ls output contains a
+	      ;; "//DIRED-OPTIONS//"-line, but no "//DIRED//"-line
+	      ;; and we went one line too far back (see above).
+	      (forward-line 1))
+	    (if (looking-at "//DIRED-OPTIONS//")
+		(delete-region (point) (progn (forward-line 1) (point)))))
 
 	  ;; Now decode what read if necessary.
 	  (let ((coding (or coding-system-for-read
--- a/lisp/international/encoded-kb.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/international/encoded-kb.el	Mon Jan 24 22:34:31 2005 +0000
@@ -130,9 +130,7 @@
 
 (defun encoded-kbd-iso2022-single-shift (ignore)
   (let ((char (encoded-kbd-last-key)))
-    (aset encoded-kbd-iso2022-invocations 2
-	  (aref encoded-kbd-iso2022-designations
-		(if (= char ?\216) 2 3))))
+    (aset encoded-kbd-iso2022-invocations 2 (if (= char ?\216) 2 3)))
   "")
 
 (defun encoded-kbd-self-insert-iso2022-7bit (ignore)
--- a/lisp/progmodes/gdb-ui.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/progmodes/gdb-ui.el	Mon Jan 24 22:34:31 2005 +0000
@@ -1243,7 +1243,7 @@
     (define-key map "d" 'gdb-delete-breakpoint)
     (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-goto-breakpoint)
-    (define-key map [mouse-2] 'gdb-mouse-goto-breakpoint)
+    (define-key map [mouse-2] 'gdb-goto-breakpoint)
     map))
 
 (defun gdb-breakpoints-mode ()
@@ -1291,9 +1291,10 @@
 	(concat gdb-server-prefix "delete " (match-string 1) "\n") 'ignore))
     (error "Not recognized as break/watchpoint line")))
 
-(defun gdb-goto-breakpoint ()
+(defun gdb-goto-breakpoint (&optional event)
   "Display the breakpoint location specified at current line."
-  (interactive)
+  (interactive (list last-input-event))
+  (if event (mouse-set-point event))
   (save-excursion
     (beginning-of-line 1)
     (if (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba))
@@ -1311,14 +1312,8 @@
 		(goto-line (string-to-number line))
 		(set-window-point window (point))))))
       (error "Not recognized as break/watchpoint line"))))
+
 
-(defun gdb-mouse-goto-breakpoint (event)
-  "Display the breakpoint location that you click on."
-  (interactive "e")
-  (mouse-set-point event)
-  (gdb-goto-breakpoint))
-
-;;
 ;; Frames buffer.  This displays a perpetually correct bactracktrace
 ;; (from the command `where').
 ;;
@@ -1372,7 +1367,7 @@
     (suppress-keymap map)
     (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-frames-select)
-    (define-key map [mouse-2] 'gdb-frames-mouse-select)
+    (define-key map [mouse-2] 'gdb-frames-select)
     map))
 
 (defun gdb-frames-mode ()
@@ -1396,20 +1391,15 @@
 	   (n (or (and pos (match-string-no-properties 1)) "0")))
       n)))
 
-(defun gdb-frames-select ()
+(defun gdb-frames-select (&optional event)
   "Select the frame and display the relevant source."
-  (interactive)
+  (interactive (list last-input-event))
+  (if event (mouse-set-point event))
   (gdb-enqueue-input
    (list (concat gdb-server-prefix "frame " (gdb-get-frame-number) "\n") 'ignore))
   (gud-display-frame))
+
 
-(defun gdb-frames-mouse-select (event)
-  "Select the frame you click on and display the relevant source."
-  (interactive "e")
-  (mouse-set-point event)
-  (gdb-frames-select))
-
-;;
 ;; Threads buffer.  This displays a selectable thread list.
 ;;
 (gdb-set-buffer-rules 'gdb-threads-buffer
@@ -1454,7 +1444,7 @@
     (suppress-keymap map)
     (define-key map "q" 'kill-this-buffer)
     (define-key map "\r" 'gdb-threads-select)
-    (define-key map [mouse-2] 'gdb-threads-mouse-select)
+    (define-key map [mouse-2] 'gdb-threads-select)
     map))
 
 (defun gdb-threads-mode ()
@@ -1474,20 +1464,15 @@
     (re-search-backward "^\\s-*\\([0-9]*\\)" nil t)
     (match-string-no-properties 1)))
 
-(defun gdb-threads-select ()
+(defun gdb-threads-select (&optional event)
   "Select the thread and display the relevant source."
-  (interactive)
+  (interactive (list last-input-event))
+  (if event (mouse-set-point event))
   (gdb-enqueue-input
    (list (concat "thread " (gdb-get-thread-number) "\n") 'ignore))
   (gud-display-frame))
+
 
-(defun gdb-threads-mouse-select (event)
-  "Select the thread you click on and display the relevant source."
-  (interactive "e")
-  (mouse-set-point event)
-  (gdb-threads-select))
-
-;;
 ;; Registers buffer.
 ;;
 (gdb-set-buffer-rules 'gdb-registers-buffer
--- a/lisp/simple.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/simple.el	Mon Jan 24 22:34:31 2005 +0000
@@ -3183,17 +3183,17 @@
 (defun line-move (arg &optional noerror to-end)
   (if auto-window-vscroll
       (let ((forward (> arg 0))
-	    (pvis (pos-visible-in-window-p (window-start) nil t)))
-	(if (and pvis (null (nth 2 pvis))
-		 (> (nth (if forward 4 3) pvis) 0))
+	    (part (nth 2 (pos-visible-in-window-p (point) nil t))))
+	(if (and (consp part)
+		 (> (setq part (if forward (cdr part) (car part))) 0))
 	    (set-window-vscroll nil
 				(if forward
 				    (+ (window-vscroll nil t)
-				       (min (nth 4 pvis)
+				       (min part
 					    (* (frame-char-height) arg)))
 				  (max 0
 				       (- (window-vscroll nil t)
-					  (min (nth 3 pvis)
+					  (min part
 					       (* (frame-char-height) (- arg))))))
 				t)
 	  (set-window-vscroll nil 0)
--- a/lisp/term/w32-win.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/term/w32-win.el	Mon Jan 24 22:34:31 2005 +0000
@@ -1,6 +1,6 @@
 ;;; w32-win.el --- parse switches controlling interface with W32 window system
 
-;; Copyright (C) 1993, 1994, 2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 ;; Author: Kevin Gallo
 ;; Keywords: terminals
@@ -139,50 +139,26 @@
   "Handle SWITCH of the form \"-switch value\" or \"-switch\"."
   (let ((aelt (assoc switch command-line-x-option-alist)))
     (if aelt
-	(let ((param (nth 3 aelt))
-	      (value (nth 4 aelt)))
-	  (if value
-	      (setq default-frame-alist
-		    (cons (cons param value)
-			  default-frame-alist))
-	    (setq default-frame-alist
-		  (cons (cons param
-			      (car x-invocation-args))
-			default-frame-alist)
- 	          x-invocation-args (cdr x-invocation-args)))))))
+	(push (cons (nth 3 aelt) (or (nth 4 aelt) (pop x-invocation-args)))
+	      default-frame-alist))))
 
 (defun x-handle-numeric-switch (switch)
   "Handle SWITCH of the form \"-switch n\"."
   (let ((aelt (assoc switch command-line-x-option-alist)))
     (if aelt
-	(let ((param (nth 3 aelt)))
-	(setq default-frame-alist
-	      (cons (cons param
-			  (string-to-int (car x-invocation-args)))
-		    default-frame-alist)
-	      x-invocation-args
-	      (cdr x-invocation-args))))))
+	(push (cons (nth 3 aelt) (string-to-int (pop x-invocation-args)))
+	      default-frame-alist))))
 
 ;; Handle options that apply to initial frame only
 (defun x-handle-initial-switch (switch)
   (let ((aelt (assoc switch command-line-x-option-alist)))
     (if aelt
-	(let ((param (nth 3 aelt))
-	      (value (nth 4 aelt)))
-	  (if value
-	      (setq initial-frame-alist
-		    (cons (cons param value)
-			  initial-frame-alist))
-	    (setq initial-frame-alist
-		  (cons (cons param
-			      (car x-invocation-args))
-			initial-frame-alist)
-		  x-invocation-args (cdr x-invocation-args)))))))
+	(push (cons (nth 3 aelt) (or (nth 4 aelt) (pop x-invocation-args)))
+	      initial-frame-alist))))
 
 (defun x-handle-iconic (switch)
   "Make \"-iconic\" SWITCH apply only to the initial frame."
-  (setq initial-frame-alist
-	(cons '(visibility . icon) initial-frame-alist)))
+  (push '(visibility . icon) initial-frame-alist))
 
 (defun x-handle-xrm-switch (switch)
   "Handle the \"-xrm\" SWITCH."
@@ -226,18 +202,15 @@
 ;; to the option's operand; set the name of the initial frame, too.
   (or (consp x-invocation-args)
       (error "%s: missing argument to `%s' option" (invocation-name) switch))
-  (setq x-resource-name (car x-invocation-args)
-	x-invocation-args (cdr x-invocation-args))
-  (setq initial-frame-alist (cons (cons 'name x-resource-name)
-				  initial-frame-alist)))
+  (setq x-resource-name (pop x-invocation-args))
+  (push (cons 'name x-resource-name) initial-frame-alist))
 
 (defvar x-display-name nil
   "The display name specifying server and frame.")
 
 (defun x-handle-display (switch)
   "Handle the \"-display\" SWITCH."
-  (setq x-display-name (car x-invocation-args)
-	x-invocation-args (cdr x-invocation-args)))
+  (setq x-display-name (pop x-invocation-args)))
 
 (defun x-handle-args (args)
   "Process the X-related command line options in ARGS.
@@ -281,7 +254,7 @@
 		     (cons argval x-invocation-args)))
 		(funcall handler this-switch))
 	    (funcall handler this-switch))
-	(setq args (cons orig-this-switch args)))))
+	(push orig-this-switch args))))
   (nconc (nreverse args) x-invocation-args))
 
 ;;
@@ -1046,16 +1019,10 @@
 (defun xw-defined-colors (&optional frame)
   "Internal function called by `defined-colors', which see."
   (or frame (setq frame (selected-frame)))
-  (let* ((color-map-colors (mapcar (lambda (clr) (car clr)) w32-color-map))
-	 (all-colors (or color-map-colors x-colors))
-	 (this-color nil)
-	 (defined-colors nil))
-    (message "Defining colors...")
-    (while all-colors
-      (setq this-color (car all-colors)
-	    all-colors (cdr all-colors))
+  (let ((defined-colors nil))
+    (dolist (this-color (or (mapcar 'car w32-color-map) x-colors))
       (and (color-supported-p this-color frame t)
-	   (setq defined-colors (cons this-color defined-colors))))
+	   (push this-color defined-colors)))
     defined-colors))
 
 
@@ -1077,13 +1044,10 @@
 
 ;;; Make sure we have a valid resource name.
 (or (stringp x-resource-name)
-    (let (i)
-      (setq x-resource-name (invocation-name))
-
-      ;; Change any . or * characters in x-resource-name to hyphens,
-      ;; so as not to choke when we use it in X resource queries.
-      (while (setq i (string-match "[.*]" x-resource-name))
-	(aset x-resource-name i ?-))))
+    (setq x-resource-name
+	  ;; Change any . or * characters in x-resource-name to hyphens,
+	  ;; so as not to choke when we use it in X resource queries.
+	  (replace-regexp-in-string "[.*]" "-" (invocation-name))))
 
 ;; For the benefit of older Emacses (19.27 and earlier) that are sharing
 ;; the same lisp directory, don't pass the third argument unless we seem
@@ -1167,21 +1131,17 @@
 	(setq initial-frame-alist (append initial-frame-alist parsed))
 	;; The size parms apply to all frames.
 	(if (assq 'height parsed)
-	    (setq default-frame-alist
-		  (cons (cons 'height (cdr (assq 'height parsed)))
-			default-frame-alist)))
+	    (push (cons 'height (cdr (assq 'height parsed)))
+		  default-frame-alist))
 	(if (assq 'width parsed)
-	    (setq default-frame-alist
-		  (cons (cons 'width (cdr (assq 'width parsed)))
-			default-frame-alist))))))
+	    (push (cons 'width (cdr (assq 'width parsed)))
+		  default-frame-alist)))))
 
 ;; Check the reverseVideo resource.
 (let ((case-fold-search t))
   (let ((rv (x-get-resource "reverseVideo" "ReverseVideo")))
-    (if (and rv
-	     (string-match "^\\(true\\|yes\\|on\\)$" rv))
-	(setq default-frame-alist
-	      (cons '(reverse . t) default-frame-alist)))))
+    (if (and rv (string-match "^\\(true\\|yes\\|on\\)$" rv))
+	(push '(reverse . t) default-frame-alist))))
 
 (defun x-win-suspend-error ()
   "Report an error when a suspend is attempted."
@@ -1245,7 +1205,7 @@
 	 (and chosen-font (list chosen-font)))
      (x-popup-menu
       last-nonmenu-event
-    ;; Append list of fontsets currently defined.
+      ;; Append list of fontsets currently defined.
       ;; Conditional on new-fontset so bootstrapping works on non-GUI compiles
       (if (fboundp 'new-fontset)
       (append w32-fixed-font-alist (list (generate-fontset-menu)))))))
@@ -1269,5 +1229,5 @@
         (tiff "libtiff3.dll" "libtiff.dll")
         (gif "libungif.dll")))
 
-;;; arch-tag: 69fb1701-28c2-4890-b351-3d1fe4b4f166
+;; arch-tag: 69fb1701-28c2-4890-b351-3d1fe4b4f166
 ;;; w32-win.el ends here
--- a/lisp/textmodes/refill.el	Mon Jan 24 03:43:01 2005 +0000
+++ b/lisp/textmodes/refill.el	Mon Jan 24 22:34:31 2005 +0000
@@ -1,6 +1,6 @@
 ;;; refill.el --- `auto-fill' by refilling paragraphs on changes
 
-;; Copyright (C) 2000, 2003  Free Software Foundation, Inc.
+;; Copyright (C) 2000, 2003, 2005  Free Software Foundation, Inc.
 
 ;; Author: Dave Love <fx@gnu.org>
 ;; Maintainer: Miles Bader <miles@gnu.org>
@@ -85,6 +85,8 @@
 
 ;;; Code:
 
+(eval-when-compile (require 'cl))
+
 (defgroup refill nil
   "Refilling paragraphs on changes."
   :group 'fill)
@@ -169,40 +171,36 @@
   "Post-command function to do refilling (conditionally)."
   (when refill-doit ; there was a change
     ;; There's probably scope for more special cases here...
-    (if (eq this-command 'self-insert-command)
-	;; Treat self-insertion commands specially, since they don't
-	;; always reset `refill-doit' -- for self-insertion commands that
-	;; *don't* cause a refill, we want to leave it turned on so that
-	;; any subsequent non-modification command will cause a refill.
-	(when (aref auto-fill-chars (char-before))
-	  ;; Respond to the same characters as auto-fill (other than
-	  ;; newline, covered below).
-	  (refill-fill-paragraph-at refill-doit)
-	  (setq refill-doit nil))
-      (cond
-       ((or (eq this-command 'quoted-insert)
-	    (eq this-command 'fill-paragraph)
-	    (eq this-command 'fill-region))
-	nil)
-       ((or (eq this-command 'newline)
-	    (eq this-command 'newline-and-indent)
-	    (eq this-command 'open-line))
-	;; Don't zap what was just inserted.
-	(save-excursion
-	  (beginning-of-line)		; for newline-and-indent
-	  (skip-chars-backward "\n")
-	  (save-restriction
-	    (narrow-to-region (point-min) (point))
-	    (refill-fill-paragraph-at refill-doit)))
-	(widen)
-	(save-excursion
-	  (skip-chars-forward "\n")
-	  (save-restriction
-	    (narrow-to-region (line-beginning-position) (point-max))
-	    (refill-fill-paragraph-at refill-doit))))
-       (t
-	(refill-fill-paragraph-at refill-doit)))
-      (setq refill-doit nil))))
+    (case this-command
+      (self-insert-command
+       ;; Treat self-insertion commands specially, since they don't
+       ;; always reset `refill-doit' -- for self-insertion commands that
+       ;; *don't* cause a refill, we want to leave it turned on so that
+       ;; any subsequent non-modification command will cause a refill.
+       (when (aref auto-fill-chars (char-before))
+	 ;; Respond to the same characters as auto-fill (other than
+	 ;; newline, covered below).
+	 (refill-fill-paragraph-at refill-doit)
+	 (setq refill-doit nil)))
+      ((quoted-insert fill-paragraph fill-region) nil)
+      ((newline newline-and-indent open-line indent-new-comment-line
+	reindent-then-newline-and-indent)
+       ;; Don't zap what was just inserted.
+       (save-excursion
+	 (beginning-of-line)		; for newline-and-indent
+	 (skip-chars-backward "\n")
+	 (save-restriction
+	   (narrow-to-region (point-min) (point))
+	   (refill-fill-paragraph-at refill-doit)))
+       (widen)
+       (save-excursion
+	 (skip-chars-forward "\n")
+	 (save-restriction
+	   (narrow-to-region (line-beginning-position) (point-max))
+	   (refill-fill-paragraph-at refill-doit))))
+      (t
+       (refill-fill-paragraph-at refill-doit)))
+    (setq refill-doit nil)))
 
 (defun refill-pre-command-function ()
   "Pre-command function to do refilling (conditionally)."
@@ -213,7 +211,7 @@
     (refill-fill-paragraph-at refill-doit)
     (setq refill-doit nil)))
 
-(defvar refill-late-fill-paragraph-function nil)
+(defvar refill-saved-state nil)
 
 ;;;###autoload
 (define-minor-mode refill-mode
@@ -228,16 +226,18 @@
   (when refill-ignorable-overlay
     (delete-overlay refill-ignorable-overlay)
     (kill-local-variable 'refill-ignorable-overlay))
-  (when (local-variable-p 'refill-late-fill-paragraph-function)
-    (setq fill-paragraph-function refill-late-fill-paragraph-function)
-    (kill-local-variable 'refill-late-fill-paragraph-function))
+  (when (local-variable-p 'refill-saved-state)
+    (dolist (x refill-saved-state)
+      (set (make-local-variable (car x)) (cdr x)))
+    (kill-local-variable 'refill-saved-state))
   (if refill-mode
       (progn
 	(add-hook 'after-change-functions 'refill-after-change-function nil t)
 	(add-hook 'post-command-hook 'refill-post-command-function nil t)
 	(add-hook 'pre-command-hook 'refill-pre-command-function nil t)
-	(set (make-local-variable 'refill-late-fill-paragraph-function)
-	     fill-paragraph-function)
+	(set (make-local-variable 'refill-saved-state)
+	     (mapcar (lambda (s) (cons s (symbol-value s)))
+		     '(fill-paragraph-function auto-fill-function)))
 	;; This provides the test for recursive paragraph filling.
 	(set (make-local-variable 'fill-paragraph-function)
 	     'refill-fill-paragraph)
@@ -257,5 +257,5 @@
 
 (provide 'refill)
 
-;;; arch-tag: 2c4ce9e8-1daa-4a3b-b6f8-fd6ac5bf6138
+;; arch-tag: 2c4ce9e8-1daa-4a3b-b6f8-fd6ac5bf6138
 ;;; refill.el ends here
--- a/lispref/ChangeLog	Mon Jan 24 03:43:01 2005 +0000
+++ b/lispref/ChangeLog	Mon Jan 24 22:34:31 2005 +0000
@@ -1,3 +1,11 @@
+2005-01-23  Kim F. Storm  <storm@cua.dk>
+
+	* windows.texi (Window Start): Fix `pos-visible-in-window-p'
+	return value.  Third element FULLY replaced by PARTIAL which
+	specifies number of invisible pixels if row is only partially visible.
+	(Textual Scrolling): Mention auto-window-vscroll.
+	(Vertical Scrolling): New defvar auto-window-vscroll.
+
 2005-01-16  Luc Teirlinck  <teirllm@auburn.edu>
 
 	* keymaps.texi (Changing Key Bindings): `suppress-keymap' now uses
--- a/lispref/windows.texi	Mon Jan 24 03:43:01 2005 +0000
+++ b/lispref/windows.texi	Mon Jan 24 22:34:31 2005 +0000
@@ -1345,10 +1345,12 @@
 If @var{position} is visible, @code{pos-visible-in-window-p} returns
 @code{t} if @var{partially} is @code{nil}; if @var{partially} is
 non-@code{nil}, it returns a list of the form @code{(@var{x} @var{y}
-@var{fully})}, where @var{x} and @var{y} are the pixel coordinates
-relative to the top left corner of the window, and @var{fully} is
-@code{t} if the character after @var{position} is fully visible and
-@code{nil} otherwise.
+@var{partial})}, where @var{x} and @var{y} are the pixel coordinates
+relative to the top left corner of the window, and @var{partial} is
+@code{nil} if the character after @var{position} is fully visible;
+otherwise it is a cons @code{(@var{rtop} . @var{rbot})} where the
+@var{rtop} and @var{rbot} specify the number of invisible pixels at
+the top and bottom of the row at @var{position}.
 
 Here is an example:
 
@@ -1397,6 +1399,12 @@
 buffer is different from the buffer that is displayed in the selected
 window.  @xref{Current Buffer}.
 
+  If the window contains a row which is taller than the height of the
+window (for example in the presense of a large image), the scroll
+functions will adjust the window vscroll to scroll the partially
+visible row.  To disable this feature, Lisp code may bind the variable
+`auto-window-vscroll' to @code{nil} (@pxref{Vertical Scrolling}).
+
 @deffn Command scroll-up &optional count
 This function scrolls the text in the selected window upward
 @var{count} lines.  If @var{count} is negative, scrolling is actually
@@ -1622,6 +1630,13 @@
 pixels.  In this case, the return value is @var{lines}.
 @end defun
 
+@defvar auto-window-vscroll
+If this variable is non-@code{nil}, the line-move, scroll-up, and
+scroll-down functions will automatically modify the window vscroll to
+scroll through display rows that are taller that the height of the
+window, for example in the presense of large images.
+@end defvar
+
 @node Horizontal Scrolling
 @section Horizontal Scrolling
 @cindex horizontal scrolling
--- a/man/ChangeLog	Mon Jan 24 03:43:01 2005 +0000
+++ b/man/ChangeLog	Mon Jan 24 22:34:31 2005 +0000
@@ -1,3 +1,7 @@
+2005-01-24  David Kastrup  <dak@gnu.org>
+
+	* faq.texi: Update AUCTeX version info.
+
 2005-01-16  Xavier Maillard <zedek@gnu-rox.org> (tiny change)
 
 	* gnus-faq.texi ([4.1]): Typo.
--- a/man/faq.texi	Mon Jan 24 03:43:01 2005 +0000
+++ b/man/faq.texi	Mon Jan 24 22:34:31 2005 +0000
@@ -4000,7 +4000,7 @@
 @email{dak@@gnu.org, David Kastrup}
 
 @item Latest version
-11.52
+11.54
 
 @item Distribution
 @uref{ftp://ftp.gnu.org/pub/gnu/auctex/}
--- a/src/ChangeLog	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/ChangeLog	Mon Jan 24 22:34:31 2005 +0000
@@ -1,3 +1,53 @@
+2005-01-24  Kim F. Storm  <storm@cua.dk>
+
+	* xdisp.c (move_it_by_lines): If we move forward after going too
+	far back, cancel move if end position is same as start position.
+
+2005-01-24  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* dispextern.h (struct glyph_string): New members clip_head and
+	clip_tail.
+
+	* xdisp.c (get_glyph_string_clip_rect): Restrict horizontal clip
+	region to the area between clip_head and clip_tail.
+	(draw_glyphs): Record the area that need to be actually redrawn to
+	the new variables clip_head and clip_tail when there are
+	overhangs.  Set values of these variables to the corresponding
+	members in struct glyph_string.  Refine x coordinates for
+	notice_overwritten_cursor using clip_head and clip_tail.
+
+	* macgui.h (STORE_XCHARSETSTRUCT): New macro.
+
+	* macterm.c (mac_compute_glyph_string_overhangs): Implement with
+	QDTextBounds.
+	(x_draw_glyph_string): Don't fill the background of the successor
+	of a glyph with a right overhang if the successor will draw a cursor.
+	(XLoadQueryFont): Obtain font metrics using QDTextBounds.
+	(x_redisplay_interface): Add entry for compute_glyph_string_overhangs.
+
+2005-01-24  Kim F. Storm  <storm@cua.dk>
+
+	* window.c (window_scroll_pixel_based): Fix scrolling in the wrong
+	direction if window height was smaller than next-screen-context-lines.
+	Now always scroll at least one line in the requested direction.
+	Ensure that we actually do scroll backwards when requested to do so.
+
+	* xdisp.c (redisplay_window): Only try to make cursor line fully
+	visible once (to avoid redisplay loop).
+
+2005-01-23  Kim F. Storm  <storm@cua.dk>
+
+	* window.c (Fpos_visible_in_window_p): Simplify return value for
+	partially visible rows.
+	(window_scroll_pixel_based): Adapt to that change.
+
+	* window.c (window_scroll_pixel_based): Force moving to next line
+	if scrolling doesn't move start point, e.g. if looking at tall image.
+
+	* xdisp.c (pos_visible_p): Return 0 if non-interactive.
+	Clear last_height before calling line_bottom_y to get real height.
+	Fix calculation of y.
+
 2005-01-22  Steven Tamm  <steventamm@mac.com>
 
 	* s/darwin.h: Removed PTY_ITERATION from here.
--- a/src/dispextern.h	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/dispextern.h	Mon Jan 24 22:34:31 2005 +0000
@@ -1193,6 +1193,11 @@
   /* Slice */
   struct glyph_slice slice;
 
+  /* Non-null means the horizontal clipping region starts from the
+     left edge of *clip_head, and ends with the right edge of
+     *clip_tail, not including their overhangs.  */
+  struct glyph_string *clip_head, *clip_tail;
+
   struct glyph_string *next, *prev;
 };
 
--- a/src/indent.c	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/indent.c	Mon Jan 24 22:34:31 2005 +0000
@@ -1,6 +1,6 @@
 /* Indentation functions.
-   Copyright (C) 1985,86,87,88,93,94,95,98,2000,01,02,03,2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
+     2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -340,7 +340,9 @@
 Ignores finite width of frame, which means that this function may return
 values greater than (frame-width).
 Whether the line is visible (if `selective-display' is t) has no effect;
-however, ^M is treated as end of line when `selective-display' is t.  */)
+however, ^M is treated as end of line when `selective-display' is t.
+Text that has an invisible property is considered as having width 0, unless
+`buffer-invisibility-spec' specifies that it is replaced by an ellipsis.  */)
      ()
 {
   Lisp_Object temp;
--- a/src/macgui.h	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/macgui.h	Mon Jan 24 22:34:31 2005 +0000
@@ -92,6 +92,13 @@
   int descent;
 } XCharStruct;
 
+#define STORE_XCHARSTRUCT(xcs, w, bds)			\
+  ((xcs).width = (w),					\
+   (xcs).lbearing = (bds).left,				\
+   (xcs).rbearing = (bds).right,			\
+   (xcs).ascent = -(bds).top,				\
+   (xcs).descent = (bds).bottom)
+
 struct MacFontStruct {
   char *fontname;
 
--- a/src/macterm.c	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/macterm.c	Mon Jan 24 22:34:31 2005 +0000
@@ -1997,20 +1997,33 @@
 mac_compute_glyph_string_overhangs (s)
      struct glyph_string *s;
 {
-#if 0
-  /* MAC_TODO: XTextExtents16 does nothing yet... */
-
-  if (s->cmp == NULL
-      && s->first_glyph->type == CHAR_GLYPH)
-    {
-      XCharStruct cs;
-      int direction, font_ascent, font_descent;
-      XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
-		      &font_ascent, &font_descent, &cs);
-      s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
-      s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
-    }
-#endif
+  Rect r;
+  MacFontStruct *font = s->font;
+
+  TextFont (font->mac_fontnum);
+  TextSize (font->mac_fontsize);
+  TextFace (font->mac_fontface);
+
+  if (s->two_byte_p)
+    QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
+  else
+    {
+      int i;
+      char *buf = xmalloc (s->nchars);
+
+      if (buf == NULL)
+	SetRect (&r, 0, 0, 0, 0);
+      else
+	{
+	  for (i = 0; i < s->nchars; ++i)
+	    buf[i] = s->char2b[i].byte2;
+	  QDTextBounds (s->nchars, buf, &r);
+	  xfree (buf);
+	}
+    }
+
+  s->right_overhang = r.right > s->width ? r.right - s->width : 0;
+  s->left_overhang = r.left < 0 ? -r.left : 0;
 }
 
 
@@ -3078,10 +3091,12 @@
 {
   int relief_drawn_p = 0;
 
-  /* If S draws into the background of its successor, draw the
-     background of the successor first so that S can draw into it.
-     This makes S->next use XDrawString instead of XDrawImageString.  */
-  if (s->next && s->right_overhang && !s->for_overlaps_p)
+  /* If S draws into the background of its successor that does not
+     draw a cursor, draw the background of the successor first so that
+     S can draw into it.  This makes S->next use XDrawString instead
+     of XDrawImageString.  */
+  if (s->next && s->right_overhang && !s->for_overlaps_p
+      && s->next->hl != DRAW_CURSOR)
     {
       xassert (s->next->img == NULL);
       x_set_glyph_string_gc (s->next);
@@ -6780,30 +6795,40 @@
        returns 15 for 12-point Monaco! */
     char_width = CharWidth ('m');
 
-  font->max_bounds.rbearing = char_width;
-  font->max_bounds.lbearing = 0;
-  font->max_bounds.width = char_width;
-  font->max_bounds.ascent = the_fontinfo.ascent;
-  font->max_bounds.descent = the_fontinfo.descent;
-
-  font->min_bounds = font->max_bounds;
-
-  if (is_two_byte_font || CharWidth ('m') == CharWidth ('i'))
-    font->per_char = NULL;
+  if (is_two_byte_font)
+    {
+      font->per_char = NULL;
+
+      if (fontface & italic)
+	font->max_bounds.rbearing = char_width + 1;
+      else
+	font->max_bounds.rbearing = char_width;
+      font->max_bounds.lbearing = 0;
+      font->max_bounds.width = char_width;
+      font->max_bounds.ascent = the_fontinfo.ascent;
+      font->max_bounds.descent = the_fontinfo.descent;
+
+      font->min_bounds = font->max_bounds;
+    }
   else
     {
       font->per_char = (XCharStruct *)
 	xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
       {
-        int c, min_width, max_width;
+	int c, min_width, max_width;
+	Rect char_bounds, min_bounds, max_bounds;
+	char ch;
 
 	min_width = max_width = char_width;
+	SetRect (&min_bounds, -32767, -32767, 32767, 32767);
+	SetRect (&max_bounds, 0, 0, 0, 0);
         for (c = 0x20; c <= 0xff; c++)
           {
-	    font->per_char[c - 0x20] = font->max_bounds;
-	    char_width = CharWidth (c);
-	    font->per_char[c - 0x20].width = char_width;
-	    font->per_char[c - 0x20].rbearing = char_width;
+	    ch = c;
+	    char_width = CharWidth (ch);
+	    QDTextBounds (1, &ch, &char_bounds);
+	    STORE_XCHARSTRUCT (font->per_char[c - 0x20],
+			       char_width, char_bounds);
 	    /* Some Japanese fonts (in SJIS encoding) return 0 as the
 	       character width of 0x7f.  */
 	    if (char_width > 0)
@@ -6811,9 +6836,25 @@
 		min_width = min (min_width, char_width);
 		max_width = max (max_width, char_width);
 	      }
-            }
-	font->min_bounds.width = min_width;
-	font->max_bounds.width = max_width;
+	    if (!EmptyRect (&char_bounds))
+	      {
+		SetRect (&min_bounds,
+			 max (min_bounds.left, char_bounds.left),
+			 max (min_bounds.top, char_bounds.top),
+			 min (min_bounds.right, char_bounds.right),
+			 min (min_bounds.bottom, char_bounds.bottom));
+		UnionRect (&max_bounds, &char_bounds, &max_bounds);
+	      }
+	  }
+	STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
+	STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
+	if (min_width == max_width
+	    && max_bounds.left >= 0 && max_bounds.right <= max_width)
+	  {
+	    /* Fixed width and no overhangs.  */
+	    xfree (font->per_char);
+	    font->per_char = NULL;
+	  }
       }
     }
 
@@ -9719,7 +9760,7 @@
   0, /* destroy_fringe_bitmap */
   mac_per_char_metric,
   mac_encode_char,
-  NULL, /* mac_compute_glyph_string_overhangs */
+  mac_compute_glyph_string_overhangs,
   x_draw_glyph_string,
   mac_define_frame_cursor,
   mac_clear_frame_area,
--- a/src/window.c	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/window.c	Mon Jan 24 22:34:31 2005 +0000
@@ -333,11 +333,10 @@
 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
 
 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
-return value is a list (X Y FULLY [RTOP RBOT]) where X and Y are the pixel
-coordinates relative to the top left corner of the window, and FULLY is t if the
-character after POS is fully visible and nil otherwise.  If FULLY is nil,
-RTOP and RBOT are the number of pixels invisible at the top and bottom row
-of the window.  */)
+return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates
+relative to the top left corner of the window. PARTIAL is nil if the character
+after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP
+and RBOT are the number of pixels invisible at the top and bottom of the row.  */)
      (pos, window, partially)
      Lisp_Object pos, window, partially;
 {
@@ -376,12 +375,10 @@
   if (!NILP (in_window) && !NILP (partially))
     in_window = Fcons (make_number (x),
 		       Fcons (make_number (y),
-			      Fcons (fully_p ? Qt : Qnil,
-				     (fully_p
-				      ? Qnil
-				      : Fcons (make_number (rtop),
-					       Fcons (make_number (rbot),
-						      Qnil))))));
+			      Fcons ((fully_p ? Qnil
+				     : Fcons (make_number (rtop),
+					      make_number (rbot))),
+				     Qnil)));
   return in_window;
 }
 
@@ -4578,21 +4575,23 @@
     }
   else if (auto_window_vscroll_p)
     {
-      if (NILP (XCAR (XCDR (XCDR (tem)))))
+      if (tem = XCAR (XCDR (XCDR (tem))), CONSP (tem))
 	{
 	  int px;
 	  int dy = WINDOW_FRAME_LINE_HEIGHT (w);
 	  if (whole)
-	    dy = window_box_height (w) - next_screen_context_lines * dy;
+	    dy = max ((window_box_height (w)
+		       - next_screen_context_lines * dy),
+		      dy);
 	  dy *= n;
 
-	  if (n < 0 && (px = XINT (Fnth (make_number (3), tem))) > 0)
+	  if (n < 0 && (px = XINT (XCAR (tem))) > 0)
 	    {
 	      px = max (0, -w->vscroll - min (px, -dy));
 	      Fset_window_vscroll (window, make_number (px), Qt);
 	      return;
 	    }
-	  if (n > 0 && (px = XINT (Fnth (make_number (4), tem))) > 0)
+	  if (n > 0 && (px = XINT (XCDR (tem))) > 0)
 	    {
 	      px = max (0, -w->vscroll + min (px, dy));
 	      Fset_window_vscroll (window, make_number (px), Qt);
@@ -4618,18 +4617,34 @@
   start_display (&it, w, start);
   if (whole)
     {
-      int screen_full = (window_box_height (w)
-			 - next_screen_context_lines * FRAME_LINE_HEIGHT (it.f));
-      int dy = n * screen_full;
+      int start_pos = IT_CHARPOS (it);
+      int dy = WINDOW_FRAME_LINE_HEIGHT (w);
+      dy = max ((window_box_height (w)
+		 - next_screen_context_lines * dy),
+		dy) * n;
 
       /* Note that move_it_vertically always moves the iterator to the
          start of a line.  So, if the last line doesn't have a newline,
 	 we would end up at the start of the line ending at ZV.  */
       if (dy <= 0)
-	move_it_vertically_backward (&it, -dy);
+	{
+	  move_it_vertically_backward (&it, -dy);
+	  /* Ensure we actually does move, e.g. in case we are currently
+	     looking at an image that is taller that the window height.  */
+	  while (start_pos == IT_CHARPOS (it)
+		 && start_pos > BEGV)
+	    move_it_by_lines (&it, -1, 1);
+	}
       else if (dy > 0)
-	move_it_to (&it, ZV, -1, it.current_y + dy, -1,
-		    MOVE_TO_POS | MOVE_TO_Y);
+	{
+	  move_it_to (&it, ZV, -1, it.current_y + dy, -1,
+		      MOVE_TO_POS | MOVE_TO_Y);
+	  /* Ensure we actually does move, e.g. in case we are currently
+	     looking at an image that is taller that the window height.  */
+	  while (start_pos == IT_CHARPOS (it)
+		 && start_pos < ZV)
+	    move_it_by_lines (&it, 1, 1);
+	}
     }
   else
     move_it_by_lines (&it, n, 1);
--- a/src/xdisp.c	Mon Jan 24 03:43:01 2005 +0000
+++ b/src/xdisp.c	Mon Jan 24 22:34:31 2005 +0000
@@ -1259,16 +1259,18 @@
 {
   struct it it;
   struct text_pos top;
-  int visible_p;
+  int visible_p = 0;
   struct buffer *old_buffer = NULL;
 
+  if (noninteractive)
+    return visible_p;
+
   if (XBUFFER (w->buffer) != current_buffer)
     {
       old_buffer = current_buffer;
       set_buffer_internal_1 (XBUFFER (w->buffer));
     }
 
-  visible_p = 0;
   SET_TEXT_POS_FROM_MARKER (top, w->start);
 
   /* Compute exact mode line heights, if requested.  */
@@ -1293,7 +1295,7 @@
   if (IT_CHARPOS (it) >= charpos)
     {
       int top_y = it.current_y;
-      int bottom_y = line_bottom_y (&it);
+      int bottom_y = (last_height = 0, line_bottom_y (&it));
       int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
 
       if (top_y < window_top_y)
@@ -1303,7 +1305,7 @@
       if (visible_p && x)
 	{
 	  *x = it.current_x;
-	  *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
+	  *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
 	  if (rtop)
 	    {
 	      *rtop = max (0, window_top_y - top_y);
@@ -1787,6 +1789,24 @@
       r.height = s->row->visible_height;
     }
 
+  if (s->clip_head)
+    if (r.x < s->clip_head->x)
+      {
+	if (r.width >= s->clip_head->x - r.x)
+	  r.width -= s->clip_head->x - r.x;
+	else
+	  r.width = 0;
+	r.x = s->clip_head->x;
+      }
+  if (s->clip_tail)
+    if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
+      {
+	if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
+	  r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
+	else
+	  r.width = 0;
+      }
+
   /* If S draws overlapping rows, it's sufficient to use the top and
      bottom of the window for clipping because this glyph string
      intentionally draws over other lines.  */
@@ -6505,11 +6525,15 @@
       it->current_y -= it2.current_y;
       it->current_x = it->hpos = 0;
 
-      /* If we moved too far, move IT some lines forward.  */
+      /* If we moved too far back, move IT some lines forward.  */
       if (it2.vpos > -dvpos)
 	{
 	  int delta = it2.vpos + dvpos;
+	  it2 = *it;
 	  move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
+	  /* Move back again if we got too far ahead.  */
+	  if (IT_CHARPOS (*it) >= start_charpos)
+	    *it = it2;
 	}
     }
 }
@@ -12332,6 +12356,8 @@
       /* If centering point failed to make the whole line visible,
 	 put point at the top instead.  That has to make the whole line
 	 visible, if it can be done.  */
+      if (centering_position == 0)
+	goto done;
       clear_glyph_matrix (w->desired_matrix);
       centering_position = 0;
       goto point_at_top;
@@ -18338,6 +18364,7 @@
 {
   struct glyph_string *head, *tail;
   struct glyph_string *s;
+  struct glyph_string *clip_head = NULL, *clip_tail = NULL;
   int last_x, area_width;
   int x_reached;
   int i, j;
@@ -18406,6 +18433,7 @@
 	  start = i;
 	  compute_overhangs_and_x (t, head->x, 1);
 	  prepend_glyph_string_lists (&head, &tail, h, t);
+	  clip_head = head;
 	}
 
       /* Prepend glyph strings for glyphs in front of the first glyph
@@ -18418,6 +18446,7 @@
       i = left_overwriting (head);
       if (i >= 0)
 	{
+	  clip_head = head;
 	  BUILD_GLYPH_STRINGS (i, start, h, t,
 			       DRAW_NORMAL_TEXT, dummy_x, last_x);
 	  for (s = h; s; s = s->next)
@@ -18437,6 +18466,7 @@
 			       DRAW_NORMAL_TEXT, x, last_x);
 	  compute_overhangs_and_x (h, tail->x + tail->width, 0);
 	  append_glyph_string_lists (&head, &tail, h, t);
+	  clip_tail = tail;
 	}
 
       /* Append glyph strings for glyphs following the last glyph
@@ -18447,6 +18477,7 @@
       i = right_overwriting (tail);
       if (i >= 0)
 	{
+	  clip_tail = tail;
 	  BUILD_GLYPH_STRINGS (end, i, h, t,
 			       DRAW_NORMAL_TEXT, x, last_x);
 	  for (s = h; s; s = s->next)
@@ -18454,6 +18485,12 @@
 	  compute_overhangs_and_x (h, tail->x + tail->width, 0);
 	  append_glyph_string_lists (&head, &tail, h, t);
 	}
+      if (clip_head || clip_tail)
+	for (s = head; s; s = s->next)
+	  {
+	    s->clip_head = clip_head;
+	    s->clip_tail = clip_tail;
+	  }
     }
 
   /* Draw all strings.  */
@@ -18467,8 +18504,9 @@
 	 completely. */
       && !overlaps_p)
     {
-      int x0 = head ? head->x : x;
-      int x1 = tail ? tail->x + tail->background_width : x;
+      int x0 = clip_head ? clip_head->x : (head ? head->x : x);
+      int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
+		: (tail ? tail->x + tail->background_width : x));
 
       int text_left = window_box_left (w, TEXT_AREA);
       x0 -= text_left;