[layout] move alternate buffer iteration logic to AlternateSet

This commit is contained in:
Ebrahim Byagowi 2020-06-18 08:37:21 +04:30
parent 1348a2c865
commit d3c169792b
2 changed files with 57 additions and 28 deletions

View File

@ -522,8 +522,6 @@ struct MultipleSubst
struct AlternateSet struct AlternateSet
{ {
friend struct AlternateSubstFormat1;
bool intersects (const hb_set_t *glyphs) const bool intersects (const hb_set_t *glyphs) const
{ return hb_any (alternates, glyphs); } { return hb_any (alternates, glyphs); }
@ -558,6 +556,20 @@ struct AlternateSet
return_trace (true); return_trace (true);
} }
unsigned
get_alternates (unsigned start_offset,
unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
{
if (alternate_count)
{
+ alternates.sub_array (start_offset, alternate_count)
| hb_sink (hb_array (alternate_glyphs, *alternate_count))
;
}
return alternates.len;
}
template <typename Iterator, template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))> hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
@ -630,13 +642,15 @@ struct AlternateSubstFormat1
bool would_apply (hb_would_apply_context_t *c) const bool would_apply (hb_would_apply_context_t *c) const
{ return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; } { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const unsigned get_coverage_index (hb_codepoint_t gid) const
{ { return (this+coverage).get_coverage (gid); }
unsigned index = (this+coverage).get_coverage (gid);
if (index == NOT_COVERED) return Null (ArrayOf<HBGlyphID>);
return (this+alternateSet[index]).alternates; unsigned
} get_alternates (unsigned index,
unsigned start_offset,
unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
{ return (this+alternateSet[index]).get_alternates (start_offset, alternate_count, alternate_glyphs); }
bool apply (hb_ot_apply_context_t *c) const bool apply (hb_ot_apply_context_t *c) const
{ {
@ -725,11 +739,24 @@ struct AlternateSubst
} }
} }
const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const unsigned
get_coverage_index (hb_codepoint_t gid) const
{ {
switch (u.format) { switch (u.format) {
case 1: return u.format1.get_alternates (gid); case 1: return u.format1.get_coverage_index (gid);
default:return Null (ArrayOf<HBGlyphID>); default:return NOT_COVERED;
}
}
unsigned
get_alternates (unsigned index,
unsigned start_offset,
unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
{
switch (u.format) {
case 1: return u.format1.get_alternates (index, start_offset, alternate_count, alternate_glyphs);
default:assert (0); return 0;
} }
} }
@ -1481,16 +1508,25 @@ struct SubstLookup : Lookup
substitute_glyphs_list)); substitute_glyphs_list));
} }
const ArrayOf<HBGlyphID> &get_alternates (hb_codepoint_t gid) const unsigned
get_alternates (hb_codepoint_t gid,
unsigned start_offset,
unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */) const
{
if (get_type () == SubTable::Alternate)
{ {
if (get_type () != SubTable::Alternate) return Null (ArrayOf<HBGlyphID>);
unsigned size = get_subtable_count (); unsigned size = get_subtable_count ();
for (unsigned i = 0; i < size; ++i) for (unsigned i = 0; i < size; ++i)
{ {
const ArrayOf<HBGlyphID> &alternates = get_subtable (i).u.alternate.get_alternates (gid); const AlternateSubst &alternate_subtable = get_subtable (i).u.alternate;
if (alternates.len) return alternates; unsigned index = alternate_subtable.get_coverage_index (gid);
if (index != NOT_COVERED)
return alternate_subtable.get_alternates (index, start_offset, alternate_count, alternate_glyphs);
} }
return Null (ArrayOf<HBGlyphID>); }
if (alternate_count) *alternate_count = 0;
return 0;
} }
bool serialize_alternate (hb_serialize_context_t *c, bool serialize_alternate (hb_serialize_context_t *c,

View File

@ -1992,18 +1992,11 @@ hb_ot_layout_lookup_get_alternates (hb_face_t *face,
unsigned lookup_index, unsigned lookup_index,
hb_codepoint_t glyph, hb_codepoint_t glyph,
unsigned start_offset, unsigned start_offset,
unsigned *alternate_count /* IN/OUT */, unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs) hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */)
{ {
const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index); const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index);
const OT::ArrayOf<OT::HBGlyphID> &alternates = lookup.get_alternates (glyph); return lookup.get_alternates (glyph, start_offset, alternate_count, alternate_glyphs);
if (alternate_count)
{
+ alternates.sub_array (start_offset, alternate_count)
| hb_sink (hb_array (alternate_glyphs, *alternate_count))
;
}
return alternates.len;
} }
#endif #endif