17842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""psCharStrings.py -- module implementing various kinds of CharStrings: 27842e56b97ce677b83bdab09cda48bc2d89ac75aJustCFF dictionary data and Type1/Type2 CharStrings. 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 47842e56b97ce677b83bdab09cda48bc2d89ac75aJust 51ae29591efbb29492ce05378909ccf4028d7c1eeBehdad Esfahbodfrom __future__ import print_function, division, absolute_import 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 38e388db566b9ba42669c7e353db4293cf27bc2a5bBehdad Esfahbodclass ByteCodeBase(object): 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_byte(self, b0, data, index): 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust return b0 - 139, index 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt1(self, b0, data, index): 44319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod b1 = byteord(data[index]) 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return (b0-247)*256 + b1 + 108, index+1 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt2(self, b0, data, index): 48319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod b1 = byteord(data[index]) 497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return -(b0-251)*256 - b1 - 108, index+1 507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_shortInt(self, b0, data, index): 5218316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod value, = struct.unpack(">h", data[index:index+2]) 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+2 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_longInt(self, b0, data, index): 5618316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod value, = struct.unpack(">l", data[index:index+4]) 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+4 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def read_fixed1616(self, b0, data, index): 6018316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod value, = struct.unpack(">l", data[index:index+4]) 6132c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod return value / 65536, index+4 6295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_realNumber(self, b0, data, index): 647842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = '' 65ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 66319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod b = byteord(data[index]) 677842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble0 = (b & 0xf0) >> 4 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble1 = b & 0x0f 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble0 == 0xf: 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble0] 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble1 == 0xf: 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble1] 76455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return float(number), index 777842e56b97ce677b83bdab09cda48bc2d89ac75aJust 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 79dbc2c173b35360386c907a3c70cb931ae4c3fac9jvrdef buildOperatorDict(operatorList): 80455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper = {} 81455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc = {} 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust for item in operatorList: 837842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(item) == 2: 84455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1] 85455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 86455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1:] 87002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod if isinstance(item[0], tuple): 88455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = item[0] 897842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 90455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = (item[0],) 91455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return oper, opc 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 937842e56b97ce677b83bdab09cda48bc2d89ac75aJust 947842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2Operators = [ 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 967842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 977842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust (16, 'blend'), 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust (18, 'hstemhm'), 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust (19, 'hintmask'), 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust (20, 'cntrmask'), 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust (23, 'vstemhm'), 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust (24, 'rcurveline'), 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust (25, 'rlinecurve'), 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust (26, 'vvcurveto'), 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust (27, 'hhcurveto'), 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust# (28, 'shortint'), # not really an operator 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust (29, 'callgsubr'), 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 1217099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr ((12, 0), 'ignore'), # dotsection. Yes, there a few very early OTF/CFF 1227099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr # fonts with this deprecated operator. Just ignore it. 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 3), 'and'), 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 4), 'or'), 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 5), 'not'), 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 8), 'store'), 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 9), 'abs'), 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 10), 'add'), 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 11), 'sub'), 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 13), 'load'), 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 14), 'neg'), 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 15), 'eq'), 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 18), 'drop'), 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 20), 'put'), 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 21), 'get'), 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 22), 'ifelse'), 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 23), 'random'), 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 24), 'mul'), 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 26), 'sqrt'), 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 27), 'dup'), 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 28), 'exch'), 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 29), 'index'), 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 30), 'roll'), 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 34), 'hflex'), 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 35), 'flex'), 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 36), 'hflex1'), 1487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 37), 'flex1'), 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 151f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 152f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef getIntEncoder(format): 153f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if format == "cff": 154b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod fourByteOp = bytechr(29) 155f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif format == "t1": 156b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod fourByteOp = bytechr(255) 157f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 158f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert format == "t2" 15995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = None 160f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 161b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod def encodeInt(value, fourByteOp=fourByteOp, bytechr=bytechr, 16295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr pack=struct.pack, unpack=struct.unpack): 163f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if -107 <= value <= 107: 164b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(value + 139) 165f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif 108 <= value <= 1131: 166f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = value - 108 167b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr((value >> 8) + 247) + bytechr(value & 0xFF) 168f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif -1131 <= value <= -108: 169f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = -value - 108 170b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr((value >> 8) + 251) + bytechr(value & 0xFF) 17195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr elif fourByteOp is None: 17295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # T2 only supports 2 byte ints 17395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if -32768 <= value <= 32767: 174b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(28) + pack(">h", value) 17595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 17695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # Backwards compatible hack: due to a previous bug in FontTools, 17795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # 16.16 fixed numbers were written out as 4-byte ints. When 17895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # these numbers were small, they were wrongly written back as 17995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # small ints instead of 4-byte ints, breaking round-tripping. 18095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # This here workaround doesn't do it any better, since we can't 18195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # distinguish anymore between small ints that were supposed to 18295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # be small fixed numbers and small ints that were just small 18395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # ints. Hence the warning. 18495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr import sys 18595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr sys.stderr.write("Warning: 4-byte T2 number got passed to the " 18695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "IntType handler. This should happen only when reading in " 18795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "old XML files.\n") 188b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod code = bytechr(255) + pack(">l", value) 189f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 190f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = fourByteOp + pack(">l", value) 191f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return code 192f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 193f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return encodeInt 194f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 195f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 196f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntCFF = getIntEncoder("cff") 197f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT1 = getIntEncoder("t1") 198f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT2 = getIntEncoder("t2") 199f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 20095c9e9fc11dc028bd1747788f2b417f3936fc59bjvrdef encodeFixed(f, pack=struct.pack): 20195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For T2 only 20218316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod return b"\xff" + pack(">l", int(round(f * 65536))) 20395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 204f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef encodeFloat(f): 20595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For CFF only, used in cffLib 206f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = str(f).upper() 207f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if s[:2] == "0.": 208f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 209f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif s[:3] == "-0.": 210f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = "-" + s[2:] 211f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles = [] 212f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr while s: 213f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = s[0] 214f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 215f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if c == "E" and s[:1] == "-": 216f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 217f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = "E-" 218f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(realNibblesDict[c]) 219f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 220f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if len(nibbles) % 2: 221f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 222b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod d = bytechr(30) 223f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr for i in range(0, len(nibbles), 2): 224b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod d = d + bytechr(nibbles[i] << 4 | nibbles[i+1]) 225f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return d 226f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 227f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 2284e5af60930726d06a58a30bae45bb27ae50aea77jvrclass CharStringCompileError(Exception): pass 2294e5af60930726d06a58a30bae45bb27ae50aea77jvr 2304e5af60930726d06a58a30bae45bb27ae50aea77jvr 231f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass T2CharString(ByteCodeBase): 2327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2337842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t2OperandEncoding 234455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t2Operators) 2357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 236489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): 2377842e56b97ce677b83bdab09cda48bc2d89ac75aJust if program is None: 2387842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 2397842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = bytecode 2407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 241489d76a340845361def6af9ab7d9152f8e66f417jvr self.private = private 242846d09e380215f8c7fdb4bbb9f083f8e68722cdaBehdad Esfahbod self.globalSubrs = globalSubrs if globalSubrs is not None else [] 2437842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __repr__(self): 2457842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is None: 2467842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) 2477842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 2487842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) 2497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 25095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 25195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT2 25295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 25395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 25495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeFixed 25595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 256586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def decompile(self): 257586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr if not self.needsDecompilation(): 258586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr return 259489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 260489d76a340845361def6af9ab7d9152f8e66f417jvr decompiler = SimpleT2Decompiler(subrs, self.globalSubrs) 261586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr decompiler.execute(self) 262586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr 263489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 264489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 265489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T2OutlineExtractor(pen, subrs, self.globalSubrs, 266489d76a340845361def6af9ab7d9152f8e66f417jvr self.private.nominalWidthX, self.private.defaultWidthX) 267489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 268489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 269489d76a340845361def6af9ab7d9152f8e66f417jvr 270455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr def compile(self): 271455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if self.bytecode is not None: 272455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return 2739920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program, "illegal CharString: decompiled to empty program" 2749920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program[-1] in ("endchar", "return", "callsubr", "callgsubr", 2759920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 276455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr bytecode = [] 277455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opcodes = self.opcodes 2784e5af60930726d06a58a30bae45bb27ae50aea77jvr program = self.program 27995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeInt = self.getIntEncoder() 28095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeFixed = self.getFixedEncoder() 2814e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 2824e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(program) 2834e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 2844e5af60930726d06a58a30bae45bb27ae50aea77jvr token = program[i] 2854e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 286455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr tp = type(token) 287278c88c0afa33fcd1a267f2741d2f95983006e4dBehdad Esfahbod if issubclass(tp, basestring): 2884e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 289b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod bytecode.extend(bytechr(b) for b in opcodes[token]) 2904e5af60930726d06a58a30bae45bb27ae50aea77jvr except KeyError: 291cd5aad92f23737ff93a110d5c73d624658a28da8Behdad Esfahbod raise CharStringCompileError("illegal operator: %s" % token) 2924e5af60930726d06a58a30bae45bb27ae50aea77jvr if token in ('hintmask', 'cntrmask'): 2934e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode.append(program[i]) # hint mask 2944e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 295002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == int: 29695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeInt(token)) 297002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == float: 29895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeFixed(token)) 299455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 300f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert 0, "unsupported type: %s" % tp 3014e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 30218316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod bytecode = bytesjoin(bytecode) 3034e5af60930726d06a58a30bae45bb27ae50aea77jvr except TypeError: 3043ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(bytecode) 3054e5af60930726d06a58a30bae45bb27ae50aea77jvr raise 306f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.setBytecode(bytecode) 307f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3087842e56b97ce677b83bdab09cda48bc2d89ac75aJust def needsDecompilation(self): 3097842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.bytecode is not None 3107842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def setProgram(self, program): 3127842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 3137842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = None 3147842e56b97ce677b83bdab09cda48bc2d89ac75aJust 315f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr def setBytecode(self, bytecode): 316f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.bytecode = bytecode 317f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.program = None 318f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3197842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getToken(self, index, 320319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod len=len, byteord=byteord, getattr=getattr, type=type, StringType=str): 3217842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3227842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.bytecode): 3237842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 324319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod b0 = byteord(self.bytecode[index]) 3257842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3267842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 3277842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 3287842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, index = handler(b0, self.bytecode, index) 3297842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3307842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.program): 3317842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3327842e56b97ce677b83bdab09cda48bc2d89ac75aJust token = self.program[index] 3337842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 334ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod isOperator = isinstance(token, StringType) 3357842e56b97ce677b83bdab09cda48bc2d89ac75aJust return token, isOperator, index 3367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getBytes(self, index, nBytes): 3387842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3397842e56b97ce677b83bdab09cda48bc2d89ac75aJust newIndex = index + nBytes 3407842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.bytecode[index:newIndex] 3417842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = newIndex 3427842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3437842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.program[index] 3447842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3457842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(bytes) == nBytes 3467842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bytes, index 3477842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3487842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 3497842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 350319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod op = (b0, byteord(data[index])) 3517842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 3527842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3537842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 3547842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator = self.operators[op] 3557842e56b97ce677b83bdab09cda48bc2d89ac75aJust return operator, index 3567842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3577842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, xmlWriter): 358dab433233bd4024ede9ad27c6c61ea0072c2edafJust from fontTools.misc.textTools import num2binary 3597842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3607842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.dumphex(self.bytecode) 3617842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3627842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 3637842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 364ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 3657842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 3667842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 3677842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 3687842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 369e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod args = [str(arg) for arg in args] 3707842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token in ('hintmask', 'cntrmask'): 3717842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMask, isOperator, index = self.getToken(index) 3727842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits = [] 3737842e56b97ce677b83bdab09cda48bc2d89ac75aJust for byte in hintMask: 374319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod bits.append(num2binary(byteord(byte), 8)) 37518316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod hintMask = strjoin(bits) 37614fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token, hintMask]) 3777842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 37814fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token]) 3797842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.write(line) 3807842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.newline() 3817842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 3827842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3837842e56b97ce677b83bdab09cda48bc2d89ac75aJust args.append(token) 3844e5af60930726d06a58a30bae45bb27ae50aea77jvr 3853a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content): 386b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr from fontTools.misc.textTools import binary2num, readHex 387b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr if attrs.get("raw"): 388b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr self.setBytecode(readHex(content)) 389b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr return 39018316aa769566eeb6f3f4a6ed2685fa8f8e861c2Behdad Esfahbod content = strjoin(content) 3914e5af60930726d06a58a30bae45bb27ae50aea77jvr content = content.split() 3924e5af60930726d06a58a30bae45bb27ae50aea77jvr program = [] 3934e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(content) 3944e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 3954e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 3964e5af60930726d06a58a30bae45bb27ae50aea77jvr token = content[i] 3974e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 3984e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 3994e5af60930726d06a58a30bae45bb27ae50aea77jvr token = int(token) 4004e5af60930726d06a58a30bae45bb27ae50aea77jvr except ValueError: 40195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr try: 40295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr token = float(token) 40395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr except ValueError: 40495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 40595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if token in ('hintmask', 'cntrmask'): 40695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr mask = content[i] 407278c88c0afa33fcd1a267f2741d2f95983006e4dBehdad Esfahbod maskBytes = b"" 40895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr for j in range(0, len(mask), 8): 409b7a2d797a40fb658d1e6dca6c08c9d2e1d83e78aBehdad Esfahbod maskBytes = maskBytes + bytechr(binary2num(mask[j:j+8])) 41095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(maskBytes) 41195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr i = i + 1 41295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 41395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 4144e5af60930726d06a58a30bae45bb27ae50aea77jvr else: 4154e5af60930726d06a58a30bae45bb27ae50aea77jvr program.append(token) 4164e5af60930726d06a58a30bae45bb27ae50aea77jvr self.setProgram(program) 4177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4187842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4197842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1Operators = [ 4207842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 4217842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 4227842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 4237842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 4247842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 4257842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 4267842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 4277842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 4287842e56b97ce677b83bdab09cda48bc2d89ac75aJust (9, 'closepath'), 4297842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 4307842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 4317842e56b97ce677b83bdab09cda48bc2d89ac75aJust (13, 'hsbw'), 4327842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 4337842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 4347842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 4357842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 4367842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 4377842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 0), 'dotsection'), 4387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 1), 'vstem3'), 4397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 2), 'hstem3'), 4407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 6), 'seac'), 4417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 7), 'sbw'), 4427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 4437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 16), 'callothersubr'), 4447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 17), 'pop'), 4457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 33), 'setcurrentpoint'), 4467842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 4477842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4487842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1CharString(T2CharString): 4497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4507842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t1OperandEncoding 451455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t1Operators) 4527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 453489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, subrs=None): 454489d76a340845361def6af9ab7d9152f8e66f417jvr if program is None: 455489d76a340845361def6af9ab7d9152f8e66f417jvr program = [] 456489d76a340845361def6af9ab7d9152f8e66f417jvr self.bytecode = bytecode 457489d76a340845361def6af9ab7d9152f8e66f417jvr self.program = program 458489d76a340845361def6af9ab7d9152f8e66f417jvr self.subrs = subrs 459489d76a340845361def6af9ab7d9152f8e66f417jvr 46095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 46195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT1 46295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 46395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 46495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeFixed(value): 46595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr raise TypeError("Type 1 charstrings don't support floating point operands") 46695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 4677842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self): 46878c02b6af38ce255eda220b69e23dad3102129e5Behdad Esfahbod if self.bytecode is None: 4697842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 4707842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 4717842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 472ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 4737842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 4747842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 4757842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 4767842e56b97ce677b83bdab09cda48bc2d89ac75aJust program.append(token) 4777842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.setProgram(program) 4787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 479489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 480489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T1OutlineExtractor(pen, self.subrs) 481489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 482489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 483489d76a340845361def6af9ab7d9152f8e66f417jvr 4847842e56b97ce677b83bdab09cda48bc2d89ac75aJust 485e388db566b9ba42669c7e353db4293cf27bc2a5bBehdad Esfahbodclass SimpleT2Decompiler(object): 4867842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4877842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, localSubrs, globalSubrs): 4887842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localSubrs = localSubrs 4897842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localBias = calcSubrBias(localSubrs) 4907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalSubrs = globalSubrs 4917842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalBias = calcSubrBias(globalSubrs) 4927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 4937842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4947842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 4957842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack = [] 4967842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack = [] 4977842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = 0 4987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = 0 4997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5007842e56b97ce677b83bdab09cda48bc2d89ac75aJust def execute(self, charString): 5017842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack.append(charString) 5027842e56b97ce677b83bdab09cda48bc2d89ac75aJust needsDecompilation = charString.needsDecompilation() 5037842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5047842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 5057842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = program.append 5067842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5077842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = lambda x: None 5087842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack = self.operandStack.append 5097842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 510ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 5117842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = charString.getToken(index) 5127842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 5137842e56b97ce677b83bdab09cda48bc2d89ac75aJust break # we're done! 5147842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(token) 5157842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 5167842e56b97ce677b83bdab09cda48bc2d89ac75aJust handlerName = "op_" + token 5177842e56b97ce677b83bdab09cda48bc2d89ac75aJust if hasattr(self, handlerName): 5187842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, handlerName) 5197842e56b97ce677b83bdab09cda48bc2d89ac75aJust rv = handler(index) 5207842e56b97ce677b83bdab09cda48bc2d89ac75aJust if rv: 5217842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = rv 5227842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(hintMaskBytes) 5237842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5247842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() 5257842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5267842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack(token) 5277842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5289920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program, "illegal CharString: decompiled to empty program" 5299920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program[-1] in ("endchar", "return", "callsubr", "callgsubr", 5309920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 5317842e56b97ce677b83bdab09cda48bc2d89ac75aJust charString.setProgram(program) 5327842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.callingStack[-1] 5337842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5347842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 5357842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.operandStack[-1] 5367842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.operandStack[-1] 5377842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 5387842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5397842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 5407842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack[:] 5417842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack[:] = [] 5427842e56b97ce677b83bdab09cda48bc2d89ac75aJust return stack 5437842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def push(self, value): 5457842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack.append(value) 5467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_return(self, index): 5487842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.operandStack: 5497842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 5527842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5537099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5547099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr def op_ignore(self, index): 5557099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr pass 5567099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5577842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 5587842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5597842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.localSubrs[subrIndex+self.localBias] 5607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5617842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5627842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callgsubr(self, index): 5637842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5647842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.globalSubrs[subrIndex+self.globalBias] 5657842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 567586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_hstem(self, index): 568586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 569586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstem(self, index): 570586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5717842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstemhm(self, index): 5727842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 573586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstemhm(self, index): 574586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5757842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5767842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hintmask(self, index): 5777842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.hintMaskBytes: 5787842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 57932c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintMaskBytes = (self.hintCount + 7) // 8 5807842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) 5817842e56b97ce677b83bdab09cda48bc2d89ac75aJust return hintMaskBytes, index 5827842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5837842e56b97ce677b83bdab09cda48bc2d89ac75aJust op_cntrmask = op_hintmask 5847842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5857842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 5867842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 58732c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintCount = self.hintCount + len(args) // 2 5887842e56b97ce677b83bdab09cda48bc2d89ac75aJust 589f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod # misc 590f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_and(self, index): 591f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 592f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_or(self, index): 593f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 594f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_not(self, index): 595f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 596f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_store(self, index): 597f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 598f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_abs(self, index): 599f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 600f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_add(self, index): 601f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 602f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sub(self, index): 603f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 604f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_div(self, index): 605f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 606f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_load(self, index): 607f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 608f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_neg(self, index): 609f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 610f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_eq(self, index): 611f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 612f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_drop(self, index): 613f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 614f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_put(self, index): 615f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 616f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_get(self, index): 617f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 618f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_ifelse(self, index): 619f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 620f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_random(self, index): 621f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 622f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_mul(self, index): 623f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 624f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sqrt(self, index): 625f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 626f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_dup(self, index): 627f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 628f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_exch(self, index): 629f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 630f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_index(self, index): 631f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 632f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_roll(self, index): 633f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 6347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6357842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T2OutlineExtractor(SimpleT2Decompiler): 6367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 637489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, localSubrs, globalSubrs, nominalWidthX, defaultWidthX): 6387842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs) 639489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 6407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.nominalWidthX = nominalWidthX 6417842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.defaultWidthX = defaultWidthX 6427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 6447842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.reset(self) 6457842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hints = [] 6467842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 0 6477842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 648489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = (0, 0) 649489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 651489d76a340845361def6af9ab7d9152f8e66f417jvr def _nextPoint(self, point): 652489d76a340845361def6af9ab7d9152f8e66f417jvr x, y = self.currentPoint 653489d76a340845361def6af9ab7d9152f8e66f417jvr point = x + point[0], y + point[1] 654489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = point 655489d76a340845361def6af9ab7d9152f8e66f417jvr return point 6567842e56b97ce677b83bdab09cda48bc2d89ac75aJust 657489d76a340845361def6af9ab7d9152f8e66f417jvr def rMoveTo(self, point): 658489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.moveTo(self._nextPoint(point)) 659489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 1 660489d76a340845361def6af9ab7d9152f8e66f417jvr 661489d76a340845361def6af9ab7d9152f8e66f417jvr def rLineTo(self, point): 662489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 663489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 664489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.lineTo(self._nextPoint(point)) 665489d76a340845361def6af9ab7d9152f8e66f417jvr 666489d76a340845361def6af9ab7d9152f8e66f417jvr def rCurveTo(self, pt1, pt2, pt3): 667489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 668489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 669489d76a340845361def6af9ab7d9152f8e66f417jvr nextPoint = self._nextPoint 670489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) 6717842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def closePath(self): 673489d76a340845361def6af9ab7d9152f8e66f417jvr if self.sawMoveTo: 674489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.closePath() 675489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 677d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 678d3ee2d4319742ec61cb299665ccba66c139e4834jvr # In T2 there are no open paths, so always do a closePath when 679d3ee2d4319742ec61cb299665ccba66c139e4834jvr # finishing a sub path. 680d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.closePath() 681d3ee2d4319742ec61cb299665ccba66c139e4834jvr 6827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 6837842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 6847842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.gotWidth: 6857842e56b97ce677b83bdab09cda48bc2d89ac75aJust if evenOdd ^ (len(args) % 2): 6867842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.nominalWidthX + args[0] 6877842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 6887842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 6897842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.defaultWidthX 6907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 1 6917842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 6927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 6947842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popallWidth() 69532c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod self.hintCount = self.hintCount + len(args) // 2 6967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6977842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6987842e56b97ce677b83bdab09cda48bc2d89ac75aJust # hint operators 6997842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 700586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstem(self, index): 701586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 702586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstem(self, index): 703586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 704586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstemhm(self, index): 705586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 706586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstemhm(self, index): 707586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 7087842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_hintmask(self, index): 7097842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7107842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_cntrmask(self, index): 7117842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7127842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7137842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7147842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, moveto 7157842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7167842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 717d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 718489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popallWidth()) 7197842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 720d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 721489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popallWidth(1)[0], 0)) 7227842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 723d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 724489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popallWidth(1)[0])) 7257842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 726d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 727382df6c42a7a6aecb690e07c6338e19f038f0543jvr args = self.popallWidth() 728382df6c42a7a6aecb690e07c6338e19f038f0543jvr if args: 729382df6c42a7a6aecb690e07c6338e19f038f0543jvr from fontTools.encodings.StandardEncoding import StandardEncoding 730382df6c42a7a6aecb690e07c6338e19f038f0543jvr # endchar can do seac accent bulding; The T2 spec says it's deprecated, 731382df6c42a7a6aecb690e07c6338e19f038f0543jvr # but recent software that shall remain nameless does output it. 732382df6c42a7a6aecb690e07c6338e19f038f0543jvr adx, ady, bchar, achar = args 733382df6c42a7a6aecb690e07c6338e19f038f0543jvr baseGlyph = StandardEncoding[bchar] 734382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 735382df6c42a7a6aecb690e07c6338e19f038f0543jvr accentGlyph = StandardEncoding[achar] 736382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 7377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7387842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7397842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, lines 7407842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7417842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlineto(self, index): 7427842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7437842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 2): 7447842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = args[i:i+2] 745489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 7467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hlineto(self, index): 7487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(1) 7497842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vlineto(self, index): 7507842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(0) 7517842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7527842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7537842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, curves 7547842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7557842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rrcurveto(self, index): 7567842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" 7577842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7587842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 6): 7597842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dya, dxb, dyb, dxc, dyc, = args[i:i+6] 760489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) 7617842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7627842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rcurveline(self, index): 7637842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" 7647842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7657842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args)-2, 6): 7667842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[i:i+6] 767489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 768489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(args[-2:]) 7697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlinecurve(self, index): 7717842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" 7727842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7737842e56b97ce677b83bdab09cda48bc2d89ac75aJust lineArgs = args[:-6] 7747842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(lineArgs), 2): 775489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(lineArgs[i:i+2]) 7767842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] 777489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 7787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7797842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vvcurveto(self, index): 7807842e56b97ce677b83bdab09cda48bc2d89ac75aJust "dx1? {dya dxb dyb dyc}+ vvcurveto" 7817842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7827842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7837842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = args[0] 7847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7857842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7867842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7877842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 7887842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dyc = args[i:i+4] 789489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) 7907842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7917842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7927842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hhcurveto(self, index): 7937842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1? {dxa dxb dyb dxc}+ hhcurveto""" 7947842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7957842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7967842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = args[0] 7977842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7987842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7997842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8007842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 8017842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dxc = args[i:i+4] 802489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) 8037842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8047842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8057842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vhcurveto(self, index): 8067842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) 8077842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto 8087842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8097842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8107842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8117842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8127842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8137842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8147842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8157842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hvcurveto(self, index): 8167842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? 8177842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? 8187842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8197842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8207842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8217842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8227842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8237842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8247842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8257842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8267842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, flex 8277842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8287842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex(self, index): 8298b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() 830d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy1 = dy3 = dy4 = dy6 = 0 831d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy5 = -dy2 8328b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8338b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8347842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex(self, index): 8358b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() 8368b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8378b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8387842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex1(self, index): 8398b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() 840d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy3 = dy4 = 0 841d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) 842d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr 8438b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8448b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8457842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex1(self, index): 8468b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() 8478b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx = dx1 + dx2 + dx3 + dx4 + dx5 8488b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy = dy1 + dy2 + dy3 + dy4 + dy5 8498b8b44904e116287ca0eb587f9c5b21296fb3123jvr if abs(dx) > abs(dy): 8508b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx6 = d6 851d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -dy 8528b8b44904e116287ca0eb587f9c5b21296fb3123jvr else: 853d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dx6 = -dx 8548b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy6 = d6 8558b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8568b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8587842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8597842e56b97ce677b83bdab09cda48bc2d89ac75aJust # MultipleMaster. Well... 8607842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8617842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_blend(self, index): 862153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod self.popall() 8637842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8647842e56b97ce677b83bdab09cda48bc2d89ac75aJust # misc 8657842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_and(self, index): 8668b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8677842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_or(self, index): 8688b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8697842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_not(self, index): 8708b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8717842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_store(self, index): 8728b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8737842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_abs(self, index): 8748b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8757842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_add(self, index): 8768b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8777842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sub(self, index): 8788b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8797842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_div(self, index): 8807842e56b97ce677b83bdab09cda48bc2d89ac75aJust num2 = self.pop() 8817842e56b97ce677b83bdab09cda48bc2d89ac75aJust num1 = self.pop() 88232c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod d1 = num1//num2 88332c10eecffb4923e0721c395e4b80fb732543f18Behdad Esfahbod d2 = num1/num2 8847842e56b97ce677b83bdab09cda48bc2d89ac75aJust if d1 == d2: 8857842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d1) 8867842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8877842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d2) 8887842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_load(self, index): 8898b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8907842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_neg(self, index): 8918b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8927842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_eq(self, index): 8938b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8947842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_drop(self, index): 8958b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8967842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_put(self, index): 8978b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8987842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_get(self, index): 8998b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9007842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_ifelse(self, index): 9018b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9027842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_random(self, index): 9038b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9047842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_mul(self, index): 9058b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9067842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sqrt(self, index): 9078b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9087842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dup(self, index): 9098b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9107842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_exch(self, index): 9118b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9127842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_index(self, index): 9138b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9147842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_roll(self, index): 9158b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9167842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9177842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 918f918ab4cf65c8000a639bc834bc0f362dd997358Behdad Esfahbod # miscellaneous helpers 9197842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9207842e56b97ce677b83bdab09cda48bc2d89ac75aJust def alternatingLineto(self, isHorizontal): 9217842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 9227842e56b97ce677b83bdab09cda48bc2d89ac75aJust for arg in args: 9237842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isHorizontal: 9247842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (arg, 0) 9257842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9267842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (0, arg) 927489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 9287842e56b97ce677b83bdab09cda48bc2d89ac75aJust isHorizontal = not isHorizontal 9297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9307842e56b97ce677b83bdab09cda48bc2d89ac75aJust def vcurveto(self, args): 9317842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dxc = args[:4] 9327842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9337842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9347842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = args[0] 9357842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9367842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9377842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = 0 938489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) 9397842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9407842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9417842e56b97ce677b83bdab09cda48bc2d89ac75aJust def hcurveto(self, args): 9427842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dyc = args[:4] 9437842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9447842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9457842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = args[0] 9467842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9477842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9487842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = 0 949489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) 9507842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9517842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9537842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1OutlineExtractor(T2OutlineExtractor): 9547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 955489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, subrs): 956489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 9577842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.subrs = subrs 9587842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 9597842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 9617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 9627842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 9637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = 0 9647842e56b97ce677b83bdab09cda48bc2d89ac75aJust T2OutlineExtractor.reset(self) 9657842e56b97ce677b83bdab09cda48bc2d89ac75aJust 966d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 967d3ee2d4319742ec61cb299665ccba66c139e4834jvr if self.sawMoveTo: 968d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.pen.endPath() 969d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.sawMoveTo = 0 970d3ee2d4319742ec61cb299665ccba66c139e4834jvr 9717842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 9727842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 9737842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def exch(self): 9757842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack 9767842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack[-1], stack[-2] = stack[-2], stack[-1] 9777842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9787842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9797842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors 9807842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9817842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 9827842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9837842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 984e56bc902cf6a707349ae6ddfe8a83a1bd7b155b9jvr self.endPath() 985489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popall()) 9867842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 9877842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9887842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9897842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9907842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 991d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 992489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popall()[0], 0)) 9937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 9947842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9957842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9967842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9977842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.exch() 9987842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 999d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 1000489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popall()[0])) 10017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_closepath(self, index): 10027842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.closePath() 10037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_setcurrentpoint(self, index): 10047842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 10057842e56b97ce677b83bdab09cda48bc2d89ac75aJust x, y = args 1006489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = x, y 10077842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10087842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 1009d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 10107842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hsbw(self, index): 10127842e56b97ce677b83bdab09cda48bc2d89ac75aJust sbx, wx = self.popall() 10137842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = wx 10147842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = sbx 1015489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = sbx, self.currentPoint[1] 10167842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sbw(self, index): 10177842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10187842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10197842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 10207842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 10217842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10227842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.subrs[subrIndex] 10237842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 10247842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callothersubr(self, index): 10257842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10267842e56b97ce677b83bdab09cda48bc2d89ac75aJust nArgs = self.pop() 10277842e56b97ce677b83bdab09cda48bc2d89ac75aJust #print nArgs, subrIndex, "callothersubr" 10287842e56b97ce677b83bdab09cda48bc2d89ac75aJust if subrIndex == 0 and nArgs == 3: 10297842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.doFlex() 10307842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 10317842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif subrIndex == 1 and nArgs == 0: 10327842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 1 10337842e56b97ce677b83bdab09cda48bc2d89ac75aJust # ignore... 10347842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_pop(self, index): 10357842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass # ignore... 10367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def doFlex(self): 10387842e56b97ce677b83bdab09cda48bc2d89ac75aJust finaly = self.pop() 10397842e56b97ce677b83bdab09cda48bc2d89ac75aJust finalx = self.pop() 10407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.pop() # flex height is unused 10417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10427842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3y = self.pop() 10437842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3x = self.pop() 10447842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4y = self.pop() 10457842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4x = self.pop() 10467842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3y = self.pop() 10477842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3x = self.pop() 10487842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2y = self.pop() 10497842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2x = self.pop() 10507842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2y = self.pop() 10517842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2x = self.pop() 10527842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1y = self.pop() 10537842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1x = self.pop() 10547842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpy = self.pop() 10557842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpx = self.pop() 10567842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10577842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10587842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1x+rpx) 10597842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1y+rpy) 10607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2x) 10617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2y) 10627842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2x) 10637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2y) 10647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10657842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10667842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10677842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3x) 10687842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3y) 10697842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4x) 10707842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4y) 10717842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3x) 10727842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3y) 10737842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10747842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10757842e56b97ce677b83bdab09cda48bc2d89ac75aJust # Push back final coords so subr 0 can find them 10767842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finalx) 10777842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finaly) 10787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10797842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dotsection(self, index): 10807842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10817842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstem3(self, index): 10827842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10837842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_seac(self, index): 10847842e56b97ce677b83bdab09cda48bc2d89ac75aJust "asb adx ady bchar achar seac" 1085489d76a340845361def6af9ab7d9152f8e66f417jvr from fontTools.encodings.StandardEncoding import StandardEncoding 1086489d76a340845361def6af9ab7d9152f8e66f417jvr asb, adx, ady, bchar, achar = self.popall() 1087489d76a340845361def6af9ab7d9152f8e66f417jvr baseGlyph = StandardEncoding[bchar] 1088489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 1089489d76a340845361def6af9ab7d9152f8e66f417jvr accentGlyph = StandardEncoding[achar] 1090489d76a340845361def6af9ab7d9152f8e66f417jvr adx = adx + self.sbx - asb # seac weirdness 1091489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 10927842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vstem3(self, index): 10937842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1096f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass DictDecompiler(ByteCodeBase): 10977842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10987842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = cffDictOperandEncoding 10997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11007842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, strings): 11017842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.stack = [] 11027842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.strings = strings 11037842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict = {} 11047842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11057842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getDict(self): 11067842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(self.stack) == 0, "non-empty stack" 11077842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.dict 11087842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data): 11107842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 11117842e56b97ce677b83bdab09cda48bc2d89ac75aJust lenData = len(data) 11127842e56b97ce677b83bdab09cda48bc2d89ac75aJust push = self.stack.append 11137842e56b97ce677b83bdab09cda48bc2d89ac75aJust while index < lenData: 1114319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod b0 = byteord(data[index]) 11157842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 11167842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 11177842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 11187842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, index = handler(b0, data, index) 11197842e56b97ce677b83bdab09cda48bc2d89ac75aJust if value is not None: 11207842e56b97ce677b83bdab09cda48bc2d89ac75aJust push(value) 11217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11227842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 11237842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.stack[-1] 11247842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[-1] 11257842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 11267842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11277842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 1128153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod args = self.stack[:] 11297842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[:] 1130153ec402094adbea673e914385b87f1d99191d0bBehdad Esfahbod return args 11317842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11327842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 11337842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 1134319c5fd10e2ea84304bd299b7483e05b5b0d5480Behdad Esfahbod op = (b0, byteord(data[index])) 11357842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 11367842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11377842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 11387842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator, argType = self.operators[op] 11397842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.handle_operator(operator, argType) 11407842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, index 11417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def handle_operator(self, operator, argType): 1143ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod if isinstance(argType, type(())): 11447842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = () 1145bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr for i in range(len(argType)-1, -1, -1): 1146bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr arg = argType[i] 11477842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + arg) 11487842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = (arghandler(operator),) + value 11497842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11507842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + argType) 11517842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = arghandler(operator) 11527842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict[operator] = value 11537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11547842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_number(self, name): 11557842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.pop() 11567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_SID(self, name): 11577842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.strings[self.pop()] 11587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_array(self, name): 11597842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 1160dc18128aa9b3f6b98a623c294ac615195159025ejvr def arg_delta(self, name): 1161dc18128aa9b3f6b98a623c294ac615195159025ejvr out = [] 1162dc18128aa9b3f6b98a623c294ac615195159025ejvr current = 0 1163dc18128aa9b3f6b98a623c294ac615195159025ejvr for v in self.popall(): 11646f03a58f59fb20662602e3d4bb153d7db2f778d3jvr current = current + v 1165dc18128aa9b3f6b98a623c294ac615195159025ejvr out.append(current) 1166dc18128aa9b3f6b98a623c294ac615195159025ejvr return out 11677842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11697842e56b97ce677b83bdab09cda48bc2d89ac75aJustdef calcSubrBias(subrs): 11707842e56b97ce677b83bdab09cda48bc2d89ac75aJust nSubrs = len(subrs) 11717842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nSubrs < 1240: 11727842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 107 11737842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif nSubrs < 33900: 11747842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 1131 11757842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11767842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 32768 11777842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bias 1178