[instance] drop and don't collect lookups from feature variations when fully instancing.

This previously incorrectly collected lookups that could be reached via feature variations that are dropped and not activated by the current instance position.
This commit is contained in:
Garret Rieger 2023-01-14 00:23:53 +00:00 committed by Behdad Esfahbod
parent d250148db0
commit ea1ee0d4b6
20 changed files with 33 additions and 6 deletions

View File

@ -4142,8 +4142,11 @@ struct GSUBGPOSVersion1_2
bool subset (hb_subset_layout_context_t *c) const bool subset (hb_subset_layout_context_t *c) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
auto *out = c->subset_context->serializer->embed (*this);
if (unlikely (!out)) return_trace (false); auto *out = c->subset_context->serializer->start_embed (this);
if (unlikely (!c->subset_context->serializer->extend_min (out))) return_trace (false);
out->version = version;
typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList; typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList;
reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList) reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList)
@ -4166,9 +4169,23 @@ struct GSUBGPOSVersion1_2
#ifndef HB_NO_VAR #ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u) if (version.to_int () >= 0x00010001u)
{ {
bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); auto snapshot = c->subset_context->serializer->snapshot ();
if (!c->subset_context->serializer->extend_min (&out->featureVars))
return_trace (false);
// TODO(qxliu76): the current implementation doesn't correctly handle feature variations
// that are dropped by instancing when the associated conditions don't trigger.
// Since partial instancing isn't yet supported this isn't an issue yet but will
// need to be fixed for partial instancing.
// if all axes are pinned all feature vars are dropped.
bool ret = !c->subset_context->plan->all_axes_pinned
&& out->featureVars.serialize_subset (c->subset_context, featureVars, this, c);
if (!ret && version.major == 1) if (!ret && version.major == 1)
{ {
c->subset_context->serializer->revert (snapshot);
out->version.major = 1; out->version.major = 1;
out->version.minor = 0; out->version.minor = 0;
} }

View File

@ -188,7 +188,17 @@ static void _collect_layout_indices (hb_subset_plan_t *plan,
f->add_lookup_indexes_to (lookup_indices); f->add_lookup_indexes_to (lookup_indices);
} }
// If all axes are pinned then all feature variations will be dropped so there's no need
// to collect lookups from them.
if (!plan->all_axes_pinned)
{
// TODO(qxliu76): this collection doesn't work correctly for feature variations that are dropped
// but not applied. The collection will collect and retain the lookup indices
// associated with those dropped but not activated rules. Since partial instancing
// isn't yet supported this isn't an issue yet but will need to be fixed for
// partial instancing.
table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices); table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices);
}
} }

View File

@ -3,10 +3,10 @@ MPLUS1-Variable.ttf
PROFILES: PROFILES:
default.txt default.txt
notdef-outline.txt
SUBSETS: SUBSETS:
*
INSTANCES: INSTANCES:
wght=100
wght=400 wght=400