Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[instancer] Allow null ConditionSet #3212

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion Lib/fontTools/varLib/instancer/featureVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
21 changes: 20 additions & 1 deletion Tests/varLib/instancer/instancer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,8 @@ def test_varComposite(self):

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)
Expand Down Expand Up @@ -1821,6 +1822,24 @@ def test_full_instance(self, location, appliedSubs):
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(
[
Expand Down