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 else
{ {
it->cmp_it.id = -1; int i;
composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
IT_BYTEPOS (*it),
it->end_charpos, Qnil);
}
}
else if (! it->cmp_it.reversed_p)
{
/* Composition created while scanning forward. */
/* 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,38 +7346,20 @@ 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. */ /* Composition created while scanning forward. Proceed
to the next grapheme cluster. */
it->cmp_it.from = it->cmp_it.to; it->cmp_it.from = it->cmp_it.to;
} }
else else if ((it->bidi_p && it->cmp_it.reversed_p)
&& it->cmp_it.from > 0)
{ {
/* No more grapheme clusters in this composition. /* Composition created while scanning backward. Proceed
Find the next stop position. */ to the previous grapheme cluster. */
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
{
/* Composition created while scanning backward. */
/* Update IT's char/byte positions to point to the last
character of the previous grapheme cluster, or the
character visually after the current composition. */
for (i = 0; i < it->cmp_it.nchars; i++)
bidi_move_to_visually_next (&it->bidi_it);
IT_BYTEPOS (*it) = it->bidi_it.bytepos;
IT_CHARPOS (*it) = it->bidi_it.charpos;
if (it->cmp_it.from > 0)
{
/* Proceed to the previous grapheme cluster. */
it->cmp_it.to = it->cmp_it.from; it->cmp_it.to = it->cmp_it.from;
} }
else else
@ -7397,6 +7367,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
/* No more grapheme clusters in this composition. /* No more grapheme clusters in this composition.
Find the next stop position. */ Find the next stop position. */
ptrdiff_t stop = it->end_charpos; ptrdiff_t stop = it->end_charpos;
if (it->bidi_it.scan_dir < 0) if (it->bidi_it.scan_dir < 0)
/* Now we are scanning backward and don't know /* Now we are scanning backward and don't know
where to stop. */ where to stop. */
@ -7405,7 +7376,6 @@ set_iterator_to_next (struct it *it, int reseat_p)
IT_BYTEPOS (*it), stop, Qnil); IT_BYTEPOS (*it), stop, Qnil);
} }
} }
}
else else
{ {
eassert (it->len != 0); eassert (it->len != 0);
@ -7532,63 +7502,65 @@ 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 else
{ {
it->cmp_it.id = -1; int i;
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
{
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) }
/* 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; it->cmp_it.to = it->cmp_it.from;
}
else else
{ {
ptrdiff_t stop = it->end_charpos; /* This composition was fully processed; find the next
if (it->bidi_it.scan_dir < 0) 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; stop = -1;
else if (it->end_charpos < stop)
{
/* Cf. PRECISION in reseat_to_string: we might be
limited in how many of the string characters we
need to deliver. */
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,
it->string); it->string);
} }
} }
}
else else
{ {
if (!it->bidi_p if (!it->bidi_p
@ -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,