xref: /aosp_15_r20/external/fonttools/Tests/pens/reverseContourPen_test.py (revision e1fe3e4ad2793916b15cccdc4a7da52a7e1dd0e9)
1*e1fe3e4aSElliott Hughesfrom fontTools.pens.recordingPen import RecordingPen
2*e1fe3e4aSElliott Hughesfrom fontTools.pens.reverseContourPen import ReverseContourPen
3*e1fe3e4aSElliott Hughesimport pytest
4*e1fe3e4aSElliott Hughes
5*e1fe3e4aSElliott Hughes
6*e1fe3e4aSElliott HughesTEST_DATA = [
7*e1fe3e4aSElliott Hughes    (
8*e1fe3e4aSElliott Hughes        [
9*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
10*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
11*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
12*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),  # last not on move, line is implied
13*e1fe3e4aSElliott Hughes            ("closePath", ()),
14*e1fe3e4aSElliott Hughes        ],
15*e1fe3e4aSElliott Hughes        False,  # outputImpliedClosingLine
16*e1fe3e4aSElliott Hughes        [
17*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
18*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),
19*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
20*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
21*e1fe3e4aSElliott Hughes            ("closePath", ()),
22*e1fe3e4aSElliott Hughes        ],
23*e1fe3e4aSElliott Hughes    ),
24*e1fe3e4aSElliott Hughes    (
25*e1fe3e4aSElliott Hughes        [
26*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
27*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
28*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
29*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),  # last line does not overlap move...
30*e1fe3e4aSElliott Hughes            ("closePath", ()),
31*e1fe3e4aSElliott Hughes        ],
32*e1fe3e4aSElliott Hughes        True,  # outputImpliedClosingLine
33*e1fe3e4aSElliott Hughes        [
34*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
35*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),
36*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
37*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
38*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # ... but closing line is NOT implied
39*e1fe3e4aSElliott Hughes            ("closePath", ()),
40*e1fe3e4aSElliott Hughes        ],
41*e1fe3e4aSElliott Hughes    ),
42*e1fe3e4aSElliott Hughes    (
43*e1fe3e4aSElliott Hughes        [
44*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
45*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
46*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
47*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # last line overlaps move, explicit line
48*e1fe3e4aSElliott Hughes            ("closePath", ()),
49*e1fe3e4aSElliott Hughes        ],
50*e1fe3e4aSElliott Hughes        False,
51*e1fe3e4aSElliott Hughes        [
52*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
53*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
54*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
55*e1fe3e4aSElliott Hughes            ("closePath", ()),  # closing line implied
56*e1fe3e4aSElliott Hughes        ],
57*e1fe3e4aSElliott Hughes    ),
58*e1fe3e4aSElliott Hughes    (
59*e1fe3e4aSElliott Hughes        [
60*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
61*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
62*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
63*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # last line overlaps move...
64*e1fe3e4aSElliott Hughes            ("closePath", ()),
65*e1fe3e4aSElliott Hughes        ],
66*e1fe3e4aSElliott Hughes        True,
67*e1fe3e4aSElliott Hughes        [
68*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
69*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
70*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
71*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # ... but line is NOT implied
72*e1fe3e4aSElliott Hughes            ("closePath", ()),
73*e1fe3e4aSElliott Hughes        ],
74*e1fe3e4aSElliott Hughes    ),
75*e1fe3e4aSElliott Hughes    (
76*e1fe3e4aSElliott Hughes        [
77*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
78*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # duplicate lineTo following moveTo
79*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
80*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
81*e1fe3e4aSElliott Hughes            ("closePath", ()),
82*e1fe3e4aSElliott Hughes        ],
83*e1fe3e4aSElliott Hughes        False,
84*e1fe3e4aSElliott Hughes        [
85*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
86*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
87*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
88*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # extra explicit lineTo is always emitted to
89*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # disambiguate from an implicit closing line
90*e1fe3e4aSElliott Hughes            ("closePath", ()),
91*e1fe3e4aSElliott Hughes        ],
92*e1fe3e4aSElliott Hughes    ),
93*e1fe3e4aSElliott Hughes    (
94*e1fe3e4aSElliott Hughes        [
95*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
96*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # duplicate lineTo following moveTo
97*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
98*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
99*e1fe3e4aSElliott Hughes            ("closePath", ()),
100*e1fe3e4aSElliott Hughes        ],
101*e1fe3e4aSElliott Hughes        True,
102*e1fe3e4aSElliott Hughes        [
103*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
104*e1fe3e4aSElliott Hughes            ("lineTo", ((2, 2),)),
105*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
106*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # duplicate lineTo is retained also in this case,
107*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # same result as with outputImpliedClosingLine=False
108*e1fe3e4aSElliott Hughes            ("closePath", ()),
109*e1fe3e4aSElliott Hughes        ],
110*e1fe3e4aSElliott Hughes    ),
111*e1fe3e4aSElliott Hughes    (
112*e1fe3e4aSElliott Hughes        [
113*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
114*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
115*e1fe3e4aSElliott Hughes            ("closePath", ()),
116*e1fe3e4aSElliott Hughes        ],
117*e1fe3e4aSElliott Hughes        False,
118*e1fe3e4aSElliott Hughes        [
119*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
120*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
121*e1fe3e4aSElliott Hughes            ("closePath", ()),
122*e1fe3e4aSElliott Hughes        ],
123*e1fe3e4aSElliott Hughes    ),
124*e1fe3e4aSElliott Hughes    (
125*e1fe3e4aSElliott Hughes        [
126*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
127*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
128*e1fe3e4aSElliott Hughes            ("closePath", ()),
129*e1fe3e4aSElliott Hughes        ],
130*e1fe3e4aSElliott Hughes        True,
131*e1fe3e4aSElliott Hughes        [
132*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
133*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
134*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),
135*e1fe3e4aSElliott Hughes            ("closePath", ()),
136*e1fe3e4aSElliott Hughes        ],
137*e1fe3e4aSElliott Hughes    ),
138*e1fe3e4aSElliott Hughes    (
139*e1fe3e4aSElliott Hughes        [
140*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
141*e1fe3e4aSElliott Hughes            ("curveTo", ((1, 1), (2, 2), (3, 3))),
142*e1fe3e4aSElliott Hughes            ("curveTo", ((4, 4), (5, 5), (0, 0))),  # closed curveTo overlaps moveTo
143*e1fe3e4aSElliott Hughes            ("closePath", ()),
144*e1fe3e4aSElliott Hughes        ],
145*e1fe3e4aSElliott Hughes        False,
146*e1fe3e4aSElliott Hughes        [
147*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),  # no extra lineTo added here
148*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (4, 4), (3, 3))),
149*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (1, 1), (0, 0))),
150*e1fe3e4aSElliott Hughes            ("closePath", ()),
151*e1fe3e4aSElliott Hughes        ],
152*e1fe3e4aSElliott Hughes    ),
153*e1fe3e4aSElliott Hughes    (
154*e1fe3e4aSElliott Hughes        [
155*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
156*e1fe3e4aSElliott Hughes            ("curveTo", ((1, 1), (2, 2), (3, 3))),
157*e1fe3e4aSElliott Hughes            ("curveTo", ((4, 4), (5, 5), (0, 0))),  # closed curveTo overlaps moveTo
158*e1fe3e4aSElliott Hughes            ("closePath", ()),
159*e1fe3e4aSElliott Hughes        ],
160*e1fe3e4aSElliott Hughes        True,
161*e1fe3e4aSElliott Hughes        [
162*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),  # no extra lineTo added here, same as preceding
163*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (4, 4), (3, 3))),
164*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (1, 1), (0, 0))),
165*e1fe3e4aSElliott Hughes            ("closePath", ()),
166*e1fe3e4aSElliott Hughes        ],
167*e1fe3e4aSElliott Hughes    ),
168*e1fe3e4aSElliott Hughes    (
169*e1fe3e4aSElliott Hughes        [
170*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
171*e1fe3e4aSElliott Hughes            ("curveTo", ((1, 1), (2, 2), (3, 3))),
172*e1fe3e4aSElliott Hughes            ("curveTo", ((4, 4), (5, 5), (6, 6))),  # closed curve not overlapping move
173*e1fe3e4aSElliott Hughes            ("closePath", ()),
174*e1fe3e4aSElliott Hughes        ],
175*e1fe3e4aSElliott Hughes        False,
176*e1fe3e4aSElliott Hughes        [
177*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
178*e1fe3e4aSElliott Hughes            ("lineTo", ((6, 6),)),  # the previously implied line
179*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (4, 4), (3, 3))),
180*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (1, 1), (0, 0))),
181*e1fe3e4aSElliott Hughes            ("closePath", ()),
182*e1fe3e4aSElliott Hughes        ],
183*e1fe3e4aSElliott Hughes    ),
184*e1fe3e4aSElliott Hughes    (
185*e1fe3e4aSElliott Hughes        [
186*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
187*e1fe3e4aSElliott Hughes            ("curveTo", ((1, 1), (2, 2), (3, 3))),
188*e1fe3e4aSElliott Hughes            ("curveTo", ((4, 4), (5, 5), (6, 6))),  # closed curve not overlapping move
189*e1fe3e4aSElliott Hughes            ("closePath", ()),
190*e1fe3e4aSElliott Hughes        ],
191*e1fe3e4aSElliott Hughes        True,
192*e1fe3e4aSElliott Hughes        [
193*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
194*e1fe3e4aSElliott Hughes            ("lineTo", ((6, 6),)),  # the previously implied line (same as above)
195*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (4, 4), (3, 3))),
196*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (1, 1), (0, 0))),
197*e1fe3e4aSElliott Hughes            ("closePath", ()),
198*e1fe3e4aSElliott Hughes        ],
199*e1fe3e4aSElliott Hughes    ),
200*e1fe3e4aSElliott Hughes    (
201*e1fe3e4aSElliott Hughes        [
202*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
203*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),  # this line becomes implied
204*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (3, 3), (4, 4))),
205*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (6, 6), (7, 7))),
206*e1fe3e4aSElliott Hughes            ("closePath", ()),
207*e1fe3e4aSElliott Hughes        ],
208*e1fe3e4aSElliott Hughes        False,
209*e1fe3e4aSElliott Hughes        [
210*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
211*e1fe3e4aSElliott Hughes            ("lineTo", ((7, 7),)),
212*e1fe3e4aSElliott Hughes            ("curveTo", ((6, 6), (5, 5), (4, 4))),
213*e1fe3e4aSElliott Hughes            ("curveTo", ((3, 3), (2, 2), (1, 1))),
214*e1fe3e4aSElliott Hughes            ("closePath", ()),
215*e1fe3e4aSElliott Hughes        ],
216*e1fe3e4aSElliott Hughes    ),
217*e1fe3e4aSElliott Hughes    (
218*e1fe3e4aSElliott Hughes        [
219*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
220*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),  # this line...
221*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (3, 3), (4, 4))),
222*e1fe3e4aSElliott Hughes            ("curveTo", ((5, 5), (6, 6), (7, 7))),
223*e1fe3e4aSElliott Hughes            ("closePath", ()),
224*e1fe3e4aSElliott Hughes        ],
225*e1fe3e4aSElliott Hughes        True,
226*e1fe3e4aSElliott Hughes        [
227*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
228*e1fe3e4aSElliott Hughes            ("lineTo", ((7, 7),)),
229*e1fe3e4aSElliott Hughes            ("curveTo", ((6, 6), (5, 5), (4, 4))),
230*e1fe3e4aSElliott Hughes            ("curveTo", ((3, 3), (2, 2), (1, 1))),
231*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),  # ... does NOT become implied
232*e1fe3e4aSElliott Hughes            ("closePath", ()),
233*e1fe3e4aSElliott Hughes        ],
234*e1fe3e4aSElliott Hughes    ),
235*e1fe3e4aSElliott Hughes    (
236*e1fe3e4aSElliott Hughes        [
237*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
238*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (2, 2))),
239*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (0, 0))),  # closed qCurve overlaps move
240*e1fe3e4aSElliott Hughes            ("closePath", ()),
241*e1fe3e4aSElliott Hughes        ],
242*e1fe3e4aSElliott Hughes        False,
243*e1fe3e4aSElliott Hughes        [
244*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),  # no extra lineTo added here
245*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (2, 2))),
246*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (0, 0))),
247*e1fe3e4aSElliott Hughes            ("closePath", ()),
248*e1fe3e4aSElliott Hughes        ],
249*e1fe3e4aSElliott Hughes    ),
250*e1fe3e4aSElliott Hughes    (
251*e1fe3e4aSElliott Hughes        [
252*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
253*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (2, 2))),
254*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (0, 0))),  # closed qCurve overlaps move
255*e1fe3e4aSElliott Hughes            ("closePath", ()),
256*e1fe3e4aSElliott Hughes        ],
257*e1fe3e4aSElliott Hughes        True,  # <--
258*e1fe3e4aSElliott Hughes        [
259*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),  # no extra lineTo added here, same as above
260*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (2, 2))),
261*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (0, 0))),
262*e1fe3e4aSElliott Hughes            ("closePath", ()),
263*e1fe3e4aSElliott Hughes        ],
264*e1fe3e4aSElliott Hughes    ),
265*e1fe3e4aSElliott Hughes    (
266*e1fe3e4aSElliott Hughes        [
267*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
268*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (2, 2))),
269*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (4, 4))),  # closed qCurve not overlapping move
270*e1fe3e4aSElliott Hughes            ("closePath", ()),
271*e1fe3e4aSElliott Hughes        ],
272*e1fe3e4aSElliott Hughes        False,
273*e1fe3e4aSElliott Hughes        [
274*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
275*e1fe3e4aSElliott Hughes            ("lineTo", ((4, 4),)),  # the previously implied line
276*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (2, 2))),
277*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (0, 0))),
278*e1fe3e4aSElliott Hughes            ("closePath", ()),
279*e1fe3e4aSElliott Hughes        ],
280*e1fe3e4aSElliott Hughes    ),
281*e1fe3e4aSElliott Hughes    (
282*e1fe3e4aSElliott Hughes        [
283*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
284*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (2, 2))),
285*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (4, 4))),  # closed qCurve not overlapping move
286*e1fe3e4aSElliott Hughes            ("closePath", ()),
287*e1fe3e4aSElliott Hughes        ],
288*e1fe3e4aSElliott Hughes        True,
289*e1fe3e4aSElliott Hughes        [
290*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
291*e1fe3e4aSElliott Hughes            ("lineTo", ((4, 4),)),  # the previously implied line (same as above)
292*e1fe3e4aSElliott Hughes            ("qCurveTo", ((3, 3), (2, 2))),
293*e1fe3e4aSElliott Hughes            ("qCurveTo", ((1, 1), (0, 0))),
294*e1fe3e4aSElliott Hughes            ("closePath", ()),
295*e1fe3e4aSElliott Hughes        ],
296*e1fe3e4aSElliott Hughes    ),
297*e1fe3e4aSElliott Hughes    (
298*e1fe3e4aSElliott Hughes        [
299*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
300*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
301*e1fe3e4aSElliott Hughes            ("qCurveTo", ((2, 2), (3, 3))),
302*e1fe3e4aSElliott Hughes            ("closePath", ()),
303*e1fe3e4aSElliott Hughes        ],
304*e1fe3e4aSElliott Hughes        False,
305*e1fe3e4aSElliott Hughes        [
306*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
307*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),
308*e1fe3e4aSElliott Hughes            ("qCurveTo", ((2, 2), (1, 1))),
309*e1fe3e4aSElliott Hughes            ("closePath", ()),
310*e1fe3e4aSElliott Hughes        ],
311*e1fe3e4aSElliott Hughes    ),
312*e1fe3e4aSElliott Hughes    (
313*e1fe3e4aSElliott Hughes        [("addComponent", ("a", (1, 0, 0, 1, 0, 0)))],
314*e1fe3e4aSElliott Hughes        False,
315*e1fe3e4aSElliott Hughes        [("addComponent", ("a", (1, 0, 0, 1, 0, 0)))],
316*e1fe3e4aSElliott Hughes    ),
317*e1fe3e4aSElliott Hughes    ([], False, []),
318*e1fe3e4aSElliott Hughes    (
319*e1fe3e4aSElliott Hughes        [
320*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
321*e1fe3e4aSElliott Hughes            ("endPath", ()),
322*e1fe3e4aSElliott Hughes        ],
323*e1fe3e4aSElliott Hughes        False,
324*e1fe3e4aSElliott Hughes        [
325*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
326*e1fe3e4aSElliott Hughes            ("endPath", ()),
327*e1fe3e4aSElliott Hughes        ],
328*e1fe3e4aSElliott Hughes    ),
329*e1fe3e4aSElliott Hughes    (
330*e1fe3e4aSElliott Hughes        [
331*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
332*e1fe3e4aSElliott Hughes            ("closePath", ()),
333*e1fe3e4aSElliott Hughes        ],
334*e1fe3e4aSElliott Hughes        False,
335*e1fe3e4aSElliott Hughes        [
336*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
337*e1fe3e4aSElliott Hughes            ("endPath", ()),  # single-point paths is always open
338*e1fe3e4aSElliott Hughes        ],
339*e1fe3e4aSElliott Hughes    ),
340*e1fe3e4aSElliott Hughes    (
341*e1fe3e4aSElliott Hughes        [("moveTo", ((0, 0),)), ("lineTo", ((1, 1),)), ("endPath", ())],
342*e1fe3e4aSElliott Hughes        False,
343*e1fe3e4aSElliott Hughes        [("moveTo", ((1, 1),)), ("lineTo", ((0, 0),)), ("endPath", ())],
344*e1fe3e4aSElliott Hughes    ),
345*e1fe3e4aSElliott Hughes    (
346*e1fe3e4aSElliott Hughes        [("moveTo", ((0, 0),)), ("curveTo", ((1, 1), (2, 2), (3, 3))), ("endPath", ())],
347*e1fe3e4aSElliott Hughes        False,
348*e1fe3e4aSElliott Hughes        [("moveTo", ((3, 3),)), ("curveTo", ((2, 2), (1, 1), (0, 0))), ("endPath", ())],
349*e1fe3e4aSElliott Hughes    ),
350*e1fe3e4aSElliott Hughes    (
351*e1fe3e4aSElliott Hughes        [
352*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
353*e1fe3e4aSElliott Hughes            ("curveTo", ((1, 1), (2, 2), (3, 3))),
354*e1fe3e4aSElliott Hughes            ("lineTo", ((4, 4),)),
355*e1fe3e4aSElliott Hughes            ("endPath", ()),
356*e1fe3e4aSElliott Hughes        ],
357*e1fe3e4aSElliott Hughes        False,
358*e1fe3e4aSElliott Hughes        [
359*e1fe3e4aSElliott Hughes            ("moveTo", ((4, 4),)),
360*e1fe3e4aSElliott Hughes            ("lineTo", ((3, 3),)),
361*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (1, 1), (0, 0))),
362*e1fe3e4aSElliott Hughes            ("endPath", ()),
363*e1fe3e4aSElliott Hughes        ],
364*e1fe3e4aSElliott Hughes    ),
365*e1fe3e4aSElliott Hughes    (
366*e1fe3e4aSElliott Hughes        [
367*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 0),)),
368*e1fe3e4aSElliott Hughes            ("lineTo", ((1, 1),)),
369*e1fe3e4aSElliott Hughes            ("curveTo", ((2, 2), (3, 3), (4, 4))),
370*e1fe3e4aSElliott Hughes            ("endPath", ()),
371*e1fe3e4aSElliott Hughes        ],
372*e1fe3e4aSElliott Hughes        False,
373*e1fe3e4aSElliott Hughes        [
374*e1fe3e4aSElliott Hughes            ("moveTo", ((4, 4),)),
375*e1fe3e4aSElliott Hughes            ("curveTo", ((3, 3), (2, 2), (1, 1))),
376*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 0),)),
377*e1fe3e4aSElliott Hughes            ("endPath", ()),
378*e1fe3e4aSElliott Hughes        ],
379*e1fe3e4aSElliott Hughes    ),
380*e1fe3e4aSElliott Hughes    (
381*e1fe3e4aSElliott Hughes        [("qCurveTo", ((0, 0), (1, 1), (2, 2), None)), ("closePath", ())],
382*e1fe3e4aSElliott Hughes        False,
383*e1fe3e4aSElliott Hughes        [("qCurveTo", ((0, 0), (2, 2), (1, 1), None)), ("closePath", ())],
384*e1fe3e4aSElliott Hughes    ),
385*e1fe3e4aSElliott Hughes    (
386*e1fe3e4aSElliott Hughes        [("qCurveTo", ((0, 0), (1, 1), (2, 2), None)), ("endPath", ())],
387*e1fe3e4aSElliott Hughes        False,
388*e1fe3e4aSElliott Hughes        [
389*e1fe3e4aSElliott Hughes            ("qCurveTo", ((0, 0), (2, 2), (1, 1), None)),
390*e1fe3e4aSElliott Hughes            ("closePath", ()),  # this is always "closed"
391*e1fe3e4aSElliott Hughes        ],
392*e1fe3e4aSElliott Hughes    ),
393*e1fe3e4aSElliott Hughes    # Test case from:
394*e1fe3e4aSElliott Hughes    # https://github.com/googlei18n/cu2qu/issues/51#issue-179370514
395*e1fe3e4aSElliott Hughes    (
396*e1fe3e4aSElliott Hughes        [
397*e1fe3e4aSElliott Hughes            ("moveTo", ((848, 348),)),
398*e1fe3e4aSElliott Hughes            ("lineTo", ((848, 348),)),  # duplicate lineTo point after moveTo
399*e1fe3e4aSElliott Hughes            ("qCurveTo", ((848, 526), (649, 704), (449, 704))),
400*e1fe3e4aSElliott Hughes            ("qCurveTo", ((449, 704), (248, 704), (50, 526), (50, 348))),
401*e1fe3e4aSElliott Hughes            ("lineTo", ((50, 348),)),
402*e1fe3e4aSElliott Hughes            ("qCurveTo", ((50, 348), (50, 171), (248, -3), (449, -3))),
403*e1fe3e4aSElliott Hughes            ("qCurveTo", ((449, -3), (649, -3), (848, 171), (848, 348))),
404*e1fe3e4aSElliott Hughes            ("closePath", ()),
405*e1fe3e4aSElliott Hughes        ],
406*e1fe3e4aSElliott Hughes        False,
407*e1fe3e4aSElliott Hughes        [
408*e1fe3e4aSElliott Hughes            ("moveTo", ((848, 348),)),
409*e1fe3e4aSElliott Hughes            ("qCurveTo", ((848, 171), (649, -3), (449, -3), (449, -3))),
410*e1fe3e4aSElliott Hughes            ("qCurveTo", ((248, -3), (50, 171), (50, 348), (50, 348))),
411*e1fe3e4aSElliott Hughes            ("lineTo", ((50, 348),)),
412*e1fe3e4aSElliott Hughes            ("qCurveTo", ((50, 526), (248, 704), (449, 704), (449, 704))),
413*e1fe3e4aSElliott Hughes            ("qCurveTo", ((649, 704), (848, 526), (848, 348))),
414*e1fe3e4aSElliott Hughes            ("lineTo", ((848, 348),)),  # the duplicate point is kept
415*e1fe3e4aSElliott Hughes            ("closePath", ()),
416*e1fe3e4aSElliott Hughes        ],
417*e1fe3e4aSElliott Hughes    ),
418*e1fe3e4aSElliott Hughes    # Test case from https://github.com/googlefonts/fontmake/issues/572
419*e1fe3e4aSElliott Hughes    # An additional closing lineTo is required to disambiguate a duplicate
420*e1fe3e4aSElliott Hughes    # point at the end of a contour from the implied closing line.
421*e1fe3e4aSElliott Hughes    (
422*e1fe3e4aSElliott Hughes        [
423*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 651),)),
424*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
425*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
426*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
427*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
428*e1fe3e4aSElliott Hughes            ("closePath", ()),
429*e1fe3e4aSElliott Hughes        ],
430*e1fe3e4aSElliott Hughes        False,
431*e1fe3e4aSElliott Hughes        [
432*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 651),)),
433*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
434*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
435*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
436*e1fe3e4aSElliott Hughes            ("closePath", ()),
437*e1fe3e4aSElliott Hughes        ],
438*e1fe3e4aSElliott Hughes    ),
439*e1fe3e4aSElliott Hughes    (
440*e1fe3e4aSElliott Hughes        [
441*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 651),)),
442*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
443*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
444*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
445*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
446*e1fe3e4aSElliott Hughes            ("closePath", ()),
447*e1fe3e4aSElliott Hughes        ],
448*e1fe3e4aSElliott Hughes        True,
449*e1fe3e4aSElliott Hughes        [
450*e1fe3e4aSElliott Hughes            ("moveTo", ((0, 651),)),
451*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),
452*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
453*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 101),)),
454*e1fe3e4aSElliott Hughes            ("lineTo", ((0, 651),)),  # closing line not implied
455*e1fe3e4aSElliott Hughes            ("closePath", ()),
456*e1fe3e4aSElliott Hughes        ],
457*e1fe3e4aSElliott Hughes    ),
458*e1fe3e4aSElliott Hughes]
459*e1fe3e4aSElliott Hughes
460*e1fe3e4aSElliott Hughes
461*e1fe3e4aSElliott Hughes@pytest.mark.parametrize("contour, outputImpliedClosingLine, expected", TEST_DATA)
462*e1fe3e4aSElliott Hughesdef test_reverse_pen(contour, outputImpliedClosingLine, expected):
463*e1fe3e4aSElliott Hughes    recpen = RecordingPen()
464*e1fe3e4aSElliott Hughes    revpen = ReverseContourPen(recpen, outputImpliedClosingLine)
465*e1fe3e4aSElliott Hughes    for operator, operands in contour:
466*e1fe3e4aSElliott Hughes        getattr(revpen, operator)(*operands)
467*e1fe3e4aSElliott Hughes    assert recpen.value == expected
468*e1fe3e4aSElliott Hughes
469*e1fe3e4aSElliott Hughes
470*e1fe3e4aSElliott Hughesdef test_reverse_pen_outputImpliedClosingLine():
471*e1fe3e4aSElliott Hughes    recpen = RecordingPen()
472*e1fe3e4aSElliott Hughes    revpen = ReverseContourPen(recpen)
473*e1fe3e4aSElliott Hughes    revpen.moveTo((0, 0))
474*e1fe3e4aSElliott Hughes    revpen.lineTo((10, 0))
475*e1fe3e4aSElliott Hughes    revpen.lineTo((0, 10))
476*e1fe3e4aSElliott Hughes    revpen.lineTo((0, 0))
477*e1fe3e4aSElliott Hughes    revpen.closePath()
478*e1fe3e4aSElliott Hughes    assert recpen.value == [
479*e1fe3e4aSElliott Hughes        ("moveTo", ((0, 0),)),
480*e1fe3e4aSElliott Hughes        ("lineTo", ((0, 10),)),
481*e1fe3e4aSElliott Hughes        ("lineTo", ((10, 0),)),
482*e1fe3e4aSElliott Hughes        # ("lineTo", ((0, 0),)),  # implied
483*e1fe3e4aSElliott Hughes        ("closePath", ()),
484*e1fe3e4aSElliott Hughes    ]
485*e1fe3e4aSElliott Hughes
486*e1fe3e4aSElliott Hughes    recpen = RecordingPen()
487*e1fe3e4aSElliott Hughes    revpen = ReverseContourPen(recpen, outputImpliedClosingLine=True)
488*e1fe3e4aSElliott Hughes    revpen.moveTo((0, 0))
489*e1fe3e4aSElliott Hughes    revpen.lineTo((10, 0))
490*e1fe3e4aSElliott Hughes    revpen.lineTo((0, 10))
491*e1fe3e4aSElliott Hughes    revpen.lineTo((0, 0))
492*e1fe3e4aSElliott Hughes    revpen.closePath()
493*e1fe3e4aSElliott Hughes    assert recpen.value == [
494*e1fe3e4aSElliott Hughes        ("moveTo", ((0, 0),)),
495*e1fe3e4aSElliott Hughes        ("lineTo", ((0, 10),)),
496*e1fe3e4aSElliott Hughes        ("lineTo", ((10, 0),)),
497*e1fe3e4aSElliott Hughes        ("lineTo", ((0, 0),)),  # not implied
498*e1fe3e4aSElliott Hughes        ("closePath", ()),
499*e1fe3e4aSElliott Hughes    ]
500*e1fe3e4aSElliott Hughes
501*e1fe3e4aSElliott Hughes
502*e1fe3e4aSElliott Hughes@pytest.mark.parametrize("contour, outputImpliedClosingLine, expected", TEST_DATA)
503*e1fe3e4aSElliott Hughesdef test_reverse_point_pen(contour, outputImpliedClosingLine, expected):
504*e1fe3e4aSElliott Hughes    from fontTools.pens.pointPen import (
505*e1fe3e4aSElliott Hughes        ReverseContourPointPen,
506*e1fe3e4aSElliott Hughes        PointToSegmentPen,
507*e1fe3e4aSElliott Hughes        SegmentToPointPen,
508*e1fe3e4aSElliott Hughes    )
509*e1fe3e4aSElliott Hughes
510*e1fe3e4aSElliott Hughes    recpen = RecordingPen()
511*e1fe3e4aSElliott Hughes    pt2seg = PointToSegmentPen(recpen, outputImpliedClosingLine)
512*e1fe3e4aSElliott Hughes    revpen = ReverseContourPointPen(pt2seg)
513*e1fe3e4aSElliott Hughes    seg2pt = SegmentToPointPen(revpen)
514*e1fe3e4aSElliott Hughes    for operator, operands in contour:
515*e1fe3e4aSElliott Hughes        getattr(seg2pt, operator)(*operands)
516*e1fe3e4aSElliott Hughes
517*e1fe3e4aSElliott Hughes    assert recpen.value == expected
518