diff --git a/Lib/ufo2ft/filters/transformations.py b/Lib/ufo2ft/filters/transformations.py index a7fe88e37..ecf8fbaac 100644 --- a/Lib/ufo2ft/filters/transformations.py +++ b/Lib/ufo2ft/filters/transformations.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import, unicode_literals - import math from collections import namedtuple import logging @@ -7,38 +5,30 @@ from ufo2ft.fontInfoData import getAttrWithFallback from ufo2ft.filters import BaseFilter -from fontTools.misc.py23 import round from fontTools.misc.fixedTools import otRound from fontTools.misc.transform import Transform, Identity -from fontTools.pens.recordingPen import RecordingPen -from fontTools.pens.transformPen import TransformPen as _TransformPen +from fontTools.pens.recordingPen import RecordingPointPen +from fontTools.pens.transformPen import TransformPointPen as _TransformPointPen from enum import IntEnum log = logging.getLogger(__name__) -class TransformPen(_TransformPen): - def __init__(self, outPen, transformation, modified=None): - super(TransformPen, self).__init__(outPen, transformation) +class TransformPointPen(_TransformPointPen): + def __init__(self, outPointPen, transformation, modified=None): + super().__init__(outPointPen, transformation) self.modified = modified if modified is not None else set() self._inverted = self._transformation.inverse() - def addComponent(self, baseGlyph, transformation): + def addComponent(self, baseGlyph, transformation, identifier=None, **kwargs): if baseGlyph in self.modified: - - if transformation[:4] == (1, 0, 0, 1): - # if the component's transform only has a simple offset, then - # we don't need to transform the component again - self._outPen.addComponent(baseGlyph, transformation) - return - # multiply the component's transformation matrix with the inverse # of the filter's transformation matrix to compensate for the # transformation already applied to the base glyph transformation = Transform(*transformation).transform(self._inverted) - super(TransformPen, self).addComponent(baseGlyph, transformation) + super().addComponent(baseGlyph, transformation, identifier=identifier, **kwargs) class TransformationsFilter(BaseFilter): @@ -123,13 +113,13 @@ def filter(self, glyph): # transformed, or there are no more components modified.add(base_name) - rec = RecordingPen() - glyph.draw(rec) + rec = RecordingPointPen() + glyph.drawPoints(rec) glyph.clearContours() glyph.clearComponents() - outpen = glyph.getPen() - filterpen = TransformPen(outpen, matrix, modified) + outpen = glyph.getPointPen() + filterpen = TransformPointPen(outpen, matrix, modified) rec.replay(filterpen) # anchors are not drawn through the pen API, diff --git a/tests/filters/transformations_test.py b/tests/filters/transformations_test.py index 2815d6d8a..79d9b4424 100644 --- a/tests/filters/transformations_test.py +++ b/tests/filters/transformations_test.py @@ -1,7 +1,6 @@ -from __future__ import print_function, division, absolute_import from ufo2ft.filters.transformations import TransformationsFilter, log from fontTools.misc.loggingTools import CapturingLogHandler -from fontTools.misc.py23 import isclose +from math import isclose import pytest @@ -30,6 +29,7 @@ "outline": [ ("addComponent", ("a", (1, 0, 0, 1, 0, 0))), ("addComponent", ("c", (1, 0, 0, 1, 0, 0))), + ("addComponent", ("a", (1, 0, 0, 1, 10, -10))), ], }, { @@ -173,11 +173,16 @@ def test_composite_glyphs(self, font): assert filter_(font) b = font["b"] - # component 'a' was not transformed, because it doesn't have a scale - # or skew and the base glyph was already included + # component 'a' #1 was not transformed, because the base glyph was already + # transformed, and the component's own transformation is identity assert b.components[0].transformation == (1, 0, 0, 1, 0, 0) # component 'c' was transformed, because base glyph was not included assert b.components[1].transformation == (0.5, 0, 0, 0.5, -10, 51) + # component 'a' #2 was partly transformed: the base glyph was transformed, but + # the component's original transformation was not identity; thus + # it was modified to compensate for the transformation already applied to + # the base glyph (scale stays same, offsets are scaled) + assert b.components[2].transformation == (1, 0, 0, 1, 5, -5) d = font["d"] # component 'b' was transformed as well as its base glyph, because