diff --git a/Lib/fontTools/varLib/instancer/featureVars.py b/Lib/fontTools/varLib/instancer/featureVars.py index 350c90a41..d9370d9d6 100644 --- a/Lib/fontTools/varLib/instancer/featureVars.py +++ b/Lib/fontTools/varLib/instancer/featureVars.py @@ -8,7 +8,10 @@ log = logging.getLogger("fontTools.varLib.instancer") def _featureVariationRecordIsUnique(rec, seen): conditionSet = [] - for cond in rec.ConditionSet.ConditionTable: + conditionSets = ( + rec.ConditionSet.ConditionTable if rec.ConditionSet is not None else [] + ) + for cond in conditionSets: if cond.Format != 1: # can't tell whether this is duplicate, assume is unique return True @@ -54,6 +57,10 @@ def _instantiateFeatureVariationRecord( from fontTools.varLib.instancer import NormalizedAxisTripleAndDistances default_triple = NormalizedAxisTripleAndDistances(-1, 0, +1) + if record.ConditionSet is None: + record.ConditionSet = ot.ConditionSet() + record.ConditionSet.ConditionTable = [] + record.ConditionSet.ConditionCount = 0 for i, condition in enumerate(record.ConditionSet.ConditionTable): if condition.Format == 1: axisIdx = condition.AxisIndex @@ -100,6 +107,8 @@ def _instantiateFeatureVariationRecord( if newConditions is not None and shouldKeep: record.ConditionSet.ConditionTable = newConditions + if not newConditions: + record.ConditionSet = None shouldKeep = True else: shouldKeep = False diff --git a/Tests/varLib/instancer/instancer_test.py b/Tests/varLib/instancer/instancer_test.py index e8bedcf81..0b0702d7a 100644 --- a/Tests/varLib/instancer/instancer_test.py +++ b/Tests/varLib/instancer/instancer_test.py @@ -1595,7 +1595,8 @@ class InstantiateVariableFontTest(object): def _conditionSetAsDict(conditionSet, axisOrder): result = {} - for cond in conditionSet.ConditionTable: + conditionSets = conditionSet.ConditionTable if conditionSet is not None else [] + for cond in conditionSets: assert cond.Format == 1 axisTag = axisOrder[cond.AxisIndex] result[axisTag] = (cond.FilterRangeMinValue, cond.FilterRangeMaxValue) @@ -1821,6 +1822,24 @@ class InstantiateFeatureVariationsTest(object): else: assert not gsub.FeatureList.FeatureRecord + def test_null_conditionset(self): + # A null ConditionSet offset should be treated like an empty ConditionTable, i.e. + # all contexts are matched; see https://github.com/fonttools/fonttools/issues/3211 + font = makeFeatureVarsFont( + [([{"wght": (-1.0, 1.0)}], {"uni0024": "uni0024.nostroke"})] + ) + gsub = font["GSUB"].table + gsub.FeatureVariations.FeatureVariationRecord[0].ConditionSet = None + + location = instancer.NormalizedAxisLimits({"wght": 0.5}) + instancer.instantiateFeatureVariations(font, location) + + assert not hasattr(gsub, "FeatureVariations") + assert gsub.Version == 0x00010000 + + lookupIndices = gsub.FeatureList.FeatureRecord[0].Feature.LookupListIndex + assert _getSubstitutions(gsub, lookupIndices) == {"uni0024": "uni0024.nostroke"} + def test_unsupported_condition_format(self, caplog): font = makeFeatureVarsFont( [