You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
5.7 KiB

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())