emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master e2f0dd2: Avoid infinite recursion while displaying


From: Eli Zaretskii
Subject: [Emacs-diffs] master e2f0dd2: Avoid infinite recursion while displaying box face
Date: Mon, 21 Sep 2015 09:36:41 +0000

branch: master
commit e2f0dd2f49d8638d20615bfa38e95a71202dd543
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Avoid infinite recursion while displaying box face
    
    * src/xdisp.c (face_before_or_after_it_pos): Fix calculation of
    the previous string/buffer character position under bidi
    iteration.  (Bug#21428)
---
 src/xdisp.c |   33 ++++++++++++++++++++-------------
 1 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/src/xdisp.c b/src/xdisp.c
index 3eff61f..34b5ca3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4014,21 +4014,23 @@ face_before_or_after_it_pos (struct it *it, bool 
before_p)
              /* 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.  */
+                supported.  Instead, we need to start from the string
+                beginning and go all the way to the current string
+                position, remembering the previous position.  */
              /* Ignore face changes before the first visible
                 character on this display line.  */
              if (it->current_x <= it->first_visible_x)
                return it->face_id;
              SAVE_IT (it_copy, *it, it_copy_data);
-             /* 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);
+             IT_STRING_CHARPOS (it_copy) = 0;
+             bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
+             while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it))
+               {
+                 charpos = IT_STRING_CHARPOS (it_copy);
+                 if (charpos >= SCHARS (it->string))
+                   break;
+                 bidi_move_to_visually_next (&it_copy.bidi_it);
+               }
              RESTORE_IT (it, it, it_copy_data);
            }
          else
@@ -4108,11 +4110,15 @@ face_before_or_after_it_pos (struct it *it, bool 
before_p)
        {
          if (before_p)
            {
+             int current_x;
+
              /* 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.  */
+                family of functions, and move to the previous
+                character starting from the beginning of the visual
+                line.  */
              /* Ignore face changes before the first visible
                 character on this display line.  */
              if (it->current_x <= it->first_visible_x)
@@ -4123,8 +4129,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
                 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);
+             current_x = it_copy.current_x;
+             move_it_vertically_backward (&it_copy, 0);
+             move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
              pos = it_copy.current.pos;
              RESTORE_IT (it, it, it_copy_data);
            }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]