changeset 107606:297c59e52ecf

Retrospective commit from 2009-12-26. Redesign handle_stop_backwards. Fix character mirroring for non-ASCII characters. xdisp.c (handle_stop_backwards): Call compute_stop_pos in the loop, instead of calling handle_stop. Call handle_stop only once, after the loop. (next_element_from_buffer): Don't call handle_stop_backwards if at stop position. If base_level_stop is zero, set it to 1. term.c (append_glyph): Fill resolved_level and bidi_type slots of struct glyph for unidirectional display. xdisp.c (set_cursor_from_row): Handle zero-width characters. bidi.c (bidi_mirror_char): More efficient code (suggested by Ehud Karni <ehud@unix.mvs.co.il>). Don't even try to mirror non-ASCII characters.
author Eli Zaretskii <eliz@gnu.org>
date Fri, 01 Jan 2010 10:04:53 -0500
parents b1e1b45c9fb6
children a04b9ac55bc5
files src/.gdbinit src/ChangeLog.bidi src/bidi.c src/term.c src/xdisp.c
diffstat 5 files changed, 62 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/.gdbinit	Fri Jan 01 09:57:27 2010 -0500
+++ b/src/.gdbinit	Fri Jan 01 10:04:53 2010 -0500
@@ -448,6 +448,9 @@
 end
 
 define pbiditype
+  if ($arg0 == 0)
+    printf "UNDEF"
+  end
   if ($arg0 == 1)
     printf "L"
   end
@@ -466,7 +469,7 @@
   if ($arg0 == 6)
     printf "B"
   end
-  if ($arg0 < 1 || $arg0 > 6)
+  if ($arg0 < 0 || $arg0 > 6)
     printf "%d??", $arg0
   end
 end
--- a/src/ChangeLog.bidi	Fri Jan 01 09:57:27 2010 -0500
+++ b/src/ChangeLog.bidi	Fri Jan 01 10:04:53 2010 -0500
@@ -1,3 +1,20 @@
+2009-12-26  Eli Zaretskii  <eliz@gnu.org>
+
+	* xdisp.c (handle_stop_backwards): Call compute_stop_pos in the
+	loop, instead of calling handle_stop.  Call handle_stop only once,
+	after the loop.
+	(next_element_from_buffer): Don't call handle_stop_backwards if at
+	stop position.  If base_level_stop is zero, set it to 1.
+
+	* term.c (append_glyph): Fill resolved_level and bidi_type slots
+	of struct glyph for unidirectional display.
+
+	* xdisp.c (set_cursor_from_row): Handle zero-width characters.
+
+	* bidi.c (bidi_mirror_char): More efficient code (suggested by
+	Ehud Karni <ehud@unix.mvs.co.il>).  Don't even try to mirror
+	non-ASCII characters.
+
 2009-12-19  Eli Zaretskii  <eliz@gnu.org>
 
 	* buffer.c (Fbuffer_swap_text): Swap the values of
--- a/src/bidi.c	Fri Jan 01 09:57:27 2010 -0500
+++ b/src/bidi.c	Fri Jan 01 10:04:53 2010 -0500
@@ -509,16 +509,13 @@
 bidi_mirror_char (int c)
 {
   static const char mirrored_pairs[] = "()<>[]{}";
-  const char *p = strchr (mirrored_pairs, c);
+  const char *p = c > 0 && c < 128 ? strchr (mirrored_pairs, c) : NULL;
 
   if (p)
     {
       size_t i = p - mirrored_pairs;
 
-      if ((i & 1) == 0)
-	return mirrored_pairs[i + 1];
-      else
-	return mirrored_pairs[i - 1];
+      return mirrored_pairs [(i ^ 1)];
     }
   return c;
 }
--- a/src/term.c	Fri Jan 01 09:57:27 2010 -0500
+++ b/src/term.c	Fri Jan 01 10:04:53 2010 -0500
@@ -1579,8 +1579,15 @@
       if (it->bidi_p)
 	{
 	  glyph->resolved_level = it->bidi_it.resolved_level;
+	  if ((it->bidi_it.type & 7) != it->bidi_it.type)
+	    abort ();
 	  glyph->bidi_type = it->bidi_it.type;
 	}
+      else
+	{
+	  glyph->resolved_level = 0;
+	  glyph->bidi_type = UNKNOWN_BT;
+	}
 
       ++it->glyph_row->used[it->area];
       ++glyph;
