instancer: partially instantiate avar and fvar

for avar, we drop segments of the axes being pinned.

for fvar, we drop the pinned axes and all the named instances whose coordinates are different from the pinned location.
This commit is contained in:
Cosimo Lupo 2019-04-29 18:04:21 +02:00
parent 691547b00b
commit d478ef050f
No known key found for this signature in database
GPG Key ID: 20D4A261E4A0E642

View File

@ -263,10 +263,7 @@ class _TupleVarStoreAdapter(object):
# dedup regions while keeping original order # dedup regions while keeping original order
uniqueRegions = collections.OrderedDict.fromkeys(prunedRegions) uniqueRegions = collections.OrderedDict.fromkeys(prunedRegions)
self.regions = [dict(items) for items in uniqueRegions if items] self.regions = [dict(items) for items in uniqueRegions if items]
# TODO(anthrotype) uncomment this once we support subsetting fvar axes self.axisOrder = [axisTag for axisTag in self.axisOrder if axisTag not in axes]
# self.axisOrder = [
# axisTag for axisTag in self.axisOrder if axisTag not in axes
# ]
def instantiate(self, location): def instantiate(self, location):
defaultDeltaArray = [] defaultDeltaArray = []
@ -448,6 +445,47 @@ def _instantiateFeatureVariations(table, fvarAxes, location):
del table.FeatureVariations del table.FeatureVariations
def instantiateAvar(varfont, location):
segments = varfont["avar"].segments
# drop table if we instantiate all the axes
if set(location).issuperset(segments):
log.info("Dropping avar table")
del varfont["avar"]
return
log.info("Instantiating avar table")
for axis in location:
if axis in segments:
del segments[axis]
def instantiateFvar(varfont, location):
# 'location' dict must contain user-space (non-normalized) coordinates
fvar = varfont["fvar"]
# drop table if we instantiate all the axes
if set(location).issuperset(axis.axisTag for axis in fvar.axes):
log.info("Dropping fvar table")
del varfont["fvar"]
return
log.info("Instantiating fvar table")
fvar.axes = [axis for axis in fvar.axes if axis.axisTag not in location]
# only keep NamedInstances whose coordinates == pinned axis location
instances = []
for instance in fvar.instances:
if any(instance.coordinates[axis] != value for axis, value in location.items()):
continue
for axis in location:
del instance.coordinates[axis]
instances.append(instance)
fvar.instances = instances
def normalize(value, triple, avar_mapping): def normalize(value, triple, avar_mapping):
value = normalizeValue(value, triple) value = normalizeValue(value, triple)
if avar_mapping: if avar_mapping:
@ -471,15 +509,17 @@ def normalizeAxisLimits(varfont, axis_limits):
avar_segments = {} avar_segments = {}
if "avar" in varfont: if "avar" in varfont:
avar_segments = varfont["avar"].segments avar_segments = varfont["avar"].segments
normalized_limits = {}
for axis_tag, triple in axes.items(): for axis_tag, triple in axes.items():
avar_mapping = avar_segments.get(axis_tag, None) avar_mapping = avar_segments.get(axis_tag, None)
value = axis_limits[axis_tag] value = axis_limits[axis_tag]
if isinstance(value, tuple): if isinstance(value, tuple):
axis_limits[axis_tag] = tuple( normalized_limits[axis_tag] = tuple(
normalize(v, triple, avar_mapping) for v in axis_limits[axis_tag] normalize(v, triple, avar_mapping) for v in axis_limits[axis_tag]
) )
else: else:
axis_limits[axis_tag] = normalize(value, triple, avar_mapping) normalized_limits[axis_tag] = normalize(value, triple, avar_mapping)
return normalized_limits
def sanityCheckVariableTables(varfont): def sanityCheckVariableTables(varfont):
@ -498,32 +538,37 @@ def instantiateVariableFont(varfont, axis_limits, inplace=False, optimize=True):
if not inplace: if not inplace:
varfont = deepcopy(varfont) varfont = deepcopy(varfont)
normalizeAxisLimits(varfont, axis_limits) normalized_limits = normalizeAxisLimits(varfont, axis_limits)
log.info("Normalized limits: %s", axis_limits) log.info("Normalized limits: %s", normalized_limits)
# TODO Remove this check once ranges are supported # TODO Remove this check once ranges are supported
if any(isinstance(v, tuple) for v in axis_limits.values()): if any(isinstance(v, tuple) for v in axis_limits.values()):
raise NotImplementedError("Axes range limits are not supported yet") raise NotImplementedError("Axes range limits are not supported yet")
if "gvar" in varfont: if "gvar" in varfont:
instantiateGvar(varfont, axis_limits, optimize=optimize) instantiateGvar(varfont, normalized_limits, optimize=optimize)
if "cvar" in varfont: if "cvar" in varfont:
instantiateCvar(varfont, axis_limits) instantiateCvar(varfont, normalized_limits)
if "MVAR" in varfont: if "MVAR" in varfont:
instantiateMVAR(varfont, axis_limits) instantiateMVAR(varfont, normalized_limits)
if "HVAR" in varfont: if "HVAR" in varfont:
instantiateHVAR(varfont, axis_limits) instantiateHVAR(varfont, normalized_limits)
if "VVAR" in varfont: if "VVAR" in varfont:
instantiateVVAR(varfont, axis_limits) instantiateVVAR(varfont, normalized_limits)
instantiateOTL(varfont, axis_limits) instantiateOTL(varfont, normalized_limits)
instantiateFeatureVariations(varfont, axis_limits) instantiateFeatureVariations(varfont, normalized_limits)
if "avar" in varfont:
instantiateAvar(varfont, normalized_limits)
instantiateFvar(varfont, axis_limits)
return varfont return varfont