diff src/window.c @ 34991:ad94ea6e6549

(Frecenter): Handle centering in graphical frames specially. Centering on the basis of line counts doesn't work reliably with variable-height lines.
author Gerd Moellmann <gerd@gnu.org>
date Tue, 02 Jan 2001 15:32:31 +0000
parents 9af4ffb4d11a
children ad30dea71688
line wrap: on
line diff
--- a/src/window.c	Tue Jan 02 14:32:37 2001 +0000
+++ b/src/window.c	Tue Jan 02 15:32:31 2001 +0000
@@ -4488,15 +4488,14 @@
   (arg)
      register Lisp_Object arg;
 {
-  register struct window *w = XWINDOW (selected_window);
-  register int ht = displayed_window_lines (w);
-  struct position pos;
+  struct window *w = XWINDOW (selected_window);
   struct buffer *buf = XBUFFER (w->buffer);
   struct buffer *obuf = current_buffer;
+  int center_p = 0;
+  int charpos, bytepos;
 
   if (NILP (arg))
     {
-      extern int frame_garbaged;
       int i;
 
       /* Invalidate pixel data calculated for all compositions.  */
@@ -4505,31 +4504,61 @@
 
       Fredraw_frame (w->frame);
       SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
-      XSETFASTINT (arg, ht / 2);
+      center_p = 1;
     }
   else if (CONSP (arg)) /* Just C-u. */
-    {
-      XSETFASTINT (arg, ht / 2);
-    }
+    center_p = 1;
   else
     {
       arg = Fprefix_numeric_value (arg);
       CHECK_NUMBER (arg, 0);
     }
 
-  if (XINT (arg) < 0)
-    XSETINT (arg, XINT (arg) + ht);
-
   set_buffer_internal (buf);
-  pos = *vmotion (PT, - XINT (arg), w);
-
-  set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
-  w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
-			   || FETCH_BYTE (pos.bytepos - 1) == '\n')
-			  ? Qt : Qnil);
+
+  /* Handle centering on a gfaphical frame specially.  Such frames can
+     have variable-height lines and centering point on the basis of
+     line counts would lead to strange effects.  */
+  if (center_p && FRAME_WINDOW_P (XFRAME (w->frame)))
+    {
+      struct it it;
+      struct text_pos pt;
+      
+      SET_TEXT_POS (pt, PT, PT_BYTE);
+      start_display (&it, w, pt);
+      move_it_vertically (&it, - it.last_visible_y / 2);
+      charpos = IT_CHARPOS (it);
+      bytepos = IT_BYTEPOS (it);
+    }
+  else
+    {
+      struct position pos;
+      
+      if (center_p)
+	{
+	  int ht = displayed_window_lines (w);
+	  arg = make_number (ht / 2);
+	}
+      else if (XINT (arg) < 0)
+	{
+	  int ht = displayed_window_lines (w);
+	  XSETINT (arg, XINT (arg) + ht);
+	}
+      
+      pos = *vmotion (PT, - XINT (arg), w);
+      charpos = pos.bufpos;
+      bytepos = pos.bytepos;
+    }
+
+  /* Set the new window start.  */
+  set_marker_both (w->start, w->buffer, charpos, bytepos);
   w->force_start = Qt;
+  if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
+    w->start_at_line_beg = Qt;
+  else
+    w->start_at_line_beg = Qnil;
+  
   set_buffer_internal (obuf);
-
   return Qnil;
 }