instancer: always calculate inferred deltas upfront to simplify code
and instead of sumDeltas method, use in-place add operator.
This commit is contained in:
parent
82085f5ea8
commit
dc99925bee
@ -530,41 +530,32 @@ class TupleVariation(object):
|
||||
if optimizedLength < unoptimizedLength:
|
||||
self.coordinates = varOpt.coordinates
|
||||
|
||||
def sumDeltas(self, variations, origCoords=None, endPts=None):
|
||||
# to sum the gvar deltas we need to first interpolate any inferred deltas
|
||||
if origCoords is not None:
|
||||
self.calcInferredDeltas(origCoords, endPts)
|
||||
def __iadd__(self, other):
|
||||
if not isinstance(other, TupleVariation):
|
||||
return NotImplemented
|
||||
deltas1 = self.coordinates
|
||||
axes = self.axes
|
||||
length = len(deltas1)
|
||||
deltaRange = range(length)
|
||||
deltaType = self.checkDeltaType()
|
||||
for other in variations:
|
||||
if other.axes != axes:
|
||||
raise ValueError(
|
||||
"cannot merge TupleVariations with different axes"
|
||||
)
|
||||
if origCoords is not None:
|
||||
other.calcInferredDeltas(origCoords, endPts)
|
||||
deltas2 = other.coordinates
|
||||
if len(deltas2) != length:
|
||||
raise ValueError(
|
||||
"cannot merge TupleVariations with different lengths"
|
||||
)
|
||||
for i, d2 in zip(deltaRange, deltas2):
|
||||
d1 = deltas1[i]
|
||||
if d1 is not None and d2 is not None:
|
||||
if deltaType == "gvar":
|
||||
deltas1[i] = (d1[0] + d2[0], d1[1] + d2[1])
|
||||
else:
|
||||
deltas1[i] = d1 + d2
|
||||
deltas2 = other.coordinates
|
||||
if len(deltas2) != length:
|
||||
raise ValueError(
|
||||
"cannot sum TupleVariation deltas with different lengths"
|
||||
)
|
||||
for i, d2 in zip(range(length), deltas2):
|
||||
d1 = deltas1[i]
|
||||
if d1 is not None and d2 is not None:
|
||||
if deltaType == "gvar":
|
||||
deltas1[i] = (d1[0] + d2[0], d1[1] + d2[1])
|
||||
else:
|
||||
if deltaType == "gvar":
|
||||
raise ValueError(
|
||||
"cannot merge gvar deltas with inferred points"
|
||||
)
|
||||
if d1 is None and d2 is not None:
|
||||
deltas1[i] = d2
|
||||
deltas1[i] = d1 + d2
|
||||
else:
|
||||
if deltaType == "gvar":
|
||||
raise ValueError(
|
||||
"cannot sum gvar deltas with inferred points"
|
||||
)
|
||||
if d1 is None and d2 is not None:
|
||||
deltas1[i] = d2
|
||||
return self
|
||||
|
||||
|
||||
def decompileSharedTuples(axisTags, sharedTupleCount, data, offset):
|
||||
|
@ -28,7 +28,7 @@ log = logging.getLogger("fontTools.varlib.instancer")
|
||||
|
||||
|
||||
def instantiateTupleVariationStore(variations, location, origCoords=None, endPts=None):
|
||||
varGroups = collections.OrderedDict()
|
||||
newVariations = collections.OrderedDict()
|
||||
for var in variations:
|
||||
# Compute the scalar support of the axes to be pinned at the desired location,
|
||||
# excluding any axes that we are not pinning.
|
||||
@ -40,44 +40,28 @@ def instantiateTupleVariationStore(variations, location, origCoords=None, endPts
|
||||
# no influence, drop the TupleVariation
|
||||
continue
|
||||
|
||||
if origCoords is not None:
|
||||
var.calcInferredDeltas(origCoords, endPts)
|
||||
|
||||
var.scaleDeltas(scalar)
|
||||
|
||||
# group TupleVariations by overlapping "tents" (can be empty if all the axes
|
||||
# were instanced)
|
||||
# merge TupleVariations with overlapping "tents"
|
||||
axes = tuple(var.axes.items())
|
||||
if axes in varGroups:
|
||||
varGroups[axes].append(var)
|
||||
if axes in newVariations:
|
||||
newVariations[axes] += var
|
||||
else:
|
||||
varGroups[axes] = [var]
|
||||
newVariations[axes] = var
|
||||
|
||||
# TupleVariations in which all axes have been pinned are dropped from gvar/cvar,
|
||||
# their deltas summed up, rounded and subsequently added to the default instance
|
||||
emptyAxes = ()
|
||||
if emptyAxes in varGroups:
|
||||
defaultVars = varGroups.pop(emptyAxes)
|
||||
var = defaultVars.pop(0)
|
||||
var.sumDeltas(defaultVars, origCoords, endPts)
|
||||
for var in newVariations.values():
|
||||
var.roundDeltas()
|
||||
defaultDeltas = var.coordinates
|
||||
else:
|
||||
defaultDeltas = []
|
||||
|
||||
# merge remaining TupleVariations having the same axes
|
||||
newVariations = []
|
||||
for varGroup in varGroups.values():
|
||||
var = varGroup.pop(0)
|
||||
if varGroup:
|
||||
var.sumDeltas(varGroup, origCoords, endPts)
|
||||
elif origCoords is not None and defaultDeltas:
|
||||
# if the default instance coordinates will be modified, all the inferred
|
||||
# deltas that still remains need to be calculated using the original
|
||||
# coordinates (can later be re-optimized using the modified ones)
|
||||
var.calcInferredDeltas(origCoords, endPts)
|
||||
var.roundDeltas()
|
||||
newVariations.append(var)
|
||||
variations[:] = newVariations
|
||||
# drop TupleVariation if all axes have been pinned (var.axes.items() is empty);
|
||||
# its deltas will be added to the default instance's coordinates
|
||||
defaultVar = newVariations.pop(tuple(), None)
|
||||
|
||||
return defaultDeltas
|
||||
variations[:] = list(newVariations.values())
|
||||
|
||||
return defaultVar.coordinates if defaultVar is not None else []
|
||||
|
||||
|
||||
def instantiateGvarGlyph(varfont, glyphname, location, optimize=True):
|
||||
|
@ -788,29 +788,23 @@ class TupleVariationTest(unittest.TestCase):
|
||||
var.optimize([(0, 0)]*129, list(range(129-4)), isComposite=True)
|
||||
self.assertEqual(var.coordinates, [(0, 0)] + [None]*128)
|
||||
|
||||
def test_sumDeltas_gvar(self):
|
||||
coordinates = [
|
||||
(0, 0), (0, 100), (100, 100), (100, 0),
|
||||
(0, 0), (100, 0), (0, 0), (0, 0),
|
||||
]
|
||||
endPts = [3]
|
||||
axes = {"wght": (0.0, 1.0, 1.0)}
|
||||
def test_sum_deltas_gvar(self):
|
||||
var1 = TupleVariation(
|
||||
axes,
|
||||
{},
|
||||
[
|
||||
(-20, 0), None, None, (20, 0),
|
||||
None, None, None, None,
|
||||
(-20, 0), (-20, 0), (20, 0), (20, 0),
|
||||
(0, 0), (0, 0), (0, 0), (0, 0),
|
||||
]
|
||||
)
|
||||
var2 = TupleVariation(
|
||||
axes,
|
||||
{},
|
||||
[
|
||||
(-10, 0), None, None, (10, 0),
|
||||
None, (20, 0), None, None,
|
||||
(-10, 0), (-10, 0), (10, 0), (10, 0),
|
||||
(0, 0), (20, 0), (0, 0), (0, 0),
|
||||
]
|
||||
)
|
||||
|
||||
var1.sumDeltas([var2], coordinates, endPts)
|
||||
var1 += var2
|
||||
|
||||
self.assertEqual(
|
||||
var1.coordinates,
|
||||
@ -820,13 +814,14 @@ class TupleVariationTest(unittest.TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
def test_sumDeltas_cvar(self):
|
||||
def test_sum_deltas_cvar(self):
|
||||
axes = {"wght": (0.0, 1.0, 1.0)}
|
||||
var1 = TupleVariation(axes, [0, 1, None, None])
|
||||
var2 = TupleVariation(axes, [None, 2, None, 3])
|
||||
var3 = TupleVariation(axes, [None, None, None, 4])
|
||||
|
||||
var1.sumDeltas([var2, var3])
|
||||
var1 += var2
|
||||
var1 += var3
|
||||
|
||||
self.assertEqual(var1.coordinates, [0, 3, None, 7])
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user