Prefer decomposed form if font has GPOS mark feature
Fixes https://github.com/harfbuzz/harfbuzz/issues/653
This commit is contained in:
parent
d7f21777e6
commit
62d1e0852a
|
@ -70,7 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
|
||||||
|
|
||||||
bool found = (bool) c->unicode->compose (a, b, ab);
|
bool found = (bool) c->unicode->compose (a, b, ab);
|
||||||
|
|
||||||
if (!found && !c->plan->has_mark)
|
if (!found)
|
||||||
{
|
{
|
||||||
/* Special-case Hebrew presentation forms that are excluded from
|
/* Special-case Hebrew presentation forms that are excluded from
|
||||||
* standard normalization, but wanted for old fonts. */
|
* standard normalization, but wanted for old fonts. */
|
||||||
|
|
|
@ -294,6 +294,14 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
_hb_buffer_assert_unicode_vars (buffer);
|
_hb_buffer_assert_unicode_vars (buffer);
|
||||||
|
|
||||||
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
|
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
|
||||||
|
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_AUTO)
|
||||||
|
{
|
||||||
|
if (plan->has_mark)
|
||||||
|
mode = HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED;
|
||||||
|
else
|
||||||
|
mode = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
|
||||||
|
}
|
||||||
|
|
||||||
const hb_ot_shape_normalize_context_t c = {
|
const hb_ot_shape_normalize_context_t c = {
|
||||||
plan,
|
plan,
|
||||||
buffer,
|
buffer,
|
||||||
|
@ -358,14 +366,27 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
|
|
||||||
i = end;
|
i = end;
|
||||||
}
|
}
|
||||||
|
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
|
||||||
|
{
|
||||||
|
/* For all CGJ, check if it prevented any reordering at all.
|
||||||
|
* If it did NOT, then make it skippable.
|
||||||
|
* https://github.com/harfbuzz/harfbuzz/issues/554
|
||||||
|
*/
|
||||||
|
for (unsigned int i = 1; i + 1 < buffer->len; i++)
|
||||||
|
if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
|
||||||
|
info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
|
||||||
|
{
|
||||||
|
_hb_glyph_info_unhide (&buffer->info[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
|
|
||||||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Third round, recompose */
|
/* Third round, recompose */
|
||||||
|
|
||||||
|
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
|
||||||
|
mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)
|
||||||
|
return;
|
||||||
|
{
|
||||||
/* As noted in the comment earlier, we don't try to combine
|
/* As noted in the comment earlier, we don't try to combine
|
||||||
* ccc=0 chars with their previous Starter. */
|
* ccc=0 chars with their previous Starter. */
|
||||||
|
|
||||||
|
@ -416,18 +437,5 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
starter = buffer->out_len - 1;
|
starter = buffer->out_len - 1;
|
||||||
}
|
}
|
||||||
buffer->swap_buffers ();
|
buffer->swap_buffers ();
|
||||||
|
|
||||||
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
|
|
||||||
{
|
|
||||||
/* For all CGJ, check if it prevented any reordering at all.
|
|
||||||
* If it did NOT, then make it skippable.
|
|
||||||
* https://github.com/harfbuzz/harfbuzz/issues/554
|
|
||||||
*/
|
|
||||||
for (unsigned int i = 1; i + 1 < buffer->len; i++)
|
|
||||||
if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
|
|
||||||
info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
|
|
||||||
{
|
|
||||||
_hb_glyph_info_unhide (&buffer->info[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,11 @@ struct hb_ot_shape_plan_t;
|
||||||
enum hb_ot_shape_normalization_mode_t {
|
enum hb_ot_shape_normalization_mode_t {
|
||||||
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
|
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
|
||||||
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
|
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
|
||||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
|
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */
|
||||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
|
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */
|
||||||
|
|
||||||
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
|
HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* Choose decomposed if GPOS mark feature available, compose otherwise. */
|
||||||
|
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO
|
||||||
};
|
};
|
||||||
|
|
||||||
HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
|
HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
|
||||||
|
|
Loading…
Reference in New Issue