From ac94ee9949f02184f32f7c8b33f97e0e5829332e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 17 Feb 2023 11:54:35 -0700 Subject: [PATCH] [Cu2QuPen] Use FilterPen --- Lib/fontTools/pens/cu2quPen.py | 62 ++++------------------------------ Tests/pens/cu2quPen_test.py | 59 ++------------------------------ 2 files changed, 8 insertions(+), 113 deletions(-) diff --git a/Lib/fontTools/pens/cu2quPen.py b/Lib/fontTools/pens/cu2quPen.py index 332c2585f..748b2dbb1 100644 --- a/Lib/fontTools/pens/cu2quPen.py +++ b/Lib/fontTools/pens/cu2quPen.py @@ -13,13 +13,14 @@ # limitations under the License. from fontTools.cu2qu import curve_to_quadratic, curves_to_quadratic -from fontTools.pens.basePen import AbstractPen, decomposeSuperBezierSegment +from fontTools.pens.basePen import decomposeSuperBezierSegment +from fontTools.pens.filterPen import FilterPen from fontTools.pens.reverseContourPen import ReverseContourPen from fontTools.pens.pointPen import BasePointToSegmentPen from fontTools.pens.pointPen import ReverseContourPointPen -class Cu2QuPen(AbstractPen): +class Cu2QuPen(FilterPen): """A filter pen to convert cubic bezier curves to quadratic b-splines using the FontTools SegmentPen protocol. @@ -41,42 +42,10 @@ class Cu2QuPen(AbstractPen): stats=None, ): if reverse_direction: - self.pen = ReverseContourPen(other_pen) - else: - self.pen = other_pen + other_pen = ReverseContourPen(other_pen) + super().__init__(other_pen) self.max_err = max_err self.stats = stats - self.current_pt = None - - def _check_contour_is_open(self): - if self.current_pt is None: - raise AssertionError("moveTo is required") - - def _check_contour_is_closed(self): - if self.current_pt is not None: - raise AssertionError("closePath or endPath is required") - - def moveTo(self, pt): - self._check_contour_is_closed() - self.current_pt = pt - self.pen.moveTo(pt) - self.current_pt = pt - - def lineTo(self, pt): - self._check_contour_is_open() - self.pen.lineTo(pt) - self.current_pt = pt - - def qCurveTo(self, *points): - self._check_contour_is_open() - n = len(points) - if n == 1: - self.lineTo(points[0]) - elif n > 1: - self.pen.qCurveTo(*points) - self.current_pt = points[-1] - else: - raise AssertionError("illegal qcurve segment point count: %d" % n) def _curve_to_quadratic(self, pt1, pt2, pt3): curve = (self.current_pt, pt1, pt2, pt3) @@ -87,7 +56,6 @@ class Cu2QuPen(AbstractPen): self.qCurveTo(*quadratic[1:]) def curveTo(self, *points): - self._check_contour_is_open() n = len(points) if n == 3: # this is the most common case, so we special-case it @@ -95,26 +63,8 @@ class Cu2QuPen(AbstractPen): elif n > 3: for segment in decomposeSuperBezierSegment(points): self._curve_to_quadratic(*segment) - elif n == 2: - self.qCurveTo(*points) - elif n == 1: - self.lineTo(points[0]) else: - raise AssertionError("illegal curve segment point count: %d" % n) - - def closePath(self): - self._check_contour_is_open() - self.pen.closePath() - self.current_pt = None - - def endPath(self): - self._check_contour_is_open() - self.pen.endPath() - self.current_pt = None - - def addComponent(self, glyphName, transformation): - self._check_contour_is_closed() - self.pen.addComponent(glyphName, transformation) + self.qCurveTo(*points) class Cu2QuPointPen(BasePointToSegmentPen): diff --git a/Tests/pens/cu2quPen_test.py b/Tests/pens/cu2quPen_test.py index f1b9c1188..b31b28c3d 100644 --- a/Tests/pens/cu2quPen_test.py +++ b/Tests/pens/cu2quPen_test.py @@ -117,52 +117,6 @@ class TestCu2QuPen(unittest.TestCase, _TestPenMixin): self.pen_getter_name = "getPen" self.draw_method_name = "draw" - def test__check_contour_is_open(self): - msg = "moveTo is required" - quadpen = Cu2QuPen(DummyPen(), MAX_ERR) - - with self.assertRaisesRegex(AssertionError, msg): - quadpen.lineTo((0, 0)) - with self.assertRaisesRegex(AssertionError, msg): - quadpen.qCurveTo((0, 0), (1, 1)) - with self.assertRaisesRegex(AssertionError, msg): - quadpen.curveTo((0, 0), (1, 1), (2, 2)) - with self.assertRaisesRegex(AssertionError, msg): - quadpen.closePath() - with self.assertRaisesRegex(AssertionError, msg): - quadpen.endPath() - - quadpen.moveTo((0, 0)) # now it works - quadpen.lineTo((1, 1)) - quadpen.qCurveTo((2, 2), (3, 3)) - quadpen.curveTo((4, 4), (5, 5), (6, 6)) - quadpen.closePath() - - def test__check_contour_closed(self): - msg = "closePath or endPath is required" - quadpen = Cu2QuPen(DummyPen(), MAX_ERR) - quadpen.moveTo((0, 0)) - - with self.assertRaisesRegex(AssertionError, msg): - quadpen.moveTo((1, 1)) - with self.assertRaisesRegex(AssertionError, msg): - quadpen.addComponent("a", (1, 0, 0, 1, 0, 0)) - - # it works if contour is closed - quadpen.closePath() - quadpen.moveTo((1, 1)) - quadpen.endPath() - quadpen.addComponent("a", (1, 0, 0, 1, 0, 0)) - - def test_qCurveTo_no_points(self): - quadpen = Cu2QuPen(DummyPen(), MAX_ERR) - quadpen.moveTo((0, 0)) - - with self.assertRaisesRegex( - AssertionError, "illegal qcurve segment point count: 0" - ): - quadpen.qCurveTo() - def test_qCurveTo_1_point(self): pen = DummyPen() quadpen = Cu2QuPen(pen, MAX_ERR) @@ -173,7 +127,7 @@ class TestCu2QuPen(unittest.TestCase, _TestPenMixin): str(pen).splitlines(), [ "pen.moveTo((0, 0))", - "pen.lineTo((1, 1))", + "pen.qCurveTo((1, 1))", ], ) @@ -191,15 +145,6 @@ class TestCu2QuPen(unittest.TestCase, _TestPenMixin): ], ) - def test_curveTo_no_points(self): - quadpen = Cu2QuPen(DummyPen(), MAX_ERR) - quadpen.moveTo((0, 0)) - - with self.assertRaisesRegex( - AssertionError, "illegal curve segment point count: 0" - ): - quadpen.curveTo() - def test_curveTo_1_point(self): pen = DummyPen() quadpen = Cu2QuPen(pen, MAX_ERR) @@ -210,7 +155,7 @@ class TestCu2QuPen(unittest.TestCase, _TestPenMixin): str(pen).splitlines(), [ "pen.moveTo((0, 0))", - "pen.lineTo((1, 1))", + "pen.qCurveTo((1, 1))", ], )