psCharStrings.py revision 4e5af60930726d06a58a30bae45bb27ae50aea77
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"
237842e56b97ce677b83bdab09cda48bc2d89ac75aJust
247842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding = t2OperandEncoding[:]
257842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[29] = "read_longInt"
267842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[30] = "read_realNumber"
277842e56b97ce677b83bdab09cda48bc2d89ac75aJustcffDictOperandEncoding[255] = "reserved"
287842e56b97ce677b83bdab09cda48bc2d89ac75aJust
297842e56b97ce677b83bdab09cda48bc2d89ac75aJust
307842e56b97ce677b83bdab09cda48bc2d89ac75aJustrealNibbles = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		'.', 'E', 'E-', None, '-']
32f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrrealNibblesDict = {}
33f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrfor _i in range(len(realNibbles)):
34f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	realNibblesDict[realNibbles[_i]] = _i
357842e56b97ce677b83bdab09cda48bc2d89ac75aJust
367842e56b97ce677b83bdab09cda48bc2d89ac75aJust
37f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass ByteCodeBase:
387842e56b97ce677b83bdab09cda48bc2d89ac75aJust
397842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_byte(self, b0, data, index):
407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return b0 - 139, index
417842e56b97ce677b83bdab09cda48bc2d89ac75aJust
427842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_smallInt1(self, b0, data, index):
437842e56b97ce677b83bdab09cda48bc2d89ac75aJust		b1 = ord(data[index])
447842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return (b0-247)*256 + b1 + 108, index+1
457842e56b97ce677b83bdab09cda48bc2d89ac75aJust
467842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_smallInt2(self, b0, data, index):
477842e56b97ce677b83bdab09cda48bc2d89ac75aJust		b1 = ord(data[index])
487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return -(b0-251)*256 - b1 - 108, index+1
497842e56b97ce677b83bdab09cda48bc2d89ac75aJust
507842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_shortInt(self, b0, data, index):
517842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bin = data[index] + data[index+1]
527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		value, = struct.unpack(">h", bin)
537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return value, index+2
547842e56b97ce677b83bdab09cda48bc2d89ac75aJust
557842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_longInt(self, b0, data, index):
567842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bin = data[index] + data[index+1] + data[index+2] + data[index+3]
577842e56b97ce677b83bdab09cda48bc2d89ac75aJust		value, = struct.unpack(">l", bin)
587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return value, index+4
597842e56b97ce677b83bdab09cda48bc2d89ac75aJust
607842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def read_realNumber(self, b0, data, index):
617842e56b97ce677b83bdab09cda48bc2d89ac75aJust		number = ''
627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while 1:
637842e56b97ce677b83bdab09cda48bc2d89ac75aJust			b = ord(data[index])
647842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index + 1
657842e56b97ce677b83bdab09cda48bc2d89ac75aJust			nibble0 = (b & 0xf0) >> 4
667842e56b97ce677b83bdab09cda48bc2d89ac75aJust			nibble1 = b & 0x0f
677842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if nibble0 == 0xf:
687842e56b97ce677b83bdab09cda48bc2d89ac75aJust				break
697842e56b97ce677b83bdab09cda48bc2d89ac75aJust			number = number + realNibbles[nibble0]
707842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if nibble1 == 0xf:
717842e56b97ce677b83bdab09cda48bc2d89ac75aJust				break
727842e56b97ce677b83bdab09cda48bc2d89ac75aJust			number = number + realNibbles[nibble1]
73455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		return float(number), index
747842e56b97ce677b83bdab09cda48bc2d89ac75aJust
757842e56b97ce677b83bdab09cda48bc2d89ac75aJust
76dbc2c173b35360386c907a3c70cb931ae4c3fac9jvrdef buildOperatorDict(operatorList):
77455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	oper = {}
78455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	opc = {}
797842e56b97ce677b83bdab09cda48bc2d89ac75aJust	for item in operatorList:
807842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if len(item) == 2:
81455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			oper[item[0]] = item[1]
82455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		else:
83455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			oper[item[0]] = item[1:]
84455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		if type(item[0]) == types.TupleType:
85455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			opc[item[1]] = item[0]
867842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
87455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			opc[item[1]] = (item[0],)
88455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	return oper, opc
897842e56b97ce677b83bdab09cda48bc2d89ac75aJust
907842e56b97ce677b83bdab09cda48bc2d89ac75aJust
917842e56b97ce677b83bdab09cda48bc2d89ac75aJustt2Operators = [
927842e56b97ce677b83bdab09cda48bc2d89ac75aJust#	opcode     name
937842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(1,        'hstem'),
947842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(3,        'vstem'),
957842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(4,        'vmoveto'),
967842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(5,        'rlineto'),
977842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(6,        'hlineto'),
987842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(7,        'vlineto'),
997842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(8,        'rrcurveto'),
1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(10,       'callsubr'),
1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(11,       'return'),
1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(14,       'endchar'),
1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(16,       'blend'),
1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(18,       'hstemhm'),
1057842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(19,       'hintmask'),
1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(20,       'cntrmask'),
1077842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(21,       'rmoveto'),
1087842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(22,       'hmoveto'),
1097842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(23,       'vstemhm'),
1107842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(24,       'rcurveline'),
1117842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(25,       'rlinecurve'),
1127842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(26,       'vvcurveto'),
1137842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(27,       'hhcurveto'),
1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust#	(28,       'shortint'),  # not really an operator
1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(29,       'callgsubr'),
1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(30,       'vhcurveto'),
1177842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(31,       'hvcurveto'),
1187842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 3),  'and'),
1197842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 4),  'or'),
1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 5),  'not'),
1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 8),  'store'),
1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 9),  'abs'),
1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 10), 'add'),
1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 11), 'sub'),
1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 12), 'div'),
1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 13), 'load'),
1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 14), 'neg'),
1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 15), 'eq'),
1297842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 18), 'drop'),
1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 20), 'put'),
1317842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 21), 'get'),
1327842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 22), 'ifelse'),
1337842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 23), 'random'),
1347842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 24), 'mul'),
1357842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 26), 'sqrt'),
1367842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 27), 'dup'),
1377842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 28), 'exch'),
1387842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 29), 'index'),
1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 30), 'roll'),
1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 34), 'hflex'),
1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 35), 'flex'),
1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 36), 'hflex1'),
1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 37), 'flex1'),
1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust]
1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust
146f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
147f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef getIntEncoder(format):
148f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	fourByteOp = chr(255)
149f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	isT1 = 0
150f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	if format == "cff":
151f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		fourByteOp = chr(29)
152f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	elif format == "t1":
153f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		isT1 = 1
154f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	else:
155f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		assert format == "t2"
156f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
157f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	def encodeInt(value, fourByteOp=fourByteOp, isT1=isT1,
158f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			chr=chr, pack=struct.pack, unpack=struct.unpack):
159f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		if -107 <= value <= 107:
160f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			code = chr(value + 139)
161f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		elif 108 <= value <= 1131:
162f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			value = value - 108
163f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			code = chr((value >> 8) + 247) + chr(value & 0xFF)
164f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		elif -1131 <= value <= -108:
165f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			value = -value - 108
166f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			code = chr((value >> 8) + 251) + chr(value & 0xFF)
167f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		elif not isT1 and -32768 <= value <= 32767:
168f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			code = chr(28) + pack(">h", value)
169f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		else:
170f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			code = fourByteOp + pack(">l", value)
171f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		return code
172f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
173f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	return encodeInt
174f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
175f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
176f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntCFF = getIntEncoder("cff")
177f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT1 = getIntEncoder("t1")
178f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrencodeIntT2 = getIntEncoder("t2")
179f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
180f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrdef encodeFloat(f):
181f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	s = str(f).upper()
182f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	if s[:2] == "0.":
183f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		s = s[1:]
184f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	elif s[:3] == "-0.":
185f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		s = "-" + s[2:]
186f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	nibbles = []
187f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	while s:
188f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		c = s[0]
189f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		s = s[1:]
190f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		if c == "E" and s[:1] == "-":
191f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			s = s[1:]
192f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr			c = "E-"
193f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		nibbles.append(realNibblesDict[c])
194f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	nibbles.append(0xf)
195f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	if len(nibbles) % 2:
196f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		nibbles.append(0xf)
197f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	d = chr(30)
198f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	for i in range(0, len(nibbles), 2):
199f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		d = d + chr(nibbles[i] << 4 | nibbles[i+1])
200f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	return d
201f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
202f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
2034e5af60930726d06a58a30bae45bb27ae50aea77jvrclass CharStringCompileError(Exception): pass
2044e5af60930726d06a58a30bae45bb27ae50aea77jvr
2054e5af60930726d06a58a30bae45bb27ae50aea77jvr
206f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass T2CharString(ByteCodeBase):
2077842e56b97ce677b83bdab09cda48bc2d89ac75aJust
2087842e56b97ce677b83bdab09cda48bc2d89ac75aJust	operandEncoding = t2OperandEncoding
209455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	operators, opcodes = buildOperatorDict(t2Operators)
2107842e56b97ce677b83bdab09cda48bc2d89ac75aJust
211586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	def __init__(self, bytecode=None, program=None, subrs=None, globalSubrs=None):
2127842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if program is None:
2137842e56b97ce677b83bdab09cda48bc2d89ac75aJust			program = []
2147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.bytecode = bytecode
2157842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.program = program
216586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		self.subrs = subrs
217586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		self.globalSubrs = globalSubrs
2187842e56b97ce677b83bdab09cda48bc2d89ac75aJust
2197842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __repr__(self):
2207842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.bytecode is None:
2217842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return "<%s (source) at %x>" % (self.__class__.__name__, id(self))
2227842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
2237842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self))
2247842e56b97ce677b83bdab09cda48bc2d89ac75aJust
225586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	def decompile(self):
226586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		if not self.needsDecompilation():
227586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr			return
228586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		decompiler = SimpleT2Decompiler(self.subrs, self.globalSubrs)
229586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		decompiler.reset()
230586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		decompiler.execute(self)
231586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr
232455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	def compile(self):
233455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		if self.bytecode is not None:
234455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			return
2354e5af60930726d06a58a30bae45bb27ae50aea77jvr		if self.program[-1] not in ("endchar", "return", "callsubr", "callgsubr", "seac"):
2364e5af60930726d06a58a30bae45bb27ae50aea77jvr			print "XXX", self.program
2374e5af60930726d06a58a30bae45bb27ae50aea77jvr			assert 0, "illegal CharString"
238455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		bytecode = []
239455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr		opcodes = self.opcodes
2404e5af60930726d06a58a30bae45bb27ae50aea77jvr		program = self.program
2414e5af60930726d06a58a30bae45bb27ae50aea77jvr		i = 0
2424e5af60930726d06a58a30bae45bb27ae50aea77jvr		end = len(program)
2434e5af60930726d06a58a30bae45bb27ae50aea77jvr		while i < end:
2444e5af60930726d06a58a30bae45bb27ae50aea77jvr			token = program[i]
2454e5af60930726d06a58a30bae45bb27ae50aea77jvr			i = i + 1
246455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			tp = type(token)
247455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			if tp == types.StringType:
2484e5af60930726d06a58a30bae45bb27ae50aea77jvr				try:
249455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr					bytecode.extend(map(chr, opcodes[token]))
2504e5af60930726d06a58a30bae45bb27ae50aea77jvr				except KeyError:
2514e5af60930726d06a58a30bae45bb27ae50aea77jvr					raise CharStringCompileError, "illegal operator: %s" % token
2524e5af60930726d06a58a30bae45bb27ae50aea77jvr				if token in ('hintmask', 'cntrmask'):
2534e5af60930726d06a58a30bae45bb27ae50aea77jvr					bytecode.append(program[i])  # hint mask
2544e5af60930726d06a58a30bae45bb27ae50aea77jvr					i = i + 1
255455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			elif tp == types.IntType:
256f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr				bytecode.append(encodeIntT2(token))
257455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr			else:
258f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr				assert 0, "unsupported type: %s" % tp
2594e5af60930726d06a58a30bae45bb27ae50aea77jvr		try:
2604e5af60930726d06a58a30bae45bb27ae50aea77jvr			bytecode = "".join(bytecode)
2614e5af60930726d06a58a30bae45bb27ae50aea77jvr		except TypeError:
2624e5af60930726d06a58a30bae45bb27ae50aea77jvr			print bytecode
2634e5af60930726d06a58a30bae45bb27ae50aea77jvr			raise
264f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		self.setBytecode(bytecode)
265f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
2667842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def needsDecompilation(self):
2677842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.bytecode is not None
2687842e56b97ce677b83bdab09cda48bc2d89ac75aJust
2697842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def setProgram(self, program):
2707842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.program = program
2717842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.bytecode = None
2727842e56b97ce677b83bdab09cda48bc2d89ac75aJust
273f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr	def setBytecode(self, bytecode):
274f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		self.bytecode = bytecode
275f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr		self.program = None
276f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvr
2777842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def getToken(self, index,
2787842e56b97ce677b83bdab09cda48bc2d89ac75aJust			len=len, ord=ord, getattr=getattr, type=type, StringType=types.StringType):
2797842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.bytecode is not None:
2807842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if index >= len(self.bytecode):
2817842e56b97ce677b83bdab09cda48bc2d89ac75aJust				return None, 0, 0
2827842e56b97ce677b83bdab09cda48bc2d89ac75aJust			b0 = ord(self.bytecode[index])
2837842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index + 1
2847842e56b97ce677b83bdab09cda48bc2d89ac75aJust			code = self.operandEncoding[b0]
2857842e56b97ce677b83bdab09cda48bc2d89ac75aJust			handler = getattr(self, code)
2867842e56b97ce677b83bdab09cda48bc2d89ac75aJust			token, index = handler(b0, self.bytecode, index)
2877842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
2887842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if index >= len(self.program):
2897842e56b97ce677b83bdab09cda48bc2d89ac75aJust				return None, 0, 0
2907842e56b97ce677b83bdab09cda48bc2d89ac75aJust			token = self.program[index]
2917842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index + 1
2927842e56b97ce677b83bdab09cda48bc2d89ac75aJust		isOperator = type(token) == StringType
2937842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return token, isOperator, index
2947842e56b97ce677b83bdab09cda48bc2d89ac75aJust
2957842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def getBytes(self, index, nBytes):
2967842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.bytecode is not None:
2977842e56b97ce677b83bdab09cda48bc2d89ac75aJust			newIndex = index + nBytes
2987842e56b97ce677b83bdab09cda48bc2d89ac75aJust			bytes = self.bytecode[index:newIndex]
2997842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = newIndex
3007842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
3017842e56b97ce677b83bdab09cda48bc2d89ac75aJust			bytes = self.program[index]
3027842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index + 1
3037842e56b97ce677b83bdab09cda48bc2d89ac75aJust		assert len(bytes) == nBytes
3047842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return bytes, index
3057842e56b97ce677b83bdab09cda48bc2d89ac75aJust
3067842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def do_operator(self, b0, data, index):
3077842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if b0 == 12:
3087842e56b97ce677b83bdab09cda48bc2d89ac75aJust			op = (b0, ord(data[index]))
3097842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index+1
3107842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
3117842e56b97ce677b83bdab09cda48bc2d89ac75aJust			op = b0
3127842e56b97ce677b83bdab09cda48bc2d89ac75aJust		operator = self.operators[op]
3137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return operator, index
3147842e56b97ce677b83bdab09cda48bc2d89ac75aJust
3157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def toXML(self, xmlWriter):
316dab433233bd4024ede9ad27c6c61ea0072c2edafJust		from fontTools.misc.textTools import num2binary
3177842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.bytecode is not None:
3187842e56b97ce677b83bdab09cda48bc2d89ac75aJust			xmlWriter.dumphex(self.bytecode)
3197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
3207842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = 0
3217842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = []
3227842e56b97ce677b83bdab09cda48bc2d89ac75aJust			while 1:
3237842e56b97ce677b83bdab09cda48bc2d89ac75aJust				token, isOperator, index = self.getToken(index)
3247842e56b97ce677b83bdab09cda48bc2d89ac75aJust				if token is None:
3257842e56b97ce677b83bdab09cda48bc2d89ac75aJust					break
3267842e56b97ce677b83bdab09cda48bc2d89ac75aJust				if isOperator:
3277842e56b97ce677b83bdab09cda48bc2d89ac75aJust					args = map(str, args)
3287842e56b97ce677b83bdab09cda48bc2d89ac75aJust					if token in ('hintmask', 'cntrmask'):
3297842e56b97ce677b83bdab09cda48bc2d89ac75aJust						hintMask, isOperator, index = self.getToken(index)
3307842e56b97ce677b83bdab09cda48bc2d89ac75aJust						bits = []
3317842e56b97ce677b83bdab09cda48bc2d89ac75aJust						for byte in hintMask:
3327842e56b97ce677b83bdab09cda48bc2d89ac75aJust							bits.append(num2binary(ord(byte), 8))
333586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr						hintMask = string.join(bits, "")
3347842e56b97ce677b83bdab09cda48bc2d89ac75aJust						line = string.join(args + [token, hintMask], " ")
3357842e56b97ce677b83bdab09cda48bc2d89ac75aJust					else:
3367842e56b97ce677b83bdab09cda48bc2d89ac75aJust						line = string.join(args + [token], " ")
3377842e56b97ce677b83bdab09cda48bc2d89ac75aJust					xmlWriter.write(line)
3387842e56b97ce677b83bdab09cda48bc2d89ac75aJust					xmlWriter.newline()
3397842e56b97ce677b83bdab09cda48bc2d89ac75aJust					args = []
3407842e56b97ce677b83bdab09cda48bc2d89ac75aJust				else:
3417842e56b97ce677b83bdab09cda48bc2d89ac75aJust					args.append(token)
3424e5af60930726d06a58a30bae45bb27ae50aea77jvr
3434e5af60930726d06a58a30bae45bb27ae50aea77jvr	def fromXML(self, (name, attrs, content)):
3444e5af60930726d06a58a30bae45bb27ae50aea77jvr		from fontTools.misc.textTools import binary2num
3454e5af60930726d06a58a30bae45bb27ae50aea77jvr		content = "".join(content)
3464e5af60930726d06a58a30bae45bb27ae50aea77jvr		content = content.split()
3474e5af60930726d06a58a30bae45bb27ae50aea77jvr		program = []
3484e5af60930726d06a58a30bae45bb27ae50aea77jvr		end = len(content)
3494e5af60930726d06a58a30bae45bb27ae50aea77jvr		i = 0
3504e5af60930726d06a58a30bae45bb27ae50aea77jvr		while i < end:
3514e5af60930726d06a58a30bae45bb27ae50aea77jvr			token = content[i]
3524e5af60930726d06a58a30bae45bb27ae50aea77jvr			i = i + 1
3534e5af60930726d06a58a30bae45bb27ae50aea77jvr			try:
3544e5af60930726d06a58a30bae45bb27ae50aea77jvr				token = int(token)
3554e5af60930726d06a58a30bae45bb27ae50aea77jvr			except ValueError:
3564e5af60930726d06a58a30bae45bb27ae50aea77jvr				program.append(token)
3574e5af60930726d06a58a30bae45bb27ae50aea77jvr				if token in ('hintmask', 'cntrmask'):
3584e5af60930726d06a58a30bae45bb27ae50aea77jvr					mask = content[i]
3594e5af60930726d06a58a30bae45bb27ae50aea77jvr					maskBytes = ""
3604e5af60930726d06a58a30bae45bb27ae50aea77jvr					for j in range(0, len(mask), 8):
3614e5af60930726d06a58a30bae45bb27ae50aea77jvr						maskBytes = maskBytes + chr(binary2num(mask[j:j+8]))
3624e5af60930726d06a58a30bae45bb27ae50aea77jvr					program.append(maskBytes)
3634e5af60930726d06a58a30bae45bb27ae50aea77jvr					i = i + 1
3644e5af60930726d06a58a30bae45bb27ae50aea77jvr			else:
3654e5af60930726d06a58a30bae45bb27ae50aea77jvr				program.append(token)
3664e5af60930726d06a58a30bae45bb27ae50aea77jvr		self.setProgram(program)
3677842e56b97ce677b83bdab09cda48bc2d89ac75aJust
3687842e56b97ce677b83bdab09cda48bc2d89ac75aJust
3697842e56b97ce677b83bdab09cda48bc2d89ac75aJustt1Operators = [
3707842e56b97ce677b83bdab09cda48bc2d89ac75aJust#	opcode     name
3717842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(1,        'hstem'),
3727842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(3,        'vstem'),
3737842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(4,        'vmoveto'),
3747842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(5,        'rlineto'),
3757842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(6,        'hlineto'),
3767842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(7,        'vlineto'),
3777842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(8,        'rrcurveto'),
3787842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(9,        'closepath'),
3797842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(10,       'callsubr'),
3807842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(11,       'return'),
3817842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(13,       'hsbw'),
3827842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(14,       'endchar'),
3837842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(21,       'rmoveto'),
3847842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(22,       'hmoveto'),
3857842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(30,       'vhcurveto'),
3867842e56b97ce677b83bdab09cda48bc2d89ac75aJust	(31,       'hvcurveto'),
3877842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 0),  'dotsection'),
3887842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 1),  'vstem3'),
3897842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 2),  'hstem3'),
3907842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 6),  'seac'),
3917842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 7),  'sbw'),
3927842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 12), 'div'),
3937842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 16), 'callothersubr'),
3947842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 17), 'pop'),
3957842e56b97ce677b83bdab09cda48bc2d89ac75aJust	((12, 33), 'setcurrentpoint'),
3967842e56b97ce677b83bdab09cda48bc2d89ac75aJust]
3977842e56b97ce677b83bdab09cda48bc2d89ac75aJust
3987842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1CharString(T2CharString):
3997842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4007842e56b97ce677b83bdab09cda48bc2d89ac75aJust	operandEncoding = t1OperandEncoding
401455af6592bffbd6f2fc9f56fbfe083022a8353d4jvr	operators, opcodes = buildOperatorDict(t1Operators)
4027842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4037842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self):
404b68a700595ff730c29d3d4b7abf92ee287678745Just		if self.program is not None:
4057842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return
4067842e56b97ce677b83bdab09cda48bc2d89ac75aJust		program = []
4077842e56b97ce677b83bdab09cda48bc2d89ac75aJust		index = 0
4087842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while 1:
4097842e56b97ce677b83bdab09cda48bc2d89ac75aJust			token, isOperator, index = self.getToken(index)
4107842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if token is None:
4117842e56b97ce677b83bdab09cda48bc2d89ac75aJust				break
4127842e56b97ce677b83bdab09cda48bc2d89ac75aJust			program.append(token)
4137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.setProgram(program)
4147842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4157842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4167842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass SimpleT2Decompiler:
4177842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4187842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __init__(self, localSubrs, globalSubrs):
4197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.localSubrs = localSubrs
4207842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.localBias = calcSubrBias(localSubrs)
4217842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.globalSubrs = globalSubrs
4227842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.globalBias = calcSubrBias(globalSubrs)
4237842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.reset()
4247842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4257842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def reset(self):
4267842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.callingStack = []
4277842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.operandStack = []
4287842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hintCount = 0
4297842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hintMaskBytes = 0
4307842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4317842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def execute(self, charString):
4327842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.callingStack.append(charString)
4337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		needsDecompilation = charString.needsDecompilation()
4347842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if needsDecompilation:
4357842e56b97ce677b83bdab09cda48bc2d89ac75aJust			program = []
4367842e56b97ce677b83bdab09cda48bc2d89ac75aJust			pushToProgram = program.append
4377842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
4387842e56b97ce677b83bdab09cda48bc2d89ac75aJust			pushToProgram = lambda x: None
4397842e56b97ce677b83bdab09cda48bc2d89ac75aJust		pushToStack = self.operandStack.append
4407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		index = 0
4417842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while 1:
4427842e56b97ce677b83bdab09cda48bc2d89ac75aJust			token, isOperator, index = charString.getToken(index)
4437842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if token is None:
4447842e56b97ce677b83bdab09cda48bc2d89ac75aJust				break  # we're done!
4457842e56b97ce677b83bdab09cda48bc2d89ac75aJust			pushToProgram(token)
4467842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if isOperator:
4477842e56b97ce677b83bdab09cda48bc2d89ac75aJust				handlerName = "op_" + token
4487842e56b97ce677b83bdab09cda48bc2d89ac75aJust				if hasattr(self, handlerName):
4497842e56b97ce677b83bdab09cda48bc2d89ac75aJust					handler = getattr(self, handlerName)
4507842e56b97ce677b83bdab09cda48bc2d89ac75aJust					rv = handler(index)
4517842e56b97ce677b83bdab09cda48bc2d89ac75aJust					if rv:
4527842e56b97ce677b83bdab09cda48bc2d89ac75aJust						hintMaskBytes, index = rv
4537842e56b97ce677b83bdab09cda48bc2d89ac75aJust						pushToProgram(hintMaskBytes)
4547842e56b97ce677b83bdab09cda48bc2d89ac75aJust				else:
4557842e56b97ce677b83bdab09cda48bc2d89ac75aJust					self.popall()
4567842e56b97ce677b83bdab09cda48bc2d89ac75aJust			else:
4577842e56b97ce677b83bdab09cda48bc2d89ac75aJust				pushToStack(token)
4587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if needsDecompilation:
4597842e56b97ce677b83bdab09cda48bc2d89ac75aJust			charString.setProgram(program)
4604e5af60930726d06a58a30bae45bb27ae50aea77jvr			if program[-1] not in ("endchar", "return", "callsubr", "callgsubr", "seac"):
4614e5af60930726d06a58a30bae45bb27ae50aea77jvr				print "XXX", program
4627842e56b97ce677b83bdab09cda48bc2d89ac75aJust			assert program[-1] in ("endchar", "return", "callsubr", "callgsubr", "seac")
4637842e56b97ce677b83bdab09cda48bc2d89ac75aJust		del self.callingStack[-1]
4647842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4657842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def pop(self):
4667842e56b97ce677b83bdab09cda48bc2d89ac75aJust		value = self.operandStack[-1]
4677842e56b97ce677b83bdab09cda48bc2d89ac75aJust		del self.operandStack[-1]
4687842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return value
4697842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4707842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def popall(self):
4717842e56b97ce677b83bdab09cda48bc2d89ac75aJust		stack = self.operandStack[:]
4727842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.operandStack[:] = []
4737842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return stack
4747842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4757842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def push(self, value):
4767842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.operandStack.append(value)
4777842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4787842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_return(self, index):
4797842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.operandStack:
4807842e56b97ce677b83bdab09cda48bc2d89ac75aJust			pass
4817842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4827842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_endchar(self, index):
4837842e56b97ce677b83bdab09cda48bc2d89ac75aJust		pass
4847842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4857842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_callsubr(self, index):
4867842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subrIndex = self.pop()
4877842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subr = self.localSubrs[subrIndex+self.localBias]
4887842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.execute(subr)
4897842e56b97ce677b83bdab09cda48bc2d89ac75aJust
4907842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_callgsubr(self, index):
4917842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subrIndex = self.pop()
4927842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subr = self.globalSubrs[subrIndex+self.globalBias]
4937842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.execute(subr)
4947842e56b97ce677b83bdab09cda48bc2d89ac75aJust
495586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	def op_hstem(self, index):
496586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		self.countHints()
497586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	def op_vstem(self, index):
498586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		self.countHints()
4997842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hstemhm(self, index):
5007842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.countHints()
501586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	def op_vstemhm(self, index):
502586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr		self.countHints()
5037842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5047842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hintmask(self, index):
5057842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if not self.hintMaskBytes:
5067842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.countHints()
5077842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.hintMaskBytes = (self.hintCount + 7) / 8
5087842e56b97ce677b83bdab09cda48bc2d89ac75aJust		hintMaskBytes, index = self.callingStack[-1].getBytes(index, self.hintMaskBytes)
5097842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return hintMaskBytes, index
5107842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5117842e56b97ce677b83bdab09cda48bc2d89ac75aJust	op_cntrmask = op_hintmask
5127842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5137842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def countHints(self):
5147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
5157842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hintCount = self.hintCount + len(args) / 2
5167842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5177842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5187842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T2OutlineExtractor(SimpleT2Decompiler):
5197842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5207842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __init__(self, localSubrs, globalSubrs, nominalWidthX, defaultWidthX):
5217842e56b97ce677b83bdab09cda48bc2d89ac75aJust		SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs)
5227842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.nominalWidthX = nominalWidthX
5237842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.defaultWidthX = defaultWidthX
5247842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5257842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def reset(self):
5267842e56b97ce677b83bdab09cda48bc2d89ac75aJust		import Numeric
5277842e56b97ce677b83bdab09cda48bc2d89ac75aJust		SimpleT2Decompiler.reset(self)
5287842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hints = []
5297842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.gotWidth = 0
5307842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.width = 0
5317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.currentPoint = Numeric.array((0, 0), Numeric.Int16)
5327842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.contours = []
5337842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5347842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def getContours(self):
5357842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.contours
5367842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5377842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def newPath(self):
5387842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.contours.append([[], [], 0])
5397842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5407842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def closePath(self):
5417842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.contours and self.contours[-1][2] == 0:
5427842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.contours[-1][2] = 1
5437842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5447842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def appendPoint(self, point, isPrimary):
5457842e56b97ce677b83bdab09cda48bc2d89ac75aJust		import Numeric
5467842e56b97ce677b83bdab09cda48bc2d89ac75aJust		point = self.currentPoint + Numeric.array(point, Numeric.Int16)
547aa00a279aee4fb40429fbcf874f61d26a9978973jvr		if not self.contours or self.contours[-1][2]:
548aa00a279aee4fb40429fbcf874f61d26a9978973jvr			# The subpath doesn't start with a moveto. Not sure whether
549239498a49628ea09ee3ac8ead586022b775237f1jvr			# this is legal, but apparently it usually works.
550239498a49628ea09ee3ac8ead586022b775237f1jvr			self.newPath()
551aa00a279aee4fb40429fbcf874f61d26a9978973jvr			self.appendPoint((0, 0), 1)
5527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.currentPoint = point
5537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		points, flags, isClosed = self.contours[-1]
5547842e56b97ce677b83bdab09cda48bc2d89ac75aJust		points.append(point)
5557842e56b97ce677b83bdab09cda48bc2d89ac75aJust		flags.append(isPrimary)
5567842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5577842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def popallWidth(self, evenOdd=0):
5587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
5597842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if not self.gotWidth:
5607842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if evenOdd ^ (len(args) % 2):
5617842e56b97ce677b83bdab09cda48bc2d89ac75aJust				self.width = self.nominalWidthX + args[0]
5627842e56b97ce677b83bdab09cda48bc2d89ac75aJust				args = args[1:]
5637842e56b97ce677b83bdab09cda48bc2d89ac75aJust			else:
5647842e56b97ce677b83bdab09cda48bc2d89ac75aJust				self.width = self.defaultWidthX
5657842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.gotWidth = 1
5667842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return args
5677842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5687842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def countHints(self):
5697842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popallWidth()
5707842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.hintCount = self.hintCount + len(args) / 2
5717842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5727842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
5737842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# hint operators
5747842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
575586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#def op_hstem(self, index):
576586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#	self.countHints()
577586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#def op_vstem(self, index):
578586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#	self.countHints()
579586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#def op_hstemhm(self, index):
580586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#	self.countHints()
581586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#def op_vstemhm(self, index):
582586345b7c1c0aa97b06f1597b67c3bb4c4e97be1jvr	#	self.countHints()
5837842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#def op_hintmask(self, index):
5847842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#	self.countHints()
5857842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#def op_cntrmask(self, index):
5867842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#	self.countHints()
5877842e56b97ce677b83bdab09cda48bc2d89ac75aJust
5887842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
5897842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# path constructors, moveto
5907842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
5917842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rmoveto(self, index):
5927842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
5937842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
5947842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(self.popallWidth(), 1)
5957842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hmoveto(self, index):
5967842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
5977842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
5987842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint((self.popallWidth(1)[0], 0), 1)
5997842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vmoveto(self, index):
6007842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
6017842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
6027842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint((0, self.popallWidth(1)[0]), 1)
6037842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_endchar(self, index):
6047842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
6057842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6067842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6077842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# path constructors, lines
6087842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6097842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rlineto(self, index):
6107842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6117842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(args), 2):
6127842e56b97ce677b83bdab09cda48bc2d89ac75aJust			point = args[i:i+2]
6137842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.appendPoint(point, 1)
6147842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hlineto(self, index):
6167842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.alternatingLineto(1)
6177842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vlineto(self, index):
6187842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.alternatingLineto(0)
6197842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6207842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6217842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# path constructors, curves
6227842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6237842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rrcurveto(self, index):
6247842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""{dxa dya dxb dyb dxc dyc}+ rrcurveto"""
6257842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6267842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(args), 6):
6277842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dxa, dya, dxb, dyb, dxc, dyc, = args[i:i+6]
6287842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.rrcurveto((dxa, dya), (dxb, dyb), (dxc, dyc))
6297842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6307842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rcurveline(self, index):
6317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""{dxa dya dxb dyb dxc dyc}+ dxd dyd rcurveline"""
6327842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(args)-2, 6):
6347842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dxb, dyb, dxc, dyc, dxd, dyd = args[i:i+6]
6357842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.rrcurveto((dxb, dyb), (dxc, dyc), (dxd, dyd))
6367842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(args[-2:], 1)
6377842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6387842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rlinecurve(self, index):
6397842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""{dxa dya}+ dxb dyb dxc dyc dxd dyd rlinecurve"""
6407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6417842e56b97ce677b83bdab09cda48bc2d89ac75aJust		lineArgs = args[:-6]
6427842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(lineArgs), 2):
6437842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.appendPoint(lineArgs[i:i+2], 1)
6447842e56b97ce677b83bdab09cda48bc2d89ac75aJust		dxb, dyb, dxc, dyc, dxd, dyd = args[-6:]
6457842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.rrcurveto((dxb, dyb), (dxc, dyc), (dxd, dyd))
6467842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6477842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vvcurveto(self, index):
6487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"dx1? {dya dxb dyb dyc}+ vvcurveto"
6497842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6507842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if len(args) % 2:
6517842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dx1 = args[0]
6527842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = args[1:]
6537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
6547842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dx1 = 0
6557842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(args), 4):
6567842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dya, dxb, dyb, dyc = args[i:i+4]
6577842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.rrcurveto((dx1, dya), (dxb, dyb), (0, dyc))
6587842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dx1 = 0
6597842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6607842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hhcurveto(self, index):
6617842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""dy1? {dxa dxb dyb dxc}+ hhcurveto"""
6627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6637842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if len(args) % 2:
6647842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dy1 = args[0]
6657842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = args[1:]
6667842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
6677842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dy1 = 0
6687842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for i in range(0, len(args), 4):
6697842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dxa, dxb, dyb, dxc = args[i:i+4]
6707842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.rrcurveto((dxa, dy1), (dxb, dyb), (dxc, 0))
6717842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dy1 = 0
6727842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6737842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vhcurveto(self, index):
6747842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf? vhcurveto (30)
6757842e56b97ce677b83bdab09cda48bc2d89ac75aJust		{dya dxb dyb dxc dxd dxe dye dyf}+ dxf? vhcurveto
6767842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""
6777842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while args:
6797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = self.vcurveto(args)
6807842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if args:
6817842e56b97ce677b83bdab09cda48bc2d89ac75aJust				args = self.hcurveto(args)
6827842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6837842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hvcurveto(self, index):
6847842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf?
6857842e56b97ce677b83bdab09cda48bc2d89ac75aJust		{dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
6867842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"""
6877842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
6887842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while args:
6897842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = self.hcurveto(args)
6907842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if args:
6917842e56b97ce677b83bdab09cda48bc2d89ac75aJust				args = self.vcurveto(args)
6927842e56b97ce677b83bdab09cda48bc2d89ac75aJust
6937842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6947842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# path constructors, flex
6957842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
6967842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hflex(self, index):
6977842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
6987842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_flex(self, index):
6997842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7007842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hflex1(self, index):
7017842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7027842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_flex1(self, index):
7037842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7047842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7057842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
7067842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# MultipleMaster. Well...
7077842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
7087842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_blend(self, index):
7097842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7107842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7117842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# misc
7127842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_and(self, index):
7137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7147842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_or(self, index):
7157842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7167842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_not(self, index):
7177842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7187842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_store(self, index):
7197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7207842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_abs(self, index):
7217842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7227842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_add(self, index):
7237842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7247842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_sub(self, index):
7257842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7267842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_div(self, index):
7277842e56b97ce677b83bdab09cda48bc2d89ac75aJust		num2 = self.pop()
7287842e56b97ce677b83bdab09cda48bc2d89ac75aJust		num1 = self.pop()
7297842e56b97ce677b83bdab09cda48bc2d89ac75aJust		d1 = num1/num2
7307842e56b97ce677b83bdab09cda48bc2d89ac75aJust		d2 = float(num1)/num2
7317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if d1 == d2:
7327842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.push(d1)
7337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
7347842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.push(d2)
7357842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_load(self, index):
7367842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7377842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_neg(self, index):
7387842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7397842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_eq(self, index):
7407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7417842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_drop(self, index):
7427842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7437842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_put(self, index):
7447842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7457842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_get(self, index):
7467842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7477842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_ifelse(self, index):
7487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7497842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_random(self, index):
7507842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7517842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_mul(self, index):
7527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7537842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_sqrt(self, index):
7547842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7557842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_dup(self, index):
7567842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7577842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_exch(self, index):
7587842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7597842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_index(self, index):
7607842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7617842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_roll(self, index):
7627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		XXX
7637842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7647842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
7657842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# miscelaneous helpers
7667842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
7677842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def alternatingLineto(self, isHorizontal):
7687842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
7697842e56b97ce677b83bdab09cda48bc2d89ac75aJust		for arg in args:
7707842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if isHorizontal:
7717842e56b97ce677b83bdab09cda48bc2d89ac75aJust				point = (arg, 0)
7727842e56b97ce677b83bdab09cda48bc2d89ac75aJust			else:
7737842e56b97ce677b83bdab09cda48bc2d89ac75aJust				point = (0, arg)
7747842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.appendPoint(point, 1)
7757842e56b97ce677b83bdab09cda48bc2d89ac75aJust			isHorizontal = not isHorizontal
7767842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7777842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def rrcurveto(self, p1, p2, p3):
7787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(p1, 0)
7797842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(p2, 0)
7807842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(p3, 1)
7817842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7827842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def vcurveto(self, args):
7837842e56b97ce677b83bdab09cda48bc2d89ac75aJust		dya, dxb, dyb, dxc = args[:4]
7847842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = args[4:]
7857842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if len(args) == 1:
7867842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dyc = args[0]
7877842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = []
7887842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
7897842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dyc = 0
7907842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.rrcurveto((0, dya), (dxb, dyb), (dxc, dyc))
7917842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return args
7927842e56b97ce677b83bdab09cda48bc2d89ac75aJust
7937842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def hcurveto(self, args):
7947842e56b97ce677b83bdab09cda48bc2d89ac75aJust		dxa, dxb, dyb, dyc = args[:4]
7957842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = args[4:]
7967842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if len(args) == 1:
7977842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dxc = args[0]
7987842e56b97ce677b83bdab09cda48bc2d89ac75aJust			args = []
7997842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
8007842e56b97ce677b83bdab09cda48bc2d89ac75aJust			dxc = 0
8017842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.rrcurveto((dxa, 0), (dxb, dyb), (dxc, dyc))
8027842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return args
8037842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8047842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8057842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass T1OutlineExtractor(T2OutlineExtractor):
8067842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8077842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __init__(self, subrs):
8087842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.subrs = subrs
8097842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.reset()
8107842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8117842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def reset(self):
8127842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.flexing = 0
8137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.width = 0
8147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.sbx = 0
8157842e56b97ce677b83bdab09cda48bc2d89ac75aJust		T2OutlineExtractor.reset(self)
8167842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8177842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def popallWidth(self, evenOdd=0):
8187842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.popall()
8197842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8207842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def exch(self):
8217842e56b97ce677b83bdab09cda48bc2d89ac75aJust		stack = self.operandStack
8227842e56b97ce677b83bdab09cda48bc2d89ac75aJust		stack[-1], stack[-2] = stack[-2], stack[-1]
8237842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8247842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
8257842e56b97ce677b83bdab09cda48bc2d89ac75aJust	# path constructors
8267842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
8277842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_rmoveto(self, index):
8287842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.flexing:
8297842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return
8307842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
8317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint(self.popall(), 1)
8327842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hmoveto(self, index):
8337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.flexing:
8347842e56b97ce677b83bdab09cda48bc2d89ac75aJust			# We must add a parameter to the stack if we are flexing
8357842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.push(0)
8367842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return
8377842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
8387842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint((self.popall()[0], 0), 1)
8397842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vmoveto(self, index):
8407842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if self.flexing:
8417842e56b97ce677b83bdab09cda48bc2d89ac75aJust			# We must add a parameter to the stack if we are flexing
8427842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.push(0)
8437842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.exch()
8447842e56b97ce677b83bdab09cda48bc2d89ac75aJust			return
8457842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.newPath()
8467842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.appendPoint((0, self.popall()[0]), 1)
8477842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_closepath(self, index):
8487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
8497842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_setcurrentpoint(self, index):
8507842e56b97ce677b83bdab09cda48bc2d89ac75aJust		args = self.popall()
8517842e56b97ce677b83bdab09cda48bc2d89ac75aJust		x, y = args
8527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.currentPoint[0] = x
8537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.currentPoint[1] = y
8547842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8557842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_endchar(self, index):
8567842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.closePath()
8577842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8587842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hsbw(self, index):
8597842e56b97ce677b83bdab09cda48bc2d89ac75aJust		sbx, wx = self.popall()
8607842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.width = wx
8617842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.sbx = sbx
8627842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.currentPoint[0] = sbx
8637842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_sbw(self, index):
8647842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.popall()  # XXX
8657842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8667842e56b97ce677b83bdab09cda48bc2d89ac75aJust	#
8677842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_callsubr(self, index):
8687842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subrIndex = self.pop()
8697842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subr = self.subrs[subrIndex]
8707842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.execute(subr)
8717842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_callothersubr(self, index):
8727842e56b97ce677b83bdab09cda48bc2d89ac75aJust		subrIndex = self.pop()
8737842e56b97ce677b83bdab09cda48bc2d89ac75aJust		nArgs = self.pop()
8747842e56b97ce677b83bdab09cda48bc2d89ac75aJust		#print nArgs, subrIndex, "callothersubr"
8757842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if subrIndex == 0 and nArgs == 3:
8767842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.doFlex()
8777842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.flexing = 0
8787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		elif subrIndex == 1 and nArgs == 0:
8797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			self.flexing = 1
8807842e56b97ce677b83bdab09cda48bc2d89ac75aJust		# ignore...
8817842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_pop(self, index):
8827842e56b97ce677b83bdab09cda48bc2d89ac75aJust		pass  # ignore...
8837842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8847842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def doFlex(self):
8857842e56b97ce677b83bdab09cda48bc2d89ac75aJust		finaly = self.pop()
8867842e56b97ce677b83bdab09cda48bc2d89ac75aJust		finalx = self.pop()
8877842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.pop()	# flex height is unused
8887842e56b97ce677b83bdab09cda48bc2d89ac75aJust
8897842e56b97ce677b83bdab09cda48bc2d89ac75aJust		p3y = self.pop()
8907842e56b97ce677b83bdab09cda48bc2d89ac75aJust		p3x = self.pop()
8917842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp4y = self.pop()
8927842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp4x = self.pop()
8937842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp3y = self.pop()
8947842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp3x = self.pop()
8957842e56b97ce677b83bdab09cda48bc2d89ac75aJust		p2y = self.pop()
8967842e56b97ce677b83bdab09cda48bc2d89ac75aJust		p2x = self.pop()
8977842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp2y = self.pop()
8987842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp2x = self.pop()
8997842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp1y = self.pop()
9007842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bcp1x = self.pop()
9017842e56b97ce677b83bdab09cda48bc2d89ac75aJust		rpy = self.pop()
9027842e56b97ce677b83bdab09cda48bc2d89ac75aJust		rpx = self.pop()
9037842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9047842e56b97ce677b83bdab09cda48bc2d89ac75aJust		# call rrcurveto
9057842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp1x+rpx)
9067842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp1y+rpy)
9077842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp2x)
9087842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp2y)
9097842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(p2x)
9107842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(p2y)
9117842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.op_rrcurveto(None)
9127842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9137842e56b97ce677b83bdab09cda48bc2d89ac75aJust		# call rrcurveto
9147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp3x)
9157842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp3y)
9167842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp4x)
9177842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(bcp4y)
9187842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(p3x)
9197842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(p3y)
9207842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.op_rrcurveto(None)
9217842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9227842e56b97ce677b83bdab09cda48bc2d89ac75aJust		# Push back final coords so subr 0 can find them
9237842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(finalx)
9247842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.push(finaly)
9257842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9267842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_dotsection(self, index):
9277842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.popall()  # XXX
9287842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_hstem3(self, index):
9297842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.popall()  # XXX
9307842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_seac(self, index):
9317842e56b97ce677b83bdab09cda48bc2d89ac75aJust		"asb adx ady bchar achar seac"
9327842e56b97ce677b83bdab09cda48bc2d89ac75aJust		asb, adx, ady, bchar, achar = self.popall()  # XXX
9337842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.contours.append([(asb, adx, ady, bchar, achar), None, -1])
9347842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def op_vstem3(self, index):
9357842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.popall()  # XXX
9367842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9377842e56b97ce677b83bdab09cda48bc2d89ac75aJust
938f2cf9c5d6d503e16ee43dc9b617d96aed38806a8jvrclass DictDecompiler(ByteCodeBase):
9397842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9407842e56b97ce677b83bdab09cda48bc2d89ac75aJust	operandEncoding = cffDictOperandEncoding
9417842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9427842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def __init__(self, strings):
9437842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.stack = []
9447842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.strings = strings
9457842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.dict = {}
9467842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9477842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def getDict(self):
9487842e56b97ce677b83bdab09cda48bc2d89ac75aJust		assert len(self.stack) == 0, "non-empty stack"
9497842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.dict
9507842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9517842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def decompile(self, data):
9527842e56b97ce677b83bdab09cda48bc2d89ac75aJust		index = 0
9537842e56b97ce677b83bdab09cda48bc2d89ac75aJust		lenData = len(data)
9547842e56b97ce677b83bdab09cda48bc2d89ac75aJust		push = self.stack.append
9557842e56b97ce677b83bdab09cda48bc2d89ac75aJust		while index < lenData:
9567842e56b97ce677b83bdab09cda48bc2d89ac75aJust			b0 = ord(data[index])
9577842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index + 1
9587842e56b97ce677b83bdab09cda48bc2d89ac75aJust			code = self.operandEncoding[b0]
9597842e56b97ce677b83bdab09cda48bc2d89ac75aJust			handler = getattr(self, code)
9607842e56b97ce677b83bdab09cda48bc2d89ac75aJust			value, index = handler(b0, data, index)
9617842e56b97ce677b83bdab09cda48bc2d89ac75aJust			if value is not None:
9627842e56b97ce677b83bdab09cda48bc2d89ac75aJust				push(value)
9637842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9647842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def pop(self):
9657842e56b97ce677b83bdab09cda48bc2d89ac75aJust		value = self.stack[-1]
9667842e56b97ce677b83bdab09cda48bc2d89ac75aJust		del self.stack[-1]
9677842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return value
9687842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9697842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def popall(self):
9707842e56b97ce677b83bdab09cda48bc2d89ac75aJust		all = self.stack[:]
9717842e56b97ce677b83bdab09cda48bc2d89ac75aJust		del self.stack[:]
9727842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return all
9737842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9747842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def do_operator(self, b0, data, index):
9757842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if b0 == 12:
9767842e56b97ce677b83bdab09cda48bc2d89ac75aJust			op = (b0, ord(data[index]))
9777842e56b97ce677b83bdab09cda48bc2d89ac75aJust			index = index+1
9787842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
9797842e56b97ce677b83bdab09cda48bc2d89ac75aJust			op = b0
9807842e56b97ce677b83bdab09cda48bc2d89ac75aJust		operator, argType = self.operators[op]
9817842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.handle_operator(operator, argType)
9827842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return None, index
9837842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9847842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def handle_operator(self, operator, argType):
9857842e56b97ce677b83bdab09cda48bc2d89ac75aJust		if type(argType) == type(()):
9867842e56b97ce677b83bdab09cda48bc2d89ac75aJust			value = ()
987bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr			for i in range(len(argType)-1, -1, -1):
988bf2f402913a2706dfa92190e60cba7acbf01c9d7jvr				arg = argType[i]
9897842e56b97ce677b83bdab09cda48bc2d89ac75aJust				arghandler = getattr(self, "arg_" + arg)
9907842e56b97ce677b83bdab09cda48bc2d89ac75aJust				value = (arghandler(operator),) + value
9917842e56b97ce677b83bdab09cda48bc2d89ac75aJust		else:
9927842e56b97ce677b83bdab09cda48bc2d89ac75aJust			arghandler = getattr(self, "arg_" + argType)
9937842e56b97ce677b83bdab09cda48bc2d89ac75aJust			value = arghandler(operator)
9947842e56b97ce677b83bdab09cda48bc2d89ac75aJust		self.dict[operator] = value
9957842e56b97ce677b83bdab09cda48bc2d89ac75aJust
9967842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def arg_number(self, name):
9977842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.pop()
9987842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def arg_SID(self, name):
9997842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.strings[self.pop()]
10007842e56b97ce677b83bdab09cda48bc2d89ac75aJust	def arg_array(self, name):
10017842e56b97ce677b83bdab09cda48bc2d89ac75aJust		return self.popall()
1002dc18128aa9b3f6b98a623c294ac615195159025ejvr	def arg_delta(self, name):
1003dc18128aa9b3f6b98a623c294ac615195159025ejvr		out = []
1004dc18128aa9b3f6b98a623c294ac615195159025ejvr		current = 0
1005dc18128aa9b3f6b98a623c294ac615195159025ejvr		for v in self.popall():
10066f03a58f59fb20662602e3d4bb153d7db2f778d3jvr			current = current + v
1007dc18128aa9b3f6b98a623c294ac615195159025ejvr			out.append(current)
1008dc18128aa9b3f6b98a623c294ac615195159025ejvr		return out
10097842e56b97ce677b83bdab09cda48bc2d89ac75aJust
10107842e56b97ce677b83bdab09cda48bc2d89ac75aJust
10117842e56b97ce677b83bdab09cda48bc2d89ac75aJustdef calcSubrBias(subrs):
10127842e56b97ce677b83bdab09cda48bc2d89ac75aJust	nSubrs = len(subrs)
10137842e56b97ce677b83bdab09cda48bc2d89ac75aJust	if nSubrs < 1240:
10147842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bias = 107
10157842e56b97ce677b83bdab09cda48bc2d89ac75aJust	elif nSubrs < 33900:
10167842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bias = 1131
10177842e56b97ce677b83bdab09cda48bc2d89ac75aJust	else:
10187842e56b97ce677b83bdab09cda48bc2d89ac75aJust		bias = 32768
10197842e56b97ce677b83bdab09cda48bc2d89ac75aJust	return bias
10207842e56b97ce677b83bdab09cda48bc2d89ac75aJust
1021