Folded CFF2 classes into CFF classes. Removed:
SimpleCFF2DEcompiler CFF2CharString GlobalSubrsIndex2 SubrsIndex2 CharstringIndex2 Working towards using one set of classes for both CFF2 and CFF data.
This commit is contained in:
parent
5fb2688567
commit
c33ae5c96a
@ -58,7 +58,7 @@ class CFFFontSet(object):
|
|||||||
cff2GetGlyphOrder = otFont.getGlyphOrder
|
cff2GetGlyphOrder = otFont.getGlyphOrder
|
||||||
self.topDictIndex = TopDictData(self.topDictSize, cff2GetGlyphOrder, file) # in CFF2, offsetSize is the size of the TopDict data.
|
self.topDictIndex = TopDictData(self.topDictSize, cff2GetGlyphOrder, file) # in CFF2, offsetSize is the size of the TopDict data.
|
||||||
self.strings = None
|
self.strings = None
|
||||||
self.GlobalSubrs = GlobalSubrsIndex2(file)
|
self.GlobalSubrs = GlobalSubrsIndex(file)
|
||||||
self.topDictIndex.strings = self.strings
|
self.topDictIndex.strings = self.strings
|
||||||
self.topDictIndex.GlobalSubrs = self.GlobalSubrs
|
self.topDictIndex.GlobalSubrs = self.GlobalSubrs
|
||||||
else:
|
else:
|
||||||
@ -177,7 +177,7 @@ class CFFFontSet(object):
|
|||||||
elif self.major == 2:
|
elif self.major == 2:
|
||||||
isCFF2 = True
|
isCFF2 = True
|
||||||
if not hasattr(self, "GlobalSubrs"):
|
if not hasattr(self, "GlobalSubrs"):
|
||||||
self.GlobalSubrs = GlobalSubrsIndex2()
|
self.GlobalSubrs = GlobalSubrsIndex()
|
||||||
if not hasattr(self, "fontNames"):
|
if not hasattr(self, "fontNames"):
|
||||||
self.fontNames = []
|
self.fontNames = []
|
||||||
fontName = "CFF2Font"
|
fontName = "CFF2Font"
|
||||||
@ -192,16 +192,9 @@ class CFFFontSet(object):
|
|||||||
name, attrs, content = element
|
name, attrs, content = element
|
||||||
topDict.fromXML(name, attrs, content)
|
topDict.fromXML(name, attrs, content)
|
||||||
elif name == "GlobalSubrs":
|
elif name == "GlobalSubrs":
|
||||||
if not isCFF2:
|
subrCharStringClass = psCharStrings.T2CharString
|
||||||
subrCharStringClass = psCharStrings.T2CharString
|
if not hasattr(self, "GlobalSubrs"):
|
||||||
if not hasattr(self, "GlobalSubrs"):
|
self.GlobalSubrs = GlobalSubrsIndex()
|
||||||
self.GlobalSubrs = GlobalSubrsIndex()
|
|
||||||
elif isCFF2:
|
|
||||||
subrCharStringClass = psCharStrings.CFF2SubrCharString
|
|
||||||
if not hasattr(self, "GlobalSubrs"):
|
|
||||||
self.GlobalSubrs = GlobalSubrsIndex2()
|
|
||||||
else:
|
|
||||||
assert False, "Unsupported CFF format"
|
|
||||||
for element in content:
|
for element in content:
|
||||||
if isinstance(element, basestring):
|
if isinstance(element, basestring):
|
||||||
continue
|
continue
|
||||||
@ -631,33 +624,9 @@ class GlobalSubrsIndex(Index):
|
|||||||
sel = self.fdSelect[index]
|
sel = self.fdSelect[index]
|
||||||
return self[index], sel
|
return self[index], sel
|
||||||
|
|
||||||
class GlobalSubrsIndex2(GlobalSubrsIndex):
|
|
||||||
subrClass = psCharStrings.CFF2SubrCharString
|
|
||||||
|
|
||||||
class SubrsIndex(GlobalSubrsIndex):
|
class SubrsIndex(GlobalSubrsIndex):
|
||||||
compilerClass = SubrsCompiler
|
compilerClass = SubrsCompiler
|
||||||
|
|
||||||
class SubrsIndex2(GlobalSubrsIndex2):
|
|
||||||
compilerClass = SubrsCompiler
|
|
||||||
charStringClass = psCharStrings.CFF2SubrCharString
|
|
||||||
|
|
||||||
class CharStringIndex2(GlobalSubrsIndex2):
|
|
||||||
compilerClass = SubrsCompiler
|
|
||||||
charStringClass = psCharStrings.CFF2CharString
|
|
||||||
|
|
||||||
def produceItem(self, index, data, file, offset, size):
|
|
||||||
if self.private is not None:
|
|
||||||
private = self.private
|
|
||||||
elif hasattr(self, 'fdArray') and self.fdArray is not None:
|
|
||||||
if hasattr(self, 'fdSelect') and self.fdSelect is not None:
|
|
||||||
fdIndex = self.fdSelect[index]
|
|
||||||
else:
|
|
||||||
fdIndex = 0
|
|
||||||
private = self.fdArray[fdIndex].Private
|
|
||||||
else:
|
|
||||||
private = None
|
|
||||||
return self.charStringClass(data, private=private, globalSubrs=self.globalSubrs)
|
|
||||||
|
|
||||||
class TopDictIndex(Index):
|
class TopDictIndex(Index):
|
||||||
|
|
||||||
compilerClass = TopDictIndexCompiler
|
compilerClass = TopDictIndexCompiler
|
||||||
@ -833,10 +802,7 @@ class CharStrings(object):
|
|||||||
def __init__(self, file, charset, globalSubrs, private, fdSelect, fdArray):
|
def __init__(self, file, charset, globalSubrs, private, fdSelect, fdArray):
|
||||||
self.globalSubrs = globalSubrs
|
self.globalSubrs = globalSubrs
|
||||||
if file is not None:
|
if file is not None:
|
||||||
if isCFF2:
|
self.charStringsIndex = SubrsIndex(file, globalSubrs, private, fdSelect, fdArray)
|
||||||
self.charStringsIndex = CharStringIndex2(file, globalSubrs, private, fdSelect, fdArray)
|
|
||||||
else:
|
|
||||||
self.charStringsIndex = SubrsIndex(file, globalSubrs, private, fdSelect, fdArray)
|
|
||||||
self.charStrings = charStrings = {}
|
self.charStrings = charStrings = {}
|
||||||
for i in range(len(charset)):
|
for i in range(len(charset)):
|
||||||
charStrings[charset[i]] = i
|
charStrings[charset[i]] = i
|
||||||
@ -939,10 +905,7 @@ class CharStrings(object):
|
|||||||
private = self.private
|
private = self.private
|
||||||
|
|
||||||
glyphName = attrs["name"]
|
glyphName = attrs["name"]
|
||||||
if isCFF2:
|
charStringClass = psCharStrings.T2CharString
|
||||||
charStringClass = psCharStrings.CFF2CharString
|
|
||||||
else:
|
|
||||||
charStringClass = psCharStrings.T2CharString
|
|
||||||
charString = charStringClass(
|
charString = charStringClass(
|
||||||
private=private,
|
private=private,
|
||||||
globalSubrs=self.globalSubrs)
|
globalSubrs=self.globalSubrs)
|
||||||
@ -1164,10 +1127,7 @@ class PrivateDictConverter(TableConverter):
|
|||||||
|
|
||||||
class SubrsConverter(TableConverter):
|
class SubrsConverter(TableConverter):
|
||||||
def getClass(self):
|
def getClass(self):
|
||||||
if isCFF2:
|
return SubrsIndex
|
||||||
return SubrsIndex2
|
|
||||||
else:
|
|
||||||
return SubrsIndex
|
|
||||||
|
|
||||||
def read(self, parent, value):
|
def read(self, parent, value):
|
||||||
file = parent.file
|
file = parent.file
|
||||||
@ -2279,7 +2239,6 @@ class FontDict(TopDict):
|
|||||||
super(FontDict, self).__init__(strings, file, offset, GlobalSubrs, None)
|
super(FontDict, self).__init__(strings, file, offset, GlobalSubrs, None)
|
||||||
self.topDict = topDict
|
self.topDict = topDict
|
||||||
|
|
||||||
|
|
||||||
class PrivateDict(BaseDict):
|
class PrivateDict(BaseDict):
|
||||||
defaults = buildDefaults(privateDictOperators)
|
defaults = buildDefaults(privateDictOperators)
|
||||||
converters = buildConverters(privateDictOperators)
|
converters = buildConverters(privateDictOperators)
|
||||||
@ -2290,7 +2249,7 @@ class PrivateDict(BaseDict):
|
|||||||
def __init__(self, strings=None, file=None, offset=None, parent= None):
|
def __init__(self, strings=None, file=None, offset=None, parent= None):
|
||||||
super(PrivateDict, self).__init__(strings, file, offset)
|
super(PrivateDict, self).__init__(strings, file, offset)
|
||||||
self.fontDict = parent
|
self.fontDict = parent
|
||||||
|
self.isCFF2 = False
|
||||||
|
|
||||||
class PrivateDict2(PrivateDict):
|
class PrivateDict2(PrivateDict):
|
||||||
defaults = buildDefaults(privateDictOperators2)
|
defaults = buildDefaults(privateDictOperators2)
|
||||||
@ -2302,6 +2261,7 @@ class PrivateDict2(PrivateDict):
|
|||||||
def __init__(self, strings=None, file=None, offset=None, parent= None):
|
def __init__(self, strings=None, file=None, offset=None, parent= None):
|
||||||
super(PrivateDict2, self).__init__(strings, file, offset, parent)
|
super(PrivateDict2, self).__init__(strings, file, offset, parent)
|
||||||
self.vstore = None
|
self.vstore = None
|
||||||
|
self.isCFF2 = True
|
||||||
|
|
||||||
def getNumRegions(self, vi = None):
|
def getNumRegions(self, vi = None):
|
||||||
# if getNumRegions is being called, we can assume that VarStore exists.
|
# if getNumRegions is being called, we can assume that VarStore exists.
|
||||||
|
@ -251,11 +251,12 @@ class CharStringCompileError(Exception): pass
|
|||||||
|
|
||||||
class SimpleT2Decompiler(object):
|
class SimpleT2Decompiler(object):
|
||||||
|
|
||||||
def __init__(self, localSubrs, globalSubrs):
|
def __init__(self, localSubrs, globalSubrs, private):
|
||||||
self.localSubrs = localSubrs
|
self.localSubrs = localSubrs
|
||||||
self.localBias = calcSubrBias(localSubrs)
|
self.localBias = calcSubrBias(localSubrs)
|
||||||
self.globalSubrs = globalSubrs
|
self.globalSubrs = globalSubrs
|
||||||
self.globalBias = calcSubrBias(globalSubrs)
|
self.globalBias = calcSubrBias(globalSubrs)
|
||||||
|
self.private = private
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
@ -263,11 +264,16 @@ class SimpleT2Decompiler(object):
|
|||||||
self.operandStack = []
|
self.operandStack = []
|
||||||
self.hintCount = 0
|
self.hintCount = 0
|
||||||
self.hintMaskBytes = 0
|
self.hintMaskBytes = 0
|
||||||
|
self.numRegions = 0
|
||||||
|
|
||||||
def check_program(self, program):
|
def check_program(self, program):
|
||||||
assert program, "illegal CharString: decompiled to empty program"
|
if self.private and self.private.isCFF2:
|
||||||
assert program[-1] in ("endchar", "return", "callsubr", "callgsubr",
|
if program:
|
||||||
"seac"), "illegal CharString"
|
assert program[-1] not in ("seac"), "illegal CharString Terminator"
|
||||||
|
else:
|
||||||
|
assert program, "illegal CharString: decompiled to empty program"
|
||||||
|
assert program[-1] in ("endchar", "return", "callsubr", "callgsubr",
|
||||||
|
"seac"), "illegal CharString"
|
||||||
|
|
||||||
def execute(self, charString):
|
def execute(self, charString):
|
||||||
self.callingStack.append(charString)
|
self.callingStack.append(charString)
|
||||||
@ -402,20 +408,6 @@ class SimpleT2Decompiler(object):
|
|||||||
def op_roll(self, index):
|
def op_roll(self, index):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class SimpleCFF2Decompiler(SimpleT2Decompiler):
|
|
||||||
def __init__(self, localSubrs, globalSubrs, private = None):
|
|
||||||
super(SimpleCFF2Decompiler, self).__init__(localSubrs, globalSubrs)
|
|
||||||
self.private = private
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
super(SimpleCFF2Decompiler, self).reset()
|
|
||||||
self.numRegions = 0
|
|
||||||
|
|
||||||
def check_program(self, program):
|
|
||||||
if program:
|
|
||||||
assert program[-1] not in ("seac"), "illegal CharString Terminator"
|
|
||||||
|
|
||||||
def op_blend(self, index):
|
def op_blend(self, index):
|
||||||
if self.numRegions == 0:
|
if self.numRegions == 0:
|
||||||
self.numRegions = self.private.getNumRegions()
|
self.numRegions = self.private.getNumRegions()
|
||||||
@ -424,13 +416,11 @@ class SimpleCFF2Decompiler(SimpleT2Decompiler):
|
|||||||
blendArgs = self.operandStack[-numOps:]
|
blendArgs = self.operandStack[-numOps:]
|
||||||
del self.operandStack[:-(numOps-numBlends)] # Leave the default operands on the stack.
|
del self.operandStack[:-(numOps-numBlends)] # Leave the default operands on the stack.
|
||||||
|
|
||||||
|
|
||||||
def op_vsindex(self, index):
|
def op_vsindex(self, index):
|
||||||
vi = self.pop()
|
vi = self.pop()
|
||||||
self.numRegions = self.private.getNumRegions(vi)
|
self.numRegions = self.private.getNumRegions(vi)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
t1Operators = [
|
t1Operators = [
|
||||||
# opcode name
|
# opcode name
|
||||||
(1, 'hstem'),
|
(1, 'hstem'),
|
||||||
@ -948,14 +938,13 @@ class T2CharString(ByteCodeBase):
|
|||||||
decompilerClass = SimpleT2Decompiler
|
decompilerClass = SimpleT2Decompiler
|
||||||
outlineExtractor = T2OutlineExtractor
|
outlineExtractor = T2OutlineExtractor
|
||||||
|
|
||||||
def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None, isCFF2 = False):
|
def __init__(self, bytecode=None, program=None, private = None, globalSubrs=None):
|
||||||
if program is None:
|
if program is None:
|
||||||
program = []
|
program = []
|
||||||
self.bytecode = bytecode
|
self.bytecode = bytecode
|
||||||
self.program = program
|
self.program = program
|
||||||
self.private = private
|
self.private = private
|
||||||
self.globalSubrs = globalSubrs if globalSubrs is not None else []
|
self.globalSubrs = globalSubrs if globalSubrs is not None else []
|
||||||
self.isCFF2 = isCFF2
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.bytecode is None:
|
if self.bytecode is None:
|
||||||
@ -984,7 +973,7 @@ class T2CharString(ByteCodeBase):
|
|||||||
self.width = extractor.width
|
self.width = extractor.width
|
||||||
|
|
||||||
def check_program(self, program):
|
def check_program(self, program):
|
||||||
if self.isCFF2:
|
if self.private and self.private.isCFF2:
|
||||||
if self.program:
|
if self.program:
|
||||||
assert self.program[-1] not in ("seac",), "illegal CFF2 CharString Termination"
|
assert self.program[-1] not in ("seac",), "illegal CFF2 CharString Termination"
|
||||||
else:
|
else:
|
||||||
@ -1027,8 +1016,8 @@ class T2CharString(ByteCodeBase):
|
|||||||
raise
|
raise
|
||||||
self.setBytecode(bytecode)
|
self.setBytecode(bytecode)
|
||||||
|
|
||||||
if self.isCFF2:
|
if self.private and self.private.isCFF2:
|
||||||
# If present, remove endchar operator.
|
# If present, remove return and endchar operators.
|
||||||
if self.bytecode and (byteord(self.bytecode[-1]) in (11, 14)):
|
if self.bytecode and (byteord(self.bytecode[-1]) in (11, 14)):
|
||||||
self.bytecode = self.bytecode[:-1]
|
self.bytecode = self.bytecode[:-1]
|
||||||
|
|
||||||
@ -1136,16 +1125,6 @@ class T2CharString(ByteCodeBase):
|
|||||||
program.append(token)
|
program.append(token)
|
||||||
self.setProgram(program)
|
self.setProgram(program)
|
||||||
|
|
||||||
class CFF2CharString(T2CharString):
|
|
||||||
|
|
||||||
decompilerClass = SimpleCFF2Decompiler
|
|
||||||
|
|
||||||
def __init__(self, bytecode=None, program=None, private=None, globalSubrs=None, isCFF2 = True):
|
|
||||||
super(CFF2CharString, self).__init__(bytecode, program, private, globalSubrs, isCFF2)
|
|
||||||
|
|
||||||
class CFF2SubrCharString(CFF2CharString):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class T1CharString(T2CharString):
|
class T1CharString(T2CharString):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user