aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/pens/explicitClosingLinePen.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/pens/explicitClosingLinePen.py')
-rw-r--r--Lib/fontTools/pens/explicitClosingLinePen.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/Lib/fontTools/pens/explicitClosingLinePen.py b/Lib/fontTools/pens/explicitClosingLinePen.py
new file mode 100644
index 00000000..e3c9c943
--- /dev/null
+++ b/Lib/fontTools/pens/explicitClosingLinePen.py
@@ -0,0 +1,101 @@
+from fontTools.pens.filterPen import ContourFilterPen
+
+
+class ExplicitClosingLinePen(ContourFilterPen):
+ """A filter pen that adds an explicit lineTo to the first point of each closed
+ contour if the end point of the last segment is not already the same as the first point.
+ Otherwise, it passes the contour through unchanged.
+
+ >>> from pprint import pprint
+ >>> from fontTools.pens.recordingPen import RecordingPen
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.lineTo((100, 0))
+ >>> pen.lineTo((100, 100))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('lineTo', ((100, 0),)),
+ ('lineTo', ((100, 100),)),
+ ('lineTo', ((0, 0),)),
+ ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.lineTo((100, 0))
+ >>> pen.lineTo((100, 100))
+ >>> pen.lineTo((0, 0))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('lineTo', ((100, 0),)),
+ ('lineTo', ((100, 100),)),
+ ('lineTo', ((0, 0),)),
+ ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.curveTo((100, 0), (0, 100), (100, 100))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('curveTo', ((100, 0), (0, 100), (100, 100))),
+ ('lineTo', ((0, 0),)),
+ ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.curveTo((100, 0), (0, 100), (100, 100))
+ >>> pen.lineTo((0, 0))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('curveTo', ((100, 0), (0, 100), (100, 100))),
+ ('lineTo', ((0, 0),)),
+ ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.curveTo((100, 0), (0, 100), (0, 0))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('curveTo', ((100, 0), (0, 100), (0, 0))),
+ ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)), ('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.closePath()
+ >>> pprint(rec.value)
+ [('closePath', ())]
+ >>> rec = RecordingPen()
+ >>> pen = ExplicitClosingLinePen(rec)
+ >>> pen.moveTo((0, 0))
+ >>> pen.lineTo((100, 0))
+ >>> pen.lineTo((100, 100))
+ >>> pen.endPath()
+ >>> pprint(rec.value)
+ [('moveTo', ((0, 0),)),
+ ('lineTo', ((100, 0),)),
+ ('lineTo', ((100, 100),)),
+ ('endPath', ())]
+ """
+
+ def filterContour(self, contour):
+ if (
+ not contour
+ or contour[0][0] != "moveTo"
+ or contour[-1][0] != "closePath"
+ or len(contour) < 3
+ ):
+ return
+ movePt = contour[0][1][0]
+ lastSeg = contour[-2][1]
+ if lastSeg and movePt != lastSeg[-1]:
+ contour[-1:] = [("lineTo", (movePt,)), ("closePath", ())]