1from __future__ import print_function, division, absolute_import 2from fontTools.misc.py23 import * 3from fontTools.pens.t2CharStringPen import T2CharStringPen 4import unittest 5 6 7class T2CharStringPenTest(unittest.TestCase): 8 9 def __init__(self, methodName): 10 unittest.TestCase.__init__(self, methodName) 11 # Python 3 renamed assertRaisesRegexp to assertRaisesRegex, 12 # and fires deprecation warnings if a program uses the old name. 13 if not hasattr(self, "assertRaisesRegex"): 14 self.assertRaisesRegex = self.assertRaisesRegexp 15 16 def assertAlmostEqualProgram(self, expected, actual): 17 self.assertEqual(len(expected), len(actual)) 18 for i1, i2 in zip(expected, actual): 19 if isinstance(i1, basestring): 20 self.assertIsInstance(i2, basestring) 21 self.assertEqual(i1, i2) 22 else: 23 self.assertAlmostEqual(i1, i2) 24 25 def test_draw_h_v_lines(self): 26 pen = T2CharStringPen(100, {}) 27 pen.moveTo((0, 0)) 28 pen.lineTo((10, 0)) 29 pen.lineTo((10, 10)) 30 pen.lineTo((0, 10)) 31 pen.closePath() # no-op 32 pen.moveTo((10, 10)) 33 pen.lineTo((10, 20)) 34 pen.lineTo((0, 20)) 35 pen.lineTo((0, 10)) 36 pen.closePath() 37 charstring = pen.getCharString(None, None) 38 39 self.assertEqual( 40 [100, 41 0, 'hmoveto', 42 10, 10, -10, 'hlineto', 43 10, 'hmoveto', 44 10, -10, -10, 'vlineto', 45 'endchar'], 46 charstring.program) 47 48 def test_draw_lines(self): 49 pen = T2CharStringPen(100, {}) 50 pen.moveTo((5, 5)) 51 pen.lineTo((25, 15)) 52 pen.lineTo((35, 35)) 53 pen.lineTo((15, 25)) 54 pen.closePath() # no-op 55 charstring = pen.getCharString(None, None) 56 57 self.assertEqual( 58 [100, 59 5, 5, 'rmoveto', 60 20, 10, 10, 20, -20, -10, 'rlineto', 61 'endchar'], 62 charstring.program) 63 64 def test_draw_h_v_curves(self): 65 pen = T2CharStringPen(100, {}) 66 pen.moveTo((0, 0)) 67 pen.curveTo((10, 0), (20, 10), (20, 20)) 68 pen.curveTo((20, 30), (10, 40), (0, 40)) 69 pen.endPath() # no-op 70 charstring = pen.getCharString(None, None) 71 72 self.assertEqual( 73 [100, 74 0, 'hmoveto', 75 10, 10, 10, 10, 10, -10, 10, -10, 'hvcurveto', 76 'endchar'], 77 charstring.program) 78 79 def test_draw_curves(self): 80 pen = T2CharStringPen(100, {}) 81 pen.moveTo((95, 25)) 82 pen.curveTo((115, 44), (115, 76), (95, 95)) 83 pen.curveTo((76, 114), (44, 115), (25, 95)) 84 pen.endPath() # no-op 85 charstring = pen.getCharString(None, None) 86 87 self.assertEqual( 88 [100, 89 95, 25, 'rmoveto', 90 20, 19, 0, 32, -20, 19, -19, 19, -32, 1, -19, -20, 'rrcurveto', 91 'endchar'], 92 charstring.program) 93 94 def test_draw_more_curves(self): 95 pen = T2CharStringPen(100, {}) 96 pen.moveTo((10, 10)) 97 pen.curveTo((20, 10), (50, 10), (60, 10)) 98 pen.curveTo((60, 20), (60, 50), (60, 60)) 99 pen.curveTo((50, 50), (40, 60), (30, 60)) 100 pen.curveTo((40, 50), (30, 40), (30, 30)) 101 pen.curveTo((30, 25), (25, 19), (20, 20)) 102 pen.curveTo((15, 20), (9, 25), (10, 30)) 103 pen.curveTo((7, 25), (6, 15), (10, 10)) 104 pen.endPath() # no-op 105 charstring = pen.getCharString(None, None) 106 107 self.assertEqual( 108 [100, 109 10, 10, 'rmoveto', 110 10, 30, 0, 10, 'hhcurveto', 111 10, 0, 30, 10, 'vvcurveto', 112 -10, -10, -10, 10, -10, 'hhcurveto', 113 10, -10, -10, -10, -10, 'vvcurveto', 114 -5, -5, -6, -5, 1, 'vhcurveto', 115 -5, -6, 5, 5, 1, 'hvcurveto', 116 -3, -5, -1, -10, 4, -5, 'rrcurveto', 117 'endchar'], 118 charstring.program) 119 120 def test_default_width(self): 121 pen = T2CharStringPen(None, {}) 122 charstring = pen.getCharString(None, None) 123 self.assertEqual(['endchar'], charstring.program) 124 125 def test_no_round(self): 126 pen = T2CharStringPen(100.1, {}, roundTolerance=0.0) 127 pen.moveTo((0, 0)) 128 pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49)) 129 pen.curveTo((20.49, 30.49), (9.9, 39.9), (0.1, 40.1)) 130 pen.closePath() 131 charstring = pen.getCharString(None, None) 132 133 self.assertAlmostEqualProgram( 134 [100, # we always round the advance width 135 0, 'hmoveto', 136 10.1, 0.1, 9.8, 9.8, 0.59, 10.59, 'rrcurveto', 137 10, -10.59, 9.41, -9.8, 0.2, 'vhcurveto', 138 'endchar'], 139 charstring.program) 140 141 def test_round_all(self): 142 pen = T2CharStringPen(100.1, {}, roundTolerance=0.5) 143 pen.moveTo((0, 0)) 144 pen.curveTo((10.1, 0.1), (19.9, 9.9), (20.49, 20.49)) 145 pen.curveTo((20.49, 30.5), (9.9, 39.9), (0.1, 40.1)) 146 pen.closePath() 147 charstring = pen.getCharString(None, None) 148 149 self.assertEqual( 150 [100, 151 0, 'hmoveto', 152 10, 10, 10, 10, 11, -10, 9, -10, 'hvcurveto', 153 'endchar'], 154 charstring.program) 155 156 def test_round_some(self): 157 pen = T2CharStringPen(100, {}, roundTolerance=0.2) 158 pen.moveTo((0, 0)) 159 # the following two are rounded as within the tolerance 160 pen.lineTo((10.1, 0.1)) 161 pen.lineTo((19.9, 9.9)) 162 # this one is not rounded as it exceeds the tolerance 163 pen.lineTo((20.49, 20.49)) 164 pen.closePath() 165 charstring = pen.getCharString(None, None) 166 167 self.assertAlmostEqualProgram( 168 [100, 169 0, 'hmoveto', 170 10, 'hlineto', 171 10, 10, 0.49, 10.49, 'rlineto', 172 'endchar'], 173 charstring.program) 174 175 def test_invalid_tolerance(self): 176 self.assertRaisesRegex( 177 ValueError, 178 "Rounding tolerance must be positive", 179 T2CharStringPen, None, {}, roundTolerance=-0.1) 180 181 182if __name__ == '__main__': 183 import sys 184 sys.exit(unittest.main()) 185