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