Use dispatch for get_glyph_alternates_t

First time we do this in a way that if target object doesn't have the matching
function we basically "ignore".  Risky but I feel like is the right decision
for this case.

I'm going to put back the template varargs and use those, which would make
the dispatcher be just that: "dispatcher", and wouldn't need to carry the
call context.  That would be a refreshing change I think.
This commit is contained in:
Behdad Esfahbod 2020-06-18 16:31:39 -07:00
parent bedf417121
commit ffe8d3f39d
3 changed files with 46 additions and 39 deletions

View File

@ -643,12 +643,9 @@ struct AlternateSubstFormat1
{ return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
unsigned
get_glyph_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
{ return (this+alternateSet[(this+coverage).get_coverage (gid)])
.get_alternates (start_offset, alternate_count, alternate_glyphs); }
get_glyph_alternates (hb_get_glyph_alternates_context_t *c) const
{ return (this+alternateSet[(this+coverage).get_coverage (c->gid)])
.get_alternates (c->start_offset, c->alternate_count, c->alternate_glyphs); }
bool apply (hb_ot_apply_context_t *c) const
{
@ -737,18 +734,6 @@ struct AlternateSubst
}
}
unsigned
get_glyph_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
{
switch (u.format) {
case 1: return u.format1.get_glyph_alternates (gid, start_offset, alternate_count, alternate_glyphs);
default:assert (0); return 0;
}
}
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
@ -1497,26 +1482,6 @@ struct SubstLookup : Lookup
substitute_glyphs_list));
}
unsigned
get_glyph_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)
{
unsigned size = get_subtable_count ();
for (unsigned i = 0; i < size; ++i)
{
const AlternateSubst &subtable = get_subtable (i).u.alternate;
auto ret = subtable.get_glyph_alternates (gid, start_offset, alternate_count, alternate_glyphs);
if (ret) return (ret);
}
}
if (alternate_count) *alternate_count = 0;
return 0;
}
bool serialize_alternate (hb_serialize_context_t *c,
uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID> glyphs,

View File

@ -227,6 +227,45 @@ struct hb_would_apply_context_t :
debug_depth (0) {}
};
struct hb_get_glyph_alternates_context_t :
hb_dispatch_context_t<hb_get_glyph_alternates_context_t, unsigned, 0>
{
const char *get_name () { return "GET_GLYPH_ALTERNATES"; }
static return_t default_return_value () { return 0; }
bool stop_sublookup_iteration (return_t r) const { return r; }
hb_face_t *face;
hb_codepoint_t gid;
unsigned start_offset;
unsigned *alternate_count;
hb_codepoint_t *alternate_glyphs;
unsigned int debug_depth;
hb_get_glyph_alternates_context_t (hb_face_t *face_,
hb_codepoint_t gid_,
unsigned start_offset_,
unsigned *alternate_count_,
hb_codepoint_t *alternate_glyphs_) :
face (face_),
gid (gid_),
start_offset (start_offset_),
alternate_count (alternate_count_),
alternate_glyphs (alternate_glyphs_),
debug_depth (0) {}
private:
template <typename T> auto
_dispatch (const T &obj, hb_priority<1>) HB_AUTO_RETURN
( obj.get_glyph_alternates (this) )
template <typename T> auto
_dispatch (const T &obj, hb_priority<0>) HB_AUTO_RETURN
( default_return_value () )
public:
template <typename T> auto
dispatch (const T &obj) HB_AUTO_RETURN
( _dispatch (obj, hb_prioritize) )
};
struct hb_collect_glyphs_context_t :
hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_empty_t, 0>

View File

@ -1994,8 +1994,11 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
unsigned *alternate_count /* IN/OUT. May be NULL. */,
hb_codepoint_t *alternate_glyphs /* OUT. May be NULL. */)
{
OT::hb_get_glyph_alternates_context_t c (face, glyph, start_offset, alternate_count, alternate_glyphs);
const OT::SubstLookup &lookup = face->table.GSUB->table->get_lookup (lookup_index);
return lookup.get_glyph_alternates (glyph, start_offset, alternate_count, alternate_glyphs);
auto ret = lookup.dispatch (&c);
if (!ret && alternate_count) *alternate_count = 0;
return ret;
}
#endif