first stab at compiling T2 CharStrings
git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@244 4cde692c-a291-49d1-8350-778aa11640f8
This commit is contained in:
parent
767102ea85
commit
455af6592b
@ -2,15 +2,14 @@
|
|||||||
CFF dictionary data and Type1/Type2 CharStrings.
|
CFF dictionary data and Type1/Type2 CharStrings.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "1.0b1"
|
|
||||||
__author__ = "jvr"
|
|
||||||
|
|
||||||
|
|
||||||
import types
|
import types
|
||||||
import struct
|
import struct
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = 0
|
||||||
|
|
||||||
|
|
||||||
t1OperandEncoding = [None] * 256
|
t1OperandEncoding = [None] * 256
|
||||||
t1OperandEncoding[0:32] = (32) * ["do_operator"]
|
t1OperandEncoding[0:32] = (32) * ["do_operator"]
|
||||||
t1OperandEncoding[32:247] = (247 - 32) * ["read_byte"]
|
t1OperandEncoding[32:247] = (247 - 32) * ["read_byte"]
|
||||||
@ -68,17 +67,22 @@ class ByteCodeDecompilerBase:
|
|||||||
if nibble1 == 0xf:
|
if nibble1 == 0xf:
|
||||||
break
|
break
|
||||||
number = number + realNibbles[nibble1]
|
number = number + realNibbles[nibble1]
|
||||||
return string.atof(number), index
|
return float(number), index
|
||||||
|
|
||||||
|
|
||||||
def buildOperatorDict(operatorList):
|
def buildOperatorDict(operatorList):
|
||||||
dict = {}
|
oper = {}
|
||||||
|
opc = {}
|
||||||
for item in operatorList:
|
for item in operatorList:
|
||||||
if len(item) == 2:
|
if len(item) == 2:
|
||||||
dict[item[0]] = item[1]
|
oper[item[0]] = item[1]
|
||||||
else:
|
else:
|
||||||
dict[item[0]] = item[1:]
|
oper[item[0]] = item[1:]
|
||||||
return dict
|
if type(item[0]) == types.TupleType:
|
||||||
|
opc[item[1]] = item[0]
|
||||||
|
else:
|
||||||
|
opc[item[1]] = (item[0],)
|
||||||
|
return oper, opc
|
||||||
|
|
||||||
|
|
||||||
t2Operators = [
|
t2Operators = [
|
||||||
@ -139,7 +143,7 @@ t2Operators = [
|
|||||||
class T2CharString(ByteCodeDecompilerBase):
|
class T2CharString(ByteCodeDecompilerBase):
|
||||||
|
|
||||||
operandEncoding = t2OperandEncoding
|
operandEncoding = t2OperandEncoding
|
||||||
operators = buildOperatorDict(t2Operators)
|
operators, opcodes = buildOperatorDict(t2Operators)
|
||||||
|
|
||||||
def __init__(self, bytecode=None, program=None):
|
def __init__(self, bytecode=None, program=None):
|
||||||
if program is None:
|
if program is None:
|
||||||
@ -153,11 +157,51 @@ class T2CharString(ByteCodeDecompilerBase):
|
|||||||
else:
|
else:
|
||||||
return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self))
|
return "<%s (bytecode) at %x>" % (self.__class__.__name__, id(self))
|
||||||
|
|
||||||
|
def compile(self):
|
||||||
|
if self.bytecode is not None:
|
||||||
|
return
|
||||||
|
bytecode = []
|
||||||
|
opcodes = self.opcodes
|
||||||
|
for token in self.program:
|
||||||
|
tp = type(token)
|
||||||
|
if tp == types.StringType:
|
||||||
|
if opcodes.has_key(token):
|
||||||
|
bytecode.extend(map(chr, opcodes[token]))
|
||||||
|
else:
|
||||||
|
bytecode.append(token) # hint mask
|
||||||
|
elif tp == types.FloatType:
|
||||||
|
# only in CFF
|
||||||
|
raise NotImplementedError
|
||||||
|
elif tp == types.IntType:
|
||||||
|
# XXX factor out, is largely OK for CFF dicts, too.
|
||||||
|
if -107 <= token <= 107:
|
||||||
|
code = chr(token + 139)
|
||||||
|
elif 108 <= token <= 1131:
|
||||||
|
token = token - 108
|
||||||
|
code = chr((token >> 8) + 247) + chr(token & 0xFF)
|
||||||
|
elif -1131 <= token <= -108:
|
||||||
|
token = -token - 108
|
||||||
|
code = chr((token >> 8) + 251) + chr(token & 0xFF)
|
||||||
|
elif -32768 <= token <= 32767:
|
||||||
|
# XXX T2/CFF-specific: doesn't exist in T1
|
||||||
|
code = chr(28) + struct.pack(">h", token)
|
||||||
|
else:
|
||||||
|
# XXX T1/T2-specific: different opcode in CFF
|
||||||
|
code = chr(255) + struct.pack(">l", token)
|
||||||
|
bytecode.append(code)
|
||||||
|
else:
|
||||||
|
assert 0
|
||||||
|
bytecode = "".join(bytecode)
|
||||||
|
if DEBUG:
|
||||||
|
assert bytecode == self.__bytecode
|
||||||
|
|
||||||
def needsDecompilation(self):
|
def needsDecompilation(self):
|
||||||
return self.bytecode is not None
|
return self.bytecode is not None
|
||||||
|
|
||||||
def setProgram(self, program):
|
def setProgram(self, program):
|
||||||
self.program = program
|
self.program = program
|
||||||
|
if DEBUG:
|
||||||
|
self.__bytecode = self.bytecode
|
||||||
self.bytecode = None
|
self.bytecode = None
|
||||||
|
|
||||||
def getToken(self, index,
|
def getToken(self, index,
|
||||||
@ -259,7 +303,7 @@ t1Operators = [
|
|||||||
class T1CharString(T2CharString):
|
class T1CharString(T2CharString):
|
||||||
|
|
||||||
operandEncoding = t1OperandEncoding
|
operandEncoding = t1OperandEncoding
|
||||||
operators = buildOperatorDict(t1Operators)
|
operators, opcodes = buildOperatorDict(t1Operators)
|
||||||
|
|
||||||
def decompile(self):
|
def decompile(self):
|
||||||
if self.program is not None:
|
if self.program is not None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user