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