]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
Merge from emacs-24; up to 2012-04-22T13:58:00Z!cyd@gnu.org
[gnu-emacs] / src / xdisp.c
index 36ca69956d493cd77d72eece1d0b1d1b61b6c47b..e7ecd2c1d915f8ac76903a998276454faa56db81 100644 (file)
@@ -849,6 +849,7 @@ static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
 static int trailing_whitespace_p (EMACS_INT);
 static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
 static void push_it (struct it *, struct text_pos *);
+static void iterate_out_of_display_property (struct it *);
 static void pop_it (struct it *);
 static void sync_frame_with_window_matrix_rows (struct window *);
 static void select_frame_for_redisplay (Lisp_Object);
@@ -1313,8 +1314,8 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
         glyph.  */
       int top_x = it.current_x;
       int top_y = it.current_y;
-      enum it_method it_method = it.method;
       /* Calling line_bottom_y may change it.method, it.position, etc.  */
+      enum it_method it_method = it.method;
       int bottom_y = (last_height = 0, line_bottom_y (&it));
       int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
 
@@ -1322,6 +1323,31 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
        visible_p = bottom_y > window_top_y;
       else if (top_y < it.last_visible_y)
        visible_p = 1;
+      if (bottom_y >= it.last_visible_y
+         && it.bidi_p && it.bidi_it.scan_dir == -1
+         && IT_CHARPOS (it) < charpos)
+       {
+         /* When the last line of the window is scanned backwards
+            under bidi iteration, we could be duped into thinking
+            that we have passed CHARPOS, when in fact move_it_to
+            simply stopped short of CHARPOS because it reached
+            last_visible_y.  To see if that's what happened, we call
+            move_it_to again with a slightly larger vertical limit,
+            and see if it actually moved vertically; if it did, we
+            didn't really reach CHARPOS, which is beyond window end.  */
+         struct it save_it = it;
+         /* Why 10? because we don't know how many canonical lines
+            will the height of the next line(s) be.  So we guess.  */
+         int ten_more_lines =
+           10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
+
+         move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
+                     MOVE_TO_POS | MOVE_TO_Y);
+         if (it.current_y > top_y)
+           visible_p = 0;
+
+         it = save_it;
+       }
       if (visible_p)
        {
          if (it_method == GET_FROM_DISPLAY_VECTOR)
@@ -3135,7 +3161,15 @@ handle_stop (struct it *it)
                 overlays even if the actual buffer text is replaced.  */
              if (!handle_overlay_change_p
                  || it->sp > 1
-                 || !get_overlay_strings_1 (it, 0, 0))
+                 /* Don't call get_overlay_strings_1 if we already
+                    have overlay strings loaded, because doing so
+                    will load them again and push the iterator state
+                    onto the stack one more time, which is not
+                    expected by the rest of the code that processes
+                    overlay strings.  */
+                 || (it->n_overlay_strings <= 0
+                     ? !get_overlay_strings_1 (it, 0, 0)
+                     : 0))
                {
                  if (it->ellipsis_p)
                    setup_for_ellipsis (it, 0);
@@ -4691,10 +4725,22 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          if (!FRAME_WINDOW_P (it->f))
            /* If we return here, POSITION has been advanced
               across the text with this property.  */
-           return 0;
+           {
+             /* Synchronize the bidi iterator with POSITION.  This is
+                needed because we are not going to push the iterator
+                on behalf of this display property, so there will be
+                no pop_it call to do this synchronization for us.  */
+             if (it->bidi_p)
+               {
+                 it->position = *position;
+                 iterate_out_of_display_property (it);
+                 *position = it->position;
+               }
+             return 1;
+           }
        }
       else if (!frame_window_p)
-       return 0;
+       return 1;
 
 #ifdef HAVE_WINDOW_SYSTEM
       value = XCAR (XCDR (spec));
@@ -4702,7 +4748,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          || !(fringe_bitmap = lookup_fringe_bitmap (value)))
        /* If we return here, POSITION has been advanced
           across the text with this property.  */
-       return 0;
+       {
+         if (it && it->bidi_p)
+           {
+             it->position = *position;
+             iterate_out_of_display_property (it);
+             *position = it->position;
+           }
+         return 1;
+       }
 
       if (it)
        {
@@ -5621,7 +5675,7 @@ push_it (struct it *it, struct text_pos *position)
 static void
 iterate_out_of_display_property (struct it *it)
 {
-  int buffer_p = BUFFERP (it->object);
+  int buffer_p = !STRINGP (it->string);
   EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
   EMACS_INT bob = (buffer_p ? BEGV : 0);
 
@@ -6790,6 +6844,16 @@ get_next_display_element (struct it *it)
               && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
        }
     }
+  /* If we reached the end of the object we've been iterating (e.g., a
+     display string or an overlay string), and there's something on
+     IT->stack, proceed with what's on the stack.  It doesn't make
+     sense to return zero if there's unprocessed stuff on the stack,
+     because otherwise that stuff will never be displayed.  */
+  if (!success_p && it->sp > 0)
+    {
+      set_iterator_to_next (it, 0);
+      success_p = get_next_display_element (it);
+    }
 
   /* Value is 0 if end of buffer or string reached.  */
   return success_p;
@@ -6971,7 +7035,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
          display vector entry (these entries may contain faces).  */
       it->face_id = it->saved_face_id;
 
-      if (it->dpvec + it->current.dpvec_index == it->dpend)
+      if (it->dpvec + it->current.dpvec_index >= it->dpend)
        {
          int recheck_faces = it->ellipsis_p;
 
@@ -7009,6 +7073,26 @@ set_iterator_to_next (struct it *it, int reseat_p)
     case GET_FROM_STRING:
       /* Current display element is a character from a Lisp string.  */
       xassert (it->s == NULL && STRINGP (it->string));
+      /* Don't advance past string end.  These conditions are true
+        when set_iterator_to_next is called at the end of
+        get_next_display_element, in which case the Lisp string is
+        already exhausted, and all we want is pop the iterator
+        stack.  */
+      if (it->current.overlay_string_index >= 0)
+       {
+         /* This is an overlay string, so there's no padding with
+            spaces, and the number of characters in the string is
+            where the string ends.  */
+         if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
+           goto consider_string_end;
+       }
+      else
+       {
+         /* Not an overlay string.  There could be padding, so test
+            against it->end_charpos . */
+         if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
+           goto consider_string_end;
+       }
       if (it->cmp_it.id >= 0)
        {
          int i;