From xemacs-m  Sun Mar 23 02:44:30 1997
Received: from GS213.SP.CS.CMU.EDU (GS213.SP.CS.CMU.EDU [128.2.209.183])
	by xemacs.org (8.8.5/8.8.5) with SMTP id CAA04603
	for <xemacs-beta@xemacs.org>; Sun, 23 Mar 1997 02:44:29 -0600 (CST)
Received: by GS213.SP.CS.CMU.EDU (AIX 3.2/UCB 5.64/4.03)
          id AA12390; Sun, 23 Mar 1997 03:44:25 -0500
Date: Sun, 23 Mar 1997 03:44:25 -0500
Message-Id: <9703230844.AA12390@GS213.SP.CS.CMU.EDU>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
From: Darrell Kindred <dkindred@cmu.edu>
To: xemacs-beta@xemacs.org
Subject: large-image recentering patch 
Organization: Carnegie Mellon University School of Computer Science
X-Mailer: VM 6.22 under 19.15 XEmacs Lucid (beta103)

In the presence of large images, C-l and other recentering
functions can put point entirely out of view.  To see this,
make a 6-line window and do
   M-x w3-fetch http://www.xemacs.org
in it.  Move point to the word "powerful" and press C-l.
That line is now out of view.  This is no good.  

The specification of start_with_line_at_pixpos is, "For
window W, what does the starting position have to be so that
the line containing POINT will cover pixel position
PIXPOS."  However, in the presence of variable-height lines
(and without pixel-based scrolling), it's sometimes
impossible to get the line to cover PIXPOS.  The current
version will put the line below PIXPOS in this case; my
patch changes it so the line goes *above* PIXPOS.  This
guarantees that the line will be visible.

I'm fairly confident in this patch, so if you'd like to put
it in 19.15, that's okay with me.

- Darrell

--- src/redisplay.c.orig	Sun Mar 16 00:56:22 1997
+++ src/redisplay.c	Sun Mar 23 03:41:39 1997
@@ -6635,7 +6635,8 @@
 {
   struct buffer *b = XBUFFER (w->buffer);
   int cur_elt;
-  Bufpos cur_pos;
+  Bufpos cur_pos, prev_pos = point;
+  int point_line_height;
   int pixheight = pixpos - WINDOW_TEXT_TOP (w);
 
   validate_line_start_cache (w);
@@ -6645,6 +6646,9 @@
   /* #### See comment in update_line_start_cache about big minibuffers. */
   if (cur_elt < 0)
     return point;
+
+  point_line_height = Dynarr_atp (w->line_start_cache, cur_elt)->height;
+
   while (1)
     {
       cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
@@ -6656,7 +6660,12 @@
       if (pixheight < 0)
 	{
 	  w->line_cache_validation_override--;
-	  return cur_pos;
+	  if (-pixheight > point_line_height)
+	    /* We can't make the target line cover pixpos, so put it
+	       above pixpos.  That way it will at least be visible. */
+	    return prev_pos;  
+	  else
+	    return cur_pos;
 	}
 
       cur_elt--;
@@ -6682,6 +6691,7 @@
 	  cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
 	  assert (cur_elt >= 0);
 	}
+      prev_pos = cur_pos;
     }
 }
 

