1) Fold back in the changes introduced by Just van Possum in patch 744

2) Moved the C_F_F__2_test.py files and script under Tests/, paralleling what was done the C_F_F test  files.
This commit is contained in:
ReadRoberts 2017-01-18 13:07:03 -08:00 committed by Cosimo Lupo
parent 2b2aca1290
commit f208bf3421
No known key found for this signature in database
GPG Key ID: B61AAAD0B53A6419
4 changed files with 66 additions and 50 deletions

View File

@ -1743,14 +1743,6 @@ topDictOperators2 = [
(25, 'maxstack', 'number', None, None),
]
fontDictOperators = [
# opcode name argument type default converter
((12, 38), 'FontName', 'SID', None, None),
((12, 7), 'FontMatrix', 'array', [0.001, 0, 0, 0.001, 0, 0], None),
(4, 'Weight', 'SID', None, None),
(18, 'Private', ('number', 'number'), None, PrivateDictConverter()),
]
# Note! FDSelect and FDArray must both preceed CharStrings in the output XML build order,
# in order for the font to compile back from xml.
@ -1820,7 +1812,6 @@ addConverters(privateDictOperators)
addConverters(privateDictOperators2)
addConverters(topDictOperators)
addConverters(topDictOperators2)
addConverters(fontDictOperators)
class TopDictDecompiler(psCharStrings.DictDecompiler):
@ -1829,9 +1820,6 @@ class TopDictDecompiler(psCharStrings.DictDecompiler):
class TopDict2Decompiler(psCharStrings.DictDecompiler):
operators = buildOperatorDict(topDictOperators2)
class FontDictDecompiler(psCharStrings.DictDecompiler):
operators = buildOperatorDict(fontDictOperators)
class PrivateDictDecompiler(psCharStrings.DictDecompiler):
operators = buildOperatorDict(privateDictOperators)
@ -2030,17 +2018,38 @@ class TopDictCompiler(DictCompiler):
return children
class FontDictCompiler(DictCompiler):
class FontDictCompiler(TopDictCompiler):
opcodes = buildOpcodeDict(fontDictOperators)
def __init__(self, dictObj, strings, parent):
super(FontDictCompiler, self).__init__(dictObj, strings, parent)
#
# We now take some effort to detect if there were any key/value pairs supplied
# that were ignored in the FontDict context, and issue a warning for those cases.
#
ignoredNames = []
dictObj = self.dictObj
for name in sorted(set(dictObj.converters) - set(dictObj.order)):
if name in dictObj.rawDict:
# The font was directly read from binary. In this
# case, we want to report *all* "useless" key/value
# pairs that are in the font, not just the ones that
# are different from the default.
ignoredNames.append(name)
else:
# The font was probably read from a TTX file. We only
# warn about keys whos value is not the default. The
# ones that have the default value will not be written
# to binary anyway.
default = dictObj.defaults.get(name)
if default is not None:
conv = dictObj.converters[name]
default = conv.read(dictObj, default)
if getattr(dictObj, name, None) != default:
ignoredNames.append(name)
if ignoredNames:
log.warning("Some CFF FDArray/FontDict keys were ignored upon compile: " +
" ".join(sorted(ignoredNames)))
def getChildren(self, strings):
children = []
if hasattr(self.dictObj, "Private"):
privComp = self.dictObj.Private.getCompiler(strings, self)
children.append(privComp)
children.extend(privComp.getChildren(strings))
return children
class PrivateDictCompiler(DictCompiler):
@ -2114,27 +2123,15 @@ class BaseDict(object):
continue
conv = self.converters[name]
conv.xmlWrite(xmlWriter, name, value, progress)
ignoredNames = set(self.rawDict) - set(self.order)
if ignoredNames:
xmlWriter.comment("some keys were ignored: %s" % " ".join(sorted(ignoredNames)))
xmlWriter.newline()
def fromXML(self, name, attrs, content):
try:
conv = self.converters[name]
value = conv.xmlRead(name, attrs, content, self)
setattr(self, name, value)
except KeyError:
"""We now silently skip fields that are not in the dictOp list. This
is because fonttools used to use a dictOp list that contained all
the TopDict fields for both TopDict and FDArray Font Dicts, and most
of the fields are not relevant in the FDArray FontDict. As result,
there are 'ttx' files in the wild that contain all these fields in
teh FDArray Font DICTS. These are not actually illegal in the
context of an FDArray FontDict - you can legally, per spec, put any
arbitrary key/value pair in a FontDict - but are useless since
current major company CFF interpreters ignore anything but the set
listed in this file. So, we just silently skip them. An exception is
Weight: this is not used by any interpreter, but some foundries have
asked that this be supported in FDArray FontDicts just to preserve
information about the design when the font is being inspected."""
pass
conv = self.converters[name]
value = conv.xmlRead(name, attrs, content, self)
setattr(self, name, value)
class TopDict(BaseDict):
@ -2204,20 +2201,39 @@ class TopDict2(TopDict):
self.GlobalSubrs = GlobalSubrs
class FontDict(TopDict):
defaults = buildDefaults(fontDictOperators)
converters = buildConverters(fontDictOperators)
order = buildOrder(fontDictOperators)
decompilerClass = FontDictDecompiler
#
# Since fonttools used to pass a lot of fields that are not relevant in the FDArray
# FontDict, there are 'ttx' files in the wild that contain all these. These got in
# the ttx files because fonttools writes explicit values for all the TopDict default
# values. These are not actually illegal in the context of an FDArray FontDict - you
# can legally, per spec, put any arbitrary key/value pair in a FontDict - but are
# useless since current major company CFF interpreters ignore anything but the set
# listed in this file. So, we just silently skip them. An exception is Weight: this
# is not used by any interpreter, but some foundries have asked that this be
# supported in FDArray FontDicts just to preserve information about the design when
# the font is being inspected.
#
# On top of that, there are fonts out there that contain such useless FontDict values.
#
# By subclassing TopDict, we *allow* all key/values from TopDict, both when reading
# from binary or when reading from XML, but by overriding `order` with a limited
# list of names, we ensure that only the useful names ever get exported to XML and
# ever get compiled into the binary font.
#
# We override compilerClass so we can warn about "useless" key/value pairs, either
# from the original binary font or from TTX input.
#
# See:
# - https://github.com/fonttools/fonttools/issues/740
# - https://github.com/fonttools/fonttools/issues/601
# - https://github.com/adobe-type-tools/afdko/issues/137
#
order = ['FontName', 'FontMatrix', 'Weight', 'Private']
compilerClass = FontDictCompiler
def __init__(self, strings=None, file=None, offset=None, GlobalSubrs=None, topDict = None):
BaseDict.__init__(self, strings, file, offset)
self.GlobalSubrs = GlobalSubrs
super(FontDict, self).__init__(strings, file, offset, GlobalSubrs, None)
self.topDict = topDict
def toXML(self, xmlWriter, progress):
BaseDict.toXML(self, xmlWriter, progress)
class PrivateDict(BaseDict):