xref: /aosp_15_r20/external/fonttools/Tests/pens/t2CharStringPen_test.py (revision e1fe3e4ad2793916b15cccdc4a7da52a7e1dd0e9)
1*e1fe3e4aSElliott Hughesfrom fontTools.pens.t2CharStringPen import T2CharStringPen
2*e1fe3e4aSElliott Hughesimport unittest
3*e1fe3e4aSElliott Hughes
4*e1fe3e4aSElliott Hughes
5*e1fe3e4aSElliott Hughesclass T2CharStringPenTest(unittest.TestCase):
6*e1fe3e4aSElliott Hughes    def __init__(self, methodName):
7*e1fe3e4aSElliott Hughes        unittest.TestCase.__init__(self, methodName)
8*e1fe3e4aSElliott Hughes
9*e1fe3e4aSElliott Hughes    def assertAlmostEqualProgram(self, expected, actual):
10*e1fe3e4aSElliott Hughes        self.assertEqual(len(expected), len(actual))
11*e1fe3e4aSElliott Hughes        for i1, i2 in zip(expected, actual):
12*e1fe3e4aSElliott Hughes            if isinstance(i1, str):
13*e1fe3e4aSElliott Hughes                self.assertIsInstance(i2, str)
14*e1fe3e4aSElliott Hughes                self.assertEqual(i1, i2)
15*e1fe3e4aSElliott Hughes            else:
16*e1fe3e4aSElliott Hughes                self.assertAlmostEqual(i1, i2)
17*e1fe3e4aSElliott Hughes
18*e1fe3e4aSElliott Hughes    def test_draw_h_v_lines(self):
19*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {})
20*e1fe3e4aSElliott Hughes        pen.moveTo((0, 0))
21*e1fe3e4aSElliott Hughes        pen.lineTo((10, 0))
22*e1fe3e4aSElliott Hughes        pen.lineTo((10, 10))
23*e1fe3e4aSElliott Hughes        pen.lineTo((0, 10))
24*e1fe3e4aSElliott Hughes        pen.closePath()  # no-op
25*e1fe3e4aSElliott Hughes        pen.moveTo((10, 10))
26*e1fe3e4aSElliott Hughes        pen.lineTo((10, 20))
27*e1fe3e4aSElliott Hughes        pen.lineTo((0, 20))
28*e1fe3e4aSElliott Hughes        pen.lineTo((0, 10))
29*e1fe3e4aSElliott Hughes        pen.closePath()
30*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
31*e1fe3e4aSElliott Hughes
32*e1fe3e4aSElliott Hughes        self.assertEqual(
33*e1fe3e4aSElliott Hughes            [
34*e1fe3e4aSElliott Hughes                100,
35*e1fe3e4aSElliott Hughes                0,
36*e1fe3e4aSElliott Hughes                "hmoveto",
37*e1fe3e4aSElliott Hughes                10,
38*e1fe3e4aSElliott Hughes                10,
39*e1fe3e4aSElliott Hughes                -10,
40*e1fe3e4aSElliott Hughes                "hlineto",
41*e1fe3e4aSElliott Hughes                10,
42*e1fe3e4aSElliott Hughes                "hmoveto",
43*e1fe3e4aSElliott Hughes                10,
44*e1fe3e4aSElliott Hughes                -10,
45*e1fe3e4aSElliott Hughes                -10,
46*e1fe3e4aSElliott Hughes                "vlineto",
47*e1fe3e4aSElliott Hughes                "endchar",
48*e1fe3e4aSElliott Hughes            ],
49*e1fe3e4aSElliott Hughes            charstring.program,
50*e1fe3e4aSElliott Hughes        )
51*e1fe3e4aSElliott Hughes
52*e1fe3e4aSElliott Hughes    def test_draw_lines(self):
53*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {})
54*e1fe3e4aSElliott Hughes        pen.moveTo((5, 5))
55*e1fe3e4aSElliott Hughes        pen.lineTo((25, 15))
56*e1fe3e4aSElliott Hughes        pen.lineTo((35, 35))
57*e1fe3e4aSElliott Hughes        pen.lineTo((15, 25))
58*e1fe3e4aSElliott Hughes        pen.closePath()  # no-op
59*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
60*e1fe3e4aSElliott Hughes
61*e1fe3e4aSElliott Hughes        self.assertEqual(
62*e1fe3e4aSElliott Hughes            [100, 5, 5, "rmoveto", 20, 10, 10, 20, -20, -10, "rlineto", "endchar"],
63*e1fe3e4aSElliott Hughes            charstring.program,
64*e1fe3e4aSElliott Hughes        )
65*e1fe3e4aSElliott Hughes
66*e1fe3e4aSElliott Hughes    def test_draw_h_v_curves(self):
67*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {})
68*e1fe3e4aSElliott Hughes        pen.moveTo((0, 0))
69*e1fe3e4aSElliott Hughes        pen.curveTo((10, 0), (20, 10), (20, 20))
70*e1fe3e4aSElliott Hughes        pen.curveTo((20, 30), (10, 40), (0, 40))
71*e1fe3e4aSElliott Hughes        pen.endPath()  # no-op
72*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
73*e1fe3e4aSElliott Hughes
74*e1fe3e4aSElliott Hughes        self.assertEqual(
75*e1fe3e4aSElliott Hughes            [
76*e1fe3e4aSElliott Hughes                100,
77*e1fe3e4aSElliott Hughes                0,
78*e1fe3e4aSElliott Hughes                "hmoveto",
79*e1fe3e4aSElliott Hughes                10,
80*e1fe3e4aSElliott Hughes                10,
81*e1fe3e4aSElliott Hughes                10,
82*e1fe3e4aSElliott Hughes                10,
83*e1fe3e4aSElliott Hughes                10,
84*e1fe3e4aSElliott Hughes                -10,
85*e1fe3e4aSElliott Hughes                10,
86*e1fe3e4aSElliott Hughes                -10,
87*e1fe3e4aSElliott Hughes                "hvcurveto",
88*e1fe3e4aSElliott Hughes                "endchar",
89*e1fe3e4aSElliott Hughes            ],
90*e1fe3e4aSElliott Hughes            charstring.program,
91*e1fe3e4aSElliott Hughes        )
92*e1fe3e4aSElliott Hughes
93*e1fe3e4aSElliott Hughes    def test_draw_curves(self):
94*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {})
95*e1fe3e4aSElliott Hughes        pen.moveTo((95, 25))
96*e1fe3e4aSElliott Hughes        pen.curveTo((115, 44), (115, 76), (95, 95))
97*e1fe3e4aSElliott Hughes        pen.curveTo((76, 114), (44, 115), (25, 95))
98*e1fe3e4aSElliott Hughes        pen.endPath()  # no-op
99*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
100*e1fe3e4aSElliott Hughes
101*e1fe3e4aSElliott Hughes        self.assertEqual(
102*e1fe3e4aSElliott Hughes            [
103*e1fe3e4aSElliott Hughes                100,
104*e1fe3e4aSElliott Hughes                95,
105*e1fe3e4aSElliott Hughes                25,
106*e1fe3e4aSElliott Hughes                "rmoveto",
107*e1fe3e4aSElliott Hughes                20,
108*e1fe3e4aSElliott Hughes                19,
109*e1fe3e4aSElliott Hughes                0,
110*e1fe3e4aSElliott Hughes                32,
111*e1fe3e4aSElliott Hughes                -20,
112*e1fe3e4aSElliott Hughes                19,
113*e1fe3e4aSElliott Hughes                -19,
114*e1fe3e4aSElliott Hughes                19,
115*e1fe3e4aSElliott Hughes                -32,
116*e1fe3e4aSElliott Hughes                1,
117*e1fe3e4aSElliott Hughes                -19,
118*e1fe3e4aSElliott Hughes                -20,
119*e1fe3e4aSElliott Hughes                "rrcurveto",
120*e1fe3e4aSElliott Hughes                "endchar",
121*e1fe3e4aSElliott Hughes            ],
122*e1fe3e4aSElliott Hughes            charstring.program,
123*e1fe3e4aSElliott Hughes        )
124*e1fe3e4aSElliott Hughes
125*e1fe3e4aSElliott Hughes    def test_draw_more_curves(self):
126*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {})
127*e1fe3e4aSElliott Hughes        pen.moveTo((10, 10))
128*e1fe3e4aSElliott Hughes        pen.curveTo((20, 10), (50, 10), (60, 10))
129*e1fe3e4aSElliott Hughes        pen.curveTo((60, 20), (60, 50), (60, 60))
130*e1fe3e4aSElliott Hughes        pen.curveTo((50, 50), (40, 60), (30, 60))
131*e1fe3e4aSElliott Hughes        pen.curveTo((40, 50), (30, 40), (30, 30))
132*e1fe3e4aSElliott Hughes        pen.curveTo((30, 25), (25, 19), (20, 20))
133*e1fe3e4aSElliott Hughes        pen.curveTo((15, 20), (9, 25), (10, 30))
134*e1fe3e4aSElliott Hughes        pen.curveTo((7, 25), (6, 15), (10, 10))
135*e1fe3e4aSElliott Hughes        pen.endPath()  # no-op
136*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
137*e1fe3e4aSElliott Hughes
138*e1fe3e4aSElliott Hughes        self.assertEqual(
139*e1fe3e4aSElliott Hughes            [
140*e1fe3e4aSElliott Hughes                100,
141*e1fe3e4aSElliott Hughes                10,
142*e1fe3e4aSElliott Hughes                10,
143*e1fe3e4aSElliott Hughes                "rmoveto",
144*e1fe3e4aSElliott Hughes                10,
145*e1fe3e4aSElliott Hughes                30,
146*e1fe3e4aSElliott Hughes                0,
147*e1fe3e4aSElliott Hughes                10,
148*e1fe3e4aSElliott Hughes                "hhcurveto",
149*e1fe3e4aSElliott Hughes                10,
150*e1fe3e4aSElliott Hughes                0,
151*e1fe3e4aSElliott Hughes                30,
152*e1fe3e4aSElliott Hughes                10,
153*e1fe3e4aSElliott Hughes                "vvcurveto",
154*e1fe3e4aSElliott Hughes                -10,
155*e1fe3e4aSElliott Hughes                -10,
156*e1fe3e4aSElliott Hughes                -10,
157*e1fe3e4aSElliott Hughes                10,
158*e1fe3e4aSElliott Hughes                -10,
159*e1fe3e4aSElliott Hughes                "hhcurveto",
160*e1fe3e4aSElliott Hughes                10,
161*e1fe3e4aSElliott Hughes                -10,
162*e1fe3e4aSElliott Hughes                -10,
163*e1fe3e4aSElliott Hughes                -10,
164*e1fe3e4aSElliott Hughes                -10,
165*e1fe3e4aSElliott Hughes                "vvcurveto",
166*e1fe3e4aSElliott Hughes                -5,
167*e1fe3e4aSElliott Hughes                -5,
168*e1fe3e4aSElliott Hughes                -6,
169*e1fe3e4aSElliott Hughes                -5,
170*e1fe3e4aSElliott Hughes                1,
171*e1fe3e4aSElliott Hughes                "vhcurveto",
172*e1fe3e4aSElliott Hughes                -5,
173*e1fe3e4aSElliott Hughes                -6,
174*e1fe3e4aSElliott Hughes                5,
175*e1fe3e4aSElliott Hughes                5,
176*e1fe3e4aSElliott Hughes                1,
177*e1fe3e4aSElliott Hughes                "hvcurveto",
178*e1fe3e4aSElliott Hughes                -3,
179*e1fe3e4aSElliott Hughes                -5,
180*e1fe3e4aSElliott Hughes                -1,
181*e1fe3e4aSElliott Hughes                -10,
182*e1fe3e4aSElliott Hughes                4,
183*e1fe3e4aSElliott Hughes                -5,
184*e1fe3e4aSElliott Hughes                "rrcurveto",
185*e1fe3e4aSElliott Hughes                "endchar",
186*e1fe3e4aSElliott Hughes            ],
187*e1fe3e4aSElliott Hughes            charstring.program,
188*e1fe3e4aSElliott Hughes        )
189*e1fe3e4aSElliott Hughes
190*e1fe3e4aSElliott Hughes    def test_default_width(self):
191*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(None, {})
192*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
193*e1fe3e4aSElliott Hughes        self.assertEqual(["endchar"], charstring.program)
194*e1fe3e4aSElliott Hughes
195*e1fe3e4aSElliott Hughes    def test_no_round(self):
196*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100.1, {}, roundTolerance=0.0)
197*e1fe3e4aSElliott Hughes        pen.moveTo((0, 0))
198*e1fe3e4aSElliott Hughes        pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49))
199*e1fe3e4aSElliott Hughes        pen.curveTo((20.49, 30.49), (9.9, 39.9), (0.1, 40.1))
200*e1fe3e4aSElliott Hughes        pen.closePath()
201*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
202*e1fe3e4aSElliott Hughes
203*e1fe3e4aSElliott Hughes        self.assertAlmostEqualProgram(
204*e1fe3e4aSElliott Hughes            [
205*e1fe3e4aSElliott Hughes                100,  # we always round the advance width
206*e1fe3e4aSElliott Hughes                0,
207*e1fe3e4aSElliott Hughes                "hmoveto",
208*e1fe3e4aSElliott Hughes                10.1,
209*e1fe3e4aSElliott Hughes                0.1,
210*e1fe3e4aSElliott Hughes                9.8,
211*e1fe3e4aSElliott Hughes                9.8,
212*e1fe3e4aSElliott Hughes                0.59,
213*e1fe3e4aSElliott Hughes                10.59,
214*e1fe3e4aSElliott Hughes                "rrcurveto",
215*e1fe3e4aSElliott Hughes                10,
216*e1fe3e4aSElliott Hughes                -10.59,
217*e1fe3e4aSElliott Hughes                9.41,
218*e1fe3e4aSElliott Hughes                -9.8,
219*e1fe3e4aSElliott Hughes                0.2,
220*e1fe3e4aSElliott Hughes                "vhcurveto",
221*e1fe3e4aSElliott Hughes                "endchar",
222*e1fe3e4aSElliott Hughes            ],
223*e1fe3e4aSElliott Hughes            charstring.program,
224*e1fe3e4aSElliott Hughes        )
225*e1fe3e4aSElliott Hughes
226*e1fe3e4aSElliott Hughes    def test_round_all(self):
227*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100.1, {}, roundTolerance=0.5)
228*e1fe3e4aSElliott Hughes        pen.moveTo((0, 0))
229*e1fe3e4aSElliott Hughes        pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49))
230*e1fe3e4aSElliott Hughes        pen.curveTo((20.49, 30.5), (9.9, 39.9), (0.1, 40.1))
231*e1fe3e4aSElliott Hughes        pen.closePath()
232*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
233*e1fe3e4aSElliott Hughes
234*e1fe3e4aSElliott Hughes        self.assertEqual(
235*e1fe3e4aSElliott Hughes            [
236*e1fe3e4aSElliott Hughes                100,
237*e1fe3e4aSElliott Hughes                0,
238*e1fe3e4aSElliott Hughes                "hmoveto",
239*e1fe3e4aSElliott Hughes                10,
240*e1fe3e4aSElliott Hughes                10,
241*e1fe3e4aSElliott Hughes                10,
242*e1fe3e4aSElliott Hughes                10,
243*e1fe3e4aSElliott Hughes                11,
244*e1fe3e4aSElliott Hughes                -10,
245*e1fe3e4aSElliott Hughes                9,
246*e1fe3e4aSElliott Hughes                -10,
247*e1fe3e4aSElliott Hughes                "hvcurveto",
248*e1fe3e4aSElliott Hughes                "endchar",
249*e1fe3e4aSElliott Hughes            ],
250*e1fe3e4aSElliott Hughes            charstring.program,
251*e1fe3e4aSElliott Hughes        )
252*e1fe3e4aSElliott Hughes
253*e1fe3e4aSElliott Hughes    def test_round_some(self):
254*e1fe3e4aSElliott Hughes        pen = T2CharStringPen(100, {}, roundTolerance=0.2)
255*e1fe3e4aSElliott Hughes        pen.moveTo((0, 0))
256*e1fe3e4aSElliott Hughes        # the following two are rounded as within the tolerance
257*e1fe3e4aSElliott Hughes        pen.lineTo((10.1, 0.1))
258*e1fe3e4aSElliott Hughes        pen.lineTo((19.9, 9.9))
259*e1fe3e4aSElliott Hughes        # this one is not rounded as it exceeds the tolerance
260*e1fe3e4aSElliott Hughes        pen.lineTo((20.49, 20.49))
261*e1fe3e4aSElliott Hughes        pen.closePath()
262*e1fe3e4aSElliott Hughes        charstring = pen.getCharString(None, None)
263*e1fe3e4aSElliott Hughes
264*e1fe3e4aSElliott Hughes        self.assertAlmostEqualProgram(
265*e1fe3e4aSElliott Hughes            [
266*e1fe3e4aSElliott Hughes                100,
267*e1fe3e4aSElliott Hughes                0,
268*e1fe3e4aSElliott Hughes                "hmoveto",
269*e1fe3e4aSElliott Hughes                10,
270*e1fe3e4aSElliott Hughes                "hlineto",
271*e1fe3e4aSElliott Hughes                10,
272*e1fe3e4aSElliott Hughes                10,
273*e1fe3e4aSElliott Hughes                0.49,
274*e1fe3e4aSElliott Hughes                10.49,
275*e1fe3e4aSElliott Hughes                "rlineto",
276*e1fe3e4aSElliott Hughes                "endchar",
277*e1fe3e4aSElliott Hughes            ],
278*e1fe3e4aSElliott Hughes            charstring.program,
279*e1fe3e4aSElliott Hughes        )
280*e1fe3e4aSElliott Hughes
281*e1fe3e4aSElliott Hughes    def test_invalid_tolerance(self):
282*e1fe3e4aSElliott Hughes        self.assertRaisesRegex(
283*e1fe3e4aSElliott Hughes            ValueError,
284*e1fe3e4aSElliott Hughes            "Rounding tolerance must be positive",
285*e1fe3e4aSElliott Hughes            T2CharStringPen,
286*e1fe3e4aSElliott Hughes            None,
287*e1fe3e4aSElliott Hughes            {},
288*e1fe3e4aSElliott Hughes            roundTolerance=-0.1,
289*e1fe3e4aSElliott Hughes        )
290*e1fe3e4aSElliott Hughes
291*e1fe3e4aSElliott Hughes
292*e1fe3e4aSElliott Hughesif __name__ == "__main__":
293*e1fe3e4aSElliott Hughes    import sys
294*e1fe3e4aSElliott Hughes
295*e1fe3e4aSElliott Hughes    sys.exit(unittest.main())
296