• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from fontTools.pens.basePen import \
4    BasePen, decomposeSuperBezierSegment, decomposeQuadraticSegment
5from fontTools.misc.loggingTools import CapturingLogHandler
6import unittest
7
8
9class _TestPen(BasePen):
10    def __init__(self):
11        BasePen.__init__(self, glyphSet={})
12        self._commands = []
13
14    def __repr__(self):
15        return " ".join(self._commands)
16
17    def getCurrentPoint(self):
18        return self._getCurrentPoint()
19
20    def _moveTo(self, pt):
21        self._commands.append("%s %s moveto" % (pt[0], pt[1]))
22
23    def _lineTo(self, pt):
24        self._commands.append("%s %s lineto" % (pt[0], pt[1]))
25
26    def _curveToOne(self, bcp1, bcp2, pt):
27        self._commands.append("%s %s %s %s %s %s curveto" %
28                              (bcp1[0], bcp1[1],
29                               bcp2[0], bcp2[1],
30                               pt[0], pt[1]))
31
32    def _closePath(self):
33        self._commands.append("closepath")
34
35    def _endPath(self):
36        self._commands.append("endpath")
37
38
39class _TestGlyph:
40    def draw(self, pen):
41        pen.moveTo((0.0, 0.0))
42        pen.lineTo((0.0, 100.0))
43        pen.curveTo((50.0, 75.0), (60.0, 50.0), (50.0, 25.0), (0.0, 0.0))
44        pen.closePath()
45
46
47class BasePenTest(unittest.TestCase):
48    def test_moveTo(self):
49        pen = _TestPen()
50        pen.moveTo((0.5, -4.3))
51        self.assertEqual("0.5 -4.3 moveto", repr(pen))
52        self.assertEqual((0.5, -4.3), pen.getCurrentPoint())
53
54    def test_lineTo(self):
55        pen = _TestPen()
56        pen.moveTo((4, 5))
57        pen.lineTo((7, 8))
58        self.assertEqual("4 5 moveto 7 8 lineto", repr(pen))
59        self.assertEqual((7, 8), pen.getCurrentPoint())
60
61    def test_curveTo_zeroPoints(self):
62        pen = _TestPen()
63        pen.moveTo((0.0, 0.0))
64        self.assertRaises(AssertionError, pen.curveTo)
65
66    def test_curveTo_onePoint(self):
67        pen = _TestPen()
68        pen.moveTo((0.0, 0.0))
69        pen.curveTo((1.0, 1.1))
70        self.assertEqual("0.0 0.0 moveto 1.0 1.1 lineto", repr(pen))
71        self.assertEqual((1.0, 1.1), pen.getCurrentPoint())
72
73    def test_curveTo_twoPoints(self):
74        pen = _TestPen()
75        pen.moveTo((0.0, 0.0))
76        pen.curveTo((6.0, 3.0), (3.0, 6.0))
77        self.assertEqual("0.0 0.0 moveto 4.0 2.0 5.0 4.0 3.0 6.0 curveto",
78                         repr(pen))
79        self.assertEqual((3.0, 6.0), pen.getCurrentPoint())
80
81    def test_curveTo_manyPoints(self):
82        pen = _TestPen()
83        pen.moveTo((0.0, 0.0))
84        pen.curveTo((1.0, 1.1), (2.0, 2.1), (3.0, 3.1), (4.0, 4.1))
85        self.assertEqual("0.0 0.0 moveto "
86                         "1.0 1.1 1.5 1.6 2.0 2.1 curveto "
87                         "2.5 2.6 3.0 3.1 4.0 4.1 curveto", repr(pen))
88        self.assertEqual((4.0, 4.1), pen.getCurrentPoint())
89
90    def test_qCurveTo_zeroPoints(self):
91        pen = _TestPen()
92        pen.moveTo((0.0, 0.0))
93        self.assertRaises(AssertionError, pen.qCurveTo)
94
95    def test_qCurveTo_onePoint(self):
96        pen = _TestPen()
97        pen.moveTo((0.0, 0.0))
98        pen.qCurveTo((77.7, 99.9))
99        self.assertEqual("0.0 0.0 moveto 77.7 99.9 lineto", repr(pen))
100        self.assertEqual((77.7, 99.9), pen.getCurrentPoint())
101
102    def test_qCurveTo_manyPoints(self):
103        pen = _TestPen()
104        pen.moveTo((0.0, 0.0))
105        pen.qCurveTo((6.0, 3.0), (3.0, 6.0))
106        self.assertEqual("0.0 0.0 moveto 4.0 2.0 5.0 4.0 3.0 6.0 curveto",
107                         repr(pen))
108        self.assertEqual((3.0, 6.0), pen.getCurrentPoint())
109
110    def test_qCurveTo_onlyOffCurvePoints(self):
111        pen = _TestPen()
112        pen.moveTo((0.0, 0.0))
113        pen.qCurveTo((6.0, -6.0), (12.0, 12.0), (18.0, -18.0), None)
114        self.assertEqual("0.0 0.0 moveto "
115                         "12.0 -12.0 moveto "
116                         "8.0 -8.0 7.0 -3.0 9.0 3.0 curveto "
117                         "11.0 9.0 13.0 7.0 15.0 -3.0 curveto "
118                         "17.0 -13.0 16.0 -16.0 12.0 -12.0 curveto", repr(pen))
119        self.assertEqual((12.0, -12.0), pen.getCurrentPoint())
120
121    def test_closePath(self):
122        pen = _TestPen()
123        pen.lineTo((3, 4))
124        pen.closePath()
125        self.assertEqual("3 4 lineto closepath", repr(pen))
126        self.assertEqual(None, pen.getCurrentPoint())
127
128    def test_endPath(self):
129        pen = _TestPen()
130        pen.lineTo((3, 4))
131        pen.endPath()
132        self.assertEqual("3 4 lineto endpath", repr(pen))
133        self.assertEqual(None, pen.getCurrentPoint())
134
135    def test_addComponent(self):
136        pen = _TestPen()
137        pen.glyphSet["oslash"] = _TestGlyph()
138        pen.addComponent("oslash", (2, 3, 0.5, 2, -10, 0))
139        self.assertEqual("-10.0 0.0 moveto "
140                         "40.0 200.0 lineto "
141                         "127.5 300.0 131.25 290.0 125.0 265.0 curveto "
142                         "118.75 240.0 102.5 200.0 -10.0 0.0 curveto "
143                         "closepath", repr(pen))
144        self.assertEqual(None, pen.getCurrentPoint())
145
146    def test_addComponent_skip_missing(self):
147        pen = _TestPen()
148        with CapturingLogHandler(pen.log, "WARNING") as captor:
149            pen.addComponent("nonexistent", (1, 0, 0, 1, 0, 0))
150        captor.assertRegex("glyph '.*' is missing from glyphSet; skipped")
151
152
153class DecomposeSegmentTest(unittest.TestCase):
154    def test_decomposeSuperBezierSegment(self):
155        decompose = decomposeSuperBezierSegment
156        self.assertRaises(AssertionError, decompose, [])
157        self.assertRaises(AssertionError, decompose, [(0, 0)])
158        self.assertRaises(AssertionError, decompose, [(0, 0), (1, 1)])
159        self.assertEqual([((0, 0), (1, 1), (2, 2))],
160                         decompose([(0, 0), (1, 1), (2, 2)]))
161        self.assertEqual(
162            [((0, 0), (2, -2), (4, 0)), ((6, 2), (8, 8), (12, -12))],
163            decompose([(0, 0), (4, -4), (8, 8), (12, -12)]))
164
165    def test_decomposeQuadraticSegment(self):
166        decompose = decomposeQuadraticSegment
167        self.assertRaises(AssertionError, decompose, [])
168        self.assertRaises(AssertionError, decompose, [(0, 0)])
169        self.assertEqual([((0,0), (4, 8))], decompose([(0, 0), (4, 8)]))
170        self.assertEqual([((0,0), (2, 4)), ((4, 8), (9, -9))],
171                         decompose([(0, 0), (4, 8), (9, -9)]))
172        self.assertEqual(
173            [((0, 0), (2.0, 4.0)), ((4, 8), (6.5, -0.5)), ((9, -9), (10, 10))],
174            decompose([(0, 0), (4, 8), (9, -9), (10, 10)]))
175
176
177if __name__ == '__main__':
178    import sys
179    sys.exit(unittest.main())
180