Revert "Merge pull request #1130 from anthrotype/temp-revert-split-glyphs"
This reverts commit 060f856f92e0fb2d8e60f6be080c89c08528bacb, reversing changes made to 1e42224af741fac73e20f7193d8115cfda7d3594.
This commit is contained in:
parent
0459aaacdf
commit
232e2b8467
@ -17,7 +17,8 @@ BUFSIZE = 0x4000
|
||||
|
||||
class XMLReader(object):
|
||||
|
||||
def __init__(self, fileOrPath, ttFont, progress=None, quiet=None):
|
||||
def __init__(self, fileOrPath, ttFont, progress=None, quiet=None, contentOnly=False):
|
||||
|
||||
if fileOrPath == '-':
|
||||
fileOrPath = sys.stdin
|
||||
if not hasattr(fileOrPath, "read"):
|
||||
@ -35,6 +36,7 @@ class XMLReader(object):
|
||||
self.quiet = quiet
|
||||
self.root = None
|
||||
self.contentStack = []
|
||||
self.contentOnly = contentOnly
|
||||
self.stackSize = 0
|
||||
|
||||
def read(self, rootless=False):
|
||||
@ -73,8 +75,24 @@ class XMLReader(object):
|
||||
parser.Parse(chunk, 0)
|
||||
|
||||
def _startElementHandler(self, name, attrs):
|
||||
if self.stackSize == 1 and self.contentOnly:
|
||||
# We already know the table we're parsing, skip
|
||||
# parsing the table tag and continue to
|
||||
# stack '2' which begins parsing content
|
||||
self.contentStack.append([])
|
||||
self.stackSize = 2
|
||||
return
|
||||
stackSize = self.stackSize
|
||||
self.stackSize = stackSize + 1
|
||||
subFile = attrs.get("src")
|
||||
if subFile is not None:
|
||||
if hasattr(self.file, 'name'):
|
||||
# if file has a name, get its parent directory
|
||||
dirname = os.path.dirname(self.file.name)
|
||||
else:
|
||||
# else fall back to using the current working directory
|
||||
dirname = os.getcwd()
|
||||
subFile = os.path.join(dirname, subFile)
|
||||
if not stackSize:
|
||||
if name != "ttFont":
|
||||
raise TTXParseError("illegal root tag: %s" % name)
|
||||
@ -85,15 +103,7 @@ class XMLReader(object):
|
||||
self.ttFont.sfntVersion = sfntVersion
|
||||
self.contentStack.append([])
|
||||
elif stackSize == 1:
|
||||
subFile = attrs.get("src")
|
||||
if subFile is not None:
|
||||
if hasattr(self.file, 'name'):
|
||||
# if file has a name, get its parent directory
|
||||
dirname = os.path.dirname(self.file.name)
|
||||
else:
|
||||
# else fall back to using the current working directory
|
||||
dirname = os.getcwd()
|
||||
subFile = os.path.join(dirname, subFile)
|
||||
subReader = XMLReader(subFile, self.ttFont, self.progress)
|
||||
subReader.read()
|
||||
self.contentStack.append([])
|
||||
@ -119,6 +129,11 @@ class XMLReader(object):
|
||||
self.currentTable = tableClass(tag)
|
||||
self.ttFont[tag] = self.currentTable
|
||||
self.contentStack.append([])
|
||||
elif stackSize == 2 and subFile is not None:
|
||||
subReader = XMLReader(subFile, self.ttFont, self.progress, contentOnly=True)
|
||||
subReader.read()
|
||||
self.contentStack.append([])
|
||||
self.root = subReader.root
|
||||
elif stackSize == 2:
|
||||
self.contentStack.append([])
|
||||
self.root = (name, attrs, self.contentStack[-1])
|
||||
@ -134,12 +149,13 @@ class XMLReader(object):
|
||||
def _endElementHandler(self, name):
|
||||
self.stackSize = self.stackSize - 1
|
||||
del self.contentStack[-1]
|
||||
if self.stackSize == 1:
|
||||
self.root = None
|
||||
elif self.stackSize == 2:
|
||||
name, attrs, content = self.root
|
||||
self.currentTable.fromXML(name, attrs, content, self.ttFont)
|
||||
self.root = None
|
||||
if not self.contentOnly:
|
||||
if self.stackSize == 1:
|
||||
self.root = None
|
||||
elif self.stackSize == 2:
|
||||
name, attrs, content = self.root
|
||||
self.currentTable.fromXML(name, attrs, content, self.ttFont)
|
||||
self.root = None
|
||||
|
||||
|
||||
class ProgressPrinter(object):
|
||||
|
@ -5,6 +5,7 @@ from collections import namedtuple
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.misc import sstruct
|
||||
from fontTools import ttLib
|
||||
from fontTools import version
|
||||
from fontTools.misc.textTools import safeEval, pad
|
||||
from fontTools.misc.arrayTools import calcBounds, calcIntBounds, pointInRect
|
||||
from fontTools.misc.bezierTools import calcQuadraticBounds
|
||||
@ -16,10 +17,17 @@ import sys
|
||||
import struct
|
||||
import array
|
||||
import logging
|
||||
|
||||
import os
|
||||
from fontTools.misc import xmlWriter
|
||||
from fontTools.misc.filenames import userNameToFileName
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# We compute the version the same as is computed in ttlib/__init__
|
||||
# so that we can write 'ttLibVersion' attribute of the glyf TTX files
|
||||
# when glyf is written to separate files.
|
||||
version = ".".join(version.split('.')[:2])
|
||||
|
||||
#
|
||||
# The Apple and MS rasterizers behave differently for
|
||||
# scaled composite components: one does scale first and then translate
|
||||
@ -110,31 +118,64 @@ class table__g_l_y_f(DefaultTable.DefaultTable):
|
||||
ttFont['maxp'].numGlyphs = len(self.glyphs)
|
||||
return data
|
||||
|
||||
def toXML(self, writer, ttFont):
|
||||
writer.newline()
|
||||
def toXML(self, writer, ttFont, splitGlyphs=False):
|
||||
notice = (
|
||||
"The xMin, yMin, xMax and yMax values\n"
|
||||
"will be recalculated by the compiler.")
|
||||
glyphNames = ttFont.getGlyphNames()
|
||||
writer.comment("The xMin, yMin, xMax and yMax values\nwill be recalculated by the compiler.")
|
||||
writer.newline()
|
||||
writer.newline()
|
||||
if not splitGlyphs:
|
||||
writer.newline()
|
||||
writer.comment(notice)
|
||||
writer.newline()
|
||||
writer.newline()
|
||||
numGlyphs = len(glyphNames)
|
||||
if splitGlyphs:
|
||||
path, ext = os.path.splitext(writer.file.name)
|
||||
existingGlyphFiles = set()
|
||||
for glyphName in glyphNames:
|
||||
glyph = self[glyphName]
|
||||
if glyph.numberOfContours:
|
||||
writer.begintag('TTGlyph', [
|
||||
("name", glyphName),
|
||||
("xMin", glyph.xMin),
|
||||
("yMin", glyph.yMin),
|
||||
("xMax", glyph.xMax),
|
||||
("yMax", glyph.yMax),
|
||||
])
|
||||
writer.newline()
|
||||
glyph.toXML(writer, ttFont)
|
||||
writer.endtag('TTGlyph')
|
||||
writer.newline()
|
||||
if splitGlyphs:
|
||||
glyphPath = userNameToFileName(
|
||||
tounicode(glyphName, 'utf-8'),
|
||||
existingGlyphFiles,
|
||||
prefix=("%s%s"%(path, "_")),
|
||||
suffix=ext)
|
||||
existingGlyphFiles.add(glyphPath.lower())
|
||||
glyphWriter = xmlWriter.XMLWriter(
|
||||
glyphPath, idlefunc=writer.idlefunc,
|
||||
newlinestr=writer.newlinestr)
|
||||
glyphWriter.begintag("ttFont", ttLibVersion=version)
|
||||
glyphWriter.newline()
|
||||
glyphWriter.begintag("glyf")
|
||||
glyphWriter.newline()
|
||||
glyphWriter.comment(notice)
|
||||
glyphWriter.newline()
|
||||
writer.simpletag("TTGlyph", src=os.path.basename(glyphPath))
|
||||
else:
|
||||
glyphWriter = writer
|
||||
glyphWriter.begintag('TTGlyph', [
|
||||
("name", glyphName),
|
||||
("xMin", glyph.xMin),
|
||||
("yMin", glyph.yMin),
|
||||
("xMax", glyph.xMax),
|
||||
("yMax", glyph.yMax),
|
||||
])
|
||||
glyphWriter.newline()
|
||||
glyph.toXML(glyphWriter, ttFont)
|
||||
glyphWriter.endtag('TTGlyph')
|
||||
glyphWriter.newline()
|
||||
if splitGlyphs:
|
||||
glyphWriter.endtag("glyf")
|
||||
glyphWriter.newline()
|
||||
glyphWriter.endtag("ttFont")
|
||||
glyphWriter.newline()
|
||||
glyphWriter.close()
|
||||
else:
|
||||
writer.simpletag('TTGlyph', name=glyphName)
|
||||
writer.comment("contains no outline data")
|
||||
writer.newline()
|
||||
if not splitGlyphs:
|
||||
writer.newline()
|
||||
writer.newline()
|
||||
|
||||
def fromXML(self, name, attrs, content, ttFont):
|
||||
|
@ -224,8 +224,8 @@ class TTFont(object):
|
||||
def _saveXML(self, writer,
|
||||
writeVersion=True,
|
||||
quiet=None, tables=None, skipTables=None, splitTables=False,
|
||||
disassembleInstructions=True, bitmapGlyphDataFormat='raw'):
|
||||
|
||||
splitGlyphs=False, disassembleInstructions=True,
|
||||
bitmapGlyphDataFormat='raw'):
|
||||
|
||||
if quiet is not None:
|
||||
deprecateArgument("quiet", "configure logging instead")
|
||||
@ -251,6 +251,9 @@ class TTFont(object):
|
||||
writer.begintag("ttFont", sfntVersion=repr(tostr(self.sfntVersion))[1:-1])
|
||||
writer.newline()
|
||||
|
||||
# always splitTables if splitGlyphs is enabled
|
||||
splitTables = splitTables or splitGlyphs
|
||||
|
||||
if not splitTables:
|
||||
writer.newline()
|
||||
else:
|
||||
@ -270,7 +273,7 @@ class TTFont(object):
|
||||
writer.newline()
|
||||
else:
|
||||
tableWriter = writer
|
||||
self._tableToXML(tableWriter, tag)
|
||||
self._tableToXML(tableWriter, tag, splitGlyphs=splitGlyphs)
|
||||
if splitTables:
|
||||
tableWriter.endtag("ttFont")
|
||||
tableWriter.newline()
|
||||
@ -278,7 +281,7 @@ class TTFont(object):
|
||||
writer.endtag("ttFont")
|
||||
writer.newline()
|
||||
|
||||
def _tableToXML(self, writer, tag, quiet=None):
|
||||
def _tableToXML(self, writer, tag, quiet=None, splitGlyphs=False):
|
||||
if quiet is not None:
|
||||
deprecateArgument("quiet", "configure logging instead")
|
||||
if tag in self:
|
||||
@ -298,8 +301,8 @@ class TTFont(object):
|
||||
attrs['raw'] = True
|
||||
writer.begintag(xmlTag, **attrs)
|
||||
writer.newline()
|
||||
if tag in ("glyf", "CFF "):
|
||||
table.toXML(writer, self)
|
||||
if tag == "glyf":
|
||||
table.toXML(writer, self, splitGlyphs=splitGlyphs)
|
||||
else:
|
||||
table.toXML(writer, self)
|
||||
writer.endtag(xmlTag)
|
||||
|
@ -38,6 +38,9 @@ usage: ttx [options] inputfile1 [... inputfileN]
|
||||
to the individual table dumps. This file can be used as
|
||||
input to ttx, as long as the table files are in the
|
||||
same directory.
|
||||
-g Split glyf table: Save the glyf data into separate TTX files
|
||||
per glyph and write a small TTX for the glyf table which
|
||||
contains references to the individual TTGlyph elements.
|
||||
-i Do NOT disassemble TT instructions: when this option is given,
|
||||
all TrueType programs (glyph programs, the font program and the
|
||||
pre-program) will be written to the TTX file as hex data
|
||||
@ -110,6 +113,7 @@ class Options(object):
|
||||
verbose = False
|
||||
quiet = False
|
||||
splitTables = False
|
||||
splitGlyphs = False
|
||||
disassembleInstructions = True
|
||||
mergeFile = None
|
||||
recalcBBoxes = True
|
||||
@ -160,6 +164,8 @@ class Options(object):
|
||||
self.skipTables.append(value)
|
||||
elif option == "-s":
|
||||
self.splitTables = True
|
||||
elif option == "-g":
|
||||
self.splitGlyphs = True
|
||||
elif option == "-i":
|
||||
self.disassembleInstructions = False
|
||||
elif option == "-z":
|
||||
@ -255,6 +261,7 @@ def ttDump(input, output, options):
|
||||
tables=options.onlyTables,
|
||||
skipTables=options.skipTables,
|
||||
splitTables=options.splitTables,
|
||||
splitGlyphs=options.splitGlyphs,
|
||||
disassembleInstructions=options.disassembleInstructions,
|
||||
bitmapGlyphDataFormat=options.bitmapGlyphDataFormat,
|
||||
newlinestr=options.newlinestr)
|
||||
@ -318,7 +325,7 @@ def guessFileType(fileName):
|
||||
|
||||
|
||||
def parseOptions(args):
|
||||
rawOptions, files = getopt.getopt(args, "ld:o:fvqht:x:sim:z:baey:",
|
||||
rawOptions, files = getopt.getopt(args, "ld:o:fvqht:x:sgim:z:baey:",
|
||||
['unicodedata=', "recalc-timestamp", 'flavor=', 'version',
|
||||
'with-zopfli', 'newline='])
|
||||
|
||||
|
@ -142,7 +142,48 @@ class TestXMLReader(unittest.TestCase):
|
||||
self.assertTrue(reader.file.closed)
|
||||
os.remove(tmp.name)
|
||||
|
||||
def test_read_sub_file(self):
|
||||
# Verifies that sub-file content is able to be read to a table.
|
||||
expectedContent = u'testContent'
|
||||
expectedNameID = '1'
|
||||
expectedPlatform = '3'
|
||||
expectedLangId = '0x409'
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||
subFileData = (
|
||||
'<ttFont ttLibVersion="3.15">'
|
||||
'<name>'
|
||||
'<namerecord nameID="%s" platformID="%s" platEncID="1" langID="%s">'
|
||||
'%s'
|
||||
'</namerecord>'
|
||||
'</name>'
|
||||
'</ttFont>'
|
||||
) % (expectedNameID, expectedPlatform, expectedLangId, expectedContent)
|
||||
tmp.write(subFileData.encode("utf-8"))
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp2:
|
||||
fileData = (
|
||||
'<ttFont ttLibVersion="3.15">'
|
||||
'<name>'
|
||||
'<namerecord src="%s"/>'
|
||||
'</name>'
|
||||
'</ttFont>'
|
||||
) % tmp.name
|
||||
tmp2.write(fileData.encode('utf-8'))
|
||||
|
||||
ttf = TTFont()
|
||||
with open(tmp2.name, "rb") as f:
|
||||
reader = XMLReader(f, ttf)
|
||||
reader.read()
|
||||
reader.close()
|
||||
nameTable = ttf['name']
|
||||
self.assertTrue(int(expectedNameID) == nameTable.names[0].nameID)
|
||||
self.assertTrue(int(expectedLangId, 16) == nameTable.names[0].langID)
|
||||
self.assertTrue(int(expectedPlatform) == nameTable.names[0].platformID)
|
||||
self.assertEqual(expectedContent, nameTable.names[0].string.decode(nameTable.names[0].getEncoding()))
|
||||
|
||||
os.remove(tmp.name)
|
||||
os.remove(tmp2.name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
Loading…
x
Reference in New Issue
Block a user