diff --git a/Lib/fontTools/feaLib/builder.py b/Lib/fontTools/feaLib/builder.py index bda855e1e..81aa8c2e2 100644 --- a/Lib/fontTools/feaLib/builder.py +++ b/Lib/fontTools/feaLib/builder.py @@ -1658,38 +1658,31 @@ class Builder(object): return default, device + def makeAnchorPos(self, varscalar, deviceTable, location): + device = None + if not isinstance(varscalar, VariableScalar): + if deviceTable is not None: + device = otl.buildDevice(dict(deviceTable)) + return varscalar, device + default, device = self.makeVariablePos(location, varscalar) + if device is not None and deviceTable is not None: + raise FeatureLibError( + "Can't define a device coordinate and variable scalar", location + ) + return default, device + def makeOpenTypeAnchor(self, location, anchor): """ast.Anchor --> otTables.Anchor""" if anchor is None: return None - variable = False deviceX, deviceY = None, None if anchor.xDeviceTable is not None: deviceX = otl.buildDevice(dict(anchor.xDeviceTable)) if anchor.yDeviceTable is not None: deviceY = otl.buildDevice(dict(anchor.yDeviceTable)) - for dim in ("x", "y"): - varscalar = getattr(anchor, dim) - if not isinstance(varscalar, VariableScalar): - continue - if getattr(anchor, dim + "DeviceTable") is not None: - raise FeatureLibError( - "Can't define a device coordinate and variable scalar", location - ) - default, device = self.makeVariablePos(location, varscalar) - setattr(anchor, dim, default) - if device is not None: - if dim == "x": - deviceX = device - else: - deviceY = device - variable = True - - otlanchor = otl.buildAnchor( - anchor.x, anchor.y, anchor.contourpoint, deviceX, deviceY - ) - if variable: - otlanchor.Format = 3 + x, deviceX = self.makeAnchorPos(anchor.x, anchor.xDeviceTable, location) + y, deviceY = self.makeAnchorPos(anchor.y, anchor.yDeviceTable, location) + otlanchor = otl.buildAnchor(x, y, anchor.contourpoint, deviceX, deviceY) return otlanchor _VALUEREC_ATTRS = { diff --git a/Tests/feaLib/builder_test.py b/Tests/feaLib/builder_test.py index 6c1fdab24..434acdce9 100644 --- a/Tests/feaLib/builder_test.py +++ b/Tests/feaLib/builder_test.py @@ -12,6 +12,7 @@ from fontTools.feaLib.lexer import Lexer from fontTools.fontBuilder import addFvar import difflib from io import StringIO +from textwrap import dedent import os import re import shutil @@ -1160,6 +1161,22 @@ class BuilderTest(unittest.TestCase): var_region_axis = var_region_list.Region[0].VarRegionAxis[0] assert self.get_region(var_region_axis) == (0.0, 0.875, 1.0) + def test_variable_anchors_round_trip(self): + """Test that calling `addOpenTypeFeatures` with parsed feature file does + not discard variations from variable anchors.""" + features = """\ + feature curs { + pos cursive one ; + } curs; + """ + + f = StringIO(features) + feafile = Parser(f).parse() + + font = self.make_mock_vf() + addOpenTypeFeatures(font, feafile) + assert dedent(str(feafile)) == dedent(features) + def generate_feature_file_test(name): return lambda self: self.check_feature_file(name)