1from __future__ import absolute_import, print_function, division
2
3from fontTools.pens.basePen import AbstractPen
4
5from fontPens.penTools import distance
6
7
8class ThresholdPen(AbstractPen):
9    """
10    This pen only draws segments longer in length than the threshold value.
11
12    - otherPen: a different segment pen object this filter should draw the results with.
13    - threshold: the minimum length of a segment
14    """
15
16    def __init__(self, otherPen, threshold=10):
17        self.threshold = threshold
18        self._lastPt = None
19        self.otherPen = otherPen
20
21    def moveTo(self, pt):
22        self._lastPt = pt
23        self.otherPen.moveTo(pt)
24
25    def lineTo(self, pt, smooth=False):
26        if self.threshold <= distance(pt, self._lastPt):
27            self.otherPen.lineTo(pt)
28            self._lastPt = pt
29
30    def curveTo(self, pt1, pt2, pt3):
31        if self.threshold <= distance(pt3, self._lastPt):
32            self.otherPen.curveTo(pt1, pt2, pt3)
33            self._lastPt = pt3
34
35    def qCurveTo(self, *points):
36        if self.threshold <= distance(points[-1], self._lastPt):
37            self.otherPen.qCurveTo(*points)
38            self._lastPt = points[-1]
39
40    def closePath(self):
41        self.otherPen.closePath()
42
43    def endPath(self):
44        self.otherPen.endPath()
45
46    def addComponent(self, glyphName, transformation):
47        self.otherPen.addComponent(glyphName, transformation)
48
49
50def thresholdGlyph(aGlyph, threshold=10):
51    """
52    Convenience function that applies the **ThresholdPen** to a glyph in place.
53    """
54    from fontTools.pens.recordingPen import RecordingPen
55    recorder = RecordingPen()
56    filterpen = ThresholdPen(recorder, threshold)
57    aGlyph.draw(filterpen)
58    aGlyph.clear()
59    recorder.replay(aGlyph.getPen())
60    return aGlyph
61
62
63# =========
64# = tests =
65# =========
66
67def _makeTestGlyph():
68    # make a simple glyph that we can test the pens with.
69    from fontParts.fontshell import RGlyph
70    testGlyph = RGlyph()
71    testGlyph.name = "testGlyph"
72    testGlyph.width = 1000
73    pen = testGlyph.getPen()
74    pen.moveTo((100, 100))
75    pen.lineTo((900, 100))
76    pen.lineTo((900, 109))
77    pen.lineTo((900, 800))
78    pen.lineTo((100, 800))
79    pen.closePath()
80    pen.addComponent("a", (1, 0, 0, 1, 0, 0))
81    return testGlyph
82
83
84def _testThresholdPen():
85    """
86    >>> from fontPens.printPen import PrintPen
87    >>> glyph = _makeTestGlyph()
88    >>> pen = ThresholdPen(PrintPen())
89    >>> glyph.draw(pen)
90    pen.moveTo((100, 100))
91    pen.lineTo((900, 100))
92    pen.lineTo((900, 800))
93    pen.lineTo((100, 800))
94    pen.closePath()
95    pen.addComponent('a', (1.0, 0.0, 0.0, 1.0, 0.0, 0.0))
96    """
97
98
99def _testThresholdGlyph():
100    """
101    >>> from fontPens.printPen import PrintPen
102    >>> glyph = _makeTestGlyph()
103    >>> thresholdGlyph(glyph) #doctest: +ELLIPSIS
104    <RGlyph...
105    >>> glyph.draw(PrintPen())
106    pen.moveTo((100, 100))
107    pen.lineTo((900, 100))
108    pen.lineTo((900, 800))
109    pen.lineTo((100, 800))
110    pen.closePath()
111    pen.addComponent('a', (1.0, 0.0, 0.0, 1.0, 0.0, 0.0))
112    """
113
114
115if __name__ == "__main__":
116    import doctest
117    doctest.testmod()
118