]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix box face decision for BEFORE_P case.
authorEli Zaretskii <eliz@gnu.org>
Sat, 18 Jun 2011 10:11:06 +0000 (13:11 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 18 Jun 2011 10:11:06 +0000 (13:11 +0300)
 src/xdisp.c (face_before_or_after_it_pos): Support bidi iteration.

src/ChangeLog
src/xdisp.c

index 772ebd4d273d7aededd97b01beac6d2112693acc..315ac040d41b68656d3c28e405cce4800e9313be 100644 (file)
@@ -1,7 +1,6 @@
 2011-06-18  Eli Zaretskii  <eliz@gnu.org>
 
-       * xdisp.c (face_before_or_after_it_pos): Support bidi iteration
-       when BEFORE_P is zero.
+       * xdisp.c (face_before_or_after_it_pos): Support bidi iteration.
        (next_element_from_c_string): Handle the case of the first string
        character that is not the first one in the visual order.
 
index 6a289bb51c0f73a8665f5888165a6c8d7c4dc8ad..998076b30bb334def627feb6315a73c68b09ea8d 100644 (file)
@@ -3480,6 +3480,7 @@ face_before_or_after_it_pos (struct it *it, int before_p)
 {
   int face_id, limit;
   EMACS_INT next_check_charpos;
+  struct it it_copy;
 
   xassert (it->s == NULL);
 
@@ -3512,15 +3513,34 @@ face_before_or_after_it_pos (struct it *it, int before_p)
       else
        {
          if (before_p)
-           charpos = IT_STRING_CHARPOS (*it) - 1; /* FIXME! */
+           {
+             /* With bidi iteration, the character before the current
+                in the visual order cannot be found by simple
+                iteration, because "reverse" reordering is not
+                supported.  Instead, we need to use the move_it_*
+                family of functions.  */
+             /* Ignore face changes before the first visible
+                character on this display line.  */
+             if (it->current_x <= it->first_visible_x)
+               return it->face_id;
+             it_copy = *it;
+             /* Implementation note: Since move_it_in_display_line
+                works in the iterator geometry, and thinks the first
+                character is always the leftmost, even in R2L lines,
+                we don't need to distinguish between the R2L and L2R
+                cases here.  */
+             move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
+                                      it_copy.current_x - 1, MOVE_TO_X);
+             charpos = IT_STRING_CHARPOS (it_copy);
+           }
          else
            {
              /* Set charpos to the string position of the character
                 that comes after IT's current position in the visual
                 order.  */
              int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
-             struct it it_copy = *it;
 
+             it_copy = *it;
              while (n--)
                bidi_move_to_visually_next (&it_copy.bidi_it);
 
@@ -3551,8 +3571,8 @@ face_before_or_after_it_pos (struct it *it, int before_p)
         suitable for unibyte text if IT->string is unibyte.  */
       if (STRING_MULTIBYTE (it->string))
        {
-         struct text_pos pos = string_pos (charpos, it->string);
-         const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
+         struct text_pos pos1 = string_pos (charpos, it->string);
+         const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
          int c, len;
          struct face *face = FACE_FROM_ID (it->f, face_id);
 
@@ -3591,15 +3611,34 @@ face_before_or_after_it_pos (struct it *it, int before_p)
       else
        {
          if (before_p)
-           DEC_TEXT_POS (pos, it->multibyte_p); /* FIXME! */
+           {
+             /* With bidi iteration, the character before the current
+                in the visual order cannot be found by simple
+                iteration, because "reverse" reordering is not
+                supported.  Instead, we need to use the move_it_*
+                family of functions.  */
+             /* Ignore face changes before the first visible
+                character on this display line.  */
+             if (it->current_x <= it->first_visible_x)
+               return it->face_id;
+             it_copy = *it;
+             /* Implementation note: Since move_it_in_display_line
+                works in the iterator geometry, and thinks the first
+                character is always the leftmost, even in R2L lines,
+                we don't need to distinguish between the R2L and L2R
+                cases here.  */
+             move_it_in_display_line (&it_copy, ZV,
+                                      it_copy.current_x - 1, MOVE_TO_X);
+             pos = it_copy.current.pos;
+           }
          else
            {
              /* Set charpos to the buffer position of the character
                 that comes after IT's current position in the visual
                 order.  */
              int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
-             struct it it_copy = *it;
 
+             it_copy = *it;
              while (n--)
                bidi_move_to_visually_next (&it_copy.bidi_it);