• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from io import StringIO
2from fontTools.pens.pointInsidePen import PointInsidePen
3import unittest
4
5
6class PointInsidePenTest(unittest.TestCase):
7    def test_line(self):
8        def draw_triangles(pen):
9            pen.moveTo((0,0)); pen.lineTo((10,5)); pen.lineTo((10,0))
10            pen.moveTo((9,1)); pen.lineTo((4,1)); pen.lineTo((9,4))
11            pen.closePath()
12
13        self.assertEqual(
14            " *********"
15            "   **    *"
16            "     **  *"
17            "       * *"
18            "         *",
19            self.render(draw_triangles, even_odd=True))
20
21        self.assertEqual(
22            " *********"
23            "   *******"
24            "     *****"
25            "       ***"
26            "         *",
27            self.render(draw_triangles, even_odd=False))
28
29    def test_curve(self):
30        def draw_curves(pen):
31            pen.moveTo((0,0)); pen.curveTo((9,1), (9,4), (0,5))
32            pen.moveTo((10,5)); pen.curveTo((1,4), (1,1), (10,0))
33            pen.closePath()
34
35        self.assertEqual(
36            "***    ***"
37            "****  ****"
38            "***    ***"
39            "****  ****"
40            "***    ***",
41            self.render(draw_curves, even_odd=True))
42
43        self.assertEqual(
44            "***    ***"
45            "**********"
46            "**********"
47            "**********"
48            "***    ***",
49            self.render(draw_curves, even_odd=False))
50
51    def test_qCurve(self):
52        def draw_qCurves(pen):
53            pen.moveTo((0,0)); pen.qCurveTo((15,2), (0,5))
54            pen.moveTo((10,5)); pen.qCurveTo((-5,3), (10,0))
55            pen.closePath()
56
57        self.assertEqual(
58            "***     **"
59            "****   ***"
60            "***    ***"
61            "***   ****"
62            "**     ***",
63            self.render(draw_qCurves, even_odd=True))
64
65        self.assertEqual(
66            "***     **"
67            "**********"
68            "**********"
69            "**********"
70            "**     ***",
71            self.render(draw_qCurves, even_odd=False))
72
73    @staticmethod
74    def render(draw_function, even_odd):
75        result = StringIO()
76        for y in range(5):
77            for x in range(10):
78                pen = PointInsidePen(None, (x + 0.5, y + 0.5), even_odd)
79                draw_function(pen)
80                if pen.getResult():
81                    result.write("*")
82                else:
83                    result.write(" ")
84        return result.getvalue()
85
86
87    def test_contour_no_solutions(self):
88        def draw_contour(pen):
89            pen.moveTo( (969, 230) )
90            pen.curveTo( (825, 348) , (715, 184) , (614, 202) )
91            pen.lineTo( (614, 160) )
92            pen.lineTo( (969, 160) )
93            pen.closePath()
94
95        piPen = PointInsidePen(None, (750, 295)) # this point is outside
96        draw_contour(piPen)
97        self.assertEqual(piPen.getWinding(), 0)
98        self.assertEqual(piPen.getResult(), False)
99
100        piPen = PointInsidePen(None, (835, 190)) # this point is inside
101        draw_contour(piPen)
102        self.assertEqual(piPen.getWinding(), 1)
103        self.assertEqual(piPen.getResult(), True)
104
105    def test_contour_square_closed(self):
106        def draw_contour(pen):
107            pen.moveTo( (100, 100) )
108            pen.lineTo( (-100, 100) )
109            pen.lineTo( (-100, -100) )
110            pen.lineTo( (100, -100) )
111            pen.closePath()
112
113        piPen = PointInsidePen(None, (0, 0)) # this point is inside
114        draw_contour(piPen)
115        self.assertEqual(piPen.getWinding(), 1)
116        self.assertEqual(piPen.getResult(), True)
117
118    def test_contour_square_opened(self):
119        def draw_contour(pen):
120            pen.moveTo( (100, 100) )
121            pen.lineTo( (-100, 100) )
122            pen.lineTo( (-100, -100) )
123            pen.lineTo( (100, -100) )
124            # contour not explicitly closed
125
126        piPen = PointInsidePen(None, (0, 0)) # this point is inside
127        draw_contour(piPen)
128        self.assertEqual(piPen.getWinding(), 1)
129        self.assertEqual(piPen.getResult(), True)
130
131    def test_contour_circle(self):
132        def draw_contour(pen):
133            pen.moveTo( (0, 100) )
134            pen.curveTo( (-55, 100) , (-100, 55) , (-100, 0) )
135            pen.curveTo( (-100, -55) , (-55, -100) , (0, -100) )
136            pen.curveTo( (55, -100) , (100, -55) , (100, 0) )
137            pen.curveTo( (100, 55) , (55, 100) , (0, 100) )
138
139        piPen = PointInsidePen(None, (50, 50)) # this point is inside
140        draw_contour(piPen)
141        self.assertEqual(piPen.getResult(), True)
142
143        piPen = PointInsidePen(None, (50, -50)) # this point is inside
144        draw_contour(piPen)
145        self.assertEqual(piPen.getResult(), True)
146
147    def test_contour_diamond(self):
148        def draw_contour(pen):
149            pen.moveTo( (0, 100) )
150            pen.lineTo( (100, 0) )
151            pen.lineTo( (0, -100) )
152            pen.lineTo( (-100, 0) )
153            pen.closePath()
154
155        piPen = PointInsidePen(None, (-200, 0)) # this point is outside
156        draw_contour(piPen)
157        self.assertEqual(piPen.getWinding(), 0)
158
159        piPen = PointInsidePen(None, (-200, 100)) # this point is outside
160        draw_contour(piPen)
161        self.assertEqual(piPen.getWinding(), 0)
162
163        piPen = PointInsidePen(None, (-200, -100)) # this point is outside
164        draw_contour(piPen)
165        self.assertEqual(piPen.getWinding(), 0)
166
167        piPen = PointInsidePen(None, (-200, 50)) # this point is outside
168        draw_contour(piPen)
169        self.assertEqual(piPen.getWinding(), 0)
170
171    def test_contour_integers(self):
172        def draw_contour(pen):
173            pen.moveTo( (728, 697) )
174            pen.lineTo( (504, 699) )
175            pen.curveTo( (487, 719) , (508, 783) , (556, 783) )
176            pen.lineTo( (718, 783) )
177            pen.curveTo( (739, 783) , (749, 712) , (728, 697) )
178            pen.closePath()
179
180        piPen = PointInsidePen(None, (416, 783)) # this point is outside
181        draw_contour(piPen)
182        self.assertEqual(piPen.getWinding(), 0)
183
184    def test_contour_decimals(self):
185        def draw_contour(pen):
186            pen.moveTo( (727.546875, 697.0) )
187            pen.lineTo( (504.375, 698.515625) )
188            pen.curveTo( (487.328125, 719.359375), (507.84375, 783.140625), (555.796875, 783.140625) )
189            pen.lineTo( (717.96875, 783.140625) )
190            pen.curveTo( (738.890625, 783.140625), (748.796875, 711.5), (727.546875, 697.0) )
191            pen.closePath()
192
193        piPen = PointInsidePen(None, (416.625, 783.140625)) # this point is outside
194        draw_contour(piPen)
195        self.assertEqual(piPen.getWinding(), 0)
196
197    def test_contour2_integers(self):
198        def draw_contour(pen):
199            pen.moveTo( (51, 22) )
200            pen.lineTo( (51, 74) )
201            pen.lineTo( (83, 50) )
202            pen.curveTo( (83, 49) , (82, 48) , (82, 47) )
203            pen.closePath()
204
205        piPen = PointInsidePen(None, (21, 50)) # this point is outside
206        draw_contour(piPen)
207        self.assertEqual(piPen.getWinding(), 0)
208
209    def test_contour2_decimals(self):
210        def draw_contour(pen):
211            pen.moveTo( (51.25, 21.859375) )
212            pen.lineTo( (51.25, 73.828125) )
213            pen.lineTo( (82.5, 50.0) )
214            pen.curveTo( (82.5, 49.09375) , (82.265625, 48.265625) , (82.234375, 47.375) )
215            pen.closePath()
216
217        piPen = PointInsidePen(None, (21.25, 50.0)) # this point is outside
218        draw_contour(piPen)
219        self.assertEqual(piPen.getWinding(), 0)
220
221if __name__ == "__main__":
222    import sys
223    sys.exit(unittest.main())
224
225