[instancer.solver] Simplify solver
This commit is contained in:
parent
32be0d46ec
commit
8ca0dab0c0
@ -239,7 +239,23 @@ def changeTupleVariationAxisLimit(var, axisTag, axisLimit):
|
||||
if axisTag not in var.axes:
|
||||
return [var]
|
||||
|
||||
return solver.changeTupleVariationAxisLimit(var, axisTag, axisLimit)
|
||||
tent = var.axes[axisTag]
|
||||
|
||||
solutions = solver.rebaseTent(tent, axisLimit)
|
||||
|
||||
out = []
|
||||
# TODO Reuse original var
|
||||
for scalar,tent in solutions:
|
||||
if scalar == 0: continue
|
||||
newVar = TupleVariation(var.axes, var.coordinates)
|
||||
newVar.axes.pop(axisTag)
|
||||
if tent[1] != 0:
|
||||
newVar.axes[axisTag] == tent
|
||||
if scalar != 1:
|
||||
newVar.scaleDeltas(scalar)
|
||||
out.append(newVar)
|
||||
|
||||
return out
|
||||
|
||||
def _instantiateGvarGlyph(
|
||||
glyphname, glyf, gvar, hMetrics, vMetrics, axisLimits, optimize=True
|
||||
|
@ -1,32 +1,31 @@
|
||||
from fontTools.varLib.models import supportScalar
|
||||
|
||||
def _solvePinned(var, axisTag, axisLimit):
|
||||
def _solvePinned(tent, axisLimit):
|
||||
|
||||
axisMin, axisDef, axisMax = axisLimit
|
||||
assert axisMin == axisDef == axisMax
|
||||
|
||||
support = {axisTag: var.axes.pop(axisTag)}
|
||||
scalar = supportScalar({axisTag: axisLimit.default}, support)
|
||||
support = {'tag': tent}
|
||||
scalar = supportScalar({'tag': axisDef}, support)
|
||||
if scalar == 0.0:
|
||||
return []
|
||||
if scalar != 1.0:
|
||||
var.scaleDeltas(scalar)
|
||||
return [var]
|
||||
return [(scalar, (-1, 0, +1))]
|
||||
|
||||
|
||||
def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
def _solveDefaultUnmoved(tent, axisLimit):
|
||||
|
||||
axisMin, axisDef, axisMax = axisLimit
|
||||
lower, peak, upper = var.axes.get(axisTag)
|
||||
lower, peak, upper = tent
|
||||
|
||||
negative = lower < 0
|
||||
if negative:
|
||||
if axisMin == -1.0:
|
||||
return [var]
|
||||
return [(1, tent)]
|
||||
elif axisMin == 0.0:
|
||||
return []
|
||||
else:
|
||||
if axisMax == 1.0:
|
||||
return [var]
|
||||
return [(1, tent)]
|
||||
elif axisMax == 0.0:
|
||||
return []
|
||||
|
||||
@ -44,8 +43,8 @@ def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
|
||||
# special case when innermost bound == peak == limit
|
||||
if newLower == newPeak == 1.0:
|
||||
var.axes[axisTag] = (-1.0, -1.0, -1.0) if negative else (1.0, 1.0, 1.0)
|
||||
return [var]
|
||||
loc = (-1.0, -1.0, -1.0) if negative else (1.0, 1.0, 1.0)
|
||||
return [(1, loc)]
|
||||
|
||||
# case 1: the whole deltaset falls outside the new limit; we can drop it
|
||||
elif newLower >= 1.0:
|
||||
@ -55,14 +54,13 @@ def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
# we keep the deltaset, update peak and outermost bound and and scale deltas
|
||||
# by the scalar value for the restricted axis at the new limit.
|
||||
elif newPeak >= 1.0:
|
||||
scalar = supportScalar({axisTag: limit}, {axisTag: (lower, peak, upper)})
|
||||
var.scaleDeltas(scalar)
|
||||
scalar = supportScalar({'tag': limit}, {'tag': (lower, peak, upper)})
|
||||
newPeak = 1.0
|
||||
newUpper = 1.0
|
||||
if negative:
|
||||
newLower, newPeak, newUpper = _negate(newUpper, newPeak, newLower)
|
||||
var.axes[axisTag] = (newLower, newPeak, newUpper)
|
||||
return [var]
|
||||
loc = (newLower, newPeak, newUpper)
|
||||
return [(scalar, loc)]
|
||||
|
||||
# case 3: peak falls inside but outermost limit still fits within F2Dot14 bounds;
|
||||
# we keep deltas as is and only scale the axes bounds. Deltas beyond -1.0
|
||||
@ -73,8 +71,8 @@ def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
elif MAX_F2DOT14 < newUpper <= 2.0:
|
||||
# we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
|
||||
newUpper = MAX_F2DOT14
|
||||
var.axes[axisTag] = (newLower, newPeak, newUpper)
|
||||
return [var]
|
||||
loc = (newLower, newPeak, newUpper)
|
||||
return [(1, loc)]
|
||||
|
||||
# case 4: new limit doesn't fit; we need to chop the deltaset into two 'tents',
|
||||
# because the shape of a triangle with part of one side cut off cannot be
|
||||
@ -84,39 +82,40 @@ def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
# duplicate the tent, then adjust lower/peak/upper so that the outermost limit
|
||||
# of the original tent is +/-2.0, whereas the new tent's starts as the old
|
||||
# one peaks and maxes out at +/-1.0.
|
||||
newVar = TupleVariation(var.axes, var.coordinates)
|
||||
if negative:
|
||||
var.axes[axisTag] = (-2.0, -1 * newPeak, -1 * newLower)
|
||||
newVar.axes[axisTag] = (-1.0, -1.0, -1 * newPeak)
|
||||
loc = (-2.0, -1 * newPeak, -1 * newLower)
|
||||
newloc = (-1.0, -1.0, -1 * newPeak)
|
||||
else:
|
||||
var.axes[axisTag] = (newLower, newPeak, MAX_F2DOT14)
|
||||
newVar.axes[axisTag] = (newPeak, 1.0, 1.0)
|
||||
loc = (newLower, newPeak, MAX_F2DOT14)
|
||||
newloc = (newPeak, 1.0, 1.0)
|
||||
# the new tent's deltas are scaled by the difference between the scalar value
|
||||
# for the old tent at the desired limit...
|
||||
scalar1 = supportScalar({axisTag: limit}, {axisTag: (lower, peak, upper)})
|
||||
scalar1 = supportScalar({tag: limit}, {tag: (lower, peak, upper)})
|
||||
# ... and the scalar value for the clamped tent (with outer limit +/-2.0),
|
||||
# which can be simplified like this:
|
||||
scalar2 = 1 / (2 - newPeak)
|
||||
newVar.scaleDeltas(scalar1 - scalar2)
|
||||
|
||||
return [var, newVar]
|
||||
return [(scalar1, loc), (scalar2, newloc)]
|
||||
|
||||
|
||||
def _solveDefaultUnmoved(var, axisTag, axisLimit):
|
||||
def _solveDefaultUnmoved(tent, axisLimit):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def changeTupleVariationAxisLimit(var, axisTag, axisLimit):
|
||||
def rebaseTent(tent, axisLimit):
|
||||
|
||||
axisMin, axisDef, axisMax = axisLimit
|
||||
assert -1 <= axisMin <= axisDef <= axisMax <= +1
|
||||
|
||||
lower, peak, upper = tent
|
||||
assert -2 <= lower <= peak <= upper <= +2
|
||||
|
||||
# Get the pinned case out of the way
|
||||
if axisMin == axisMax:
|
||||
return _solvePinned(var, axisTag, axisLimit)
|
||||
return _solvePinned(tent, axisLimit)
|
||||
|
||||
# If default isn't moving, get that out of the way as well
|
||||
if axisDef == 0:
|
||||
return _solveDefaultUnmoved(var, axisTag, axisLimit)
|
||||
return _solveDefaultUnmoved(tent, axisLimit)
|
||||
|
||||
return _solveGeneral(var, axisTag, axisLimit)
|
||||
return _solveGeneral(tent, axisLimit)
|
||||
|
Loading…
x
Reference in New Issue
Block a user