diff options
Diffstat (limited to 'Lib/fontTools/pens/explicitClosingLinePen.py')
-rw-r--r-- | Lib/fontTools/pens/explicitClosingLinePen.py | 101 |
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", ())] |