[Cu2QuPen] Use FilterPen

This commit is contained in:
Behdad Esfahbod 2023-02-17 11:54:35 -07:00
parent e18fca76ef
commit ac94ee9949
2 changed files with 8 additions and 113 deletions

View File

@ -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):

View File

@ -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))",
],
)