changeset 107624:552007beee69

Finish and debug display of invisible text. xdisp.c (handle_invisible_prop): If we are `reseat'ed, init the paragraph direction and set the `reversed_p' flag in the IT's glyph row. Fix exit conditions of the loop that skips invisible text. Update IT->prev_stop after skipping invisible text. Check for additional overlays at IT->stop_charpos, not at start_pos. Clean up the mess with setting the glyph row reversed_p flag. dispnew.c (prepare_desired_row): Preserve the reversed_p flag. bidi.c (bidi_cache_find): Use bidi_copy_it instead of copying the whole struct (which includes uninitialized parts). (bidi_init_it): Don't initialize bidi_it->paragraph_dir. xdisp.c (display_line): Remove misplaced setting of row->reversed_p flags. Copy the reversed_p flag to the next glyph row. (next_element_from_buffer): Check bidi_it.paragraph_dir rather than level_stack[0].level. Reset the reversed_p flag for non-R2L paragraphs.
author Eli Zaretskii <eliz@gnu.org>
date Mon, 25 Jan 2010 12:29:38 -0500
parents 86c10cac941a
children f839a8fbe740
files src/ChangeLog.bidi src/bidi.c src/dispnew.c src/xdisp.c
diffstat 4 files changed, 89 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog.bidi	Sat Jan 23 03:49:15 2010 -0500
+++ b/src/ChangeLog.bidi	Mon Jan 25 12:29:38 2010 -0500
@@ -1,3 +1,27 @@
+2010-01-25  Eli Zaretskii  <eliz@gnu.org>
+
+	Clean up the mess with setting the glyph row reversed_p flag.
+	* dispnew.c (prepare_desired_row): Preserve the reversed_p flag.
+
+	* bidi.c (bidi_cache_find): Use bidi_copy_it instead of copying
+	the whole struct (which includes uninitialized parts).
+	(bidi_init_it): Don't initialize bidi_it->paragraph_dir.
+
+	* xdisp.c (display_line): Remove misplaced setting of
+	row->reversed_p flags.  Copy the reversed_p flag to the next glyph
+	row.
+	(next_element_from_buffer): Check bidi_it.paragraph_dir rather
+	than level_stack[0].level.  Reset the reversed_p flag for non-R2L
+	paragraphs.
+
+	Fix display of invisible text.
+	* xdisp.c (handle_invisible_prop): If we are `reseat'ed, init the
+	paragraph direction and set the `reversed_p' flag in the IT's
+	glyph row.  Fix exit conditions of the loop that skips invisible
+	text.  Update IT->prev_stop after skipping invisible text.  Check
+	for additional overlays at IT->stop_charpos, not at start_pos.
+	(next_element_from_buffer):
+
 2010-01-16  Eli Zaretskii  <eliz@gnu.org>
 
 	* xdisp.c (handle_invisible_prop): Under bidi iteration, skip
--- a/src/bidi.c	Sat Jan 23 03:49:15 2010 -0500
+++ b/src/bidi.c	Mon Jan 25 12:29:38 2010 -0500
@@ -715,7 +715,7 @@
     {
       bidi_dir_t current_scan_dir = bidi_it->scan_dir;
 
-      *bidi_it = bidi_cache[i];
+      bidi_copy_it (bidi_it, &bidi_cache[i]);
       bidi_cache_last_idx = i;
       /* Don't let scan direction from from the cached state override
 	 the current scan direction.  */
@@ -971,7 +971,6 @@
   bidi_set_paragraph_end (bidi_it);
   bidi_it->new_paragraph = 1;
   bidi_it->separator_limit = -1;
-  bidi_it->paragraph_dir = NEUTRAL_DIR;
   bidi_it->type = NEUTRAL_B;
   bidi_it->type_after_w1 = UNKNOWN_BT;
   bidi_it->orig_type = UNKNOWN_BT;
--- a/src/dispnew.c	Sat Jan 23 03:49:15 2010 -0500
+++ b/src/dispnew.c	Mon Jan 25 12:29:38 2010 -0500
@@ -1388,8 +1388,11 @@
 {
   if (!row->enabled_p)
     {
+      unsigned rp = row->reversed_p;
+
       clear_glyph_row (row);
       row->enabled_p = 1;
+      row->reversed_p = rp;
     }
 }
 
--- a/src/xdisp.c	Sat Jan 23 03:49:15 2010 -0500
+++ b/src/xdisp.c	Mon Jan 25 12:29:38 2010 -0500
@@ -3789,7 +3789,7 @@
 
       /* First of all, is there invisible text at this position?  */
       tem = start_charpos = IT_CHARPOS (*it);
-      pos = make_number (IT_CHARPOS (*it));
+      pos = make_number (tem);
       prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
 					    &overlay);
       invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
@@ -3852,17 +3852,43 @@
 		 embedding level.  Therefore, we need to skip
 		 invisible text using the bidi iterator, starting at
 		 IT's current position, until we find ourselves