--- a/src/xdisp.c	Fri Jan 01 09:57:27 2010 -0500
+++ b/src/xdisp.c	Fri Jan 01 10:04:53 2010 -0500
@@ -6549,8 +6549,8 @@
 }
 
 /* Scan forward from CHARPOS in the current buffer, until we find a
-   stop position > current IT's position, handling all the stop
-   positions in between.
+   stop position > current IT's position.  Then handle the stop
+   position before that.
 
    This is called when we are reordering bidirectional text.  The
    caller should save and restore IT and in particular the bidi_p
@@ -6563,6 +6563,7 @@
 {
   struct text_pos pos1;
   EMACS_INT where_we_are = IT_CHARPOS (*it);
+  EMACS_INT next_stop;
 
   /* Scan in strict logical order.  */
   it->bidi_p = 0;
@@ -6571,12 +6572,18 @@
       it->prev_stop = charpos;
       SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
       reseat_1 (it, pos1, 0);
-      handle_stop (it);
+      compute_stop_pos (it);
       /* We must advance forward, right?  */
       if (it->stop_charpos <= it->prev_stop)
 	abort ();
-    }
-  while (it->stop_charpos <= where_we_are);
+      charpos = it->stop_charpos;
+    }
+  while (charpos <= where_we_are);
+
+  next_stop = it->stop_charpos;
+  it->stop_charpos = it->prev_stop;
+  handle_stop (it);
+  it->stop_charpos = next_stop;
 }
 
 /* Load IT with the next display element from current_buffer.  Value
@@ -6668,26 +6675,31 @@
 	      success_p = 0;
 	    }
 	}
-      else if (it->bidi_p && !BIDI_AT_BASE_LEVEL (it->bidi_it))
+      else if (!(!it->bidi_p
+		 || BIDI_AT_BASE_LEVEL (it->bidi_it)
+		 || IT_CHARPOS (*it) == it->stop_charpos))
 	{
 	  /* With bidi non-linear iteration, we could find ourselves
 	     far beyond the last computed stop_charpos, with several
 	     other stop positions in between that we missed.  Scan
-	     them all now, in buffer's logical order.  */
+	     them all now, in buffer's logical order, until we find
+	     and handle the last stop_charpos that precedes our
+	     current position.  */
 	  struct it save_it = *it;
 
 	  handle_stop_backwards (it, it->stop_charpos);
-	  save_it.stop_charpos = it->stop_charpos;
-	  save_it.prev_stop = it->prev_stop;
-	  *it = save_it;
+	  it->bidi_p = 1;
+	  it->current = save_it.current;
+	  it->position = save_it.position;
 	  return GET_NEXT_DISPLAY_ELEMENT (it);
 	}
       else
 	{
+	  /* If we are at base paragraph embedding level, take note of
+	     the last stop position seen at this level.  */
+	  if (BIDI_AT_BASE_LEVEL (it->bidi_it))
+	    it->base_level_stop = it->stop_charpos;
 	  handle_stop (it);
-	  /* We are at base paragraph embedding level, so take note of
-	     the last stop_pos seen at this level.  */
-	  it->base_level_stop = it->stop_charpos;
 	  return GET_NEXT_DISPLAY_ELEMENT (it);
 	}
     }
@@ -6696,15 +6708,15 @@
       struct it save_it = *it;
 
       if (it->base_level_stop <= 0)
-	abort ();
+	it->base_level_stop = 1;
       if (IT_CHARPOS (*it) < it->base_level_stop)
 	abort ();
       if (BIDI_AT_BASE_LEVEL (it->bidi_it))
 	abort ();
       handle_stop_backwards (it, it->base_level_stop);
-      save_it.stop_charpos = it->stop_charpos;
-      save_it.prev_stop = it->prev_stop;
-      *it = save_it;
+      it->bidi_p = 1;
+      it->current = save_it.current;
+      it->position = save_it.position;
       return GET_NEXT_DISPLAY_ELEMENT (it);
     }
   else
@@ -12771,7 +12783,9 @@
 	      glyph--;
 	    }
 	}
-      else if (match_with_avoid_cursor)
+      else if (match_with_avoid_cursor
+	       /* zero-width characters produce no glyphs */
+	       || eabs (glyph_after - glyph_before) == 1)
 	{
 	  cursor = glyph_after;
 	  x = -1;