[OTLayout] Respect lookup-flags skipping over non-mark glyphs

Before, when matching ligatures, we never skipping over base / liga
glyphs even if that was what the LookupFlags asked for.

Fixed now.  We carefully reviewed all instances of this, and tested with
Amiri as well as some Indic scripts, and are confident that this should
NOT break anyone's fonts.  It's also how Uniscribe does it, from what
we can tell.
This commit is contained in:
Behdad Esfahbod 2013-02-11 13:27:17 -05:00
parent 9082efc4aa
commit 54f7b4d9ec
2 changed files with 11 additions and 16 deletions

View File

@ -1250,7 +1250,7 @@ struct MarkMarkPosFormat1
/* now we search backwards for a suitable mark glyph until a non-mark glyph */ /* now we search backwards for a suitable mark glyph until a non-mark glyph */
unsigned int property; unsigned int property;
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1); hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (!skippy_iter.prev (&property)) return TRACE_RETURN (false); if (!skippy_iter.prev (&property, c->lookup_props & ~LookupFlag::IgnoreFlags)) return TRACE_RETURN (false);
if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false); if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false);

View File

@ -317,7 +317,7 @@ struct hb_apply_context_t
if (has_no_chance ()) if (has_no_chance ())
return false; return false;
idx++; idx++;
} while (c->should_skip_mark (&c->buffer->info[idx], lookup_props, property_out)); } while (c->should_skip (&c->buffer->info[idx], lookup_props, property_out));
num_items--; num_items--;
return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ()); return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->buffer->info[idx].syllable ());
} }
@ -366,7 +366,7 @@ struct hb_apply_context_t
if (has_no_chance ()) if (has_no_chance ())
return false; return false;
idx--; idx--;
} while (c->should_skip_mark (&c->buffer->out_info[idx], lookup_props, property_out)); } while (c->should_skip (&c->buffer->out_info[idx], lookup_props, property_out));
num_items--; num_items--;
return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ()); return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
} }
@ -435,9 +435,9 @@ struct hb_apply_context_t
} }
inline bool inline bool
should_skip_mark (hb_glyph_info_t *info, should_skip (hb_glyph_info_t *info,
unsigned int lookup_props, unsigned int lookup_props,
unsigned int *property_out) const unsigned int *property_out) const
{ {
unsigned int property; unsigned int property;
@ -445,18 +445,13 @@ struct hb_apply_context_t
if (property_out) if (property_out)
*property_out = property; *property_out = property;
/* If it's a mark, skip it if we don't accept it. */ return !match_properties (info->codepoint, property, lookup_props);
if (unlikely (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
return !match_properties (info->codepoint, property, lookup_props);
/* If not a mark, don't skip. */
return false;
} }
inline bool should_mark_skip_current_glyph (void) const inline bool should_skip_current_glyph (void) const
{ {
return should_skip_mark (&buffer->cur(), lookup_props, NULL); return should_skip (&buffer->cur(), lookup_props, NULL);
} }
inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
@ -720,7 +715,7 @@ static inline void ligate_input (hb_apply_context_t *c,
for (unsigned int i = 1; i < count; i++) for (unsigned int i = 1; i < count; i++)
{ {
while (c->should_mark_skip_current_glyph ()) while (c->should_skip_current_glyph ())
{ {
if (!is_mark_ligature) { if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components + unsigned int new_lig_comp = components_so_far - last_num_components +
@ -849,7 +844,7 @@ static inline bool apply_lookup (hb_apply_context_t *c,
{ {
if (unlikely (c->buffer->idx == end)) if (unlikely (c->buffer->idx == end))
return TRACE_RETURN (true); return TRACE_RETURN (true);
while (c->should_mark_skip_current_glyph ()) while (c->should_skip_current_glyph ())
{ {
/* No lookup applied for this index */ /* No lookup applied for this index */
c->buffer->next_glyph (); c->buffer->next_glyph ();