-		 outside the invisible text.  This avoids affecting
-		 the visual order of the displayed text when invisible
-		 properties are added or removed.  */
+		 outside the invisible text.  Skipping invisible text
+		 _after_ bidi iteration avoids affecting the visual
+		 order of the displayed text when invisible properties
+		 are added or removed.  */
+	      if (it->bidi_it.first_elt)
+		{
+		  /* If we were `reseat'ed to a new paragraph,
+		     determine the paragraph base direction.  We need
+		     to do it now because next_element_from_buffer may
+		     not have a chance to do it, if we are going to
+		     skip any text at the beginning, which resets the
+		     FIRST_ELT flag.  */
+		  bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+		  /* If the paragraph base direction is R2L, its
+		     glyphs should be reversed.  */
+		  if (it->glyph_row)
+		    {
+		      if (it->bidi_it.paragraph_dir == R2L)
+			it->glyph_row->reversed_p = 1;
+		      else
+			it->glyph_row->reversed_p = 0;
+		    }
+		}
 	      do
 		{
 		  bidi_get_next_char_visually (&it->bidi_it);
 		}
-	      while (start_charpos <= it->bidi_it.charpos
+	      while (it->stop_charpos <= it->bidi_it.charpos
 		     && it->bidi_it.charpos < newpos);
 	      IT_CHARPOS (*it) = it->bidi_it.charpos;
-	      IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
+	      IT_BYTEPOS (*it) = it->bidi_it.bytepos;
+	      /* If we overstepped NEWPOS, record its position in the
+		 iterator, so that we skip invisible text if later the
+		 bidi iteration lands us in the invisible region
+		 again. */
+	      if (IT_CHARPOS (*it) >= newpos)
+		it->prev_stop = newpos;
 	    }
 	  else
 	    {
@@ -3877,7 +3903,7 @@
 	     overlay property instead of a text property, this is
 	     already handled in the overlay code.)  */
 	  if (NILP (overlay)
-	      && get_overlay_strings (it, start_charpos))
+	      && get_overlay_strings (it, it->stop_charpos))
 	    {
 	      handled = HANDLED_RECOMPUTE_PROPS;
 	      it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
@@ -6200,7 +6226,16 @@
 	      /* If this is a new paragraph, determine its base
 		 direction (a.k.a. its base embedding level).  */
 	      if (it->bidi_it.new_paragraph)
-		bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+		{
+		  bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
+		  if (it->glyph_row)
+		    {
+		      if (it->bidi_it.paragraph_dir == R2L)
+			it->glyph_row->reversed_p = 1;
+		      else
+			it->glyph_row->reversed_p = 0;
+		    }
+		}
 	      bidi_get_next_char_visually (&it->bidi_it);
 	      IT_BYTEPOS (*it) = it->bidi_it.bytepos;
 	      IT_CHARPOS (*it) = it->bidi_it.charpos;
@@ -6663,8 +6698,13 @@
 	  bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
 	  /* If the paragraph base direction is R2L, its glyphs should
 	     be reversed.  */
-	  if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0)
-	    it->glyph_row->reversed_p = 1;
+	  if (it->glyph_row)
+	    {
+	      if (it->bidi_it.paragraph_dir == R2L)
+		it->glyph_row->reversed_p = 1;
+	      else
+		it->glyph_row->reversed_p = 0;
+	    }
 	  bidi_get_next_char_visually (&it->bidi_it);
 	}
       else
@@ -6679,8 +6719,13 @@
 	  it->bidi_it.charpos = IT_CHARPOS (*it);
 	  it->bidi_it.bytepos = IT_BYTEPOS (*it);
 	  bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
-	  if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0)
-	    it->glyph_row->reversed_p = 1;
+	  if (it->glyph_row)
+	    {
+	      if (it->bidi_it.paragraph_dir == R2L)
+		it->glyph_row->reversed_p = 1;
+	      else
+		it->glyph_row->reversed_p = 0;
+	    }
 	  do
 	    {
 	      /* Now return to buffer position where we were asked to
@@ -17028,10 +17073,6 @@
   row->displays_text_p = 1;
   row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
   it->starts_in_middle_of_char_p = 0;
-  /* If the paragraph base direction is R2L, its glyphs should be
-     reversed.  */
-  if (it->bidi_p && (it->bidi_it.level_stack[0].level & 1) != 0)
-    row->reversed_p = 1;
 
   /* Arrange the overlays nicely for our purposes.  Usually, we call
      display_line on only one line at a time, in which case this
@@ -17566,6 +17607,10 @@
   it->current_y += row->height;
   ++it->vpos;
   ++it->glyph_row;
+  /* The next row should use same value of the reversed_p flag as this
+     one.  set_iterator_to_next decides when it's a new paragraph and
+     recomputes the value of the flag accordingly.  */
+  it->glyph_row->reversed_p = row->reversed_p;
   it->start = row_end;
   return row->displays_text_p;
 }