psCharStrings.py revision 14fb031125b773f0a15eb19be4f02ed8540b2db6
17842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""psCharStrings.py -- module implementing various kinds of CharStrings: 27842e56b97ce677b83bdab09cda48bc2d89ac75aJustCFF dictionary data and Type1/Type2 CharStrings. 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 47842e56b97ce677b83bdab09cda48bc2d89ac75aJust 57842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport struct 67842e56b97ce677b83bdab09cda48bc2d89ac75aJust 77842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8455af6592bffbd6f2fc9f56fbfe083022a8353d4jvrDEBUG = 0 9455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 10455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 117842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding = [None] * 256 127842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[0:32] = (32) * ["do_operator"] 137842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[32:247] = (247 - 32) * ["read_byte"] 147842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[247:251] = (251 - 247) * ["read_smallInt1"] 157842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[251:255] = (255 - 251) * ["read_smallInt2"] 167842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[255] = "read_longInt" 177842e56b97ce677b83bdab09cda48bc2d89ac75aJustassert len(t1OperandEncoding) == 256 187842e56b97ce677b83bdab09cda48bc2d89ac75aJust 197842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding = t1OperandEncoding[:] 207842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding[28] = "read_shortInt" 2195c9e9fc11dc028bd1747788f2b417f3936fc59bjvrt2OperandEncoding[255] = "read_fixed1616" 227842e56b97ce677b83bdab09cda48bc2d89ac75aJust 237842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding = t2OperandEncoding[:] 247842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[29] = "read_longInt" 257842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[30] = "read_realNumber" 267842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[255] = "reserved" 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust 287842e56b97ce677b83bdab09cda48bc2d89ac75aJust 297842e56b97ce677b83bdab09cda48bc2d89ac75aJustrealNibbles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust '.', 'E', 'E-', None, '-'] 31f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrrealNibblesDict = {} 32f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrfor _i in range(len(realNibbles)): 33f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr realNibblesDict[realNibbles[_i]] = _i 347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 36f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass ByteCodeBase: 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 387842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_byte(self, b0, data, index): 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust return b0 - 139, index 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt1(self, b0, data, index): 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 437842e56b97ce677b83bdab09cda48bc2d89ac75aJust return (b0-247)*256 + b1 + 108, index+1 447842e56b97ce677b83bdab09cda48bc2d89ac75aJust 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt2(self, b0, data, index): 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 477842e56b97ce677b83bdab09cda48bc2d89ac75aJust return -(b0-251)*256 - b1 - 108, index+1 487842e56b97ce677b83bdab09cda48bc2d89ac75aJust 497842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_shortInt(self, b0, data, index): 507842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">h", bin) 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+2 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_longInt(self, b0, data, index): 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] + data[index+2] + data[index+3] 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">l", bin) 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+4 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def read_fixed1616(self, b0, data, index): 6095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bin = data[index] + data[index+1] + data[index+2] + data[index+3] 6195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr value, = struct.unpack(">l", bin) 6295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return value / 65536.0, index+4 6395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 647842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_realNumber(self, b0, data, index): 657842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = '' 66ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 677842e56b97ce677b83bdab09cda48bc2d89ac75aJust b = ord(data[index]) 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble0 = (b & 0xf0) >> 4 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble1 = b & 0x0f 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble0 == 0xf: 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble0] 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble1 == 0xf: 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble1] 77455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return float(number), index 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 80dbc2c173b35360386c907a3c70cb931ae4c3fac9jvrdef buildOperatorDict(operatorList): 81455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper = {} 82455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc = {} 837842e56b97ce677b83bdab09cda48bc2d89ac75aJust for item in operatorList: 847842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(item) == 2: 85455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1] 86455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 87455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1:] 88002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod if isinstance(item[0], tuple): 89455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = item[0] 907842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 91455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = (item[0],) 92455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return oper, opc 937842e56b97ce677b83bdab09cda48bc2d89ac75aJust 947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 957842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2Operators = [ 967842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 977842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust (16, 'blend'), 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust (18, 'hstemhm'), 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust (19, 'hintmask'), 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust (20, 'cntrmask'), 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust (23, 'vstemhm'), 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust (24, 'rcurveline'), 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust (25, 'rlinecurve'), 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust (26, 'vvcurveto'), 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust (27, 'hhcurveto'), 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust# (28, 'shortint'), # not really an operator 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust (29, 'callgsubr'), 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 1227099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr ((12, 0), 'ignore'), # dotsection. Yes, there a few very early OTF/CFF 1237099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr # fonts with this deprecated operator. Just ignore it. 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 3), 'and'), 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 4), 'or'), 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 5), 'not'), 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 8), 'store'), 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 9), 'abs'), 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 10), 'add'), 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 11), 'sub'), 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 13), 'load'), 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 14), 'neg'), 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 15), 'eq'), 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 18), 'drop'), 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 20), 'put'), 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 21), 'get'), 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 22), 'ifelse'), 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 23), 'random'), 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 24), 'mul'), 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 26), 'sqrt'), 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 27), 'dup'), 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 28), 'exch'), 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 29), 'index'), 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 30), 'roll'), 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 34), 'hflex'), 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 35), 'flex'), 1487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 36), 'hflex1'), 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 37), 'flex1'), 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust 152f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 153f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef getIntEncoder(format): 154f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if format == "cff": 155f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr fourByteOp = chr(29) 156f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif format == "t1": 15795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = chr(255) 158f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 159f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert format == "t2" 16095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = None 161f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 16295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeInt(value, fourByteOp=fourByteOp, chr=chr, 16395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr pack=struct.pack, unpack=struct.unpack): 164f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if -107 <= value <= 107: 165f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr(value + 139) 166f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif 108 <= value <= 1131: 167f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = value - 108 168f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr((value >> 8) + 247) + chr(value & 0xFF) 169f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif -1131 <= value <= -108: 170f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = -value - 108 171f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr((value >> 8) + 251) + chr(value & 0xFF) 17295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr elif fourByteOp is None: 17395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # T2 only supports 2 byte ints 17495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if -32768 <= value <= 32767: 17595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr code = chr(28) + pack(">h", value) 17695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 17795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # Backwards compatible hack: due to a previous bug in FontTools, 17895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # 16.16 fixed numbers were written out as 4-byte ints. When 17995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # these numbers were small, they were wrongly written back as 18095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # small ints instead of 4-byte ints, breaking round-tripping. 18195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # This here workaround doesn't do it any better, since we can't 18295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # distinguish anymore between small ints that were supposed to 18395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # be small fixed numbers and small ints that were just small 18495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # ints. Hence the warning. 18595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr import sys 18695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr sys.stderr.write("Warning: 4-byte T2 number got passed to the " 18795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "IntType handler. This should happen only when reading in " 18895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "old XML files.\n") 18995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr code = chr(255) + pack(">l", value) 190f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 191f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = fourByteOp + pack(">l", value) 192f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return code 193f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 194f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return encodeInt 195f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 196f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 197f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntCFF = getIntEncoder("cff") 198f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT1 = getIntEncoder("t1") 199f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT2 = getIntEncoder("t2") 200f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 20195c9e9fc11dc028bd1747788f2b417f3936fc59bjvrdef encodeFixed(f, pack=struct.pack): 20295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For T2 only 20395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return "\xff" + pack(">l", int(round(f * 65536))) 20495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 205f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef encodeFloat(f): 20695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For CFF only, used in cffLib 207f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = str(f).upper() 208f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if s[:2] == "0.": 209f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 210f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif s[:3] == "-0.": 211f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = "-" + s[2:] 212f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles = [] 213f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr while s: 214f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = s[0] 215f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 216f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if c == "E" and s[:1] == "-": 217f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 218f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = "E-" 219f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(realNibblesDict[c]) 220f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 221f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if len(nibbles) % 2: 222f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 223f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr d = chr(30) 224f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr for i in range(0, len(nibbles), 2): 225f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr d = d + chr(nibbles[i] << 4 | nibbles[i+1]) 226f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return d 227f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 228f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 2294e5af60930726d06a58a30bae45bb27ae50aea77jvrclass CharStringCompileError(Exception): pass 2304e5af60930726d06a58a30bae45bb27ae50aea77jvr 2314e5af60930726d06a58a30bae45bb27ae50aea77jvr 232f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass T2CharString(ByteCodeBase): 2337842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2347842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t2OperandEncoding 235455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t2Operators) 2367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 237489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): 2387842e56b97ce677b83bdab09cda48bc2d89ac75aJust if program is None: 2397842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 2407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = bytecode 2417842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 242489d76a340845361def6af9ab7d9152f8e66f417jvr self.private = private 243846d09e380215f8c7fdb4bbb9f083f8e68722cdaBehdad Esfahbod self.globalSubrs = globalSubrs if globalSubrs is not None else [] 2447842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2457842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __repr__(self): 2467842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is None: 2477842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) 2487842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 2497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) 2507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 25195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 25295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT2 25395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 25495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 25595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeFixed 25695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 257586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def decompile(self): 258586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr if not self.needsDecompilation(): 259586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr return 260489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 261489d76a340845361def6af9ab7d9152f8e66f417jvr decompiler = SimpleT2Decompiler(subrs, self.globalSubrs) 262586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr decompiler.execute(self) 263586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr 264489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 265489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 266489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T2OutlineExtractor(pen, subrs, self.globalSubrs, 267489d76a340845361def6af9ab7d9152f8e66f417jvr self.private.nominalWidthX, self.private.defaultWidthX) 268489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 269489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 270489d76a340845361def6af9ab7d9152f8e66f417jvr 271455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr def compile(self): 272455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if self.bytecode is not None: 273455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return 2749920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program, "illegal CharString: decompiled to empty program" 2759920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program[-1] in ("endchar", "return", "callsubr", "callgsubr", 2769920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 277455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr bytecode = [] 278455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opcodes = self.opcodes 2794e5af60930726d06a58a30bae45bb27ae50aea77jvr program = self.program 28095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeInt = self.getIntEncoder() 28195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeFixed = self.getFixedEncoder() 2824e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 2834e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(program) 2844e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 2854e5af60930726d06a58a30bae45bb27ae50aea77jvr token = program[i] 2864e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 287455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr tp = type(token) 288002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod if tp == str: 2894e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 290e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod bytecode.extend(chr(b) for b in opcodes[token]) 2914e5af60930726d06a58a30bae45bb27ae50aea77jvr except KeyError: 292cd5aad92f23737ff93a110d5c73d624658a28da8Behdad Esfahbod raise CharStringCompileError("illegal operator: %s" % token) 2934e5af60930726d06a58a30bae45bb27ae50aea77jvr if token in ('hintmask', 'cntrmask'): 2944e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode.append(program[i]) # hint mask 2954e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 296002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == int: 29795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeInt(token)) 298002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod elif tp == float: 29995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeFixed(token)) 300455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 301f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert 0, "unsupported type: %s" % tp 3024e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 3034e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode = "".join(bytecode) 3044e5af60930726d06a58a30bae45bb27ae50aea77jvr except TypeError: 3053ec6a258238b6068e4eef3fe579f1f5c0a06bbbaBehdad Esfahbod print(bytecode) 3064e5af60930726d06a58a30bae45bb27ae50aea77jvr raise 307f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.setBytecode(bytecode) 308f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def needsDecompilation(self): 3107842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.bytecode is not None 3117842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3127842e56b97ce677b83bdab09cda48bc2d89ac75aJust def setProgram(self, program): 3137842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 3147842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = None 3157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 316f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr def setBytecode(self, bytecode): 317f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.bytecode = bytecode 318f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.program = None 319f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3207842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getToken(self, index, 321002c32fd0d869e280783777ec57916a9267aaea5Behdad Esfahbod len=len, ord=ord, getattr=getattr, type=type, StringType=str): 3227842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3237842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.bytecode): 3247842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3257842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(self.bytecode[index]) 3267842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3277842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 3287842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 3297842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, index = handler(b0, self.bytecode, index) 3307842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3317842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.program): 3327842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3337842e56b97ce677b83bdab09cda48bc2d89ac75aJust token = self.program[index] 3347842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 335ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod isOperator = isinstance(token, StringType) 3367842e56b97ce677b83bdab09cda48bc2d89ac75aJust return token, isOperator, index 3377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3387842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getBytes(self, index, nBytes): 3397842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3407842e56b97ce677b83bdab09cda48bc2d89ac75aJust newIndex = index + nBytes 3417842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.bytecode[index:newIndex] 3427842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = newIndex 3437842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3447842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.program[index] 3457842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3467842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(bytes) == nBytes 3477842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bytes, index 3487842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3497842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 3507842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 3517842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 3527842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 3537842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3547842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 3557842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator = self.operators[op] 3567842e56b97ce677b83bdab09cda48bc2d89ac75aJust return operator, index 3577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, xmlWriter): 359dab433233bd4024ede9ad27c6c61ea0072c2edafJust from fontTools.misc.textTools import num2binary 3607842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3617842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.dumphex(self.bytecode) 3627842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3637842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 3647842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 365ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 3667842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 3677842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 3687842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 3697842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 370e5ca79699d00fdf7ac6eaceaed372aea8d6bc1fdBehdad Esfahbod args = [str(arg) for arg in args] 3717842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token in ('hintmask', 'cntrmask'): 3727842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMask, isOperator, index = self.getToken(index) 3737842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits = [] 3747842e56b97ce677b83bdab09cda48bc2d89ac75aJust for byte in hintMask: 3757842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits.append(num2binary(ord(byte), 8)) 37614fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod hintMask = ''.join(bits) 37714fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token, hintMask]) 3787842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 37914fb031125b773f0a15eb19be4f02ed8540b2db6Behdad Esfahbod line = ' '.join(args + [token]) 3807842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.write(line) 3817842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.newline() 3827842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 3837842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args.append(token) 3854e5af60930726d06a58a30bae45bb27ae50aea77jvr 3863a9fd301808f5a8991ca9ac44028d1ecb22d307fBehdad Esfahbod def fromXML(self, name, attrs, content): 387b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr from fontTools.misc.textTools import binary2num, readHex 388b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr if attrs.get("raw"): 389b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr self.setBytecode(readHex(content)) 390b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr return 3914e5af60930726d06a58a30bae45bb27ae50aea77jvr content = "".join(content) 3924e5af60930726d06a58a30bae45bb27ae50aea77jvr content = content.split() 3934e5af60930726d06a58a30bae45bb27ae50aea77jvr program = [] 3944e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(content) 3954e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 3964e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 3974e5af60930726d06a58a30bae45bb27ae50aea77jvr token = content[i] 3984e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 3994e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 4004e5af60930726d06a58a30bae45bb27ae50aea77jvr token = int(token) 4014e5af60930726d06a58a30bae45bb27ae50aea77jvr except ValueError: 40295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr try: 40395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr token = float(token) 40495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr except ValueError: 40595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 40695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if token in ('hintmask', 'cntrmask'): 40795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr mask = content[i] 40895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr maskBytes = "" 40995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr for j in range(0, len(mask), 8): 41095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr maskBytes = maskBytes + chr(binary2num(mask[j:j+8])) 41195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(maskBytes) 41295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr i = i + 1 41395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 41495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 4154e5af60930726d06a58a30bae45bb27ae50aea77jvr else: 4164e5af60930726d06a58a30bae45bb27ae50aea77jvr program.append(token) 4174e5af60930726d06a58a30bae45bb27ae50aea77jvr self.setProgram(program) 4187842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4197842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4207842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1Operators = [ 4217842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 4227842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 4237842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 4247842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 4257842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 4267842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 4277842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 4287842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 4297842e56b97ce677b83bdab09cda48bc2d89ac75aJust (9, 'closepath'), 4307842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 4317842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 4327842e56b97ce677b83bdab09cda48bc2d89ac75aJust (13, 'hsbw'), 4337842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 4347842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 4357842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 4367842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 4377842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 4387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 0), 'dotsection'), 4397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 1), 'vstem3'), 4407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 2), 'hstem3'), 4417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 6), 'seac'), 4427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 7), 'sbw'), 4437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 4447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 16), 'callothersubr'), 4457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 17), 'pop'), 4467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 33), 'setcurrentpoint'), 4477842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 4487842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4497842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1CharString(T2CharString): 4507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4517842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t1OperandEncoding 452455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t1Operators) 4537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 454489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, subrs=None): 455489d76a340845361def6af9ab7d9152f8e66f417jvr if program is None: 456489d76a340845361def6af9ab7d9152f8e66f417jvr program = [] 457489d76a340845361def6af9ab7d9152f8e66f417jvr self.bytecode = bytecode 458489d76a340845361def6af9ab7d9152f8e66f417jvr self.program = program 459489d76a340845361def6af9ab7d9152f8e66f417jvr self.subrs = subrs 460489d76a340845361def6af9ab7d9152f8e66f417jvr 46195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 46295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT1 46395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 46495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 46595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeFixed(value): 46695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr raise TypeError("Type 1 charstrings don't support floating point operands") 46795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 4687842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self): 469b68a700595ff730c29d3d4b7abf92ee287678745Just if self.program is not None: 4707842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 4717842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 4727842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 473ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 4747842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 4757842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 4767842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 4777842e56b97ce677b83bdab09cda48bc2d89ac75aJust program.append(token) 4787842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.setProgram(program) 4797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 480489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 481489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T1OutlineExtractor(pen, self.subrs) 482489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 483489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 484489d76a340845361def6af9ab7d9152f8e66f417jvr 4857842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4867842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass SimpleT2Decompiler: 4877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4887842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, localSubrs, globalSubrs): 4897842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localSubrs = localSubrs 4907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localBias = calcSubrBias(localSubrs) 4917842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalSubrs = globalSubrs 4927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalBias = calcSubrBias(globalSubrs) 4937842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 4947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 4967842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack = [] 4977842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack = [] 4987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = 0 4997842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = 0 5007842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def execute(self, charString): 5027842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack.append(charString) 5037842e56b97ce677b83bdab09cda48bc2d89ac75aJust needsDecompilation = charString.needsDecompilation() 5047842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5057842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 5067842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = program.append 5077842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5087842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = lambda x: None 5097842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack = self.operandStack.append 5107842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 511ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod while True: 5127842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = charString.getToken(index) 5137842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 5147842e56b97ce677b83bdab09cda48bc2d89ac75aJust break # we're done! 5157842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(token) 5167842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 5177842e56b97ce677b83bdab09cda48bc2d89ac75aJust handlerName = "op_" + token 5187842e56b97ce677b83bdab09cda48bc2d89ac75aJust if hasattr(self, handlerName): 5197842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, handlerName) 5207842e56b97ce677b83bdab09cda48bc2d89ac75aJust rv = handler(index) 5217842e56b97ce677b83bdab09cda48bc2d89ac75aJust if rv: 5227842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = rv 5237842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(hintMaskBytes) 5247842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5257842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() 5267842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5277842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack(token) 5287842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5299920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program, "illegal CharString: decompiled to empty program" 5309920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program[-1] in ("endchar", "return", "callsubr", "callgsubr", 5319920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 5327842e56b97ce677b83bdab09cda48bc2d89ac75aJust charString.setProgram(program) 5337842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.callingStack[-1] 5347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 5367842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.operandStack[-1] 5377842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.operandStack[-1] 5387842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 5397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 5417842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack[:] 5427842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack[:] = [] 5437842e56b97ce677b83bdab09cda48bc2d89ac75aJust return stack 5447842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5457842e56b97ce677b83bdab09cda48bc2d89ac75aJust def push(self, value): 5467842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack.append(value) 5477842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5487842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_return(self, index): 5497842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.operandStack: 5507842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5517842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5527842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 5537842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5547099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5557099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr def op_ignore(self, index): 5567099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr pass 5577099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 5597842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5607842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.localSubrs[subrIndex+self.localBias] 5617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5627842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callgsubr(self, index): 5647842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5657842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.globalSubrs[subrIndex+self.globalBias] 5667842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5677842e56b97ce677b83bdab09cda48bc2d89ac75aJust 568586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_hstem(self, index): 569586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 570586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstem(self, index): 571586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstemhm(self, index): 5737842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 574586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstemhm(self, index): 575586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5777842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hintmask(self, index): 5787842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.hintMaskBytes: 5797842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 5807842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = (self.hintCount + 7) / 8 5817842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) 5827842e56b97ce677b83bdab09cda48bc2d89ac75aJust return hintMaskBytes, index 5837842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5847842e56b97ce677b83bdab09cda48bc2d89ac75aJust op_cntrmask = op_hintmask 5857842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5867842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 5877842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 5887842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = self.hintCount + len(args) / 2 5897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 590f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod # misc 591f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_and(self, index): 592f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 593f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_or(self, index): 594f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 595f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_not(self, index): 596f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 597f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_store(self, index): 598f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 599f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_abs(self, index): 600f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 601f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_add(self, index): 602f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 603f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sub(self, index): 604f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 605f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_div(self, index): 606f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 607f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_load(self, index): 608f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 609f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_neg(self, index): 610f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 611f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_eq(self, index): 612f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 613f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_drop(self, index): 614f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 615f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_put(self, index): 616f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 617f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_get(self, index): 618f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 619f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_ifelse(self, index): 620f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 621f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_random(self, index): 622f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 623f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_mul(self, index): 624f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 625f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_sqrt(self, index): 626f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 627f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_dup(self, index): 628f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 629f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_exch(self, index): 630f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 631f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_index(self, index): 632f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 633f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod def op_roll(self, index): 634f09f1d406446d1e249ab89b5c345d0a86e8392e3Behdad Esfahbod raise NotImplementedError 6357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6367842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T2OutlineExtractor(SimpleT2Decompiler): 6377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 638489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, localSubrs, globalSubrs, nominalWidthX, defaultWidthX): 6397842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs) 640489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 6417842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.nominalWidthX = nominalWidthX 6427842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.defaultWidthX = defaultWidthX 6437842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 6457842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.reset(self) 6467842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hints = [] 6477842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 0 6487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 649489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = (0, 0) 650489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6517842e56b97ce677b83bdab09cda48bc2d89ac75aJust 652489d76a340845361def6af9ab7d9152f8e66f417jvr def _nextPoint(self, point): 653489d76a340845361def6af9ab7d9152f8e66f417jvr x, y = self.currentPoint 654489d76a340845361def6af9ab7d9152f8e66f417jvr point = x + point[0], y + point[1] 655489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = point 656489d76a340845361def6af9ab7d9152f8e66f417jvr return point 6577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 658489d76a340845361def6af9ab7d9152f8e66f417jvr def rMoveTo(self, point): 659489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.moveTo(self._nextPoint(point)) 660489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 1 661489d76a340845361def6af9ab7d9152f8e66f417jvr 662489d76a340845361def6af9ab7d9152f8e66f417jvr def rLineTo(self, point): 663489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 664489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 665489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.lineTo(self._nextPoint(point)) 666489d76a340845361def6af9ab7d9152f8e66f417jvr 667489d76a340845361def6af9ab7d9152f8e66f417jvr def rCurveTo(self, pt1, pt2, pt3): 668489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 669489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 670489d76a340845361def6af9ab7d9152f8e66f417jvr nextPoint = self._nextPoint 671489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) 6727842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6737842e56b97ce677b83bdab09cda48bc2d89ac75aJust def closePath(self): 674489d76a340845361def6af9ab7d9152f8e66f417jvr if self.sawMoveTo: 675489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.closePath() 676489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6777842e56b97ce677b83bdab09cda48bc2d89ac75aJust 678d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 679d3ee2d4319742ec61cb299665ccba66c139e4834jvr # In T2 there are no open paths, so always do a closePath when 680d3ee2d4319742ec61cb299665ccba66c139e4834jvr # finishing a sub path. 681d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.closePath() 682d3ee2d4319742ec61cb299665ccba66c139e4834jvr 6837842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 6847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 6857842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.gotWidth: 6867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if evenOdd ^ (len(args) % 2): 6877842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.nominalWidthX + args[0] 6887842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 6897842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 6907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.defaultWidthX 6917842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 1 6927842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 6937842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6947842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 6957842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popallWidth() 6967842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = self.hintCount + len(args) / 2 6977842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6987842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6997842e56b97ce677b83bdab09cda48bc2d89ac75aJust # hint operators 7007842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 701586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstem(self, index): 702586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 703586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstem(self, index): 704586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 705586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstemhm(self, index): 706586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 707586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstemhm(self, index): 708586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 7097842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_hintmask(self, index): 7107842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7117842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_cntrmask(self, index): 7127842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 7137842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7147842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7157842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, moveto 7167842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7177842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 718d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 719489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popallWidth()) 7207842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 721d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 722489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popallWidth(1)[0], 0)) 7237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 724d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 725489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popallWidth(1)[0])) 7267842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 727d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 728382df6c42a7a6aecb690e07c6338e19f038f0543jvr args = self.popallWidth() 729382df6c42a7a6aecb690e07c6338e19f038f0543jvr if args: 730382df6c42a7a6aecb690e07c6338e19f038f0543jvr from fontTools.encodings.StandardEncoding import StandardEncoding 731382df6c42a7a6aecb690e07c6338e19f038f0543jvr # endchar can do seac accent bulding; The T2 spec says it's deprecated, 732382df6c42a7a6aecb690e07c6338e19f038f0543jvr # but recent software that shall remain nameless does output it. 733382df6c42a7a6aecb690e07c6338e19f038f0543jvr adx, ady, bchar, achar = args 734382df6c42a7a6aecb690e07c6338e19f038f0543jvr baseGlyph = StandardEncoding[bchar] 735382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 736382df6c42a7a6aecb690e07c6338e19f038f0543jvr accentGlyph = StandardEncoding[achar] 737382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 7387842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7397842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7407842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, lines 7417842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlineto(self, index): 7437842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7447842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 2): 7457842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = args[i:i+2] 746489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 7477842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7487842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hlineto(self, index): 7497842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(1) 7507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vlineto(self, index): 7517842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(0) 7527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7537842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7547842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, curves 7557842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rrcurveto(self, index): 7577842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" 7587842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7597842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 6): 7607842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dya, dxb, dyb, dxc, dyc, = args[i:i+6] 761489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) 7627842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rcurveline(self, index): 7647842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" 7657842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7667842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args)-2, 6): 7677842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[i:i+6] 768489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 769489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(args[-2:]) 7707842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7717842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlinecurve(self, index): 7727842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" 7737842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7747842e56b97ce677b83bdab09cda48bc2d89ac75aJust lineArgs = args[:-6] 7757842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(lineArgs), 2): 776489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(lineArgs[i:i+2]) 7777842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] 778489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 7797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vvcurveto(self, index): 7817842e56b97ce677b83bdab09cda48bc2d89ac75aJust "dx1? {dya dxb dyb dyc}+ vvcurveto" 7827842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7837842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7847842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = args[0] 7857842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7867842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7877842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7887842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 7897842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dyc = args[i:i+4] 790489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) 7917842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hhcurveto(self, index): 7947842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1? {dxa dxb dyb dxc}+ hhcurveto""" 7957842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7967842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7977842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = args[0] 7987842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7997842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8007842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8017842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 8027842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dxc = args[i:i+4] 803489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) 8047842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 8057842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8067842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vhcurveto(self, index): 8077842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) 8087842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto 8097842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8107842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8117842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8127842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8137842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8147842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8167842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hvcurveto(self, index): 8177842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? 8187842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? 8197842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 8207842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8217842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 8227842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 8237842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 8247842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 8257842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8267842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8277842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, flex 8287842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8297842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex(self, index): 8308b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() 831d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy1 = dy3 = dy4 = dy6 = 0 832d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy5 = -dy2 8338b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8348b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex(self, index): 8368b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() 8378b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8388b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8397842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex1(self, index): 8408b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() 841d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy3 = dy4 = 0 842d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) 843d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr 8448b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8458b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8467842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex1(self, index): 8478b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() 8488b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx = dx1 + dx2 + dx3 + dx4 + dx5 8498b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy = dy1 + dy2 + dy3 + dy4 + dy5 8508b8b44904e116287ca0eb587f9c5b21296fb3123jvr if abs(dx) > abs(dy): 8518b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx6 = d6 852d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -dy 8538b8b44904e116287ca0eb587f9c5b21296fb3123jvr else: 854d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dx6 = -dx 8558b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy6 = d6 8568b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8578b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8587842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8597842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8607842e56b97ce677b83bdab09cda48bc2d89ac75aJust # MultipleMaster. Well... 8617842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8627842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_blend(self, index): 8638b8b44904e116287ca0eb587f9c5b21296fb3123jvr args = self.popall() 8647842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8657842e56b97ce677b83bdab09cda48bc2d89ac75aJust # misc 8667842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_and(self, index): 8678b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8687842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_or(self, index): 8698b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_not(self, index): 8718b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_store(self, index): 8738b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_abs(self, index): 8758b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8767842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_add(self, index): 8778b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8787842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sub(self, index): 8798b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_div(self, index): 8817842e56b97ce677b83bdab09cda48bc2d89ac75aJust num2 = self.pop() 8827842e56b97ce677b83bdab09cda48bc2d89ac75aJust num1 = self.pop() 8837842e56b97ce677b83bdab09cda48bc2d89ac75aJust d1 = num1/num2 8847842e56b97ce677b83bdab09cda48bc2d89ac75aJust d2 = float(num1)/num2 8857842e56b97ce677b83bdab09cda48bc2d89ac75aJust if d1 == d2: 8867842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d1) 8877842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8887842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d2) 8897842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_load(self, index): 8908b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8917842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_neg(self, index): 8928b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_eq(self, index): 8948b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_drop(self, index): 8968b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8977842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_put(self, index): 8988b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8997842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_get(self, index): 9008b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_ifelse(self, index): 9028b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_random(self, index): 9048b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9057842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_mul(self, index): 9068b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9077842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sqrt(self, index): 9088b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dup(self, index): 9108b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_exch(self, index): 9128b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9137842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_index(self, index): 9148b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9157842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_roll(self, index): 9168b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 9177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9187842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9197842e56b97ce677b83bdab09cda48bc2d89ac75aJust # miscelaneous helpers 9207842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9217842e56b97ce677b83bdab09cda48bc2d89ac75aJust def alternatingLineto(self, isHorizontal): 9227842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 9237842e56b97ce677b83bdab09cda48bc2d89ac75aJust for arg in args: 9247842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isHorizontal: 9257842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (arg, 0) 9267842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9277842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (0, arg) 928489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 9297842e56b97ce677b83bdab09cda48bc2d89ac75aJust isHorizontal = not isHorizontal 9307842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9317842e56b97ce677b83bdab09cda48bc2d89ac75aJust def vcurveto(self, args): 9327842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dxc = args[:4] 9337842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9347842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9357842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = args[0] 9367842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9377842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9387842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = 0 939489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) 9407842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def hcurveto(self, args): 9437842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dyc = args[:4] 9447842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9457842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9467842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = args[0] 9477842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9487842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9497842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = 0 950489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) 9517842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9547842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1OutlineExtractor(T2OutlineExtractor): 9557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 956489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, subrs): 957489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 9587842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.subrs = subrs 9597842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 9607842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9617842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 9627842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 9637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 9647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = 0 9657842e56b97ce677b83bdab09cda48bc2d89ac75aJust T2OutlineExtractor.reset(self) 9667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 967d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 968d3ee2d4319742ec61cb299665ccba66c139e4834jvr if self.sawMoveTo: 969d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.pen.endPath() 970d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.sawMoveTo = 0 971d3ee2d4319742ec61cb299665ccba66c139e4834jvr 9727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 9737842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 9747842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9757842e56b97ce677b83bdab09cda48bc2d89ac75aJust def exch(self): 9767842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack 9777842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack[-1], stack[-2] = stack[-2], stack[-1] 9787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9797842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9807842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors 9817842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 9837842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9847842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 985e56bc902cf6a707349ae6ddfe8a83a1bd7b155b9jvr self.endPath() 986489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popall()) 9877842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 9887842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9897842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9917842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 992d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 993489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popall()[0], 0)) 9947842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 9957842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9967842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9977842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.exch() 9997842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 1000d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 1001489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popall()[0])) 10027842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_closepath(self, index): 10037842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.closePath() 10047842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_setcurrentpoint(self, index): 10057842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 10067842e56b97ce677b83bdab09cda48bc2d89ac75aJust x, y = args 1007489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = x, y 10087842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10097842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 1010d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 10117842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10127842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hsbw(self, index): 10137842e56b97ce677b83bdab09cda48bc2d89ac75aJust sbx, wx = self.popall() 10147842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = wx 10157842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = sbx 1016489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = sbx, self.currentPoint[1] 10177842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sbw(self, index): 10187842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10197842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10207842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 10217842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 10227842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10237842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.subrs[subrIndex] 10247842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 10257842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callothersubr(self, index): 10267842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 10277842e56b97ce677b83bdab09cda48bc2d89ac75aJust nArgs = self.pop() 10287842e56b97ce677b83bdab09cda48bc2d89ac75aJust #print nArgs, subrIndex, "callothersubr" 10297842e56b97ce677b83bdab09cda48bc2d89ac75aJust if subrIndex == 0 and nArgs == 3: 10307842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.doFlex() 10317842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 10327842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif subrIndex == 1 and nArgs == 0: 10337842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 1 10347842e56b97ce677b83bdab09cda48bc2d89ac75aJust # ignore... 10357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_pop(self, index): 10367842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass # ignore... 10377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10387842e56b97ce677b83bdab09cda48bc2d89ac75aJust def doFlex(self): 10397842e56b97ce677b83bdab09cda48bc2d89ac75aJust finaly = self.pop() 10407842e56b97ce677b83bdab09cda48bc2d89ac75aJust finalx = self.pop() 10417842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.pop() # flex height is unused 10427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10437842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3y = self.pop() 10447842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3x = self.pop() 10457842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4y = self.pop() 10467842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4x = self.pop() 10477842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3y = self.pop() 10487842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3x = self.pop() 10497842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2y = self.pop() 10507842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2x = self.pop() 10517842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2y = self.pop() 10527842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2x = self.pop() 10537842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1y = self.pop() 10547842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1x = self.pop() 10557842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpy = self.pop() 10567842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpx = self.pop() 10577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10587842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10597842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1x+rpx) 10607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1y+rpy) 10617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2x) 10627842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2y) 10637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2x) 10647842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2y) 10657842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10677842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10687842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3x) 10697842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3y) 10707842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4x) 10717842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4y) 10727842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3x) 10737842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3y) 10747842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10757842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10767842e56b97ce677b83bdab09cda48bc2d89ac75aJust # Push back final coords so subr 0 can find them 10777842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finalx) 10787842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finaly) 10797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dotsection(self, index): 10817842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstem3(self, index): 10837842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10847842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_seac(self, index): 10857842e56b97ce677b83bdab09cda48bc2d89ac75aJust "asb adx ady bchar achar seac" 1086489d76a340845361def6af9ab7d9152f8e66f417jvr from fontTools.encodings.StandardEncoding import StandardEncoding 1087489d76a340845361def6af9ab7d9152f8e66f417jvr asb, adx, ady, bchar, achar = self.popall() 1088489d76a340845361def6af9ab7d9152f8e66f417jvr baseGlyph = StandardEncoding[bchar] 1089489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 1090489d76a340845361def6af9ab7d9152f8e66f417jvr accentGlyph = StandardEncoding[achar] 1091489d76a340845361def6af9ab7d9152f8e66f417jvr adx = adx + self.sbx - asb # seac weirdness 1092489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 10937842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vstem3(self, index): 10947842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1097f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass DictDecompiler(ByteCodeBase): 10987842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10997842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = cffDictOperandEncoding 11007842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, strings): 11027842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.stack = [] 11037842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.strings = strings 11047842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict = {} 11057842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11067842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getDict(self): 11077842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(self.stack) == 0, "non-empty stack" 11087842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.dict 11097842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11107842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data): 11117842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 11127842e56b97ce677b83bdab09cda48bc2d89ac75aJust lenData = len(data) 11137842e56b97ce677b83bdab09cda48bc2d89ac75aJust push = self.stack.append 11147842e56b97ce677b83bdab09cda48bc2d89ac75aJust while index < lenData: 11157842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(data[index]) 11167842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 11177842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 11187842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 11197842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, index = handler(b0, data, index) 11207842e56b97ce677b83bdab09cda48bc2d89ac75aJust if value is not None: 11217842e56b97ce677b83bdab09cda48bc2d89ac75aJust push(value) 11227842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 11247842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.stack[-1] 11257842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[-1] 11267842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 11277842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11287842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 11297842e56b97ce677b83bdab09cda48bc2d89ac75aJust all = self.stack[:] 11307842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[:] 11317842e56b97ce677b83bdab09cda48bc2d89ac75aJust return all 11327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11337842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 11347842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 11357842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 11367842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 11377842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11387842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 11397842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator, argType = self.operators[op] 11407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.handle_operator(operator, argType) 11417842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, index 11427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def handle_operator(self, operator, argType): 1144ac1b4359467ca3deab03186a15eae1d55eb35567Behdad Esfahbod if isinstance(argType, type(())): 11457842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = () 1146bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr for i in range(len(argType)-1, -1, -1): 1147bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr arg = argType[i] 11487842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + arg) 11497842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = (arghandler(operator),) + value 11507842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11517842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + argType) 11527842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = arghandler(operator) 11537842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict[operator] = value 11547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11557842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_number(self, name): 11567842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.pop() 11577842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_SID(self, name): 11587842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.strings[self.pop()] 11597842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_array(self, name): 11607842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 1161dc18128aa9b3f6b98a623c294ac615195159025ejvr def arg_delta(self, name): 1162dc18128aa9b3f6b98a623c294ac615195159025ejvr out = [] 1163dc18128aa9b3f6b98a623c294ac615195159025ejvr current = 0 1164dc18128aa9b3f6b98a623c294ac615195159025ejvr for v in self.popall(): 11656f03a58f59fb20662602e3d4bb153d7db2f778d3jvr current = current + v 1166dc18128aa9b3f6b98a623c294ac615195159025ejvr out.append(current) 1167dc18128aa9b3f6b98a623c294ac615195159025ejvr return out 11687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11707842e56b97ce677b83bdab09cda48bc2d89ac75aJustdef calcSubrBias(subrs): 11717842e56b97ce677b83bdab09cda48bc2d89ac75aJust nSubrs = len(subrs) 11727842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nSubrs < 1240: 11737842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 107 11747842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif nSubrs < 33900: 11757842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 1131 11767842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11777842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 32768 11787842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bias 1179