[VARC] More towards drawing
This commit is contained in:
parent
68277fc0b5
commit
4b6c574d54
@ -17,6 +17,7 @@ from fontTools.misc.arrayTools import quantizeRect
|
||||
from fontTools.misc.roundTools import otRound
|
||||
from fontTools.misc.transform import Transform, Identity, DecomposedTransform
|
||||
from fontTools.misc.textTools import bytesjoin, pad, safeEval
|
||||
from fontTools.misc.vector import Vector
|
||||
from fontTools.pens.boundsPen import ControlBoundsPen
|
||||
from fontTools.pens.transformPen import TransformPen
|
||||
from .otBase import (
|
||||
@ -244,6 +245,7 @@ class VarComponent:
|
||||
|
||||
for attr_name, mapping_values in VAR_COMPONENT_TRANSFORM_MAPPING.items():
|
||||
value = getattr(self.transform, attr_name)
|
||||
# How to drop scaleX == scaleY here?
|
||||
data.append(write_transform_component(value, mapping_values))
|
||||
|
||||
if flags & VarComponentFlags.TRANSFORM_HAS_VARIATION:
|
||||
@ -323,6 +325,30 @@ class VarComponent:
|
||||
result = self.__eq__(other)
|
||||
return result if result is NotImplemented else not result
|
||||
|
||||
def getComponentValues(self):
|
||||
flags = self.flags
|
||||
|
||||
if flags & VarComponentFlags.AXIS_VALUES_HAVE_VARIATION:
|
||||
locationValues = [fl2fi(v, 14) for v in self.location.values()]
|
||||
else:
|
||||
locationValues = []
|
||||
|
||||
transformValues = []
|
||||
|
||||
def append_transform_component(value, values):
|
||||
nonlocal transformValues
|
||||
if flags & values.flag:
|
||||
transformValues.append(
|
||||
fl2fi(value / values.scale, values.fractionalBits)
|
||||
)
|
||||
|
||||
if flags & VarComponentFlags.TRANSFORM_HAS_VARIATION:
|
||||
for attr_name, mapping_values in VAR_COMPONENT_TRANSFORM_MAPPING.items():
|
||||
value = getattr(self.transform, attr_name)
|
||||
append_transform_component(value, mapping_values)
|
||||
|
||||
return Vector(locationValues), Vector(transformValues)
|
||||
|
||||
|
||||
class CvarEncodedValues(BaseTable):
|
||||
def __init__(self, values=None):
|
||||
|
@ -102,6 +102,7 @@ class _TTGlyphSetGlyf(_TTGlyphSet):
|
||||
def __getitem__(self, glyphName):
|
||||
return _TTGlyphGlyf(self, glyphName, recalcBounds=self.recalcBounds)
|
||||
|
||||
|
||||
class _TTGlyphSetGlyf(_TTGlyphSet):
|
||||
def __init__(self, font, location, recalcBounds=True):
|
||||
self.glyfTable = font["glyf"]
|
||||
@ -275,12 +276,15 @@ class _TTGlyphCFF(_TTGlyph):
|
||||
|
||||
|
||||
class _TTGlyphVARC(_TTGlyph):
|
||||
|
||||
def _draw(self, pen, isPointPen):
|
||||
"""Draw the glyph onto ``pen``. See fontTools.pens.basePen for details
|
||||
how that works.
|
||||
"""
|
||||
from fontTools.ttLib.tables.otTables import VarComponentFlags
|
||||
from fontTools.ttLib.tables.otTables import (
|
||||
VarComponentFlags,
|
||||
NO_VARIATION_INDEX,
|
||||
)
|
||||
|
||||
glyphSet = self.glyphSet
|
||||
varc = glyphSet.varcTable
|
||||
idx = varc.Coverage.glyphs.index(self.name)
|
||||
@ -288,27 +292,42 @@ class _TTGlyphVARC(_TTGlyph):
|
||||
|
||||
from fontTools.varLib.multiVarStore import MultiVarStoreInstancer
|
||||
|
||||
instancer = MultiVarStoreInstancer(varc.MultiVarStore, self.glyphSet.font["fvar"].axes, self.glyphSet.location)
|
||||
instancer = MultiVarStoreInstancer(
|
||||
varc.MultiVarStore, self.glyphSet.font["fvar"].axes, self.glyphSet.location
|
||||
)
|
||||
instancer.setLocation(self.glyphSet.location)
|
||||
|
||||
for comp in glyph.components:
|
||||
comp = copy(comp) # Shallow copy
|
||||
locationValues, transformValues = comp.getComponentValues()
|
||||
|
||||
comp = copy(comp) # Shallow copy
|
||||
if comp.locationVarIndex != NO_VARIATION_INDEX:
|
||||
assert locationValues
|
||||
locationDeltas = instancer[comp.locationVarIndex]
|
||||
locationValues = list(locationValues + locationDeltas)
|
||||
if comp.transformVarIndex != NO_VARIATION_INDEX:
|
||||
assert transformValues
|
||||
transformDeltas = instancer[comp.transformVarIndex]
|
||||
transformValues = list(transformValues + transformDeltas)
|
||||
|
||||
with self.glyphSet.glyphSet.pushLocation(
|
||||
comp.location, comp.flags & VarComponentFlags.RESET_UNSPECIFIED_AXES
|
||||
):
|
||||
try:
|
||||
pen.addVarComponent(
|
||||
comp.glyphName, comp.transform, self.glyphSet.rawLocation
|
||||
)
|
||||
except AttributeError:
|
||||
t = comp.transform.toTransform()
|
||||
if isPointPen:
|
||||
tPen = TransformPointPen(pen, t)
|
||||
self.glyphSet[comp.glyphName].drawPoints(tPen)
|
||||
else:
|
||||
tPen = TransformPen(pen, t)
|
||||
self.glyphSet[comp.glyphName].draw(tPen)
|
||||
with self.glyphSet.pushLocation(
|
||||
comp.location, comp.flags & VarComponentFlags.RESET_UNSPECIFIED_AXES
|
||||
):
|
||||
try:
|
||||
pen.addVarComponent(
|
||||
comp.glyphName, comp.transform, self.glyphSet.rawLocation
|
||||
)
|
||||
except AttributeError:
|
||||
t = comp.transform.toTransform()
|
||||
if isPointPen:
|
||||
tPen = TransformPointPen(pen, t)
|
||||
self.glyphSet[comp.glyphName].drawPoints(tPen)
|
||||
else:
|
||||
tPen = TransformPen(pen, t)
|
||||
self.glyphSet[comp.glyphName].draw(tPen)
|
||||
|
||||
def draw(self, pen):
|
||||
self._draw(pen, False)
|
||||
|
@ -166,19 +166,22 @@ class MultiVarStoreInstancer(object):
|
||||
|
||||
@staticmethod
|
||||
def interpolateFromDeltasAndScalars(deltas, scalars):
|
||||
assert len(deltas) % len(scalars) == 0
|
||||
deltas = deltas.values
|
||||
if not deltas:
|
||||
return Vector([])
|
||||
assert len(deltas) % len(scalars) == 0, (len(deltas), len(scalars))
|
||||
m = len(deltas) // len(scalars)
|
||||
delta = Vector([0] * m)
|
||||
for d, s in zip((Vector(d) for d in batched(deltas, m)), scalars):
|
||||
for d, s in zip(batched(deltas, m), scalars):
|
||||
if not s:
|
||||
continue
|
||||
delta += d * s
|
||||
return tuple(delta)
|
||||
delta += Vector(d) * s
|
||||
return delta
|
||||
|
||||
def __getitem__(self, varidx):
|
||||
major, minor = varidx >> 16, varidx & 0xFFFF
|
||||
if varidx == NO_VARIATION_INDEX:
|
||||
return ()
|
||||
return Vector([])
|
||||
varData = self._varData
|
||||
scalars = [self._getScalar(ri) for ri in varData[major].VarRegionIndex]
|
||||
deltas = varData[major].Item[minor]
|
||||
|
Loading…
x
Reference in New Issue
Block a user