[indic] Don't reorder reph/pref if ligature was expanded
Normally if you want to, say, conditionally prevent a 'pref', you would use blocking contextual matching. Some designers instead form the 'pref' form, then undo it in context. To detect that we now also remember glyphs that went through MultipleSubst. In the only place that this is used, Uniscribe seems to only care about the "last" transformation between Ligature and Multiple substitions. Ie. if you ligate, expand, and ligate again, it moves the pref, but if you ligate and expand it doesn't. That's why we clear the MULTIPLIED bit when setting LIGATED. Micro-test added. Test: U+0D2F,0D4D,0D30 with font from: [1] https://code.google.com/a/google.com/p/noto-alpha/issues/detail?id=186#c29
This commit is contained in:
parent
b5be231720
commit
832a6f99b3
|
@ -295,7 +295,7 @@ struct Sequence
|
|||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
_hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
|
||||
c->output_glyph (substitute.array[i], klass);
|
||||
c->output_glyph_for_component (substitute.array[i], klass);
|
||||
}
|
||||
c->buffer->skip_glyph ();
|
||||
|
||||
|
|
|
@ -567,13 +567,25 @@ struct hb_apply_context_t
|
|||
|
||||
inline void _set_glyph_props (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess = 0,
|
||||
bool ligature = false) const
|
||||
bool ligature = false,
|
||||
bool component = false) const
|
||||
{
|
||||
unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
|
||||
if (ligature)
|
||||
{
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
|
||||
/* In the only place that the MULTIPLIED bit is used, Uniscribe
|
||||
* seems to only care about the "last" transformation between
|
||||
* Ligature and Multiple substitions. Ie. if you ligate, expand,
|
||||
* and ligate again, it forgives the multiplication and acts as
|
||||
* if only ligation happened. As such, clear MULTIPLIED bit.
|
||||
*/
|
||||
add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
}
|
||||
if (component)
|
||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||
if (likely (has_glyph_classes))
|
||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
|
||||
else if (class_guess)
|
||||
|
@ -596,10 +608,10 @@ struct hb_apply_context_t
|
|||
_set_glyph_props (glyph_index, class_guess, true);
|
||||
buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
inline void output_glyph (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
inline void output_glyph_for_component (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_set_glyph_props (glyph_index, class_guess);
|
||||
_set_glyph_props (glyph_index, class_guess, false, true);
|
||||
buffer->output_glyph (glyph_index);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -50,9 +50,11 @@ typedef enum
|
|||
/* The following are used internally; not derived from GDEF. */
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u,
|
||||
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
|
||||
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
|
||||
} hb_ot_layout_glyph_class_mask_t;
|
||||
|
||||
|
||||
|
@ -381,6 +383,18 @@ _hb_glyph_info_ligated (const hb_glyph_info_t *info)
|
|||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_multiplied (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated_and_didnt_multiply (const hb_glyph_info_t *info)
|
||||
{
|
||||
return _hb_glyph_info_ligated (info) && !_hb_glyph_info_multiplied (info);
|
||||
}
|
||||
|
||||
/* Allocation / deallocation. */
|
||||
|
||||
static inline void
|
||||
|
|
|
@ -1446,7 +1446,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
if (start + 1 < end &&
|
||||
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
|
||||
((info[start].indic_category() == OT_Repha) ^
|
||||
_hb_glyph_info_ligated (&info[start])))
|
||||
_hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
|
||||
{
|
||||
unsigned int new_reph_pos;
|
||||
reph_position_t reph_pos = indic_plan->config->reph_pos;
|
||||
|
@ -1599,7 +1599,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* If pref len is longer than one, then only reorder if it ligated. If
|
||||
* pref len is one, only reorder if it didn't ligate with other things. */
|
||||
if (_hb_glyph_info_substituted (&info[i]) &&
|
||||
((pref_len == 1) ^ _hb_glyph_info_ligated (&info[i])))
|
||||
((pref_len == 1) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
|
||||
{
|
||||
/*
|
||||
* 2. Try to find a target position the same way as for pre-base matra.
|
||||
|
|
|
@ -34,7 +34,10 @@ CLEANFILES += \
|
|||
hb_test_tools.py[co] \
|
||||
$(NULL)
|
||||
|
||||
TESTS = tests/context-matching.tests
|
||||
TESTS = \
|
||||
tests/context-matching.tests \
|
||||
tests/indic-pref-blocking.tests \
|
||||
$(NULL)
|
||||
|
||||
TEST_EXTENSIONS = \
|
||||
.tests \
|
||||
|
|
Binary file not shown.
|
@ -1 +1,2 @@
|
|||
context-matching.tests
|
||||
indic-pref-blocking.tests
|
||||
|
|
Loading…
Reference in New Issue