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