[instancer] Implement featureVariations L4 instancing

I *think* this is all.
This commit is contained in:
Behdad Esfahbod 2022-08-09 17:18:58 -06:00
parent 890938ef09
commit e2a875b26c
2 changed files with 26 additions and 24 deletions

View File

@ -678,21 +678,21 @@ def _featureVariationRecordIsUnique(rec, seen):
return True
def _limitFeatureVariationConditionRange(condition, axisRange):
def _limitFeatureVariationConditionRange(condition, axisLimit):
minValue = condition.FilterRangeMinValue
maxValue = condition.FilterRangeMaxValue
if (
minValue > maxValue
or minValue > axisRange.maximum
or maxValue < axisRange.minimum
or minValue > axisLimit.maximum
or maxValue < axisLimit.minimum
):
# condition invalid or out of range
return
values = [minValue, maxValue]
for i, value in enumerate(values):
values[i] = normalizeValue(value, (axisRange.minimum, 0, axisRange.maximum))
values[i] = normalizeValue(value, axisLimit)
return AxisRange(*values)
@ -737,15 +737,15 @@ def _instantiateFeatureVariationRecord(
return applies, shouldKeep
def _limitFeatureVariationRecord(record, axisRanges, axisOrder):
def _limitFeatureVariationRecord(record, axisLimits, axisOrder):
newConditions = []
for i, condition in enumerate(record.ConditionSet.ConditionTable):
if condition.Format == 1:
axisIdx = condition.AxisIndex
axisTag = axisOrder[axisIdx]
if axisTag in axisRanges:
axisRange = axisRanges[axisTag]
newRange = _limitFeatureVariationConditionRange(condition, axisRange)
if axisTag in axisLimits:
axisLimit = axisLimits[axisTag]
newRange = _limitFeatureVariationConditionRange(condition, axisLimit)
if newRange:
# keep condition with updated limits and remapped axis index
condition.FilterRangeMinValue = newRange.minimum
@ -786,7 +786,7 @@ def _instantiateFeatureVariations(table, fvarAxes, axisLimits):
record, i, location, fvarAxes, axisIndexMap
)
if shouldKeep:
shouldKeep = _limitFeatureVariationRecord(record, axisRanges, axisOrder)
shouldKeep = _limitFeatureVariationRecord(record, axisLimits, axisOrder)
if shouldKeep and _featureVariationRecordIsUnique(record, uniqueRecords):
newRecords.append(record)

View File

@ -1589,7 +1589,9 @@ class InstantiateFeatureVariationsTest(object):
]
)
instancer.instantiateFeatureVariations(font, location)
limits = {tag:instancer.NormalizedAxisTent(l, l, l)
for tag,l in location.items()}
instancer.instantiateFeatureVariations(font, limits)
gsub = font["GSUB"].table
featureVariations = gsub.FeatureVariations
@ -1668,7 +1670,7 @@ class InstantiateFeatureVariationsTest(object):
rec1.ConditionSet.ConditionTable[0].Format = 2
with caplog.at_level(logging.WARNING, logger="fontTools.varLib.instancer"):
instancer.instantiateFeatureVariations(font, {"wdth": 0})
instancer.instantiateFeatureVariations(font, {"wdth": instancer.NormalizedAxisTent(0,0,0)})
assert (
"Condition table 0 of FeatureVariationRecord 0 "
@ -1864,25 +1866,25 @@ class LimitTupleVariationAxisRangesTest:
@pytest.mark.parametrize(
"oldRange, newRange, expected",
"oldRange, newLimit, expected",
[
((1.0, -1.0), (-1.0, 1.0), None), # invalid oldRange min > max
((0.6, 1.0), (0, 0.5), None),
((-1.0, -0.6), (-0.5, 0), None),
((0.4, 1.0), (0, 0.5), (0.8, 1.0)),
((-1.0, -0.4), (-0.5, 0), (-1.0, -0.8)),
((0.4, 1.0), (0, 0.4), (1.0, 1.0)),
((-1.0, -0.4), (-0.4, 0), (-1.0, -1.0)),
((-0.5, 0.5), (-0.4, 0.4), (-1.0, 1.0)),
((0, 1.0), (-1.0, 0), (0, 0)), # or None?
((-1.0, 0), (0, 1.0), (0, 0)), # or None?
((1.0, -1.0), (-1.0, 0, 1.0), None), # invalid oldRange min > max
((0.6, 1.0), (0, 0, 0.5), None),
((-1.0, -0.6), (-0.5, 0, 0), None),
((0.4, 1.0), (0, 0, 0.5), (0.8, 1.0)),
((-1.0, -0.4), (-0.5, 0, 0), (-1.0, -0.8)),
((0.4, 1.0), (0, 0, 0.4), (1.0, 1.0)),
((-1.0, -0.4), (-0.4, 0, 0), (-1.0, -1.0)),
((-0.5, 0.5), (-0.4, 0, 0.4), (-1.0, 1.0)),
((0, 1.0), (-1.0, 0, 0), (0, 0)), # or None?
((-1.0, 0), (0, 0, 1.0), (0, 0)), # or None?
],
)
def test_limitFeatureVariationConditionRange(oldRange, newRange, expected):
def test_limitFeatureVariationConditionRange(oldRange, newLimit, expected):
condition = featureVars.buildConditionTable(0, *oldRange)
result = instancer._limitFeatureVariationConditionRange(
condition, instancer.NormalizedAxisRange(*newRange)
condition, instancer.NormalizedAxisTent(*newLimit)
)
assert result == expected