Adjust normalizer for out-of-order marks
We are going to implement Unicode Arabic Mark Ordering Algorithm: http://www.unicode.org/reports/tr53/tr53-1.pdf which will reorder marks out of their sorted ccc order. Adjust normalizer to stop combining as soon as dangerous ordering is detected.
This commit is contained in:
parent
a252ad61f0
commit
7f9e7f8689
@ -369,46 +369,58 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
|||||||
buffer->clear_output ();
|
buffer->clear_output ();
|
||||||
count = buffer->len;
|
count = buffer->len;
|
||||||
unsigned int starter = 0;
|
unsigned int starter = 0;
|
||||||
|
bool combine = true;
|
||||||
buffer->next_glyph ();
|
buffer->next_glyph ();
|
||||||
while (buffer->idx < count && !buffer->in_error)
|
while (buffer->idx < count && !buffer->in_error)
|
||||||
{
|
{
|
||||||
hb_codepoint_t composed, glyph;
|
hb_codepoint_t composed, glyph;
|
||||||
if (/* We don't try to compose a non-mark character with it's preceding starter.
|
if (combine &&
|
||||||
|
/* We don't try to compose a non-mark character with it's preceding starter.
|
||||||
* This is both an optimization to avoid trying to compose every two neighboring
|
* This is both an optimization to avoid trying to compose every two neighboring
|
||||||
* glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
|
* glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
|
||||||
* fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
|
* fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
|
||||||
HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
|
HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())))
|
||||||
/* If there's anything between the starter and this char, they should have CCC
|
|
||||||
* smaller than this character's. */
|
|
||||||
(starter == buffer->out_len - 1 ||
|
|
||||||
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
|
|
||||||
/* And compose. */
|
|
||||||
c.compose (&c,
|
|
||||||
buffer->out_info[starter].codepoint,
|
|
||||||
buffer->cur().codepoint,
|
|
||||||
&composed) &&
|
|
||||||
/* And the font has glyph for the composite. */
|
|
||||||
font->get_nominal_glyph (composed, &glyph))
|
|
||||||
{
|
{
|
||||||
/* Composes. */
|
if (/* If there's anything between the starter and this char, they should have CCC
|
||||||
buffer->next_glyph (); /* Copy to out-buffer. */
|
* smaller than this character's. */
|
||||||
if (unlikely (buffer->in_error))
|
(starter == buffer->out_len - 1 ||
|
||||||
return;
|
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
|
||||||
buffer->merge_out_clusters (starter, buffer->out_len);
|
/* And compose. */
|
||||||
buffer->out_len--; /* Remove the second composable. */
|
c.compose (&c,
|
||||||
/* Modify starter and carry on. */
|
buffer->out_info[starter].codepoint,
|
||||||
buffer->out_info[starter].codepoint = composed;
|
buffer->cur().codepoint,
|
||||||
buffer->out_info[starter].glyph_index() = glyph;
|
&composed) &&
|
||||||
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
|
/* And the font has glyph for the composite. */
|
||||||
|
font->get_nominal_glyph (composed, &glyph))
|
||||||
|
{
|
||||||
|
/* Composes. */
|
||||||
|
buffer->next_glyph (); /* Copy to out-buffer. */
|
||||||
|
if (unlikely (buffer->in_error))
|
||||||
|
return;
|
||||||
|
buffer->merge_out_clusters (starter, buffer->out_len);
|
||||||
|
buffer->out_len--; /* Remove the second composable. */
|
||||||
|
/* Modify starter and carry on. */
|
||||||
|
buffer->out_info[starter].codepoint = composed;
|
||||||
|
buffer->out_info[starter].glyph_index() = glyph;
|
||||||
|
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
|
||||||
|
* trying to combine as soon as combining-class drops. */
|
||||||
|
starter < buffer->out_len - 1 &&
|
||||||
|
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) > _hb_glyph_info_get_modified_combining_class (&buffer->cur()))
|
||||||
|
combine = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Blocked, or doesn't compose. */
|
/* Blocked, or doesn't compose. */
|
||||||
buffer->next_glyph ();
|
buffer->next_glyph ();
|
||||||
|
|
||||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
|
if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
|
||||||
|
{
|
||||||
starter = buffer->out_len - 1;
|
starter = buffer->out_len - 1;
|
||||||
|
combine = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buffer->swap_buffers ();
|
buffer->swap_buffers ();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user