psCharStrings.py revision 32c10eecffb4923e0721c395e4b80fb732543f18
17842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""psCharStrings.py -- module implementing various kinds of CharStrings: 27842e56b97ce677b83bdab09cda48bc2d89ac75aJustCFF dictionary data and Type1/Type2 CharStrings. 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 47842e56b97ce677b83bdab09cda48bc2d89ac75aJust 532c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbodfrom __future__ import print_function, division 630e691edd056ba22fa8970280e986747817bec3dBehdad Esfahbodfrom fontTools.misc.py23 import * 77842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport struct 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10455af6592bffbd6f2fc9f56fbfe083022a8353d4jvrDEBUG = 0 11455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 12455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 137842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding = [None] * 256 147842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[0:32] = (32) * ["do_operator"] 157842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[32:247] = (247 - 32) * ["read_byte"] 167842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[247:251] = (251 - 247) * ["read_smallInt1"] 177842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[251:255] = (255 - 251) * ["read_smallInt2"] 187842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[255] = "read_longInt" 197842e56b97ce677b83bdab09cda48bc2d89ac75aJustassert len(t1OperandEncoding) == 256 207842e56b97ce677b83bdab09cda48bc2d89ac75aJust 217842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding = t1OperandEncoding[:] 227842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding[28] = "read_shortInt" 2395c9e9fc11dc028bd1747788f2b417f3936fc59bjvrt2OperandEncoding[255] = "read_fixed1616" 247842e56b97ce677b83bdab09cda48bc2d89ac75aJust 257842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding = t2OperandEncoding[:] 267842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[29] = "read_longInt" 277842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[30] = "read_realNumber" 287842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[255] = "reserved" 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust 317842e56b97ce677b83bdab09cda48bc2d89ac75aJustrealNibbles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust '.', 'E', 'E-', None, '-'] 33f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrrealNibblesDict = {} 34f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrfor _i in range(len(realNibbles)): 35f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr realNibblesDict[realNibbles[_i]] = _i 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 38f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass ByteCodeBase: 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_byte(self, b0, data, index): 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust return b0 - 139, index 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt1(self, b0, data, index): 447842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return (b0-247)*256 + b1 + 108, index+1 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt2(self, b0, data, index): 487842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return -(b0-251)*256 - b1 - 108, index+1 507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_shortInt(self, b0, data, index): 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">h", bin) 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+2 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_longInt(self, b0, data, index): 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] + data[index+2] + data[index+3] 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">l", bin) 597842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+4 607842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def read_fixed1616(self, b0, data, index): 6295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bin = data[index] + data[index+1] + data[index+2] + data[index+3] 6395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr value, = struct.unpack(">l", bin) 6432c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod return value / 65536, index+4 6595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 667842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_realNumber(self, b0, data, index): 677842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = '' 68ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust b = ord(data[index]) 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble0 = (b & 0xf0) >> 4 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble1 = b & 0x0f 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble0 == 0xf: 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble0] 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble1 == 0xf: 777842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble1] 79455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return float(number), index 807842e56b97ce677b83bdab09cda48bc2d89ac75aJust 817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 82dbc2c173b35360386c907a3c70cb931ae4c3fac9jvrdef buildOperatorDict(operatorList): 83455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper = {} 84455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc = {} 857842e56b97ce677b83bdab09cda48bc2d89ac75aJust for item in operatorList: 867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(item) == 2: 87455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1] 88455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 89455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1:] 90002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod if isinstance(item[0], tuple): 91455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = item[0] 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 93455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = (item[0],) 94455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return oper, opc 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 977842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2Operators = [ 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust (16, 'blend'), 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust (18, 'hstemhm'), 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust (19, 'hintmask'), 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust (20, 'cntrmask'), 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust (23, 'vstemhm'), 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust (24, 'rcurveline'), 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust (25, 'rlinecurve'), 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust (26, 'vvcurveto'), 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust (27, 'hhcurveto'), 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust# (28, 'shortint'), # not really an operator 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust (29, 'callgsubr'), 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 1247099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr ((12, 0), 'ignore'), # dotsection. Yes, there a few very early OTF/CFF 1257099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr # fonts with this deprecated operator. Just ignore it. 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 3), 'and'), 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 4), 'or'), 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 5), 'not'), 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 8), 'store'), 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 9), 'abs'), 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 10), 'add'), 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 11), 'sub'), 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 13), 'load'), 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 14), 'neg'), 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 15), 'eq'), 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 18), 'drop'), 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 20), 'put'), 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 21), 'get'), 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 22), 'ifelse'), 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 23), 'random'), 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 24), 'mul'), 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 26), 'sqrt'), 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 27), 'dup'), 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 28), 'exch'), 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 29), 'index'), 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 30), 'roll'), 1487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 34), 'hflex'), 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 35), 'flex'), 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 36), 'hflex1'), 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 37), 'flex1'), 1527842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 154f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 155f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef getIntEncoder(format): 156f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if format == "cff": 157b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod fourByteOp = bytechr(29) 158f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif format == "t1": 159b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod fourByteOp = bytechr(255) 160f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 161f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert format == "t2" 16295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = None 163f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 164b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod def encodeInt(value, fourByteOp=fourByteOp, bytechr=bytechr, 16595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr pack=struct.pack, unpack=struct.unpack): 166f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if -107 <= value <= 107: 167b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(value + 139) 168f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif 108 <= value <= 1131: 169f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = value - 108 170b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr((value >> 8) + 247) + bytechr(value & 0xFF) 171f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif -1131 <= value <= -108: 172f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = -value - 108 173b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr((value >> 8) + 251) + bytechr(value & 0xFF) 17495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr elif fourByteOp is None: 17595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # T2 only supports 2 byte ints 17695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if -32768 <= value <= 32767: 177b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(28) + pack(">h", value) 17895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 17995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # Backwards compatible hack: due to a previous bug in FontTools, 18095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # 16.16 fixed numbers were written out as 4-byte ints. When 18195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # these numbers were small, they were wrongly written back as 18295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # small ints instead of 4-byte ints, breaking round-tripping. 18395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # This here workaround doesn't do it any better, since we can't 18495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # distinguish anymore between small ints that were supposed to 18595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # be small fixed numbers and small ints that were just small 18695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # ints. Hence the warning. 18795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr import sys 18895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr sys.stderr.write("Warning: 4-byte T2 number got passed to the " 18995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "IntType handler. This should happen only when reading in " 19095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "old XML files.\n") 191b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(255) + pack(">l", value) 192f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 193f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = fourByteOp + pack(">l", value) 194f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return code 195f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 196f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return encodeInt 197f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 198f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 199f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntCFF = getIntEncoder("cff") 200f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT1 = getIntEncoder("t1") 201f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT2 = getIntEncoder("t2") 202f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 20395c9e9fc11dc028bd1747788f2b417f3936fc59bjvrdef encodeFixed(f, pack=struct.pack): 20495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For T2 only 20595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return "\xff" + pack(">l", int(round(f * 65536))) 20695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 207f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef encodeFloat(f): 20895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For CFF only, used in cffLib 209f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = str(f).upper() 210f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if s[:2] == "0.": 211f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 212f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif s[:3] == "-0.": 213f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = "-" + s[2:] 214f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles = [] 215f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr while s: 216f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = s[0] 217f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 218f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if c == "E" and s[:1] == "-": 219f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 220f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = "E-" 221f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(realNibblesDict[c]) 222f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 223f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if len(nibbles) % 2: 224f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 225b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod d = bytechr(30) 226f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr for i in range(0, len(nibbles), 2): 227b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod d = d + bytechr(nibbles[i] << 4 | nibbles[i+1]) 228f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return d 229f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 230f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 2314e5af60930726d06a58a30bae45bb27ae50aea77jvrclass CharStringCompileError(Exception): pass 2324e5af60930726d06a58a30bae45bb27ae50aea77jvr 2334e5af60930726d06a58a30bae45bb27ae50aea77jvr 234f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass T2CharString(ByteCodeBase): 2357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2367842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t2OperandEncoding 237455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t2Operators) 2387842e56b97ce677b83bdab09cda48bc2d89ac75aJust 239489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): 2407842e56b97ce677b83bdab09cda48bc2d89ac75aJust if program is None: 2417842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 2427842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = bytecode 2437842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 244489d76a340845361def6af9ab7d9152f8e66f417jvr self.private = private 245846d09e380215f8c7fdb4bbb9f083f8e68722cdaBehdad Esfahbod self.globalSubrs = globalSubrs if globalSubrs is not None else [] 2467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __repr__(self): 2487842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is None: 2497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) 2507842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 2517842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) 2527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 25395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 25495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT2 25595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 25695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 25795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeFixed 25895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 259586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def decompile(self): 260586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr if not self.needsDecompilation(): 261586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr return 262489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 263489d76a340845361def6af9ab7d9152f8e66f417jvr decompiler = SimpleT2Decompiler(subrs, self.globalSubrs) 264586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr decompiler.execute(self) 265586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr 266489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 267489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 268489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T2OutlineExtractor(pen, subrs, self.globalSubrs, 269489d76a340845361def6af9ab7d9152f8e66f417jvr self.private.nominalWidthX, self.private.defaultWidthX) 270489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 271489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 272489d76a340845361def6af9ab7d9152f8e66f417jvr 273455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr def compile(self): 274455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if self.bytecode is not None: 275455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return 2769920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program, "illegal CharString: decompiled to empty program" 2779920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program[-1] in ("endchar", "return", "callsubr", "callgsubr", 2789920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 279455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr bytecode = [] 280455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opcodes = self.opcodes 2814e5af60930726d06a58a30bae45bb27ae50aea77jvr program = self.program 28295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeInt = self.getIntEncoder() 28395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeFixed = self.getFixedEncoder() 2844e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 2854e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(program) 2864e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 2874e5af60930726d06a58a30bae45bb27ae50aea77jvr token = program[i] 2884e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 289455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr tp = type(token) 290002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod if tp == str: 2914e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 292b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod bytecode.extend(bytechr(b) for b in opcodes[token]) 2934e5af60930726d06a58a30bae45bb27ae50aea77jvr except KeyError: 294cd5aad92f23737ff93a110d5c73d624658a28da8Behdad Esfahbod raise CharStringCompileError("illegal operator: %s" % token) 2954e5af60930726d06a58a30bae45bb27ae50aea77jvr if token in ('hintmask', 'cntrmask'): 2964e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode.append(program[i]) # hint mask 2974e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 298002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == int: 29995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeInt(token)) 300002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == float: 30195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeFixed(token)) 302455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 303f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert 0, "unsupported type: %s" % tp 3044e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 3054e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode = "".join(bytecode) 3064e5af60930726d06a58a30bae45bb27ae50aea77jvr except TypeError: 3073ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(bytecode) 3084e5af60930726d06a58a30bae45bb27ae50aea77jvr raise 309f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.setBytecode(bytecode) 310f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def needsDecompilation(self): 3127842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.bytecode is not None 3137842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3147842e56b97ce677b83bdab09cda48bc2d89ac75aJust def setProgram(self, program): 3157842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 3167842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = None 3177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 318f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr def setBytecode(self, bytecode): 319f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.bytecode = bytecode 320f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.program = None 321f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3227842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getToken(self, index, 323002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod len=len, ord=ord, getattr=getattr, type=type, StringType=str): 3247842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3257842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.bytecode): 3267842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3277842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(self.bytecode[index]) 3287842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3297842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 3307842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 3317842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, index = handler(b0, self.bytecode, index) 3327842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3337842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.program): 3347842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3357842e56b97ce677b83bdab09cda48bc2d89ac75aJust token = self.program[index] 3367842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 337ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod isOperator = isinstance(token, StringType) 3387842e56b97ce677b83bdab09cda48bc2d89ac75aJust return token, isOperator, index 3397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getBytes(self, index, nBytes): 3417842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3427842e56b97ce677b83bdab09cda48bc2d89ac75aJust newIndex = index + nBytes 3437842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.bytecode[index:newIndex] 3447842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = newIndex 3457842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3467842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.program[index] 3477842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3487842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(bytes) == nBytes 3497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bytes, index 3507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 3527842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 3537842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 3547842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 3557842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3567842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 3577842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator = self.operators[op] 3587842e56b97ce677b83bdab09cda48bc2d89ac75aJust return operator, index 3597842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, xmlWriter): 361dab433233bd4024ede9ad27c6c61ea0072c2edafJust from fontTools.misc.textTools import num2binary 3627842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3637842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.dumphex(self.bytecode) 3647842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3657842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 3667842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 367ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 3687842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 3697842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 3707842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 3717842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 372e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod args = [str(arg) for arg in args] 3737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token in ('hintmask', 'cntrmask'): 3747842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMask, isOperator, index = self.getToken(index) 3757842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits = [] 3767842e56b97ce677b83bdab09cda48bc2d89ac75aJust for byte in hintMask: 3777842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits.append(num2binary(ord(byte), 8)) 37814fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod hintMask = ''.join(bits) 37914fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token, hintMask]) 3807842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 38114fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token]) 3827842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.write(line) 3837842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.newline() 3847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 3857842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3867842e56b97ce677b83bdab09cda48bc2d89ac75aJust args.append(token) 3874e5af60930726d06a58a30bae45bb27ae50aea77jvr 3883a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content): 389b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr from fontTools.misc.textTools import binary2num, readHex 390b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr if attrs.get("raw"): 391b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr self.setBytecode(readHex(content)) 392b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr return 3934e5af60930726d06a58a30bae45bb27ae50aea77jvr content = "".join(content) 3944e5af60930726d06a58a30bae45bb27ae50aea77jvr content = content.split() 3954e5af60930726d06a58a30bae45bb27ae50aea77jvr program = [] 3964e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(content) 3974e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 3984e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 3994e5af60930726d06a58a30bae45bb27ae50aea77jvr token = content[i] 4004e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 4014e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 4024e5af60930726d06a58a30bae45bb27ae50aea77jvr token = int(token) 4034e5af60930726d06a58a30bae45bb27ae50aea77jvr except ValueError: 40495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr try: 40595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr token = float(token) 40695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr except ValueError: 40795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 40895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if token in ('hintmask', 'cntrmask'): 40995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr mask = content[i] 41095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr maskBytes = "" 41195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr for j in range(0, len(mask), 8): 412b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod maskBytes = maskBytes + bytechr(binary2num(mask[j:j+8])) 41395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(maskBytes) 41495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr i = i + 1 41595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 41695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 4174e5af60930726d06a58a30bae45bb27ae50aea77jvr else: 4184e5af60930726d06a58a30bae45bb27ae50aea77jvr program.append(token) 4194e5af60930726d06a58a30bae45bb27ae50aea77jvr self.setProgram(program) 4207842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4227842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1Operators = [ 4237842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 4247842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 4257842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 4267842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 4277842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 4287842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 4297842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 4307842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 4317842e56b97ce677b83bdab09cda48bc2d89ac75aJust (9, 'closepath'), 4327842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 4337842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 4347842e56b97ce677b83bdab09cda48bc2d89ac75aJust (13, 'hsbw'), 4357842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 4367842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 4377842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 4387842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 4397842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 4407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 0), 'dotsection'), 4417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 1), 'vstem3'), 4427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 2), 'hstem3'), 4437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 6), 'seac'), 4447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 7), 'sbw'), 4457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 4467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 16), 'callothersubr'), 4477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 17), 'pop'), 4487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 33), 'setcurrentpoint'), 4497842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 4507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4517842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1CharString(T2CharString): 4527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4537842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t1OperandEncoding 454455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t1Operators) 4557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 456489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, subrs=None): 457489d76a340845361def6af9ab7d9152f8e66f417jvr if program is None: 458489d76a340845361def6af9ab7d9152f8e66f417jvr program = [] 459489d76a340845361def6af9ab7d9152f8e66f417jvr self.bytecode = bytecode 460489d76a340845361def6af9ab7d9152f8e66f417jvr self.program = program 461489d76a340845361def6af9ab7d9152f8e66f417jvr self.subrs = subrs 462489d76a340845361def6af9ab7d9152f8e66f417jvr 46395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 46495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT1 46595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 46695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 46795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeFixed(value): 46895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr raise TypeError("Type 1 charstrings don't support floating point operands") 46995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 4707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self): 471b68a700595ff730c29d3d4b7abf92ee287678745Just if self.program is not None: 4727842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 4737842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 4747842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 475ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 4767842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 4777842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 4787842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 4797842e56b97ce677b83bdab09cda48bc2d89ac75aJust program.append(token) 4807842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.setProgram(program) 4817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 482489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 483489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T1OutlineExtractor(pen, self.subrs) 484489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 485489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 486489d76a340845361def6af9ab7d9152f8e66f417jvr 4877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4887842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass SimpleT2Decompiler: 4897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4907842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, localSubrs, globalSubrs): 4917842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localSubrs = localSubrs 4927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localBias = calcSubrBias(localSubrs) 4937842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalSubrs = globalSubrs 4947842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalBias = calcSubrBias(globalSubrs) 4957842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 4967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4977842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 4987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack = [] 4997842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack = [] 5007842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = 0 5017842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = 0 5027842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def execute(self, charString): 5047842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack.append(charString) 5057842e56b97ce677b83bdab09cda48bc2d89ac75aJust needsDecompilation = charString.needsDecompilation() 5067842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5077842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 5087842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = program.append 5097842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5107842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = lambda x: None 5117842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack = self.operandStack.append 5127842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 513ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 5147842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = charString.getToken(index) 5157842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 5167842e56b97ce677b83bdab09cda48bc2d89ac75aJust break # we're done! 5177842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(token) 5187842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 5197842e56b97ce677b83bdab09cda48bc2d89ac75aJust handlerName = "op_" + token 5207842e56b97ce677b83bdab09cda48bc2d89ac75aJust if hasattr(self, handlerName): 5217842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, handlerName) 5227842e56b97ce677b83bdab09cda48bc2d89ac75aJust rv = handler(index) 5237842e56b97ce677b83bdab09cda48bc2d89ac75aJust if rv: 5247842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = rv 5257842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(hintMaskBytes) 5267842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5277842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() 5287842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5297842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack(token) 5307842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5319920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program, "illegal CharString: decompiled to empty program" 5329920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program[-1] in ("endchar", "return", "callsubr", "callgsubr", 5339920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 5347842e56b97ce677b83bdab09cda48bc2d89ac75aJust charString.setProgram(program) 5357842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.callingStack[-1] 5367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 5387842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.operandStack[-1] 5397842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.operandStack[-1] 5407842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 5417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 5437842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack[:] 5447842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack[:] = [] 5457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return stack 5467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def push(self, value): 5487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack.append(value) 5497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_return(self, index): 5517842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.operandStack: 5527842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5547842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 5557842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5567099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5577099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr def op_ignore(self, index): 5587099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr pass 5597099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 5617842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5627842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.localSubrs[subrIndex+self.localBias] 5637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5647842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5657842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callgsubr(self, index): 5667842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5677842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.globalSubrs[subrIndex+self.globalBias] 5687842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 570586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_hstem(self, index): 571586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 572586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstem(self, index): 573586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstemhm(self, index): 5757842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 576586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstemhm(self, index): 577586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5797842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hintmask(self, index): 5807842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.hintMaskBytes: 5817842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 58232c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintMaskBytes = (self.hintCount + 7) // 8 5837842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) 5847842e56b97ce677b83bdab09cda48bc2d89ac75aJust return hintMaskBytes, index 5857842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5867842e56b97ce677b83bdab09cda48bc2d89ac75aJust op_cntrmask = op_hintmask 5877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5887842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 5897842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 59032c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintCount = self.hintCount + len(args) // 2 5917842e56b97ce677b83bdab09cda48bc2d89ac75aJust 592f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod # misc 593f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_and(self, index): 594f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 595f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_or(self, index): 596f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 597f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_not(self, index): 598f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 599f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_store(self, index): 600f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 601f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_abs(self, index): 602f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 603f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_add(self, index): 604f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 605f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sub(self, index): 606f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 607f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_div(self, index): 608f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 609f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_load(self, index): 610f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 611f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_neg(self, index): 612f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 613f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_eq(self, index): 614f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 615f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_drop(self, index): 616f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 617f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_put(self, index): 618f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 619f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_get(self, index): 620f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 621f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_ifelse(self, index): 622f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 623f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_random(self, index): 624f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 625f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_mul(self, index): 626f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 627f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sqrt(self, index): 628f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 629f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_dup(self, index): 630f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 631f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_exch(self, index): 632f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 633f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_index(self, index): 634f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 635f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_roll(self, index): 636f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 6377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6387842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T2OutlineExtractor(SimpleT2Decompiler): 6397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 640489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, localSubrs, globalSubrs, nominalWidthX, defaultWidthX): 6417842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs) 642489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 6437842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.nominalWidthX = nominalWidthX 6447842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.defaultWidthX = defaultWidthX 6457842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6467842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 6477842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.reset(self) 6487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hints = [] 6497842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 0 6507842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 651489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = (0, 0) 652489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 654489d76a340845361def6af9ab7d9152f8e66f417jvr def _nextPoint(self, point): 655489d76a340845361def6af9ab7d9152f8e66f417jvr x, y = self.currentPoint 656489d76a340845361def6af9ab7d9152f8e66f417jvr point = x + point[0], y + point[1] 657489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = point 658489d76a340845361def6af9ab7d9152f8e66f417jvr return point 6597842e56b97ce677b83bdab09cda48bc2d89ac75aJust 660489d76a340845361def6af9ab7d9152f8e66f417jvr def rMoveTo(self, point): 661489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.moveTo(self._nextPoint(point)) 662489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 1 663489d76a340845361def6af9ab7d9152f8e66f417jvr 664489d76a340845361def6af9ab7d9152f8e66f417jvr def rLineTo(self, point): 665489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 666489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 667489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.lineTo(self._nextPoint(point)) 668489d76a340845361def6af9ab7d9152f8e66f417jvr 669489d76a340845361def6af9ab7d9152f8e66f417jvr def rCurveTo(self, pt1, pt2, pt3): 670489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 671489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 672489d76a340845361def6af9ab7d9152f8e66f417jvr nextPoint = self._nextPoint 673489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) 6747842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6757842e56b97ce677b83bdab09cda48bc2d89ac75aJust def closePath(self): 676489d76a340845361def6af9ab7d9152f8e66f417jvr if self.sawMoveTo: 677489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.closePath() 678489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 680d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 681d3ee2d4319742ec61cb299665ccba66c139e4834jvr # In T2 there are no open paths, so always do a closePath when 682d3ee2d4319742ec61cb299665ccba66c139e4834jvr # finishing a sub path. 683d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.closePath() 684d3ee2d4319742ec61cb299665ccba66c139e4834jvr 6857842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 6867842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 6877842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.gotWidth: 6887842e56b97ce677b83bdab09cda48bc2d89ac75aJust if evenOdd ^ (len(args) % 2): 6897842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.nominalWidthX + args[0] 6907842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 6917842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 6927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.defaultWidthX 6937842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 1 6947842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 6957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6967842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 6977842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popallWidth() 69832c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintCount = self.hintCount + len(args) // 2 6997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7007842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7017842e56b97ce677b83bdab09cda48bc2d89ac75aJust # hint operators 7027842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 703586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstem(self, index): 704586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 705586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstem(self, index): 706586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 707586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstemhm(self, index): 708586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 709586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstemhm(self, index): 710586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 7117842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_hintmask(self, index): 7127842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7137842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_cntrmask(self, index): 7147842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7167842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7177842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, moveto 7187842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7197842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 720d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 721489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popallWidth()) 7227842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 723d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 724489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popallWidth(1)[0], 0)) 7257842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 726d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 727489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popallWidth(1)[0])) 7287842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 729d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 730382df6c42a7a6aecb690e07c6338e19f038f0543jvr args = self.popallWidth() 731382df6c42a7a6aecb690e07c6338e19f038f0543jvr if args: 732382df6c42a7a6aecb690e07c6338e19f038f0543jvr from fontTools.encodings.StandardEncoding import StandardEncoding 733382df6c42a7a6aecb690e07c6338e19f038f0543jvr # endchar can do seac accent bulding; The T2 spec says it's deprecated, 734382df6c42a7a6aecb690e07c6338e19f038f0543jvr # but recent software that shall remain nameless does output it. 735382df6c42a7a6aecb690e07c6338e19f038f0543jvr adx, ady, bchar, achar = args 736382df6c42a7a6aecb690e07c6338e19f038f0543jvr baseGlyph = StandardEncoding[bchar] 737382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 738382df6c42a7a6aecb690e07c6338e19f038f0543jvr accentGlyph = StandardEncoding[achar] 739382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 7407842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7417842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7427842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, lines 7437842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlineto(self, index): 7457842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7467842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 2): 7477842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = args[i:i+2] 748489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 7497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hlineto(self, index): 7517842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(1) 7527842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vlineto(self, index): 7537842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(0) 7547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7557842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7567842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, curves 7577842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rrcurveto(self, index): 7597842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" 7607842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7617842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 6): 7627842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dya, dxb, dyb, dxc, dyc, = args[i:i+6] 763489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) 7647842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7657842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rcurveline(self, index): 7667842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" 7677842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7687842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args)-2, 6): 7697842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[i:i+6] 770489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 771489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(args[-2:]) 7727842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7737842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlinecurve(self, index): 7747842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" 7757842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7767842e56b97ce677b83bdab09cda48bc2d89ac75aJust lineArgs = args[:-6] 7777842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(lineArgs), 2): 778489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(lineArgs[i:i+2]) 7797842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] 780489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 7817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vvcurveto(self, index): 7837842e56b97ce677b83bdab09cda48bc2d89ac75aJust "dx1? {dya dxb dyb dyc}+ vvcurveto" 7847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7857842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7867842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = args[0] 7877842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7887842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7897842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7907842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 7917842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dyc = args[i:i+4] 792489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) 7937842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hhcurveto(self, index): 7967842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1? {dxa dxb dyb dxc}+ hhcurveto""" 7977842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7987842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7997842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = args[0] 8007842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 8017842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8027842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8037842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 8047842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dxc = args[i:i+4] 805489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) 8067842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8077842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8087842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vhcurveto(self, index): 8097842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) 8107842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto 8117842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8127842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8137842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8147842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8157842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8167842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8187842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hvcurveto(self, index): 8197842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? 8207842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? 8217842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8227842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8237842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8247842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8257842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8267842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8277842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8287842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8297842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, flex 8307842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8317842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex(self, index): 8328b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() 833d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy1 = dy3 = dy4 = dy6 = 0 834d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy5 = -dy2 8358b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8368b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex(self, index): 8388b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() 8398b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8408b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8417842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex1(self, index): 8428b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() 843d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy3 = dy4 = 0 844d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) 845d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr 8468b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8478b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8487842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex1(self, index): 8498b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() 8508b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx = dx1 + dx2 + dx3 + dx4 + dx5 8518b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy = dy1 + dy2 + dy3 + dy4 + dy5 8528b8b44904e116287ca0eb587f9c5b21296fb3123jvr if abs(dx) > abs(dy): 8538b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx6 = d6 854d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -dy 8558b8b44904e116287ca0eb587f9c5b21296fb3123jvr else: 856d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dx6 = -dx 8578b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy6 = d6 8588b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8598b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8607842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8617842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8627842e56b97ce677b83bdab09cda48bc2d89ac75aJust # MultipleMaster. Well... 8637842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8647842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_blend(self, index): 8658b8b44904e116287ca0eb587f9c5b21296fb3123jvr args = self.popall() 8667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8677842e56b97ce677b83bdab09cda48bc2d89ac75aJust # misc 8687842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_and(self, index): 8698b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_or(self, index): 8718b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_not(self, index): 8738b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_store(self, index): 8758b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8767842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_abs(self, index): 8778b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8787842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_add(self, index): 8798b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sub(self, index): 8818b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_div(self, index): 8837842e56b97ce677b83bdab09cda48bc2d89ac75aJust num2 = self.pop() 8847842e56b97ce677b83bdab09cda48bc2d89ac75aJust num1 = self.pop() 88532c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod d1 = num1//num2 88632c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod d2 = num1/num2 8877842e56b97ce677b83bdab09cda48bc2d89ac75aJust if d1 == d2: 8887842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d1) 8897842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d2) 8917842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_load(self, index): 8928b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_neg(self, index): 8948b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_eq(self, index): 8968b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8977842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_drop(self, index): 8988b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8997842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_put(self, index): 9008b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_get(self, index): 9028b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_ifelse(self, index): 9048b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9057842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_random(self, index): 9068b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9077842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_mul(self, index): 9088b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sqrt(self, index): 9108b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dup(self, index): 9128b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9137842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_exch(self, index): 9148b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9157842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_index(self, index): 9168b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9177842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_roll(self, index): 9188b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9197842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9207842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9217842e56b97ce677b83bdab09cda48bc2d89ac75aJust # miscelaneous helpers 9227842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def alternatingLineto(self, isHorizontal): 9247842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 9257842e56b97ce677b83bdab09cda48bc2d89ac75aJust for arg in args: 9267842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isHorizontal: 9277842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (arg, 0) 9287842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9297842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (0, arg) 930489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 9317842e56b97ce677b83bdab09cda48bc2d89ac75aJust isHorizontal = not isHorizontal 9327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9337842e56b97ce677b83bdab09cda48bc2d89ac75aJust def vcurveto(self, args): 9347842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dxc = args[:4] 9357842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9367842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9377842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = args[0] 9387842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9397842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9407842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = 0 941489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) 9427842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9437842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def hcurveto(self, args): 9457842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dyc = args[:4] 9467842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9477842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9487842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = args[0] 9497842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9507842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9517842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = 0 952489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) 9537842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9567842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1OutlineExtractor(T2OutlineExtractor): 9577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 958489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, subrs): 959489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 9607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.subrs = subrs 9617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 9627842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 9647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 9657842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 9667842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = 0 9677842e56b97ce677b83bdab09cda48bc2d89ac75aJust T2OutlineExtractor.reset(self) 9687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 969d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 970d3ee2d4319742ec61cb299665ccba66c139e4834jvr if self.sawMoveTo: 971d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.pen.endPath() 972d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.sawMoveTo = 0 973d3ee2d4319742ec61cb299665ccba66c139e4834jvr 9747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 9757842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 9767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9777842e56b97ce677b83bdab09cda48bc2d89ac75aJust def exch(self): 9787842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack 9797842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack[-1], stack[-2] = stack[-2], stack[-1] 9807842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9817842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9827842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors 9837842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9847842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 9857842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9867842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 987e56bc902cf6a707349ae6ddfe8a83a1bd7b155b9jvr self.endPath() 988489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popall()) 9897842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 9907842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9917842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9937842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 994d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 995489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popall()[0], 0)) 9967842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 9977842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9987842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9997842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 10007842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.exch() 10017842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 1002d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 1003489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popall()[0])) 10047842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_closepath(self, index): 10057842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.closePath() 10067842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_setcurrentpoint(self, index): 10077842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 10087842e56b97ce677b83bdab09cda48bc2d89ac75aJust x, y = args 1009489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = x, y 10107842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 1012d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 10137842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10147842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hsbw(self, index): 10157842e56b97ce677b83bdab09cda48bc2d89ac75aJust sbx, wx = self.popall() 10167842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = wx 10177842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = sbx 1018489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = sbx, self.currentPoint[1] 10197842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sbw(self, index): 10207842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10227842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 10237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 10247842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10257842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.subrs[subrIndex] 10267842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 10277842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callothersubr(self, index): 10287842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10297842e56b97ce677b83bdab09cda48bc2d89ac75aJust nArgs = self.pop() 10307842e56b97ce677b83bdab09cda48bc2d89ac75aJust #print nArgs, subrIndex, "callothersubr" 10317842e56b97ce677b83bdab09cda48bc2d89ac75aJust if subrIndex == 0 and nArgs == 3: 10327842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.doFlex() 10337842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 10347842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif subrIndex == 1 and nArgs == 0: 10357842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 1 10367842e56b97ce677b83bdab09cda48bc2d89ac75aJust # ignore... 10377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_pop(self, index): 10387842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass # ignore... 10397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def doFlex(self): 10417842e56b97ce677b83bdab09cda48bc2d89ac75aJust finaly = self.pop() 10427842e56b97ce677b83bdab09cda48bc2d89ac75aJust finalx = self.pop() 10437842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.pop() # flex height is unused 10447842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10457842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3y = self.pop() 10467842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3x = self.pop() 10477842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4y = self.pop() 10487842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4x = self.pop() 10497842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3y = self.pop() 10507842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3x = self.pop() 10517842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2y = self.pop() 10527842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2x = self.pop() 10537842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2y = self.pop() 10547842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2x = self.pop() 10557842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1y = self.pop() 10567842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1x = self.pop() 10577842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpy = self.pop() 10587842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpx = self.pop() 10597842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10607842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1x+rpx) 10627842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1y+rpy) 10637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2x) 10647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2y) 10657842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2x) 10667842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2y) 10677842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10697842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10707842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3x) 10717842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3y) 10727842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4x) 10737842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4y) 10747842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3x) 10757842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3y) 10767842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10777842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10787842e56b97ce677b83bdab09cda48bc2d89ac75aJust # Push back final coords so subr 0 can find them 10797842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finalx) 10807842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finaly) 10817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dotsection(self, index): 10837842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10847842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstem3(self, index): 10857842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10867842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_seac(self, index): 10877842e56b97ce677b83bdab09cda48bc2d89ac75aJust "asb adx ady bchar achar seac" 1088489d76a340845361def6af9ab7d9152f8e66f417jvr from fontTools.encodings.StandardEncoding import StandardEncoding 1089489d76a340845361def6af9ab7d9152f8e66f417jvr asb, adx, ady, bchar, achar = self.popall() 1090489d76a340845361def6af9ab7d9152f8e66f417jvr baseGlyph = StandardEncoding[bchar] 1091489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 1092489d76a340845361def6af9ab7d9152f8e66f417jvr accentGlyph = StandardEncoding[achar] 1093489d76a340845361def6af9ab7d9152f8e66f417jvr adx = adx + self.sbx - asb # seac weirdness 1094489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 10957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vstem3(self, index): 10967842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10977842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10987842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1099f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass DictDecompiler(ByteCodeBase): 11007842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11017842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = cffDictOperandEncoding 11027842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, strings): 11047842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.stack = [] 11057842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.strings = strings 11067842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict = {} 11077842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11087842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getDict(self): 11097842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(self.stack) == 0, "non-empty stack" 11107842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.dict 11117842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11127842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data): 11137842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 11147842e56b97ce677b83bdab09cda48bc2d89ac75aJust lenData = len(data) 11157842e56b97ce677b83bdab09cda48bc2d89ac75aJust push = self.stack.append 11167842e56b97ce677b83bdab09cda48bc2d89ac75aJust while index < lenData: 11177842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(data[index]) 11187842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 11197842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 11207842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 11217842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, index = handler(b0, data, index) 11227842e56b97ce677b83bdab09cda48bc2d89ac75aJust if value is not None: 11237842e56b97ce677b83bdab09cda48bc2d89ac75aJust push(value) 11247842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11257842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 11267842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.stack[-1] 11277842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[-1] 11287842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 11297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11307842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 11317842e56b97ce677b83bdab09cda48bc2d89ac75aJust all = self.stack[:] 11327842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[:] 11337842e56b97ce677b83bdab09cda48bc2d89ac75aJust return all 11347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 11367842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 11377842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 11387842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 11397842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11407842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 11417842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator, argType = self.operators[op] 11427842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.handle_operator(operator, argType) 11437842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, index 11447842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11457842e56b97ce677b83bdab09cda48bc2d89ac75aJust def handle_operator(self, operator, argType): 1146ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod if isinstance(argType, type(())): 11477842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = () 1148bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr for i in range(len(argType)-1, -1, -1): 1149bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr arg = argType[i] 11507842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + arg) 11517842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = (arghandler(operator),) + value 11527842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11537842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + argType) 11547842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = arghandler(operator) 11557842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict[operator] = value 11567842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11577842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_number(self, name): 11587842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.pop() 11597842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_SID(self, name): 11607842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.strings[self.pop()] 11617842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_array(self, name): 11627842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 1163dc18128aa9b3f6b98a623c294ac615195159025ejvr def arg_delta(self, name): 1164dc18128aa9b3f6b98a623c294ac615195159025ejvr out = [] 1165dc18128aa9b3f6b98a623c294ac615195159025ejvr current = 0 1166dc18128aa9b3f6b98a623c294ac615195159025ejvr for v in self.popall(): 11676f03a58f59fb20662602e3d4bb153d7db2f778d3jvr current = current + v 1168dc18128aa9b3f6b98a623c294ac615195159025ejvr out.append(current) 1169dc18128aa9b3f6b98a623c294ac615195159025ejvr return out 11707842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11717842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11727842e56b97ce677b83bdab09cda48bc2d89ac75aJustdef calcSubrBias(subrs): 11737842e56b97ce677b83bdab09cda48bc2d89ac75aJust nSubrs = len(subrs) 11747842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nSubrs < 1240: 11757842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 107 11767842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif nSubrs < 33900: 11777842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 1131 11787842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11797842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 32768 11807842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bias 1181