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)
}
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 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);
+ /* 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
- {
- 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);
+ do
+ {
+ 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));