From f8abda4570b2d011357b7a4a48efbe76c4946af3 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 27 May 2023 02:39:53 +0300 Subject: [PATCH 1/2] [feaLib] Refactor-out builder code handling variable scalars Refactor-out this piece of code to simplify the next commit. --- Lib/fontTools/feaLib/builder.py | 49 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/Lib/fontTools/feaLib/builder.py b/Lib/fontTools/feaLib/builder.py index 867d059e6..6eaff843a 100644 --- a/Lib/fontTools/feaLib/builder.py +++ b/Lib/fontTools/feaLib/builder.py @@ -1606,6 +1606,23 @@ class Builder(object): self.conditionsets_[key] = value + def makeVariablePos(self, location, varscalar): + if not self.varstorebuilder: + raise FeatureLibError( + "Can't define a variable scalar in a non-variable font", location + ) + + varscalar.axes = self.axes + default, index = varscalar.add_to_variation_store( + self.varstorebuilder, self.model_cache, self.font.get("avar") + ) + + device = None + if index is not None and index != 0xFFFFFFFF: + device = buildVarDevTable(index) + + return default, device + def makeOpenTypeAnchor(self, location, anchor): """ast.Anchor --> otTables.Anchor""" if anchor is None: @@ -1616,7 +1633,6 @@ class Builder(object): deviceX = otl.buildDevice(dict(anchor.xDeviceTable)) if anchor.yDeviceTable is not None: deviceY = otl.buildDevice(dict(anchor.yDeviceTable)) - avar = self.font.get("avar") for dim in ("x", "y"): varscalar = getattr(anchor, dim) if not isinstance(varscalar, VariableScalar): @@ -1625,20 +1641,13 @@ class Builder(object): raise FeatureLibError( "Can't define a device coordinate and variable scalar", location ) - if not self.varstorebuilder: - raise FeatureLibError( - "Can't define a variable scalar in a non-variable font", location - ) - varscalar.axes = self.axes - default, index = varscalar.add_to_variation_store( - self.varstorebuilder, self.model_cache, avar - ) + default, device = self.makeVariablePos(location, varscalar) setattr(anchor, dim, default) - if index is not None and index != 0xFFFFFFFF: + if device is not None: if dim == "x": - deviceX = buildVarDevTable(index) + deviceX = device else: - deviceY = buildVarDevTable(index) + deviceY = device variable = True otlanchor = otl.buildAnchor( @@ -1659,7 +1668,6 @@ class Builder(object): if not v: return None - avar = self.font.get("avar") vr = {} for astName, (otName, isDevice) in self._VALUEREC_ATTRS.items(): val = getattr(v, astName, None) @@ -1674,18 +1682,9 @@ class Builder(object): raise FeatureLibError( "Can't define a device coordinate and variable scalar", location ) - if not self.varstorebuilder: - raise FeatureLibError( - "Can't define a variable scalar in a non-variable font", - location, - ) - val.axes = self.axes - default, index = val.add_to_variation_store( - self.varstorebuilder, self.model_cache, avar - ) - vr[otName] = default - if index is not None and index != 0xFFFFFFFF: - vr[otDeviceName] = buildVarDevTable(index) + vr[otName], device = self.makeVariablePos(location, val) + if device is not None: + vr[otDeviceName] = device else: vr[otName] = val From fd854d70d81fb2e1922d799dd31f8fdc44dc19ea Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sat, 27 May 2023 02:50:15 +0300 Subject: [PATCH 2/2] =?UTF-8?q?[feaLib]=20Simplify=20variable=20scalars=20?= =?UTF-8?q?that=20don=E2=80=99t=20vary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a variable scalar does not vary (i.e. all values are the same), we can simplify it and use a simple value instead. Arguably users shouldn’t be using variable scalar in this case, but it helps when the feature code is auto generated so each feaLib users doesn’t have to do the check done here themselves. --- Lib/fontTools/feaLib/builder.py | 3 +++ Tests/feaLib/data/variable_scalar_valuerecord.fea | 1 + Tests/feaLib/data/variable_scalar_valuerecord.ttx | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/fontTools/feaLib/builder.py b/Lib/fontTools/feaLib/builder.py index 6eaff843a..e0e102864 100644 --- a/Lib/fontTools/feaLib/builder.py +++ b/Lib/fontTools/feaLib/builder.py @@ -1613,6 +1613,9 @@ class Builder(object): ) varscalar.axes = self.axes + if not varscalar.does_vary: + return varscalar.default, None + default, index = varscalar.add_to_variation_store( self.varstorebuilder, self.model_cache, self.font.get("avar") ) diff --git a/Tests/feaLib/data/variable_scalar_valuerecord.fea b/Tests/feaLib/data/variable_scalar_valuerecord.fea index bf9a26b7d..0b4026544 100644 --- a/Tests/feaLib/data/variable_scalar_valuerecord.fea +++ b/Tests/feaLib/data/variable_scalar_valuerecord.fea @@ -2,4 +2,5 @@ languagesystem DFLT dflt; feature kern { pos one 1; pos two <0 (wght=200:12 wght=900:22 wdth=150,wght=900:42) 0 0>; + pos three <0 (wght=200:12 wght=900:12 wdth=150,wght=900:12) 0 0>; } kern; diff --git a/Tests/feaLib/data/variable_scalar_valuerecord.ttx b/Tests/feaLib/data/variable_scalar_valuerecord.ttx index 338b72213..e3251f691 100644 --- a/Tests/feaLib/data/variable_scalar_valuerecord.ttx +++ b/Tests/feaLib/data/variable_scalar_valuerecord.ttx @@ -76,7 +76,7 @@ - + @@ -97,6 +97,13 @@ + + + + + + +