From d478ef050fc36ec24937718d63c6401b8c534b1c Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Mon, 29 Apr 2019 18:04:21 +0200 Subject: [PATCH] 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. --- Lib/fontTools/varLib/instancer.py | 75 ++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/Lib/fontTools/varLib/instancer.py b/Lib/fontTools/varLib/instancer.py index 4df669f86..f5b6c2dd2 100644 --- a/Lib/fontTools/varLib/instancer.py +++ b/Lib/fontTools/varLib/instancer.py @@ -263,10 +263,7 @@ class _TupleVarStoreAdapter(object): # dedup regions while keeping original order uniqueRegions = collections.OrderedDict.fromkeys(prunedRegions) 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): defaultDeltaArray = [] @@ -448,6 +445,47 @@ def _instantiateFeatureVariations(table, fvarAxes, location): 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): value = normalizeValue(value, triple) if avar_mapping: @@ -471,15 +509,17 @@ def normalizeAxisLimits(varfont, axis_limits): avar_segments = {} if "avar" in varfont: avar_segments = varfont["avar"].segments + normalized_limits = {} for axis_tag, triple in axes.items(): avar_mapping = avar_segments.get(axis_tag, None) value = axis_limits[axis_tag] 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] ) 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): @@ -498,32 +538,37 @@ def instantiateVariableFont(varfont, axis_limits, inplace=False, optimize=True): if not inplace: 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 if any(isinstance(v, tuple) for v in axis_limits.values()): raise NotImplementedError("Axes range limits are not supported yet") if "gvar" in varfont: - instantiateGvar(varfont, axis_limits, optimize=optimize) + instantiateGvar(varfont, normalized_limits, optimize=optimize) if "cvar" in varfont: - instantiateCvar(varfont, axis_limits) + instantiateCvar(varfont, normalized_limits) if "MVAR" in varfont: - instantiateMVAR(varfont, axis_limits) + instantiateMVAR(varfont, normalized_limits) if "HVAR" in varfont: - instantiateHVAR(varfont, axis_limits) + instantiateHVAR(varfont, normalized_limits) 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