1from __future__ import print_function, division, absolute_import 2from fontTools.cffLib import PrivateDict 3from fontTools.cffLib.specializer import stringToProgram 4from fontTools.misc.psCharStrings import T2CharString, encodeFloat, read_realNumber 5import unittest 6 7 8class T2CharStringTest(unittest.TestCase): 9 10 @classmethod 11 def stringToT2CharString(cls, string): 12 return T2CharString(program=stringToProgram(string), private=PrivateDict()) 13 14 def test_calcBounds_empty(self): 15 cs = self.stringToT2CharString("endchar") 16 bounds = cs.calcBounds(None) 17 self.assertEqual(bounds, None) 18 19 def test_calcBounds_line(self): 20 cs = self.stringToT2CharString("100 100 rmoveto 40 10 rlineto -20 50 rlineto endchar") 21 bounds = cs.calcBounds(None) 22 self.assertEqual(bounds, (100, 100, 140, 160)) 23 24 def test_calcBounds_curve(self): 25 cs = self.stringToT2CharString("100 100 rmoveto -50 -150 200 0 -50 150 rrcurveto endchar") 26 bounds = cs.calcBounds(None) 27 self.assertEqual(bounds, (91.90524980688875, -12.5, 208.09475019311125, 100)) 28 29 def test_charstring_bytecode_optimization(self): 30 cs = self.stringToT2CharString( 31 "100.0 100 rmoveto -50.0 -150 200.5 0.0 -50 150 rrcurveto endchar") 32 cs.isCFF2 = False 33 cs.private._isCFF2 = False 34 cs.compile() 35 cs.decompile() 36 self.assertEqual( 37 cs.program, [100, 100, 'rmoveto', -50, -150, 200.5, 0, -50, 150, 38 'rrcurveto', 'endchar']) 39 40 cs2 = self.stringToT2CharString( 41 "100.0 rmoveto -50.0 -150 200.5 0.0 -50 150 rrcurveto") 42 cs2.isCFF2 = True 43 cs2.private._isCFF2 = True 44 cs2.compile(isCFF2=True) 45 cs2.decompile() 46 self.assertEqual( 47 cs2.program, [100, 'rmoveto', -50, -150, 200.5, 0, -50, 150, 48 'rrcurveto']) 49 50 def test_encodeFloat(self): 51 import sys 52 def hexenc(s): 53 return ' '.join('%02x' % ord(x) for x in s) 54 if sys.version_info[0] >= 3: 55 def hexenc_py3(s): 56 return ' '.join('%02x' % x for x in s) 57 hexenc = hexenc_py3 58 59 testNums = [ 60 # value expected result 61 (-9.399999999999999, '1e e9 a4 ff'), # -9.4 62 (9.399999999999999999, '1e 9a 4f'), # 9.4 63 (456.8, '1e 45 6a 8f'), # 456.8 64 (0.0, '1e 0f'), # 0 65 (-0.0, '1e 0f'), # 0 66 (1.0, '1e 1f'), # 1 67 (-1.0, '1e e1 ff'), # -1 68 (98765.37e2, '1e 98 76 53 7f'), # 9876537 69 (1234567890.0, '1e 1a 23 45 67 9b 09 ff'), # 1234567890 70 (9.876537e-4, '1e a0 00 98 76 53 7f'), # 9.876537e-24 71 (9.876537e+4, '1e 98 76 5a 37 ff'), # 9.876537e+24 72 ] 73 74 for sample in testNums: 75 encoded_result = encodeFloat(sample[0]) 76 77 # check to see if we got the expected bytes 78 self.assertEqual(hexenc(encoded_result), sample[1]) 79 80 # check to see if we get the same value by decoding the data 81 decoded_result = read_realNumber( 82 None, 83 None, 84 encoded_result, 85 1, 86 ) 87 self.assertEqual(decoded_result[0], float('%.8g' % sample[0])) 88 # We limit to 8 digits of precision to match the implementation 89 # of encodeFloat. 90 91 92if __name__ == "__main__": 93 import sys 94 sys.exit(unittest.main()) 95