psCharStrings.py revision 7099f4c0f9fbaf1a5c811113fdfd2404dee04361
17842e56b97ce677b83bdab09cda48bc2d89ac75aJust"""psCharStrings.py -- module implementing various kinds of CharStrings: 27842e56b97ce677b83bdab09cda48bc2d89ac75aJustCFF dictionary data and Type1/Type2 CharStrings. 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust""" 47842e56b97ce677b83bdab09cda48bc2d89ac75aJust 57842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport types 67842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport struct 77842e56b97ce677b83bdab09cda48bc2d89ac75aJustimport string 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10455af6592bffbd6f2fc9f56fbfe083022a8353d4jvrDEBUG = 0 11455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 12455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr 137842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding = [None] * 256 147842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[0:32] = (32) * ["do_operator"] 157842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[32:247] = (247 - 32) * ["read_byte"] 167842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[247:251] = (251 - 247) * ["read_smallInt1"] 177842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[251:255] = (255 - 251) * ["read_smallInt2"] 187842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1OperandEncoding[255] = "read_longInt" 197842e56b97ce677b83bdab09cda48bc2d89ac75aJustassert len(t1OperandEncoding) == 256 207842e56b97ce677b83bdab09cda48bc2d89ac75aJust 217842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding = t1OperandEncoding[:] 227842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2OperandEncoding[28] = "read_shortInt" 2395c9e9fc11dc028bd1747788f2b417f3936fc59bjvrt2OperandEncoding[255] = "read_fixed1616" 247842e56b97ce677b83bdab09cda48bc2d89ac75aJust 257842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding = t2OperandEncoding[:] 267842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[29] = "read_longInt" 277842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[30] = "read_realNumber" 287842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[255] = "reserved" 297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust 317842e56b97ce677b83bdab09cda48bc2d89ac75aJustrealNibbles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust '.', 'E', 'E-', None, '-'] 33f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrrealNibblesDict = {} 34f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrfor _i in range(len(realNibbles)): 35f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr realNibblesDict[realNibbles[_i]] = _i 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust 38f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass ByteCodeBase: 397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_byte(self, b0, data, index): 417842e56b97ce677b83bdab09cda48bc2d89ac75aJust return b0 - 139, index 427842e56b97ce677b83bdab09cda48bc2d89ac75aJust 437842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt1(self, b0, data, index): 447842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return (b0-247)*256 + b1 + 108, index+1 467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_smallInt2(self, b0, data, index): 487842e56b97ce677b83bdab09cda48bc2d89ac75aJust b1 = ord(data[index]) 497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return -(b0-251)*256 - b1 - 108, index+1 507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_shortInt(self, b0, data, index): 527842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] 537842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">h", bin) 547842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+2 557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_longInt(self, b0, data, index): 577842e56b97ce677b83bdab09cda48bc2d89ac75aJust bin = data[index] + data[index+1] + data[index+2] + data[index+3] 587842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, = struct.unpack(">l", bin) 597842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value, index+4 607842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def read_fixed1616(self, b0, data, index): 6295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bin = data[index] + data[index+1] + data[index+2] + data[index+3] 6395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr value, = struct.unpack(">l", bin) 6495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return value / 65536.0, index+4 6595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 667842e56b97ce677b83bdab09cda48bc2d89ac75aJust def read_realNumber(self, b0, data, index): 677842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = '' 687842e56b97ce677b83bdab09cda48bc2d89ac75aJust while 1: 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust b = ord(data[index]) 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble0 = (b & 0xf0) >> 4 727842e56b97ce677b83bdab09cda48bc2d89ac75aJust nibble1 = b & 0x0f 737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble0 == 0xf: 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble0] 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nibble1 == 0xf: 777842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 787842e56b97ce677b83bdab09cda48bc2d89ac75aJust number = number + realNibbles[nibble1] 79455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return float(number), index 807842e56b97ce677b83bdab09cda48bc2d89ac75aJust 817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 82dbc2c173b35360386c907a3c70cb931ae4c3fac9jvrdef buildOperatorDict(operatorList): 83455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper = {} 84455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc = {} 857842e56b97ce677b83bdab09cda48bc2d89ac75aJust for item in operatorList: 867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(item) == 2: 87455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1] 88455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 89455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr oper[item[0]] = item[1:] 90455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if type(item[0]) == types.TupleType: 91455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = item[0] 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 93455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opc[item[1]] = (item[0],) 94455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return oper, opc 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 977842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2Operators = [ 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust (16, 'blend'), 1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust (18, 'hstemhm'), 1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust (19, 'hintmask'), 1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust (20, 'cntrmask'), 1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust (23, 'vstemhm'), 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust (24, 'rcurveline'), 1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust (25, 'rlinecurve'), 1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust (26, 'vvcurveto'), 1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust (27, 'hhcurveto'), 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust# (28, 'shortint'), # not really an operator 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust (29, 'callgsubr'), 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 1247099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr ((12, 0), 'ignore'), # dotsection. Yes, there a few very early OTF/CFF 1257099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr # fonts with this deprecated operator. Just ignore it. 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 3), 'and'), 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 4), 'or'), 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 5), 'not'), 1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 8), 'store'), 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 9), 'abs'), 1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 10), 'add'), 1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 11), 'sub'), 1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 13), 'load'), 1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 14), 'neg'), 1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 15), 'eq'), 1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 18), 'drop'), 1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 20), 'put'), 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 21), 'get'), 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 22), 'ifelse'), 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 23), 'random'), 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 24), 'mul'), 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 26), 'sqrt'), 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 27), 'dup'), 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 28), 'exch'), 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 29), 'index'), 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 30), 'roll'), 1487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 34), 'hflex'), 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 35), 'flex'), 1507842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 36), 'hflex1'), 1517842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 37), 'flex1'), 1527842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 154f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 155f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef getIntEncoder(format): 156f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if format == "cff": 157f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr fourByteOp = chr(29) 158f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif format == "t1": 15995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = chr(255) 160f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 161f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert format == "t2" 16295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr fourByteOp = None 163f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 16495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeInt(value, fourByteOp=fourByteOp, chr=chr, 16595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr pack=struct.pack, unpack=struct.unpack): 166f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if -107 <= value <= 107: 167f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr(value + 139) 168f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif 108 <= value <= 1131: 169f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = value - 108 170f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr((value >> 8) + 247) + chr(value & 0xFF) 171f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif -1131 <= value <= -108: 172f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr value = -value - 108 173f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = chr((value >> 8) + 251) + chr(value & 0xFF) 17495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr elif fourByteOp is None: 17595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # T2 only supports 2 byte ints 17695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if -32768 <= value <= 32767: 17795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr code = chr(28) + pack(">h", value) 17895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 17995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # Backwards compatible hack: due to a previous bug in FontTools, 18095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # 16.16 fixed numbers were written out as 4-byte ints. When 18195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # these numbers were small, they were wrongly written back as 18295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # small ints instead of 4-byte ints, breaking round-tripping. 18395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # This here workaround doesn't do it any better, since we can't 18495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # distinguish anymore between small ints that were supposed to 18595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # be small fixed numbers and small ints that were just small 18695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # ints. Hence the warning. 18795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr import sys 18895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr sys.stderr.write("Warning: 4-byte T2 number got passed to the " 18995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "IntType handler. This should happen only when reading in " 19095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr "old XML files.\n") 19195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr code = chr(255) + pack(">l", value) 192f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr else: 193f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr code = fourByteOp + pack(">l", value) 194f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return code 195f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 196f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return encodeInt 197f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 198f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 199f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntCFF = getIntEncoder("cff") 200f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT1 = getIntEncoder("t1") 201f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT2 = getIntEncoder("t2") 202f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 20395c9e9fc11dc028bd1747788f2b417f3936fc59bjvrdef encodeFixed(f, pack=struct.pack): 20495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For T2 only 20595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return "\xff" + pack(">l", int(round(f * 65536))) 20695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 207f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef encodeFloat(f): 20895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr # For CFF only, used in cffLib 209f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = str(f).upper() 210f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if s[:2] == "0.": 211f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 212f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr elif s[:3] == "-0.": 213f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = "-" + s[2:] 214f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles = [] 215f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr while s: 216f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = s[0] 217f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 218f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if c == "E" and s[:1] == "-": 219f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr s = s[1:] 220f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr c = "E-" 221f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(realNibblesDict[c]) 222f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 223f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr if len(nibbles) % 2: 224f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr nibbles.append(0xf) 225f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr d = chr(30) 226f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr for i in range(0, len(nibbles), 2): 227f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr d = d + chr(nibbles[i] << 4 | nibbles[i+1]) 228f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr return d 229f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 230f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 2314e5af60930726d06a58a30bae45bb27ae50aea77jvrclass CharStringCompileError(Exception): pass 2324e5af60930726d06a58a30bae45bb27ae50aea77jvr 2334e5af60930726d06a58a30bae45bb27ae50aea77jvr 234f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass T2CharString(ByteCodeBase): 2357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2367842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t2OperandEncoding 237455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t2Operators) 2387842e56b97ce677b83bdab09cda48bc2d89ac75aJust 239489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None): 2407842e56b97ce677b83bdab09cda48bc2d89ac75aJust if program is None: 2417842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 2427842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = bytecode 2437842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 244489d76a340845361def6af9ab7d9152f8e66f417jvr self.private = private 245586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.globalSubrs = globalSubrs 2467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 2477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __repr__(self): 2487842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is None: 2497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (source) at %x>" % (self.__class__.__name__, id(self)) 2507842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 2517842e56b97ce677b83bdab09cda48bc2d89ac75aJust return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self)) 2527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 25395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 25495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT2 25595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 25695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 25795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeFixed 25895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 259586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def decompile(self): 260586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr if not self.needsDecompilation(): 261586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr return 262489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 263489d76a340845361def6af9ab7d9152f8e66f417jvr decompiler = SimpleT2Decompiler(subrs, self.globalSubrs) 264586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr decompiler.execute(self) 265586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr 266489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 267489d76a340845361def6af9ab7d9152f8e66f417jvr subrs = getattr(self.private, "Subrs", []) 268489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T2OutlineExtractor(pen, subrs, self.globalSubrs, 269489d76a340845361def6af9ab7d9152f8e66f417jvr self.private.nominalWidthX, self.private.defaultWidthX) 270489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 271489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 272489d76a340845361def6af9ab7d9152f8e66f417jvr 273455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr def compile(self): 274455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if self.bytecode is not None: 275455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr return 2769920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program, "illegal CharString: decompiled to empty program" 2779920ad5286b6e61d67f07f908107d65f7fa817acjvr assert self.program[-1] in ("endchar", "return", "callsubr", "callgsubr", 2789920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 279455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr bytecode = [] 280455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr opcodes = self.opcodes 2814e5af60930726d06a58a30bae45bb27ae50aea77jvr program = self.program 28295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeInt = self.getIntEncoder() 28395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr encodeFixed = self.getFixedEncoder() 2844e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 2854e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(program) 2864e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 2874e5af60930726d06a58a30bae45bb27ae50aea77jvr token = program[i] 2884e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 289455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr tp = type(token) 290455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr if tp == types.StringType: 2914e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 292455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr bytecode.extend(map(chr, opcodes[token])) 2934e5af60930726d06a58a30bae45bb27ae50aea77jvr except KeyError: 2944e5af60930726d06a58a30bae45bb27ae50aea77jvr raise CharStringCompileError, "illegal operator: %s" % token 2954e5af60930726d06a58a30bae45bb27ae50aea77jvr if token in ('hintmask', 'cntrmask'): 2964e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode.append(program[i]) # hint mask 2974e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 298455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr elif tp == types.IntType: 29995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeInt(token)) 30095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr elif tp == types.FloatType: 30195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr bytecode.append(encodeFixed(token)) 302455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr else: 303f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr assert 0, "unsupported type: %s" % tp 3044e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 3054e5af60930726d06a58a30bae45bb27ae50aea77jvr bytecode = "".join(bytecode) 3064e5af60930726d06a58a30bae45bb27ae50aea77jvr except TypeError: 3074e5af60930726d06a58a30bae45bb27ae50aea77jvr print bytecode 3084e5af60930726d06a58a30bae45bb27ae50aea77jvr raise 309f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.setBytecode(bytecode) 310f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3117842e56b97ce677b83bdab09cda48bc2d89ac75aJust def needsDecompilation(self): 3127842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.bytecode is not None 3137842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3147842e56b97ce677b83bdab09cda48bc2d89ac75aJust def setProgram(self, program): 3157842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.program = program 3167842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.bytecode = None 3177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 318f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr def setBytecode(self, bytecode): 319f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.bytecode = bytecode 320f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr self.program = None 321f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr 3227842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getToken(self, index, 3237842e56b97ce677b83bdab09cda48bc2d89ac75aJust len=len, ord=ord, getattr=getattr, type=type, StringType=types.StringType): 3247842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3257842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.bytecode): 3267842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3277842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(self.bytecode[index]) 3287842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3297842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 3307842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 3317842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, index = handler(b0, self.bytecode, index) 3327842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3337842e56b97ce677b83bdab09cda48bc2d89ac75aJust if index >= len(self.program): 3347842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, 0, 0 3357842e56b97ce677b83bdab09cda48bc2d89ac75aJust token = self.program[index] 3367842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3377842e56b97ce677b83bdab09cda48bc2d89ac75aJust isOperator = type(token) == StringType 3387842e56b97ce677b83bdab09cda48bc2d89ac75aJust return token, isOperator, index 3397842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getBytes(self, index, nBytes): 3417842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3427842e56b97ce677b83bdab09cda48bc2d89ac75aJust newIndex = index + nBytes 3437842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.bytecode[index:newIndex] 3447842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = newIndex 3457842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3467842e56b97ce677b83bdab09cda48bc2d89ac75aJust bytes = self.program[index] 3477842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 3487842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(bytes) == nBytes 3497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bytes, index 3507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 3527842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 3537842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 3547842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 3557842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3567842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 3577842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator = self.operators[op] 3587842e56b97ce677b83bdab09cda48bc2d89ac75aJust return operator, index 3597842e56b97ce677b83bdab09cda48bc2d89ac75aJust 3607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def toXML(self, xmlWriter): 361dab433233bd4024ede9ad27c6c61ea0072c2edafJust from fontTools.misc.textTools import num2binary 3627842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.bytecode is not None: 3637842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.dumphex(self.bytecode) 3647842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3657842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 3667842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 3677842e56b97ce677b83bdab09cda48bc2d89ac75aJust while 1: 3687842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 3697842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 3707842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 3717842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 3727842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = map(str, args) 3737842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token in ('hintmask', 'cntrmask'): 3747842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMask, isOperator, index = self.getToken(index) 3757842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits = [] 3767842e56b97ce677b83bdab09cda48bc2d89ac75aJust for byte in hintMask: 3777842e56b97ce677b83bdab09cda48bc2d89ac75aJust bits.append(num2binary(ord(byte), 8)) 378586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr hintMask = string.join(bits, "") 3797842e56b97ce677b83bdab09cda48bc2d89ac75aJust line = string.join(args + [token, hintMask], " ") 3807842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3817842e56b97ce677b83bdab09cda48bc2d89ac75aJust line = string.join(args + [token], " ") 3827842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.write(line) 3837842e56b97ce677b83bdab09cda48bc2d89ac75aJust xmlWriter.newline() 3847842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 3857842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 3867842e56b97ce677b83bdab09cda48bc2d89ac75aJust args.append(token) 3874e5af60930726d06a58a30bae45bb27ae50aea77jvr 3884e5af60930726d06a58a30bae45bb27ae50aea77jvr def fromXML(self, (name, attrs, content)): 389b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr from fontTools.misc.textTools import binary2num, readHex 390b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr if attrs.get("raw"): 391b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr self.setBytecode(readHex(content)) 392b58176e5ac4d1e0b0e6a6c71c3020f5e85bd4dfejvr return 3934e5af60930726d06a58a30bae45bb27ae50aea77jvr content = "".join(content) 3944e5af60930726d06a58a30bae45bb27ae50aea77jvr content = content.split() 3954e5af60930726d06a58a30bae45bb27ae50aea77jvr program = [] 3964e5af60930726d06a58a30bae45bb27ae50aea77jvr end = len(content) 3974e5af60930726d06a58a30bae45bb27ae50aea77jvr i = 0 3984e5af60930726d06a58a30bae45bb27ae50aea77jvr while i < end: 3994e5af60930726d06a58a30bae45bb27ae50aea77jvr token = content[i] 4004e5af60930726d06a58a30bae45bb27ae50aea77jvr i = i + 1 4014e5af60930726d06a58a30bae45bb27ae50aea77jvr try: 4024e5af60930726d06a58a30bae45bb27ae50aea77jvr token = int(token) 4034e5af60930726d06a58a30bae45bb27ae50aea77jvr except ValueError: 40495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr try: 40595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr token = float(token) 40695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr except ValueError: 40795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 40895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr if token in ('hintmask', 'cntrmask'): 40995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr mask = content[i] 41095c9e9fc11dc028bd1747788f2b417f3936fc59bjvr maskBytes = "" 41195c9e9fc11dc028bd1747788f2b417f3936fc59bjvr for j in range(0, len(mask), 8): 41295c9e9fc11dc028bd1747788f2b417f3936fc59bjvr maskBytes = maskBytes + chr(binary2num(mask[j:j+8])) 41395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(maskBytes) 41495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr i = i + 1 41595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr else: 41695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr program.append(token) 4174e5af60930726d06a58a30bae45bb27ae50aea77jvr else: 4184e5af60930726d06a58a30bae45bb27ae50aea77jvr program.append(token) 4194e5af60930726d06a58a30bae45bb27ae50aea77jvr self.setProgram(program) 4207842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4227842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1Operators = [ 4237842e56b97ce677b83bdab09cda48bc2d89ac75aJust# opcode name 4247842e56b97ce677b83bdab09cda48bc2d89ac75aJust (1, 'hstem'), 4257842e56b97ce677b83bdab09cda48bc2d89ac75aJust (3, 'vstem'), 4267842e56b97ce677b83bdab09cda48bc2d89ac75aJust (4, 'vmoveto'), 4277842e56b97ce677b83bdab09cda48bc2d89ac75aJust (5, 'rlineto'), 4287842e56b97ce677b83bdab09cda48bc2d89ac75aJust (6, 'hlineto'), 4297842e56b97ce677b83bdab09cda48bc2d89ac75aJust (7, 'vlineto'), 4307842e56b97ce677b83bdab09cda48bc2d89ac75aJust (8, 'rrcurveto'), 4317842e56b97ce677b83bdab09cda48bc2d89ac75aJust (9, 'closepath'), 4327842e56b97ce677b83bdab09cda48bc2d89ac75aJust (10, 'callsubr'), 4337842e56b97ce677b83bdab09cda48bc2d89ac75aJust (11, 'return'), 4347842e56b97ce677b83bdab09cda48bc2d89ac75aJust (13, 'hsbw'), 4357842e56b97ce677b83bdab09cda48bc2d89ac75aJust (14, 'endchar'), 4367842e56b97ce677b83bdab09cda48bc2d89ac75aJust (21, 'rmoveto'), 4377842e56b97ce677b83bdab09cda48bc2d89ac75aJust (22, 'hmoveto'), 4387842e56b97ce677b83bdab09cda48bc2d89ac75aJust (30, 'vhcurveto'), 4397842e56b97ce677b83bdab09cda48bc2d89ac75aJust (31, 'hvcurveto'), 4407842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 0), 'dotsection'), 4417842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 1), 'vstem3'), 4427842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 2), 'hstem3'), 4437842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 6), 'seac'), 4447842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 7), 'sbw'), 4457842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 12), 'div'), 4467842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 16), 'callothersubr'), 4477842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 17), 'pop'), 4487842e56b97ce677b83bdab09cda48bc2d89ac75aJust ((12, 33), 'setcurrentpoint'), 4497842e56b97ce677b83bdab09cda48bc2d89ac75aJust] 4507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4517842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1CharString(T2CharString): 4527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4537842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = t1OperandEncoding 454455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr operators, opcodes = buildOperatorDict(t1Operators) 4557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 456489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, bytecode=None, program=None, subrs=None): 457489d76a340845361def6af9ab7d9152f8e66f417jvr if program is None: 458489d76a340845361def6af9ab7d9152f8e66f417jvr program = [] 459489d76a340845361def6af9ab7d9152f8e66f417jvr self.bytecode = bytecode 460489d76a340845361def6af9ab7d9152f8e66f417jvr self.program = program 461489d76a340845361def6af9ab7d9152f8e66f417jvr self.subrs = subrs 462489d76a340845361def6af9ab7d9152f8e66f417jvr 46395c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getIntEncoder(self): 46495c9e9fc11dc028bd1747788f2b417f3936fc59bjvr return encodeIntT1 46595c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 46695c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def getFixedEncoder(self): 46795c9e9fc11dc028bd1747788f2b417f3936fc59bjvr def encodeFixed(value): 46895c9e9fc11dc028bd1747788f2b417f3936fc59bjvr raise TypeError("Type 1 charstrings don't support floating point operands") 46995c9e9fc11dc028bd1747788f2b417f3936fc59bjvr 4707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self): 471b68a700595ff730c29d3d4b7abf92ee287678745Just if self.program is not None: 4727842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 4737842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 4747842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 4757842e56b97ce677b83bdab09cda48bc2d89ac75aJust while 1: 4767842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = self.getToken(index) 4777842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 4787842e56b97ce677b83bdab09cda48bc2d89ac75aJust break 4797842e56b97ce677b83bdab09cda48bc2d89ac75aJust program.append(token) 4807842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.setProgram(program) 4817842e56b97ce677b83bdab09cda48bc2d89ac75aJust 482489d76a340845361def6af9ab7d9152f8e66f417jvr def draw(self, pen): 483489d76a340845361def6af9ab7d9152f8e66f417jvr extractor = T1OutlineExtractor(pen, self.subrs) 484489d76a340845361def6af9ab7d9152f8e66f417jvr extractor.execute(self) 485489d76a340845361def6af9ab7d9152f8e66f417jvr self.width = extractor.width 486489d76a340845361def6af9ab7d9152f8e66f417jvr 4877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4887842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass SimpleT2Decompiler: 4897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4907842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, localSubrs, globalSubrs): 4917842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localSubrs = localSubrs 4927842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.localBias = calcSubrBias(localSubrs) 4937842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalSubrs = globalSubrs 4947842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.globalBias = calcSubrBias(globalSubrs) 4957842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 4967842e56b97ce677b83bdab09cda48bc2d89ac75aJust 4977842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 4987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack = [] 4997842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack = [] 5007842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = 0 5017842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = 0 5027842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def execute(self, charString): 5047842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.callingStack.append(charString) 5057842e56b97ce677b83bdab09cda48bc2d89ac75aJust needsDecompilation = charString.needsDecompilation() 5067842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5077842e56b97ce677b83bdab09cda48bc2d89ac75aJust program = [] 5087842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = program.append 5097842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5107842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram = lambda x: None 5117842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack = self.operandStack.append 5127842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 5137842e56b97ce677b83bdab09cda48bc2d89ac75aJust while 1: 5147842e56b97ce677b83bdab09cda48bc2d89ac75aJust token, isOperator, index = charString.getToken(index) 5157842e56b97ce677b83bdab09cda48bc2d89ac75aJust if token is None: 5167842e56b97ce677b83bdab09cda48bc2d89ac75aJust break # we're done! 5177842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(token) 5187842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isOperator: 5197842e56b97ce677b83bdab09cda48bc2d89ac75aJust handlerName = "op_" + token 5207842e56b97ce677b83bdab09cda48bc2d89ac75aJust if hasattr(self, handlerName): 5217842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, handlerName) 5227842e56b97ce677b83bdab09cda48bc2d89ac75aJust rv = handler(index) 5237842e56b97ce677b83bdab09cda48bc2d89ac75aJust if rv: 5247842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = rv 5257842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToProgram(hintMaskBytes) 5267842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5277842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() 5287842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 5297842e56b97ce677b83bdab09cda48bc2d89ac75aJust pushToStack(token) 5307842e56b97ce677b83bdab09cda48bc2d89ac75aJust if needsDecompilation: 5319920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program, "illegal CharString: decompiled to empty program" 5329920ad5286b6e61d67f07f908107d65f7fa817acjvr assert program[-1] in ("endchar", "return", "callsubr", "callgsubr", 5339920ad5286b6e61d67f07f908107d65f7fa817acjvr "seac"), "illegal CharString" 5347842e56b97ce677b83bdab09cda48bc2d89ac75aJust charString.setProgram(program) 5357842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.callingStack[-1] 5367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 5387842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.operandStack[-1] 5397842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.operandStack[-1] 5407842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 5417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5427842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 5437842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack[:] 5447842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack[:] = [] 5457842e56b97ce677b83bdab09cda48bc2d89ac75aJust return stack 5467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5477842e56b97ce677b83bdab09cda48bc2d89ac75aJust def push(self, value): 5487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.operandStack.append(value) 5497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_return(self, index): 5517842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.operandStack: 5527842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5547842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 5557842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass 5567099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5577099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr def op_ignore(self, index): 5587099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr pass 5597099f4c0f9fbaf1a5c811113fdfd2404dee04361jvr 5607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 5617842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5627842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.localSubrs[subrIndex+self.localBias] 5637842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5647842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5657842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callgsubr(self, index): 5667842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 5677842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.globalSubrs[subrIndex+self.globalBias] 5687842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 5697842e56b97ce677b83bdab09cda48bc2d89ac75aJust 570586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_hstem(self, index): 571586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 572586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstem(self, index): 573586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstemhm(self, index): 5757842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 576586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr def op_vstemhm(self, index): 577586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr self.countHints() 5787842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5797842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hintmask(self, index): 5807842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.hintMaskBytes: 5817842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.countHints() 5827842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintMaskBytes = (self.hintCount + 7) / 8 5837842e56b97ce677b83bdab09cda48bc2d89ac75aJust hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes) 5847842e56b97ce677b83bdab09cda48bc2d89ac75aJust return hintMaskBytes, index 5857842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5867842e56b97ce677b83bdab09cda48bc2d89ac75aJust op_cntrmask = op_hintmask 5877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5887842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 5897842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 5907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = self.hintCount + len(args) / 2 5917842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 5937842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T2OutlineExtractor(SimpleT2Decompiler): 5947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 595489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, localSubrs, globalSubrs, nominalWidthX, defaultWidthX): 5967842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs) 597489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 5987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.nominalWidthX = nominalWidthX 5997842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.defaultWidthX = defaultWidthX 6007842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6017842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 6027842e56b97ce677b83bdab09cda48bc2d89ac75aJust SimpleT2Decompiler.reset(self) 6037842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hints = [] 6047842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 0 6057842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 606489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = (0, 0) 607489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6087842e56b97ce677b83bdab09cda48bc2d89ac75aJust 609489d76a340845361def6af9ab7d9152f8e66f417jvr def _nextPoint(self, point): 610489d76a340845361def6af9ab7d9152f8e66f417jvr x, y = self.currentPoint 611489d76a340845361def6af9ab7d9152f8e66f417jvr point = x + point[0], y + point[1] 612489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = point 613489d76a340845361def6af9ab7d9152f8e66f417jvr return point 6147842e56b97ce677b83bdab09cda48bc2d89ac75aJust 615489d76a340845361def6af9ab7d9152f8e66f417jvr def rMoveTo(self, point): 616489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.moveTo(self._nextPoint(point)) 617489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 1 618489d76a340845361def6af9ab7d9152f8e66f417jvr 619489d76a340845361def6af9ab7d9152f8e66f417jvr def rLineTo(self, point): 620489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 621489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 622489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.lineTo(self._nextPoint(point)) 623489d76a340845361def6af9ab7d9152f8e66f417jvr 624489d76a340845361def6af9ab7d9152f8e66f417jvr def rCurveTo(self, pt1, pt2, pt3): 625489d76a340845361def6af9ab7d9152f8e66f417jvr if not self.sawMoveTo: 626489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, 0)) 627489d76a340845361def6af9ab7d9152f8e66f417jvr nextPoint = self._nextPoint 628489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.curveTo(nextPoint(pt1), nextPoint(pt2), nextPoint(pt3)) 6297842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6307842e56b97ce677b83bdab09cda48bc2d89ac75aJust def closePath(self): 631489d76a340845361def6af9ab7d9152f8e66f417jvr if self.sawMoveTo: 632489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.closePath() 633489d76a340845361def6af9ab7d9152f8e66f417jvr self.sawMoveTo = 0 6347842e56b97ce677b83bdab09cda48bc2d89ac75aJust 635d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 636d3ee2d4319742ec61cb299665ccba66c139e4834jvr # In T2 there are no open paths, so always do a closePath when 637d3ee2d4319742ec61cb299665ccba66c139e4834jvr # finishing a sub path. 638d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.closePath() 639d3ee2d4319742ec61cb299665ccba66c139e4834jvr 6407842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 6417842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 6427842e56b97ce677b83bdab09cda48bc2d89ac75aJust if not self.gotWidth: 6437842e56b97ce677b83bdab09cda48bc2d89ac75aJust if evenOdd ^ (len(args) % 2): 6447842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.nominalWidthX + args[0] 6457842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 6467842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 6477842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = self.defaultWidthX 6487842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.gotWidth = 1 6497842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 6507842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def countHints(self): 6527842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popallWidth() 6537842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.hintCount = self.hintCount + len(args) / 2 6547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6557842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6567842e56b97ce677b83bdab09cda48bc2d89ac75aJust # hint operators 6577842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 658586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstem(self, index): 659586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 660586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstem(self, index): 661586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 662586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_hstemhm(self, index): 663586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 664586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr #def op_vstemhm(self, index): 665586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr # self.countHints() 6667842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_hintmask(self, index): 6677842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 6687842e56b97ce677b83bdab09cda48bc2d89ac75aJust #def op_cntrmask(self, index): 6697842e56b97ce677b83bdab09cda48bc2d89ac75aJust # self.countHints() 6707842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6717842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6727842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, moveto 6737842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 675d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 676489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popallWidth()) 6777842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 678d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 679489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popallWidth(1)[0], 0)) 6807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 681d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 682489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popallWidth(1)[0])) 6837842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 684d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 685382df6c42a7a6aecb690e07c6338e19f038f0543jvr args = self.popallWidth() 686382df6c42a7a6aecb690e07c6338e19f038f0543jvr if args: 687382df6c42a7a6aecb690e07c6338e19f038f0543jvr from fontTools.encodings.StandardEncoding import StandardEncoding 688382df6c42a7a6aecb690e07c6338e19f038f0543jvr # endchar can do seac accent bulding; The T2 spec says it's deprecated, 689382df6c42a7a6aecb690e07c6338e19f038f0543jvr # but recent software that shall remain nameless does output it. 690382df6c42a7a6aecb690e07c6338e19f038f0543jvr adx, ady, bchar, achar = args 691382df6c42a7a6aecb690e07c6338e19f038f0543jvr baseGlyph = StandardEncoding[bchar] 692382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 693382df6c42a7a6aecb690e07c6338e19f038f0543jvr accentGlyph = StandardEncoding[achar] 694382df6c42a7a6aecb690e07c6338e19f038f0543jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 6957842e56b97ce677b83bdab09cda48bc2d89ac75aJust 6967842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6977842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, lines 6987842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 6997842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlineto(self, index): 7007842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7017842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 2): 7027842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = args[i:i+2] 703489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 7047842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7057842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hlineto(self, index): 7067842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(1) 7077842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vlineto(self, index): 7087842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.alternatingLineto(0) 7097842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7107842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7117842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, curves 7127842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7137842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rrcurveto(self, index): 7147842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ rrcurveto""" 7157842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7167842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 6): 7177842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dya, dxb, dyb, dxc, dyc, = args[i:i+6] 718489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dya), (dxb, dyb), (dxc, dyc)) 7197842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7207842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rcurveline(self, index): 7217842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline""" 7227842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7237842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args)-2, 6): 7247842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[i:i+6] 725489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 726489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(args[-2:]) 7277842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7287842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rlinecurve(self, index): 7297842e56b97ce677b83bdab09cda48bc2d89ac75aJust """{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve""" 7307842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7317842e56b97ce677b83bdab09cda48bc2d89ac75aJust lineArgs = args[:-6] 7327842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(lineArgs), 2): 733489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(lineArgs[i:i+2]) 7347842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxb, dyb, dxc, dyc, dxd, dyd = args[-6:] 735489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxb, dyb), (dxc, dyc), (dxd, dyd)) 7367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vvcurveto(self, index): 7387842e56b97ce677b83bdab09cda48bc2d89ac75aJust "dx1? {dya dxb dyb dyc}+ vvcurveto" 7397842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7407842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7417842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = args[0] 7427842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7437842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7447842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7457842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 7467842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dyc = args[i:i+4] 747489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dx1, dya), (dxb, dyb), (0, dyc)) 7487842e56b97ce677b83bdab09cda48bc2d89ac75aJust dx1 = 0 7497842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hhcurveto(self, index): 7517842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1? {dxa dxb dyb dxc}+ hhcurveto""" 7527842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7537842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) % 2: 7547842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = args[0] 7557842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[1:] 7567842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 7577842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 7587842e56b97ce677b83bdab09cda48bc2d89ac75aJust for i in range(0, len(args), 4): 7597842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dxc = args[i:i+4] 760489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, dy1), (dxb, dyb), (dxc, 0)) 7617842e56b97ce677b83bdab09cda48bc2d89ac75aJust dy1 = 0 7627842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vhcurveto(self, index): 7647842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30) 7657842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto 7667842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 7677842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7687842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 7697842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 7707842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 7717842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 7727842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7737842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hvcurveto(self, index): 7747842e56b97ce677b83bdab09cda48bc2d89ac75aJust """dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf? 7757842e56b97ce677b83bdab09cda48bc2d89ac75aJust {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf? 7767842e56b97ce677b83bdab09cda48bc2d89ac75aJust """ 7777842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 7787842e56b97ce677b83bdab09cda48bc2d89ac75aJust while args: 7797842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.hcurveto(args) 7807842e56b97ce677b83bdab09cda48bc2d89ac75aJust if args: 7817842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.vcurveto(args) 7827842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7837842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7847842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors, flex 7857842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 7867842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex(self, index): 7878b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dx2, dy2, dx3, dx4, dx5, dx6 = self.popall() 788d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy1 = dy3 = dy4 = dy6 = 0 789d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy5 = -dy2 7908b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 7918b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 7927842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex(self, index): 7938b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, dx6, dy6, fd = self.popall() 7948b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 7958b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 7967842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hflex1(self, index): 7978b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dx4, dx5, dy5, dx6 = self.popall() 798d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy3 = dy4 = 0 799d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -(dy1 + dy2 + dy3 + dy4 + dy5) 800d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr 8018b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8028b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8037842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_flex1(self, index): 8048b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx1, dy1, dx2, dy2, dx3, dy3, dx4, dy4, dx5, dy5, d6 = self.popall() 8058b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx = dx1 + dx2 + dx3 + dx4 + dx5 8068b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy = dy1 + dy2 + dy3 + dy4 + dy5 8078b8b44904e116287ca0eb587f9c5b21296fb3123jvr if abs(dx) > abs(dy): 8088b8b44904e116287ca0eb587f9c5b21296fb3123jvr dx6 = d6 809d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dy6 = -dy 8108b8b44904e116287ca0eb587f9c5b21296fb3123jvr else: 811d4561ec1b4ac67b2c29d0db13913431a3d2fbd50jvr dx6 = -dx 8128b8b44904e116287ca0eb587f9c5b21296fb3123jvr dy6 = d6 8138b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx1, dy1), (dx2, dy2), (dx3, dy3)) 8148b8b44904e116287ca0eb587f9c5b21296fb3123jvr self.rCurveTo((dx4, dy4), (dx5, dy5), (dx6, dy6)) 8157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8167842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8177842e56b97ce677b83bdab09cda48bc2d89ac75aJust # MultipleMaster. Well... 8187842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8197842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_blend(self, index): 8208b8b44904e116287ca0eb587f9c5b21296fb3123jvr args = self.popall() 8217842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8227842e56b97ce677b83bdab09cda48bc2d89ac75aJust # misc 8237842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_and(self, index): 8248b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8257842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_or(self, index): 8268b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8277842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_not(self, index): 8288b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8297842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_store(self, index): 8308b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8317842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_abs(self, index): 8328b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8337842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_add(self, index): 8348b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8357842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sub(self, index): 8368b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_div(self, index): 8387842e56b97ce677b83bdab09cda48bc2d89ac75aJust num2 = self.pop() 8397842e56b97ce677b83bdab09cda48bc2d89ac75aJust num1 = self.pop() 8407842e56b97ce677b83bdab09cda48bc2d89ac75aJust d1 = num1/num2 8417842e56b97ce677b83bdab09cda48bc2d89ac75aJust d2 = float(num1)/num2 8427842e56b97ce677b83bdab09cda48bc2d89ac75aJust if d1 == d2: 8437842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d1) 8447842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8457842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(d2) 8467842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_load(self, index): 8478b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8487842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_neg(self, index): 8498b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_eq(self, index): 8518b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8527842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_drop(self, index): 8538b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8547842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_put(self, index): 8558b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8567842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_get(self, index): 8578b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_ifelse(self, index): 8598b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8607842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_random(self, index): 8618b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8627842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_mul(self, index): 8638b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8647842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sqrt(self, index): 8658b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8667842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dup(self, index): 8678b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8687842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_exch(self, index): 8698b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8707842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_index(self, index): 8718b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8727842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_roll(self, index): 8738b8b44904e116287ca0eb587f9c5b21296fb3123jvr raise NotImplementedError 8747842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8757842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8767842e56b97ce677b83bdab09cda48bc2d89ac75aJust # miscelaneous helpers 8777842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 8787842e56b97ce677b83bdab09cda48bc2d89ac75aJust def alternatingLineto(self, isHorizontal): 8797842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 8807842e56b97ce677b83bdab09cda48bc2d89ac75aJust for arg in args: 8817842e56b97ce677b83bdab09cda48bc2d89ac75aJust if isHorizontal: 8827842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (arg, 0) 8837842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8847842e56b97ce677b83bdab09cda48bc2d89ac75aJust point = (0, arg) 885489d76a340845361def6af9ab7d9152f8e66f417jvr self.rLineTo(point) 8867842e56b97ce677b83bdab09cda48bc2d89ac75aJust isHorizontal = not isHorizontal 8877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8887842e56b97ce677b83bdab09cda48bc2d89ac75aJust def vcurveto(self, args): 8897842e56b97ce677b83bdab09cda48bc2d89ac75aJust dya, dxb, dyb, dxc = args[:4] 8907842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 8917842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 8927842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = args[0] 8937842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 8947842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 8957842e56b97ce677b83bdab09cda48bc2d89ac75aJust dyc = 0 896489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((0, dya), (dxb, dyb), (dxc, dyc)) 8977842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 8987842e56b97ce677b83bdab09cda48bc2d89ac75aJust 8997842e56b97ce677b83bdab09cda48bc2d89ac75aJust def hcurveto(self, args): 9007842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxa, dxb, dyb, dyc = args[:4] 9017842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = args[4:] 9027842e56b97ce677b83bdab09cda48bc2d89ac75aJust if len(args) == 1: 9037842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = args[0] 9047842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = [] 9057842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 9067842e56b97ce677b83bdab09cda48bc2d89ac75aJust dxc = 0 907489d76a340845361def6af9ab7d9152f8e66f417jvr self.rCurveTo((dxa, 0), (dxb, dyb), (dxc, dyc)) 9087842e56b97ce677b83bdab09cda48bc2d89ac75aJust return args 9097842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9107842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9117842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1OutlineExtractor(T2OutlineExtractor): 9127842e56b97ce677b83bdab09cda48bc2d89ac75aJust 913489d76a340845361def6af9ab7d9152f8e66f417jvr def __init__(self, pen, subrs): 914489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen = pen 9157842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.subrs = subrs 9167842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.reset() 9177842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9187842e56b97ce677b83bdab09cda48bc2d89ac75aJust def reset(self): 9197842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 9207842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = 0 9217842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = 0 9227842e56b97ce677b83bdab09cda48bc2d89ac75aJust T2OutlineExtractor.reset(self) 9237842e56b97ce677b83bdab09cda48bc2d89ac75aJust 924d3ee2d4319742ec61cb299665ccba66c139e4834jvr def endPath(self): 925d3ee2d4319742ec61cb299665ccba66c139e4834jvr if self.sawMoveTo: 926d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.pen.endPath() 927d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.sawMoveTo = 0 928d3ee2d4319742ec61cb299665ccba66c139e4834jvr 9297842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popallWidth(self, evenOdd=0): 9307842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 9317842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9327842e56b97ce677b83bdab09cda48bc2d89ac75aJust def exch(self): 9337842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack = self.operandStack 9347842e56b97ce677b83bdab09cda48bc2d89ac75aJust stack[-1], stack[-2] = stack[-2], stack[-1] 9357842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9367842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9377842e56b97ce677b83bdab09cda48bc2d89ac75aJust # path constructors 9387842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9397842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_rmoveto(self, index): 940d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 9417842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9427842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 943489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo(self.popall()) 9447842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hmoveto(self, index): 9457842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9467842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9477842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9487842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 949d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 950489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((self.popall()[0], 0)) 9517842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vmoveto(self, index): 9527842e56b97ce677b83bdab09cda48bc2d89ac75aJust if self.flexing: 9537842e56b97ce677b83bdab09cda48bc2d89ac75aJust # We must add a parameter to the stack if we are flexing 9547842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(0) 9557842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.exch() 9567842e56b97ce677b83bdab09cda48bc2d89ac75aJust return 957d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 958489d76a340845361def6af9ab7d9152f8e66f417jvr self.rMoveTo((0, self.popall()[0])) 9597842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_closepath(self, index): 9607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.closePath() 9617842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_setcurrentpoint(self, index): 9627842e56b97ce677b83bdab09cda48bc2d89ac75aJust args = self.popall() 9637842e56b97ce677b83bdab09cda48bc2d89ac75aJust x, y = args 964489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = x, y 9657842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9667842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_endchar(self, index): 967d3ee2d4319742ec61cb299665ccba66c139e4834jvr self.endPath() 9687842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9697842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hsbw(self, index): 9707842e56b97ce677b83bdab09cda48bc2d89ac75aJust sbx, wx = self.popall() 9717842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.width = wx 9727842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.sbx = sbx 973489d76a340845361def6af9ab7d9152f8e66f417jvr self.currentPoint = sbx, self.currentPoint[1] 9747842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_sbw(self, index): 9757842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 9767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9777842e56b97ce677b83bdab09cda48bc2d89ac75aJust # 9787842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callsubr(self, index): 9797842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 9807842e56b97ce677b83bdab09cda48bc2d89ac75aJust subr = self.subrs[subrIndex] 9817842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.execute(subr) 9827842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_callothersubr(self, index): 9837842e56b97ce677b83bdab09cda48bc2d89ac75aJust subrIndex = self.pop() 9847842e56b97ce677b83bdab09cda48bc2d89ac75aJust nArgs = self.pop() 9857842e56b97ce677b83bdab09cda48bc2d89ac75aJust #print nArgs, subrIndex, "callothersubr" 9867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if subrIndex == 0 and nArgs == 3: 9877842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.doFlex() 9887842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 0 9897842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif subrIndex == 1 and nArgs == 0: 9907842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.flexing = 1 9917842e56b97ce677b83bdab09cda48bc2d89ac75aJust # ignore... 9927842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_pop(self, index): 9937842e56b97ce677b83bdab09cda48bc2d89ac75aJust pass # ignore... 9947842e56b97ce677b83bdab09cda48bc2d89ac75aJust 9957842e56b97ce677b83bdab09cda48bc2d89ac75aJust def doFlex(self): 9967842e56b97ce677b83bdab09cda48bc2d89ac75aJust finaly = self.pop() 9977842e56b97ce677b83bdab09cda48bc2d89ac75aJust finalx = self.pop() 9987842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.pop() # flex height is unused 9997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10007842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3y = self.pop() 10017842e56b97ce677b83bdab09cda48bc2d89ac75aJust p3x = self.pop() 10027842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4y = self.pop() 10037842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp4x = self.pop() 10047842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3y = self.pop() 10057842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp3x = self.pop() 10067842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2y = self.pop() 10077842e56b97ce677b83bdab09cda48bc2d89ac75aJust p2x = self.pop() 10087842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2y = self.pop() 10097842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp2x = self.pop() 10107842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1y = self.pop() 10117842e56b97ce677b83bdab09cda48bc2d89ac75aJust bcp1x = self.pop() 10127842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpy = self.pop() 10137842e56b97ce677b83bdab09cda48bc2d89ac75aJust rpx = self.pop() 10147842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10157842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10167842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1x+rpx) 10177842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp1y+rpy) 10187842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2x) 10197842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp2y) 10207842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2x) 10217842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p2y) 10227842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10237842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10247842e56b97ce677b83bdab09cda48bc2d89ac75aJust # call rrcurveto 10257842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3x) 10267842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp3y) 10277842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4x) 10287842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(bcp4y) 10297842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3x) 10307842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(p3y) 10317842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.op_rrcurveto(None) 10327842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10337842e56b97ce677b83bdab09cda48bc2d89ac75aJust # Push back final coords so subr 0 can find them 10347842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finalx) 10357842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.push(finaly) 10367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10377842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_dotsection(self, index): 10387842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10397842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_hstem3(self, index): 10407842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10417842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_seac(self, index): 10427842e56b97ce677b83bdab09cda48bc2d89ac75aJust "asb adx ady bchar achar seac" 1043489d76a340845361def6af9ab7d9152f8e66f417jvr from fontTools.encodings.StandardEncoding import StandardEncoding 1044489d76a340845361def6af9ab7d9152f8e66f417jvr asb, adx, ady, bchar, achar = self.popall() 1045489d76a340845361def6af9ab7d9152f8e66f417jvr baseGlyph = StandardEncoding[bchar] 1046489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(baseGlyph, (1, 0, 0, 1, 0, 0)) 1047489d76a340845361def6af9ab7d9152f8e66f417jvr accentGlyph = StandardEncoding[achar] 1048489d76a340845361def6af9ab7d9152f8e66f417jvr adx = adx + self.sbx - asb # seac weirdness 1049489d76a340845361def6af9ab7d9152f8e66f417jvr self.pen.addComponent(accentGlyph, (1, 0, 0, 1, adx, ady)) 10507842e56b97ce677b83bdab09cda48bc2d89ac75aJust def op_vstem3(self, index): 10517842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.popall() # XXX 10527842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10537842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1054f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass DictDecompiler(ByteCodeBase): 10557842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10567842e56b97ce677b83bdab09cda48bc2d89ac75aJust operandEncoding = cffDictOperandEncoding 10577842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10587842e56b97ce677b83bdab09cda48bc2d89ac75aJust def __init__(self, strings): 10597842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.stack = [] 10607842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.strings = strings 10617842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict = {} 10627842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10637842e56b97ce677b83bdab09cda48bc2d89ac75aJust def getDict(self): 10647842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert len(self.stack) == 0, "non-empty stack" 10657842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.dict 10667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10677842e56b97ce677b83bdab09cda48bc2d89ac75aJust def decompile(self, data): 10687842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = 0 10697842e56b97ce677b83bdab09cda48bc2d89ac75aJust lenData = len(data) 10707842e56b97ce677b83bdab09cda48bc2d89ac75aJust push = self.stack.append 10717842e56b97ce677b83bdab09cda48bc2d89ac75aJust while index < lenData: 10727842e56b97ce677b83bdab09cda48bc2d89ac75aJust b0 = ord(data[index]) 10737842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index + 1 10747842e56b97ce677b83bdab09cda48bc2d89ac75aJust code = self.operandEncoding[b0] 10757842e56b97ce677b83bdab09cda48bc2d89ac75aJust handler = getattr(self, code) 10767842e56b97ce677b83bdab09cda48bc2d89ac75aJust value, index = handler(b0, data, index) 10777842e56b97ce677b83bdab09cda48bc2d89ac75aJust if value is not None: 10787842e56b97ce677b83bdab09cda48bc2d89ac75aJust push(value) 10797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10807842e56b97ce677b83bdab09cda48bc2d89ac75aJust def pop(self): 10817842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = self.stack[-1] 10827842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[-1] 10837842e56b97ce677b83bdab09cda48bc2d89ac75aJust return value 10847842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10857842e56b97ce677b83bdab09cda48bc2d89ac75aJust def popall(self): 10867842e56b97ce677b83bdab09cda48bc2d89ac75aJust all = self.stack[:] 10877842e56b97ce677b83bdab09cda48bc2d89ac75aJust del self.stack[:] 10887842e56b97ce677b83bdab09cda48bc2d89ac75aJust return all 10897842e56b97ce677b83bdab09cda48bc2d89ac75aJust 10907842e56b97ce677b83bdab09cda48bc2d89ac75aJust def do_operator(self, b0, data, index): 10917842e56b97ce677b83bdab09cda48bc2d89ac75aJust if b0 == 12: 10927842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = (b0, ord(data[index])) 10937842e56b97ce677b83bdab09cda48bc2d89ac75aJust index = index+1 10947842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 10957842e56b97ce677b83bdab09cda48bc2d89ac75aJust op = b0 10967842e56b97ce677b83bdab09cda48bc2d89ac75aJust operator, argType = self.operators[op] 10977842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.handle_operator(operator, argType) 10987842e56b97ce677b83bdab09cda48bc2d89ac75aJust return None, index 10997842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11007842e56b97ce677b83bdab09cda48bc2d89ac75aJust def handle_operator(self, operator, argType): 11017842e56b97ce677b83bdab09cda48bc2d89ac75aJust if type(argType) == type(()): 11027842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = () 1103bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr for i in range(len(argType)-1, -1, -1): 1104bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr arg = argType[i] 11057842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + arg) 11067842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = (arghandler(operator),) + value 11077842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11087842e56b97ce677b83bdab09cda48bc2d89ac75aJust arghandler = getattr(self, "arg_" + argType) 11097842e56b97ce677b83bdab09cda48bc2d89ac75aJust value = arghandler(operator) 11107842e56b97ce677b83bdab09cda48bc2d89ac75aJust self.dict[operator] = value 11117842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11127842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_number(self, name): 11137842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.pop() 11147842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_SID(self, name): 11157842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.strings[self.pop()] 11167842e56b97ce677b83bdab09cda48bc2d89ac75aJust def arg_array(self, name): 11177842e56b97ce677b83bdab09cda48bc2d89ac75aJust return self.popall() 1118dc18128aa9b3f6b98a623c294ac615195159025ejvr def arg_delta(self, name): 1119dc18128aa9b3f6b98a623c294ac615195159025ejvr out = [] 1120dc18128aa9b3f6b98a623c294ac615195159025ejvr current = 0 1121dc18128aa9b3f6b98a623c294ac615195159025ejvr for v in self.popall(): 11226f03a58f59fb20662602e3d4bb153d7db2f778d3jvr current = current + v 1123dc18128aa9b3f6b98a623c294ac615195159025ejvr out.append(current) 1124dc18128aa9b3f6b98a623c294ac615195159025ejvr return out 11257842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11267842e56b97ce677b83bdab09cda48bc2d89ac75aJust 11277842e56b97ce677b83bdab09cda48bc2d89ac75aJustdef calcSubrBias(subrs): 11287842e56b97ce677b83bdab09cda48bc2d89ac75aJust nSubrs = len(subrs) 11297842e56b97ce677b83bdab09cda48bc2d89ac75aJust if nSubrs < 1240: 11307842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 107 11317842e56b97ce677b83bdab09cda48bc2d89ac75aJust elif nSubrs < 33900: 11327842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 1131 11337842e56b97ce677b83bdab09cda48bc2d89ac75aJust else: 11347842e56b97ce677b83bdab09cda48bc2d89ac75aJust bias = 32768 11357842e56b97ce677b83bdab09cda48bc2d89ac75aJust return bias 1136