Fix rendering of composed caharacters on the mode line. (Bug#19435)

src/xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in
 composition_compute_stop_pos to the number of characters in the
 string.
 <GET_FROM_BUFFER, GET_FROM_STRING>: Simplify code.
 src/composite.c (composition_compute_stop_pos): If no composition
 was found in a string before ENDPOS, and ENDPOS is the string end,
 no need to back up to a safe point.
 src/dispextern.h (struct it) <end_charpos>: Improve commentary.
This commit is contained in:
Eli Zaretskii 2014-12-25 17:38:15 +02:00
parent b70977ce02
commit a41d07b329
4 changed files with 96 additions and 102 deletions

View file

@ -1,3 +1,16 @@
2014-12-25 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in
composition_compute_stop_pos to the number of characters in the
string. (Bug#19435)
<GET_FROM_BUFFER, GET_FROM_STRING>: Simplify code.
* composite.c (composition_compute_stop_pos): If no composition
was found in a string before ENDPOS, and ENDPOS is the string end,
no need to back up to a safe point.
* dispextern.h (struct it) <end_charpos>: Improve commentary.
2014-12-24 Jan Djärv <jan.h.d@swipnet.se> 2014-12-24 Jan Djärv <jan.h.d@swipnet.se>
* nsimage.m (allocInitFromFile:): Initialize bmRep. * nsimage.m (allocInitFromFile:): Initialize bmRep.

View file

@ -1036,7 +1036,8 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
} }
} }
} }
if (charpos == endpos) if (charpos == endpos
&& !(STRINGP (string) && endpos == SCHARS (string)))
{ {
/* We couldn't find a composition point before ENDPOS. But, /* We couldn't find a composition point before ENDPOS. But,
some character after ENDPOS may be composed with some character after ENDPOS may be composed with

View file

@ -2222,7 +2222,10 @@ struct it
ptrdiff_t base_level_stop; ptrdiff_t base_level_stop;
/* Maximum string or buffer position + 1. ZV when iterating over /* Maximum string or buffer position + 1. ZV when iterating over
current_buffer. */ current_buffer. When iterating over a string in display_string,
this can be smaller or greater than the number of string
characters, depending on the values of PRECISION and FIELD_WIDTH
with which display_string was called. */
ptrdiff_t end_charpos; ptrdiff_t end_charpos;
/* C string to iterate over. Non-null means get characters from /* C string to iterate over. Non-null means get characters from

View file

@ -7330,27 +7330,15 @@ set_iterator_to_next (struct it *it, int reseat_p)
else if (it->cmp_it.id >= 0) else if (it->cmp_it.id >= 0)
{ {
/* We are currently getting glyphs from a composition. */ /* We are currently getting glyphs from a composition. */
int i;
if (! it->bidi_p) if (! it->bidi_p)
{ {
IT_CHARPOS (*it) += it->cmp_it.nchars; IT_CHARPOS (*it) += it->cmp_it.nchars;
IT_BYTEPOS (*it) += it->cmp_it.nbytes; IT_BYTEPOS (*it) += it->cmp_it.nbytes;
if (it->cmp_it.to < it->cmp_it.nglyphs)
{
it->cmp_it.from = it->cmp_it.to;
}
else
{
it->cmp_it.id = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it),
it->end_charpos, Qnil);
}
} }
else if (! it->cmp_it.reversed_p) else
{ {
/* Composition created while scanning forward. */ int i;
/* Update IT's char/byte positions to point to the first /* Update IT's char/byte positions to point to the first
character of the next grapheme cluster, or to the character of the next grapheme cluster, or to the
character visually after the current composition. */ character visually after the current composition. */
@ -7358,52 +7346,34 @@ set_iterator_to_next (struct it *it, int reseat_p)
bidi_move_to_visually_next (&it->bidi_it); bidi_move_to_visually_next (&it->bidi_it);
IT_BYTEPOS (*it) = it->bidi_it.bytepos; IT_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_CHARPOS (*it) = it->bidi_it.charpos; IT_CHARPOS (*it) = it->bidi_it.charpos;
}
if (it->cmp_it.to < it->cmp_it.nglyphs) if ((! it->bidi_p || ! it->cmp_it.reversed_p)
{ && it->cmp_it.to < it->cmp_it.nglyphs)
/* Proceed to the next grapheme cluster. */ {
it->cmp_it.from = it->cmp_it.to; /* Composition created while scanning forward. Proceed
} to the next grapheme cluster. */
else it->cmp_it.from = it->cmp_it.to;
{ }
/* No more grapheme clusters in this composition. else if ((it->bidi_p && it->cmp_it.reversed_p)
Find the next stop position. */ && it->cmp_it.from > 0)
ptrdiff_t stop = it->end_charpos; {
if (it->bidi_it.scan_dir < 0) /* Composition created while scanning backward. Proceed
/* Now we are scanning backward and don't know to the previous grapheme cluster. */
where to stop. */ it->cmp_it.to = it->cmp_it.from;
stop = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it), stop, Qnil);
}
} }
else else
{ {
/* Composition created while scanning backward. */ /* No more grapheme clusters in this composition.
/* Update IT's char/byte positions to point to the last Find the next stop position. */
character of the previous grapheme cluster, or the ptrdiff_t stop = it->end_charpos;
character visually after the current composition. */
for (i = 0; i < it->cmp_it.nchars; i++) if (it->bidi_it.scan_dir < 0)
bidi_move_to_visually_next (&it->bidi_it); /* Now we are scanning backward and don't know
IT_BYTEPOS (*it) = it->bidi_it.bytepos; where to stop. */
IT_CHARPOS (*it) = it->bidi_it.charpos; stop = -1;
if (it->cmp_it.from > 0) composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
{ IT_BYTEPOS (*it), stop, Qnil);
/* Proceed to the previous grapheme cluster. */
it->cmp_it.to = it->cmp_it.from;
}
else
{
/* No more grapheme clusters in this composition.
Find the next stop position. */
ptrdiff_t stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
/* Now we are scanning backward and don't know
where to stop. */
stop = -1;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it), stop, Qnil);
}
} }
} }
else else
@ -7532,61 +7502,63 @@ set_iterator_to_next (struct it *it, int reseat_p)
} }
if (it->cmp_it.id >= 0) if (it->cmp_it.id >= 0)
{ {
int i; /* We are delivering display elements from a composition.
Update the string position past the grapheme cluster
we've just processed. */
if (! it->bidi_p) if (! it->bidi_p)
{ {
IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
if (it->cmp_it.to < it->cmp_it.nglyphs)
it->cmp_it.from = it->cmp_it.to;
else
{
it->cmp_it.id = -1;
composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it),
it->end_charpos, it->string);
}
}
else if (! it->cmp_it.reversed_p)
{
for (i = 0; i < it->cmp_it.nchars; i++)
bidi_move_to_visually_next (&it->bidi_it);
IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
if (it->cmp_it.to < it->cmp_it.nglyphs)
it->cmp_it.from = it->cmp_it.to;
else
{
ptrdiff_t stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0)
stop = -1;
composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it), stop,
it->string);
}
} }
else else
{ {
int i;
for (i = 0; i < it->cmp_it.nchars; i++) for (i = 0; i < it->cmp_it.nchars; i++)
bidi_move_to_visually_next (&it->bidi_it); bidi_move_to_visually_next (&it->bidi_it);
IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
if (it->cmp_it.from > 0) }
it->cmp_it.to = it->cmp_it.from;
else /* Did we exhaust all the grapheme clusters of this
composition? */
if ((! it->bidi_p || ! it->cmp_it.reversed_p)
&& (it->cmp_it.to < it->cmp_it.nglyphs))
{
/* Not all the grapheme clusters were processed yet;
advance to the next cluster. */
it->cmp_it.from = it->cmp_it.to;
}
else if ((it->bidi_p && it->cmp_it.reversed_p)
&& it->cmp_it.from > 0)
{
/* Likewise: advance to the next cluster, but going in
the reverse direction. */
it->cmp_it.to = it->cmp_it.from;
}
else
{
/* This composition was fully processed; find the next
candidate place for checking for composed
characters. */
/* Always limit string searches to the string length;
any padding spaces are not part of the string, and
there cannot be any compositions in that padding. */
ptrdiff_t stop = SCHARS (it->string);
if (it->bidi_p && it->bidi_it.scan_dir < 0)
stop = -1;
else if (it->end_charpos < stop)
{ {
ptrdiff_t stop = it->end_charpos; /* Cf. PRECISION in reseat_to_string: we might be
if (it->bidi_it.scan_dir < 0) limited in how many of the string characters we
stop = -1; need to deliver. */
composition_compute_stop_pos (&it->cmp_it, stop = it->end_charpos;
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it), stop,
it->string);
} }
composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it), stop,
it->string);
} }
} }
else else
@ -7609,12 +7581,17 @@ set_iterator_to_next (struct it *it, int reseat_p)
bidi_move_to_visually_next (&it->bidi_it); bidi_move_to_visually_next (&it->bidi_it);
IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos; IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_STRING_CHARPOS (*it) = it->bidi_it.charpos; IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
/* If the scan direction changes, we may need to update
the place where to check for composed characters. */
if (prev_scan_dir != it->bidi_it.scan_dir) if (prev_scan_dir != it->bidi_it.scan_dir)
{ {
ptrdiff_t stop = it->end_charpos; ptrdiff_t stop = SCHARS (it->string);
if (it->bidi_it.scan_dir < 0) if (it->bidi_it.scan_dir < 0)
stop = -1; stop = -1;
else if (it->end_charpos < stop)
stop = it->end_charpos;
composition_compute_stop_pos (&it->cmp_it, composition_compute_stop_pos (&it->cmp_it,
IT_STRING_CHARPOS (*it), IT_STRING_CHARPOS (*it),
IT_STRING_BYTEPOS (*it), stop, IT_STRING_BYTEPOS (*it), stop,