[layout] Memoize collect_features
Fixes https://github.com/harfbuzz/harfbuzz/pull/1317 Fixes https://oss-fuzz.com/v2/testcase-detail/6543700493598720
This commit is contained in:
parent
84098b1639
commit
eb44bfc864
|
@ -664,8 +664,46 @@ struct hb_collect_features_context_t
|
|||
: g (get_gsubgpos_table (face, table_tag)),
|
||||
feature_indexes (feature_indexes_) {}
|
||||
|
||||
bool inline visited (const OT::Script &s)
|
||||
{
|
||||
/* We might have Null() object here. Don't want to involve
|
||||
* that in the memoize. So, detect empty objects and return. */
|
||||
if (unlikely (!s.has_default_lang_sys () &&
|
||||
!s.get_lang_sys_count ()))
|
||||
return true;
|
||||
|
||||
return visited (s, visited_script);
|
||||
}
|
||||
bool inline visited (const OT::LangSys &l)
|
||||
{
|
||||
/* We might have Null() object here. Don't want to involve
|
||||
* that in the memoize. So, detect empty objects and return. */
|
||||
if (unlikely (!l.has_required_feature () &&
|
||||
!l.get_feature_count ()))
|
||||
return true;
|
||||
|
||||
return visited (l, visited_langsys);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool inline visited (const T &p, hb_set_t &visited_set)
|
||||
{
|
||||
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) &p - (uintptr_t) &g);
|
||||
if (visited_set.has (delta))
|
||||
return true;
|
||||
|
||||
visited_set.add (delta);
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
const OT::GSUBGPOS &g;
|
||||
hb_set_t *feature_indexes;
|
||||
|
||||
private:
|
||||
hb_auto_t<hb_set_t> visited_script;
|
||||
hb_auto_t<hb_set_t> visited_langsys;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -673,12 +711,13 @@ langsys_collect_features (hb_collect_features_context_t *c,
|
|||
const OT::LangSys &l,
|
||||
const hb_tag_t *features)
|
||||
{
|
||||
if (c->visited (l)) return;
|
||||
|
||||
if (!features)
|
||||
{
|
||||
/* All features. */
|
||||
unsigned int index = l.get_required_feature_index ();
|
||||
if (index != HB_OT_LAYOUT_NO_FEATURE_INDEX)
|
||||
c->feature_indexes->add (index);
|
||||
if (l.has_required_feature ())
|
||||
c->feature_indexes->add (l.get_required_feature_index ());
|
||||
|
||||
l.add_feature_indexes_to (c->feature_indexes);
|
||||
}
|
||||
|
@ -688,7 +727,6 @@ langsys_collect_features (hb_collect_features_context_t *c,
|
|||
for (; *features; features++)
|
||||
{
|
||||
hb_tag_t feature_tag = *features;
|
||||
unsigned int feature_index;
|
||||
unsigned int num_features = l.get_feature_count ();
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
|
@ -710,12 +748,15 @@ script_collect_features (hb_collect_features_context_t *c,
|
|||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features)
|
||||
{
|
||||
if (c->visited (s)) return;
|
||||
|
||||
if (!languages)
|
||||
{
|
||||
/* All languages. */
|
||||
langsys_collect_features (c,
|
||||
s.get_default_lang_sys (),
|
||||
features);
|
||||
if (s.has_default_lang_sys ())
|
||||
langsys_collect_features (c,
|
||||
s.get_default_lang_sys (),
|
||||
features);
|
||||
|
||||
unsigned int count = s.get_lang_sys_count ();
|
||||
for (unsigned int language_index = 0; language_index < count; language_index++)
|
||||
|
|
Loading…
Reference in New Issue