(pos_fully_visible_in_window_p):
authorMiles Bader <miles@gnu.org>
Sat, 21 Oct 2000 07:57:20 +0000 (07:57 +0000)
committerMiles Bader <miles@gnu.org>
Sat, 21 Oct 2000 07:57:20 +0000 (07:57 +0000)
  New function.
(Fpos_visible_in_window_p):
  Add FULLY argument.
  Use pos_fully_visible_in_window_p.
(window_scroll_pixel_based, window_scroll_line_based):
  Update calls to Fpos_visible_in_window_p.

src/window.c

index c196937..215ceea 100644 (file)
@@ -290,13 +290,52 @@ DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1,
   return (MINI_WINDOW_P (w) ? Qt : Qnil);
 }
 
+
+/* Return true if POS is fully visible in the window W.  If W's end
+   position is not known, then return false.  */
+
+static int
+pos_fully_visible_in_window_p (pos, w)
+     int pos;
+     struct window *w;
+{
+  struct glyph_row *first_row = &w->desired_matrix->rows[0];
+  struct glyph_row *last_row;
+
+  if (pos < first_row->start.pos.charpos)
+    /* POS is before the beginning of W.  */
+    return 0;
+  else if (pos < first_row->end.pos.charpos)
+    /* POS is on the first row of W, so see if that row is fully visible.  */
+    return !MATRIX_ROW_PARTIALLY_VISIBLE_P (first_row);
+
+  if (NILP (w->window_end_valid))
+    /* We can't determine where the end is, so we don't know.  */
+    return 0;
+
+  last_row = &w->desired_matrix->rows[XFASTINT (w->window_end_vpos)];
+
+  if (pos < last_row->start.pos.charpos)
+    /* POS is somewhere in the middle of the window, not on the first or
+       last row, so it must be visible.  */
+    return 1;
+  else if (pos >= last_row->end.pos.charpos)
+    /* POS is after the end of W.  */
+    return 0;
+  else
+    /* POS is on the last row of W, so see if that row is fully visible.  */
+    return !MATRIX_ROW_PARTIALLY_VISIBLE_P (last_row);
+}
+
+
 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
-  Spos_visible_in_window_p, 0, 2, 0,
+  Spos_visible_in_window_p, 0, 3, 0,
   "Return t if position POS is currently on the frame in WINDOW.\n\
 Returns nil if that position is scrolled vertically out of view.\n\
+If FULLY is non-nil, then only return t when POS is completely visible.\n\
 POS defaults to point; WINDOW, to the selected window.")
-  (pos, window)
-     Lisp_Object pos, window;
+  (pos, window, fully)
+     Lisp_Object pos, window, fully;
 {
   register struct window *w;
   register int posint;
@@ -320,13 +359,18 @@ POS defaults to point; WINDOW, to the selected window.")
   if (posint < CHARPOS (top))
     in_window = Qnil;
   else if (XFASTINT (w->last_modified) >= BUF_MODIFF (buf)
-      && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (buf)
-      && posint < BUF_Z (buf) - XFASTINT (w->window_end_pos))
+          && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (buf)
+          && posint < BUF_Z (buf) - XFASTINT (w->window_end_pos))
     /* If frame is up to date, and POSINT is < window end pos, use
        that info.  This doesn't work for POSINT == end pos, because
        the window end pos is actually the position _after_ the last
        char in the window.  */
-    in_window = Qt;
+    {
+      if (NILP (fully) || pos_fully_visible_in_window_p (posint, w))
+       in_window = Qt;
+      else
+       in_window = Qnil;
+    }
   else if (posint > BUF_ZV (buf))
     in_window = Qnil;
   else if (CHARPOS (top) < BUF_BEGV (buf) || CHARPOS (top) > BUF_ZV (buf))
@@ -338,7 +382,18 @@ POS defaults to point; WINDOW, to the selected window.")
       start_display (&it, w, top);
       move_it_to (&it, posint, 0, it.last_visible_y, -1,
                  MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
-      in_window = IT_CHARPOS (it) == posint ? Qt : Qnil;
+      if (IT_CHARPOS (it) == posint)
+       {
+         if (NILP (fully))
+           in_window = Qt;
+         else
+           {
+             struct glyph_row *pos_row = &w->desired_matrix->rows[it.vpos];
+             return MATRIX_ROW_PARTIALLY_VISIBLE_P(pos_row) ? Qnil : Qt;
+           }
+       }
+      else
+       in_window = Qnil;
     }
 
   return in_window;
@@ -3784,7 +3839,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
   /* If PT is not visible in WINDOW, move back one half of
      the screen.  */
   XSETFASTINT (tem, PT);
-  tem = Fpos_visible_in_window_p (tem, window);
+  tem = Fpos_visible_in_window_p (tem, window, Qt);
   if (NILP (tem))
     {
       /* Move backward half the height of the window.  Performance note:
@@ -3928,7 +3983,7 @@ window_scroll_line_based (window, n, whole, noerror)
   original_vpos = posit.vpos;
 
   XSETFASTINT (tem, PT);
-  tem = Fpos_visible_in_window_p (tem, window);
+  tem = Fpos_visible_in_window_p (tem, window, Qt);
 
   if (NILP (tem))
     {