[varLib.avar] Test & fix _pruneLocations
This commit is contained in:
parent
700b6a7b0e
commit
2742c6287c
@ -22,15 +22,16 @@ def _pruneLocations(locations, poles, axisTags):
|
||||
model = VariationModel(locations, axisTags)
|
||||
modelMapping = model.mapping
|
||||
modelSupports = model.supports
|
||||
pins = poles.copy()
|
||||
for pole in poles.keys():
|
||||
location = dict(pole)
|
||||
pins = {tuple(k.items()): None for k in poles}
|
||||
for location in poles:
|
||||
i = locations.index(location)
|
||||
i = modelMapping[i]
|
||||
support = modelSupports[i]
|
||||
supportAxes = set(support.keys())
|
||||
for supportIndex, (axisTag, (minV, _, maxV)) in enumerate(support.items()):
|
||||
for axisTag, (minV, _, maxV) in support.items():
|
||||
for v in (minV, maxV):
|
||||
if v in (-1, 0, 1):
|
||||
continue
|
||||
for pin in pins.keys():
|
||||
pinLocation = dict(pin)
|
||||
pinAxes = set(pinLocation.keys())
|
||||
@ -40,21 +41,27 @@ def _pruneLocations(locations, poles, axisTags):
|
||||
continue
|
||||
if pinLocation[axisTag] == v:
|
||||
break
|
||||
else:
|
||||
# No pin found. Go through the previous masters
|
||||
# and find a suitable pin. Going backwards is
|
||||
# better because it can find a pin that is close
|
||||
# to the pole in more dimensions, and reducing
|
||||
# the total number of pins needed.
|
||||
for candidateIdx in range(supportIndex - 1, -1, -1):
|
||||
candidate = modelSupports[candidateIdx]
|
||||
candidateAxes = set(candidate.keys())
|
||||
if candidateAxes != supportAxes:
|
||||
continue
|
||||
if axisTag not in candidateAxes:
|
||||
continue
|
||||
if candidateLocation[axisTag] == v:
|
||||
pins[tuple(candidateLocation.items())] = None
|
||||
else:
|
||||
# No pin found. Go through the previous masters
|
||||
# and find a suitable pin. Going backwards is
|
||||
# better because it can find a pin that is close
|
||||
# to the pole in more dimensions, and reducing
|
||||
# the total number of pins needed.
|
||||
for candidateIdx in range(i - 1, -1, -1):
|
||||
candidate = modelSupports[candidateIdx]
|
||||
candidateAxes = set(candidate.keys())
|
||||
if candidateAxes != supportAxes:
|
||||
continue
|
||||
if axisTag not in candidateAxes:
|
||||
continue
|
||||
candidate = {
|
||||
k: defaultV for k, (_, defaultV, _) in candidate.items()
|
||||
}
|
||||
if candidate[axisTag] == v:
|
||||
pins[tuple(candidate.items())] = None
|
||||
break
|
||||
else:
|
||||
assert False, "No pin found"
|
||||
return [dict(t) for t in pins.keys()]
|
||||
|
||||
|
||||
@ -115,7 +122,8 @@ def mappings_from_avar(font, denormalize=True):
|
||||
key=lambda t: (len(t), tuple(axisIndexes[tag] for tag, _ in t)),
|
||||
)
|
||||
]
|
||||
inputLocations = _pruneLocations(inputLocations, poles, axisTags)
|
||||
poles = [dict(t) for t in poles.keys()]
|
||||
inputLocations = _pruneLocations(inputLocations, list(poles), axisTags)
|
||||
|
||||
# Find the output locations, at input locations
|
||||
varIdxMap = avar.table.VarIdxMap
|
||||
@ -210,6 +218,7 @@ def main(args=None):
|
||||
segments, mappings = mappings_from_avar(font)
|
||||
pprint(segments)
|
||||
pprint(mappings)
|
||||
print(len(mappings), "mappings")
|
||||
return
|
||||
|
||||
axisTags = [a.axisTag for a in font["fvar"].axes]
|
||||
|
59
Tests/varLib/avar_test.py
Normal file
59
Tests/varLib/avar_test.py
Normal file
@ -0,0 +1,59 @@
|
||||
from fontTools.varLib.avar import _pruneLocations
|
||||
import unittest
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"locations, poles, expected",
|
||||
[
|
||||
(
|
||||
[
|
||||
{"wght": 1},
|
||||
{"wght": 0.5},
|
||||
],
|
||||
[
|
||||
{"wght": 0.5},
|
||||
],
|
||||
[
|
||||
{"wght": 0.5},
|
||||
],
|
||||
),
|
||||
(
|
||||
[
|
||||
{"wght": 1, "wdth": 1},
|
||||
{"wght": 0.5, "wdth": 1},
|
||||
],
|
||||
[
|
||||
{"wght": 1, "wdth": 1},
|
||||
],
|
||||
[
|
||||
{"wght": 1, "wdth": 1},
|
||||
{"wght": 0.5, "wdth": 1},
|
||||
],
|
||||
),
|
||||
(
|
||||
[
|
||||
{"wght": 1},
|
||||
{"wdth": 1},
|
||||
{"wght": 0.5, "wdth": 0.5},
|
||||
],
|
||||
[
|
||||
{"wght": 0.5, "wdth": 0.5},
|
||||
],
|
||||
[
|
||||
{"wght": 0.5, "wdth": 0.5},
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_pruneLocations(locations, poles, expected):
|
||||
axisTags = set()
|
||||
for location in locations:
|
||||
axisTags.update(location.keys())
|
||||
axisTags = sorted(axisTags)
|
||||
|
||||
locations = [{}] + locations
|
||||
|
||||
output = _pruneLocations(locations, poles, axisTags)
|
||||
|
||||
assert output == expected, (output, expected)
|
Loading…
x
Reference in New Issue
Block a user