Fix display of mode-line with bidi formatting controls
* src/xdisp.c (face_before_or_after_it_pos): Reimplement the bidi iteration to find the character after the current in visual order. (Bug#49562)
This commit is contained in:
parent
12a193f876
commit
595eddd848
1 changed files with 32 additions and 34 deletions
66
src/xdisp.c
66
src/xdisp.c
|
@ -4557,11 +4557,13 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
|
|||
ptrdiff_t bufpos, charpos;
|
||||
int base_face_id;
|
||||
|
||||
/* No face change past the end of the string (for the case
|
||||
we are padding with spaces). No face change before the
|
||||
string start. */
|
||||
/* No face change past the end of the string (for the case we
|
||||
are padding with spaces). No face change before the string
|
||||
start. Ignore face changes before the first visible
|
||||
character on this display line. */
|
||||
if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
|
||||
|| (IT_STRING_CHARPOS (*it) == 0 && before_p))
|
||||
|| (IT_STRING_CHARPOS (*it) == 0 && before_p)
|
||||
|| it->current_x <= it->first_visible_x)
|
||||
return it->face_id;
|
||||
|
||||
if (!it->bidi_p)
|
||||
|
@ -4580,51 +4582,47 @@ face_before_or_after_it_pos (struct it *it, bool before_p)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (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 start from the string beginning and go all the
|
||||
way to the current string position, remembering the
|
||||
visually-previous position. We need to start from the
|
||||
string beginning for the character after the current as
|
||||
well, since the iterator state in IT may have been
|
||||
pushed, and the bidi cache is no longer coherent with the
|
||||
string's text. */
|
||||
SAVE_IT (it_copy, *it, it_copy_data);
|
||||
IT_STRING_CHARPOS (it_copy) = 0;
|
||||
bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
|
||||
|
||||
do
|
||||
{
|
||||
/* 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 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);
|
||||
IT_STRING_CHARPOS (it_copy) = 0;
|
||||
bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
|
||||
|
||||
do
|
||||
{
|
||||
charpos = IT_STRING_CHARPOS (it_copy);
|
||||
if (charpos >= SCHARS (it->string))
|
||||
break;
|
||||
bidi_move_to_visually_next (&it_copy.bidi_it);
|
||||
}
|
||||
while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
|
||||
|
||||
RESTORE_IT (it, it, it_copy_data);
|
||||
charpos = it_copy.bidi_it.charpos;
|
||||
if (charpos >= SCHARS (it->string))
|
||||
break;
|
||||
bidi_move_to_visually_next (&it_copy.bidi_it);
|
||||
}
|
||||
else
|
||||
while (it_copy.bidi_it.charpos != IT_STRING_CHARPOS (*it));
|
||||
|
||||
if (!before_p)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
it_copy = *it;
|
||||
/* If this is the first display element,
|
||||
/* If this is the first string character,
|
||||
bidi_move_to_visually_next will deliver character at
|
||||
current position without moving, so we need to enlarge N. */
|
||||
if (it->bidi_it.first_elt)
|
||||
if (it_copy.bidi_it.first_elt)
|
||||
n++;
|
||||
while (n--)
|
||||
bidi_move_to_visually_next (&it_copy.bidi_it);
|
||||
|
||||
charpos = it_copy.bidi_it.charpos;
|
||||
}
|
||||
|
||||
RESTORE_IT (it, it, it_copy_data);
|
||||
}
|
||||
eassert (0 <= charpos && charpos <= SCHARS (it->string));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue