296 lines
7.5 KiB
Python
296 lines
7.5 KiB
Python
from fontTools.pens.t2CharStringPen import T2CharStringPen
|
|
import unittest
|
|
|
|
|
|
class T2CharStringPenTest(unittest.TestCase):
|
|
def __init__(self, methodName):
|
|
unittest.TestCase.__init__(self, methodName)
|
|
|
|
def assertAlmostEqualProgram(self, expected, actual):
|
|
self.assertEqual(len(expected), len(actual))
|
|
for i1, i2 in zip(expected, actual):
|
|
if isinstance(i1, str):
|
|
self.assertIsInstance(i2, str)
|
|
self.assertEqual(i1, i2)
|
|
else:
|
|
self.assertAlmostEqual(i1, i2)
|
|
|
|
def test_draw_h_v_lines(self):
|
|
pen = T2CharStringPen(100, {})
|
|
pen.moveTo((0, 0))
|
|
pen.lineTo((10, 0))
|
|
pen.lineTo((10, 10))
|
|
pen.lineTo((0, 10))
|
|
pen.closePath() # no-op
|
|
pen.moveTo((10, 10))
|
|
pen.lineTo((10, 20))
|
|
pen.lineTo((0, 20))
|
|
pen.lineTo((0, 10))
|
|
pen.closePath()
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[
|
|
100,
|
|
0,
|
|
"hmoveto",
|
|
10,
|
|
10,
|
|
-10,
|
|
"hlineto",
|
|
10,
|
|
"hmoveto",
|
|
10,
|
|
-10,
|
|
-10,
|
|
"vlineto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_draw_lines(self):
|
|
pen = T2CharStringPen(100, {})
|
|
pen.moveTo((5, 5))
|
|
pen.lineTo((25, 15))
|
|
pen.lineTo((35, 35))
|
|
pen.lineTo((15, 25))
|
|
pen.closePath() # no-op
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[100, 5, 5, "rmoveto", 20, 10, 10, 20, -20, -10, "rlineto", "endchar"],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_draw_h_v_curves(self):
|
|
pen = T2CharStringPen(100, {})
|
|
pen.moveTo((0, 0))
|
|
pen.curveTo((10, 0), (20, 10), (20, 20))
|
|
pen.curveTo((20, 30), (10, 40), (0, 40))
|
|
pen.endPath() # no-op
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[
|
|
100,
|
|
0,
|
|
"hmoveto",
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
-10,
|
|
10,
|
|
-10,
|
|
"hvcurveto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_draw_curves(self):
|
|
pen = T2CharStringPen(100, {})
|
|
pen.moveTo((95, 25))
|
|
pen.curveTo((115, 44), (115, 76), (95, 95))
|
|
pen.curveTo((76, 114), (44, 115), (25, 95))
|
|
pen.endPath() # no-op
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[
|
|
100,
|
|
95,
|
|
25,
|
|
"rmoveto",
|
|
20,
|
|
19,
|
|
0,
|
|
32,
|
|
-20,
|
|
19,
|
|
-19,
|
|
19,
|
|
-32,
|
|
1,
|
|
-19,
|
|
-20,
|
|
"rrcurveto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_draw_more_curves(self):
|
|
pen = T2CharStringPen(100, {})
|
|
pen.moveTo((10, 10))
|
|
pen.curveTo((20, 10), (50, 10), (60, 10))
|
|
pen.curveTo((60, 20), (60, 50), (60, 60))
|
|
pen.curveTo((50, 50), (40, 60), (30, 60))
|
|
pen.curveTo((40, 50), (30, 40), (30, 30))
|
|
pen.curveTo((30, 25), (25, 19), (20, 20))
|
|
pen.curveTo((15, 20), (9, 25), (10, 30))
|
|
pen.curveTo((7, 25), (6, 15), (10, 10))
|
|
pen.endPath() # no-op
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[
|
|
100,
|
|
10,
|
|
10,
|
|
"rmoveto",
|
|
10,
|
|
30,
|
|
0,
|
|
10,
|
|
"hhcurveto",
|
|
10,
|
|
0,
|
|
30,
|
|
10,
|
|
"vvcurveto",
|
|
-10,
|
|
-10,
|
|
-10,
|
|
10,
|
|
-10,
|
|
"hhcurveto",
|
|
10,
|
|
-10,
|
|
-10,
|
|
-10,
|
|
-10,
|
|
"vvcurveto",
|
|
-5,
|
|
-5,
|
|
-6,
|
|
-5,
|
|
1,
|
|
"vhcurveto",
|
|
-5,
|
|
-6,
|
|
5,
|
|
5,
|
|
1,
|
|
"hvcurveto",
|
|
-3,
|
|
-5,
|
|
-1,
|
|
-10,
|
|
4,
|
|
-5,
|
|
"rrcurveto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_default_width(self):
|
|
pen = T2CharStringPen(None, {})
|
|
charstring = pen.getCharString(None, None)
|
|
self.assertEqual(["endchar"], charstring.program)
|
|
|
|
def test_no_round(self):
|
|
pen = T2CharStringPen(100.1, {}, roundTolerance=0.0)
|
|
pen.moveTo((0, 0))
|
|
pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49))
|
|
pen.curveTo((20.49, 30.49), (9.9, 39.9), (0.1, 40.1))
|
|
pen.closePath()
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertAlmostEqualProgram(
|
|
[
|
|
100, # we always round the advance width
|
|
0,
|
|
"hmoveto",
|
|
10.1,
|
|
0.1,
|
|
9.8,
|
|
9.8,
|
|
0.59,
|
|
10.59,
|
|
"rrcurveto",
|
|
10,
|
|
-10.59,
|
|
9.41,
|
|
-9.8,
|
|
0.2,
|
|
"vhcurveto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_round_all(self):
|
|
pen = T2CharStringPen(100.1, {}, roundTolerance=0.5)
|
|
pen.moveTo((0, 0))
|
|
pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49))
|
|
pen.curveTo((20.49, 30.5), (9.9, 39.9), (0.1, 40.1))
|
|
pen.closePath()
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertEqual(
|
|
[
|
|
100,
|
|
0,
|
|
"hmoveto",
|
|
10,
|
|
10,
|
|
10,
|
|
10,
|
|
11,
|
|
-10,
|
|
9,
|
|
-10,
|
|
"hvcurveto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_round_some(self):
|
|
pen = T2CharStringPen(100, {}, roundTolerance=0.2)
|
|
pen.moveTo((0, 0))
|
|
# the following two are rounded as within the tolerance
|
|
pen.lineTo((10.1, 0.1))
|
|
pen.lineTo((19.9, 9.9))
|
|
# this one is not rounded as it exceeds the tolerance
|
|
pen.lineTo((20.49, 20.49))
|
|
pen.closePath()
|
|
charstring = pen.getCharString(None, None)
|
|
|
|
self.assertAlmostEqualProgram(
|
|
[
|
|
100,
|
|
0,
|
|
"hmoveto",
|
|
10,
|
|
"hlineto",
|
|
10,
|
|
10,
|
|
0.49,
|
|
10.49,
|
|
"rlineto",
|
|
"endchar",
|
|
],
|
|
charstring.program,
|
|
)
|
|
|
|
def test_invalid_tolerance(self):
|
|
self.assertRaisesRegex(
|
|
ValueError,
|
|
"Rounding tolerance must be positive",
|
|
T2CharStringPen,
|
|
None,
|
|
{},
|
|
roundTolerance=-0.1,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
sys.exit(unittest.main())
|