changeset 107597:7361a2f37d8e

Retrospective commit from 2009-10-10. Continue working on set_cursor_from_row. Disable redisplay optimizations that interfere with R2L glyph rows. Misc cleanups in bidi.c. xdisp.c (set_cursor_from_row): Skip over glyphs near end of row with integer OBJECT even if their CHARPOS is zero. bidi.c (bidi_cache_iterator_state): Don't cache NEW_PARAGRAPH. Abort if someone tries to add a cached state whose position is not the immediate successor to that of the last cached state. (bidi_paragraph_init): Don't bail out too early after a reseat. xdisp.c (text_outside_line_unchanged_p, try_window_id): Disable optimizations if we are reordering bidirectional text and the paragraph direction can be affected by the change.
author Eli Zaretskii <eliz@gnu.org>
date Fri, 01 Jan 2010 06:35:03 -0500
parents 866e76f8ad75
children 4bad2c6338cc
files src/ChangeLog.bidi src/bidi.c src/xdisp.c
diffstat 3 files changed, 54 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog.bidi	Fri Jan 01 06:27:51 2010 -0500
+++ b/src/ChangeLog.bidi	Fri Jan 01 06:35:03 2010 -0500
@@ -1,3 +1,19 @@
+2009-10-10  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (set_cursor_from_row): Skip over glyphs near end of row
+	with integer OBJECT even if their CHARPOS is zero.
+
+	* bidi.c (bidi_cache_iterator_state): Don't cache NEW_PARAGRAPH.
+	Abort if someone tries to add a cached state whose position is not
+	the immediate successor to that of the last cached state.
+	(bidi_paragraph_init): Don't bail out too early after a reseat.
+
+2009-10-09  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (text_outside_line_unchanged_p, try_window_id): Disable
+	optimizations if we are reordering bidirectional text and the
+	paragraph direction can be affected by the change.
+
 2009-10-08  Eli Zaretskii  <eliz@gnu.org>
 
 	* xdisp.c (string_buffer_position_lim): New function.
--- a/src/bidi.c	Fri Jan 01 06:27:51 2010 -0500
+++ b/src/bidi.c	Fri Jan 01 06:35:03 2010 -0500
@@ -531,6 +531,7 @@
 
   /* Copy everything except the level stack.  */
   memcpy (to, from, ((int)&((struct bidi_it *)0)->level_stack[0]));
+  /* Don't copy FIRST_ELT flag.  */
   to->first_elt = save_first_elt;
   if (to->first_elt != 0 && to->first_elt != 1)
     to->first_elt = 0;
@@ -675,11 +676,17 @@
   if (idx < 0)
     {
       idx = bidi_cache_idx;
+      /* Don't overrun the cache limit.  */
       if (idx > sizeof (bidi_cache) / sizeof (bidi_cache[0]) - 1)
 	abort ();
+      /* Don't violate cache integrity: character positions should
+	 correspond to cache positions 1:1.  */
+      if (idx > 0 && bidi_it->charpos != bidi_cache[idx - 1].charpos + 1)
+	abort ();
       bidi_copy_it (&bidi_cache[idx], bidi_it);
       if (!resolved)
 	bidi_cache[idx].resolved_level = -1;
+      bidi_cache[idx].new_paragraph = 0;
     }
   else
     {
@@ -869,8 +876,10 @@
 
       /* If we are inside a paragraph separator, we are just waiting
 	 for the separator to be exhausted; use the previous paragraph
-	 direction.  */
-      if (bidi_it->charpos < bidi_it->separator_limit)
+	 direction.  But don't do that if we have been just reseated,
+	 because we need to reinitialize below in that case.  */
+      if (!bidi_it->first_elt
+	  && bidi_it->charpos < bidi_it->separator_limit)
 	return;
 
       /* If we are on a newline, get past it to where the next
--- a/src/xdisp.c	Fri Jan 01 06:27:51 2010 -0500
+++ b/src/xdisp.c	Fri Jan 01 06:35:03 2010 -0500
@@ -11147,6 +11147,17 @@
 	      && overlay_touches_p (Z - end))
 	    unchanged_p = 0;
 	}
+
+      /* Under bidi reordering, adding or deleting a character in the
+	 beginning of a paragraph, before the first strong directional
+	 character, can change the base direction of the paragraph (unless
+	 the buffer specifies a fixed paragraph direction), which will
+	 require to redisplay the whole paragraph.  It might be worthwhile
+	 to find the paragraph limits and widen the range of redisplayed
+	 lines to that, but for now just give up this optimization.  */
+      if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
+	  && NILP (XBUFFER (w->buffer)->paragraph_direction))
+	unchanged_p = 0;
     }
 
   return unchanged_p;
@@ -12468,7 +12479,9 @@
 	    }
 	  while (end > glyph
 		 && INTEGERP ((end - 1)->object)
-		 && (end - 1)->charpos < 0)
+		 /* CHARPOS is zero for blanks inserted by
+		    extend_face_to_end_of_line.  */
+		 && (end - 1)->charpos <= 0)
 	    --end;
 	  glyph_before = glyph - 1;
 	  glyph_after = end;
@@ -12500,7 +12513,7 @@
 	  cursor_x = x;
 	  while (end < glyph
 		 && INTEGERP (end->object)
-		 && end->charpos < 0)
+		 && end->charpos <= 0)
 	    ++end;
 	  glyph_before = glyph + 1;
 	  glyph_after = end;
@@ -15203,6 +15216,18 @@
   if (!NILP (XBUFFER (w->buffer)->word_wrap))
     GIVE_UP (21);
 
+  /* Under bidi reordering, adding or deleting a character in the
+     beginning of a paragraph, before the first strong directional
+     character, can change the base direction of the paragraph (unless
+     the buffer specifies a fixed paragraph direction), which will
+     require to redisplay the whole paragraph.  It might be worthwhile
+     to find the paragraph limits and widen the range of redisplayed
+     lines to that, but for now just give up this optimization and
+     redisplay from scratch.  */
+  if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
+      && NILP (XBUFFER (w->buffer)->paragraph_direction))
+    GIVE_UP (22);
+
   /* Make sure beg_unchanged and end_unchanged are up to date.  Do it
      only if buffer has really changed.  The reason is that the gap is
      initially at Z for freshly visited files.  The code below would