[varLib] Take total bounding box into account when resolving model

Umm. Not sure how useful this is, but helps with cases where there
were not masters on extremes and people expected this to work.
Happens in Higher-Order Interpolation since the axis extremes
are not interesting.

Fixes https://github.com/googlei18n/fontmake/issues/473

Test case (in case someone wants to add it to test suite!):

Before:
$ ./fonttools varLib.models 0,0 .5,0 0,.5 .5,.5 1,1
Sorted locations:
[{}, {'A': 0.5}, {'B': 0.5}, {'A': 0.5, 'B': 0.5}, {'A': 1.0, 'B': 1.0}]
Supports:
[{},
 {'A': (0, 0.5, 0.5)},
 {'B': (0, 0.5, 0.5)},
 {'A': (0, 0.5, 0.5), 'B': (0, 0.5, 0.5)},
 {'A': (0.5, 1.0, 1.0), 'B': (0, 1.0, 1.0)}]

After:
$ ./fonttools varLib.models 0,0 .5,0 0,.5 .5,.5 1,1
Sorted locations:
[{}, {'A': 0.5}, {'B': 0.5}, {'A': 0.5, 'B': 0.5}, {'A': 1.0, 'B': 1.0}]
Supports:
[{},
 {'A': (0, 0.5, 1.0)},
 {'B': (0, 0.5, 1.0)},
 {'A': (0, 0.5, 1.0), 'B': (0, 0.5, 1.0)},
 {'A': (0.5, 1.0, 1.0), 'B': (0, 1.0, 1.0)}]
This commit is contained in:
Behdad Esfahbod 2018-10-25 19:45:21 -07:00
parent 10e10a2c82
commit 7ee81c8821

View File

@ -228,19 +228,21 @@ class VariationModel(object):
supports = []
deltaWeights = []
locations = self.locations
# Compute min/max across each axis, use it as total range.
# TODO Take this as input from outside?
minV = {}
maxV = {}
for l in locations:
for k,v in l.items():
minV[k] = min(v, minV.get(k))
maxV[k] = max(v, maxV.get(k))
for i,loc in enumerate(locations):
box = {}
# Account for axisPoints first
# TODO Use axis min/max instead? Isn't that always -1/+1?
for axis,values in axisPoints.items():
if not axis in loc:
continue
locV = loc[axis]
for axis,locV in loc.items():
if locV > 0:
box[axis] = (0, locV, max({locV}|values))
box[axis] = (0, locV, maxV[axis])
else:
box[axis] = (min({locV}|values), locV, 0)
box[axis] = (minV[axis], locV, 0)
locAxes = set(loc.keys())
# Walk over previous masters now