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)
This commit is contained in:
parent
18028318d8
commit
e2f0dd2f49
1 changed files with 20 additions and 13 deletions
33
src/xdisp.c
33
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue