1*e1fe3e4aSElliott Hughesfrom fontTools.pens.filterPen import ContourFilterPen 2*e1fe3e4aSElliott Hughes 3*e1fe3e4aSElliott Hughes 4*e1fe3e4aSElliott Hughesclass ExplicitClosingLinePen(ContourFilterPen): 5*e1fe3e4aSElliott Hughes """A filter pen that adds an explicit lineTo to the first point of each closed 6*e1fe3e4aSElliott Hughes contour if the end point of the last segment is not already the same as the first point. 7*e1fe3e4aSElliott Hughes Otherwise, it passes the contour through unchanged. 8*e1fe3e4aSElliott Hughes 9*e1fe3e4aSElliott Hughes >>> from pprint import pprint 10*e1fe3e4aSElliott Hughes >>> from fontTools.pens.recordingPen import RecordingPen 11*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 12*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 13*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 14*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 0)) 15*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 100)) 16*e1fe3e4aSElliott Hughes >>> pen.closePath() 17*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 18*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 19*e1fe3e4aSElliott Hughes ('lineTo', ((100, 0),)), 20*e1fe3e4aSElliott Hughes ('lineTo', ((100, 100),)), 21*e1fe3e4aSElliott Hughes ('lineTo', ((0, 0),)), 22*e1fe3e4aSElliott Hughes ('closePath', ())] 23*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 24*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 25*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 26*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 0)) 27*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 100)) 28*e1fe3e4aSElliott Hughes >>> pen.lineTo((0, 0)) 29*e1fe3e4aSElliott Hughes >>> pen.closePath() 30*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 31*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 32*e1fe3e4aSElliott Hughes ('lineTo', ((100, 0),)), 33*e1fe3e4aSElliott Hughes ('lineTo', ((100, 100),)), 34*e1fe3e4aSElliott Hughes ('lineTo', ((0, 0),)), 35*e1fe3e4aSElliott Hughes ('closePath', ())] 36*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 37*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 38*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 39*e1fe3e4aSElliott Hughes >>> pen.curveTo((100, 0), (0, 100), (100, 100)) 40*e1fe3e4aSElliott Hughes >>> pen.closePath() 41*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 42*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 43*e1fe3e4aSElliott Hughes ('curveTo', ((100, 0), (0, 100), (100, 100))), 44*e1fe3e4aSElliott Hughes ('lineTo', ((0, 0),)), 45*e1fe3e4aSElliott Hughes ('closePath', ())] 46*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 47*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 48*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 49*e1fe3e4aSElliott Hughes >>> pen.curveTo((100, 0), (0, 100), (100, 100)) 50*e1fe3e4aSElliott Hughes >>> pen.lineTo((0, 0)) 51*e1fe3e4aSElliott Hughes >>> pen.closePath() 52*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 53*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 54*e1fe3e4aSElliott Hughes ('curveTo', ((100, 0), (0, 100), (100, 100))), 55*e1fe3e4aSElliott Hughes ('lineTo', ((0, 0),)), 56*e1fe3e4aSElliott Hughes ('closePath', ())] 57*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 58*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 59*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 60*e1fe3e4aSElliott Hughes >>> pen.curveTo((100, 0), (0, 100), (0, 0)) 61*e1fe3e4aSElliott Hughes >>> pen.closePath() 62*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 63*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 64*e1fe3e4aSElliott Hughes ('curveTo', ((100, 0), (0, 100), (0, 0))), 65*e1fe3e4aSElliott Hughes ('closePath', ())] 66*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 67*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 68*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 69*e1fe3e4aSElliott Hughes >>> pen.closePath() 70*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 71*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), ('closePath', ())] 72*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 73*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 74*e1fe3e4aSElliott Hughes >>> pen.closePath() 75*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 76*e1fe3e4aSElliott Hughes [('closePath', ())] 77*e1fe3e4aSElliott Hughes >>> rec = RecordingPen() 78*e1fe3e4aSElliott Hughes >>> pen = ExplicitClosingLinePen(rec) 79*e1fe3e4aSElliott Hughes >>> pen.moveTo((0, 0)) 80*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 0)) 81*e1fe3e4aSElliott Hughes >>> pen.lineTo((100, 100)) 82*e1fe3e4aSElliott Hughes >>> pen.endPath() 83*e1fe3e4aSElliott Hughes >>> pprint(rec.value) 84*e1fe3e4aSElliott Hughes [('moveTo', ((0, 0),)), 85*e1fe3e4aSElliott Hughes ('lineTo', ((100, 0),)), 86*e1fe3e4aSElliott Hughes ('lineTo', ((100, 100),)), 87*e1fe3e4aSElliott Hughes ('endPath', ())] 88*e1fe3e4aSElliott Hughes """ 89*e1fe3e4aSElliott Hughes 90*e1fe3e4aSElliott Hughes def filterContour(self, contour): 91*e1fe3e4aSElliott Hughes if ( 92*e1fe3e4aSElliott Hughes not contour 93*e1fe3e4aSElliott Hughes or contour[0][0] != "moveTo" 94*e1fe3e4aSElliott Hughes or contour[-1][0] != "closePath" 95*e1fe3e4aSElliott Hughes or len(contour) < 3 96*e1fe3e4aSElliott Hughes ): 97*e1fe3e4aSElliott Hughes return 98*e1fe3e4aSElliott Hughes movePt = contour[0][1][0] 99*e1fe3e4aSElliott Hughes lastSeg = contour[-2][1] 100*e1fe3e4aSElliott Hughes if lastSeg and movePt != lastSeg[-1]: 101*e1fe3e4aSElliott Hughes contour[-1:] = [("lineTo", (movePt,)), ("closePath", ())] 102