Apply remainder of #1675210: add support for TrueType Collection (TTC) files.
git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@564 4cde692c-a291-49d1-8350-778aa11640f8
This commit is contained in:
parent
d67cf25974
commit
7e91e776c9
@ -42,7 +42,7 @@ Dumping 'prep' table...
|
||||
"""
|
||||
|
||||
#
|
||||
# $Id: __init__.py,v 1.50 2008-03-01 11:43:00 jvr Exp $
|
||||
# $Id: __init__.py,v 1.51 2009-02-22 08:55:00 pabs3 Exp $
|
||||
#
|
||||
|
||||
import sys
|
||||
@ -70,7 +70,8 @@ class TTFont:
|
||||
|
||||
def __init__(self, file=None, res_name_or_index=None,
|
||||
sfntVersion="\000\001\000\000", checkChecksums=0,
|
||||
verbose=0, recalcBBoxes=1, allowVID=0, ignoreDecompileErrors=False):
|
||||
verbose=0, recalcBBoxes=1, allowVID=0, ignoreDecompileErrors=False,
|
||||
fontNumber=-1):
|
||||
|
||||
"""The constructor can be called with a few different arguments.
|
||||
When reading a font from disk, 'file' should be either a pathname
|
||||
@ -152,7 +153,7 @@ class TTFont:
|
||||
file = open(file, "rb")
|
||||
else:
|
||||
pass # assume "file" is a readable file object
|
||||
self.reader = sfnt.SFNTReader(file, checkChecksums)
|
||||
self.reader = sfnt.SFNTReader(file, checkChecksums, fontNumber=fontNumber)
|
||||
self.sfntVersion = self.reader.sfntVersion
|
||||
|
||||
def close(self):
|
||||
|
@ -20,7 +20,7 @@ import os
|
||||
|
||||
class SFNTReader:
|
||||
|
||||
def __init__(self, file, checkChecksums=1):
|
||||
def __init__(self, file, checkChecksums=1, fontNumber=-1):
|
||||
self.file = file
|
||||
self.checkChecksums = checkChecksums
|
||||
data = self.file.read(sfntDirectorySize)
|
||||
@ -28,6 +28,19 @@ class SFNTReader:
|
||||
from fontTools import ttLib
|
||||
raise ttLib.TTLibError, "Not a TrueType or OpenType font (not enough data)"
|
||||
sstruct.unpack(sfntDirectoryFormat, data, self)
|
||||
if self.sfntVersion == "ttcf":
|
||||
assert ttcHeaderSize == sfntDirectorySize
|
||||
sstruct.unpack(ttcHeaderFormat, data, self)
|
||||
assert self.Version == 0x00010000 or self.Version == 0x00020000, "unrecognized TTC version 0x%08x" % self.Version
|
||||
if not 0 <= fontNumber < self.numFonts:
|
||||
from fontTools import ttLib
|
||||
raise ttLib.TTLibError, "specify a font number between 0 and %d (inclusive)" % (self.numFonts - 1)
|
||||
offsetTable = struct.unpack(">%dL" % self.numFonts, self.file.read(self.numFonts * 4))
|
||||
if self.Version == 0x00020000:
|
||||
pass # ignoring version 2.0 signatures
|
||||
self.file.seek(offsetTable[fontNumber])
|
||||
data = self.file.read(sfntDirectorySize)
|
||||
sstruct.unpack(sfntDirectoryFormat, data, self)
|
||||
if self.sfntVersion not in ("\000\001\000\000", "OTTO", "true"):
|
||||
from fontTools import ttLib
|
||||
raise ttLib.TTLibError, "Not a TrueType or OpenType font (bad sfntVersion)"
|
||||
@ -165,6 +178,19 @@ class SFNTWriter:
|
||||
|
||||
# -- sfnt directory helpers and cruft
|
||||
|
||||
ttcHeaderFormat = """
|
||||
> # big endian
|
||||
TTCTag: 4s # "ttcf"
|
||||
Version: L # 0x00010000 or 0x00020000
|
||||
numFonts: L # number of fonts
|
||||
# OffsetTable[numFonts]: L # array with offsets from beginning of file
|
||||
# ulDsigTag: L # version 2.0 only
|
||||
# ulDsigLength: L # version 2.0 only
|
||||
# ulDsigOffset: L # version 2.0 only
|
||||
"""
|
||||
|
||||
ttcHeaderSize = sstruct.calcsize(ttcHeaderFormat)
|
||||
|
||||
sfntDirectoryFormat = """
|
||||
> # big endian
|
||||
sfntVersion: 4s
|
||||
|
@ -41,6 +41,8 @@ usage: ttx [options] inputfile1 [... inputfileN]
|
||||
file smaller.
|
||||
-e Don't ignore decompilation errors, but show a full traceback
|
||||
and abort.
|
||||
-y <number> Select font number for TrueTrue Collection,
|
||||
starting from 0.
|
||||
|
||||
Compile options:
|
||||
-m Merge with TrueType-input-file: specify a TrueType or OpenType
|
||||
@ -99,6 +101,7 @@ class Options:
|
||||
def __init__(self, rawOptions, numFiles):
|
||||
self.onlyTables = []
|
||||
self.skipTables = []
|
||||
self.fontNumber = -1
|
||||
for option, value in rawOptions:
|
||||
# general options
|
||||
if option == "-h":
|
||||
@ -122,6 +125,8 @@ class Options:
|
||||
self.splitTables = 1
|
||||
elif option == "-i":
|
||||
self.disassembleInstructions = 0
|
||||
elif option == "-y":
|
||||
self.fontNumber = int(value)
|
||||
# compile options
|
||||
elif option == "-m":
|
||||
self.mergeFile = value
|
||||
@ -141,7 +146,7 @@ class Options:
|
||||
|
||||
def ttList(input, output, options):
|
||||
import string
|
||||
ttf = TTFont(input)
|
||||
ttf = TTFont(input, fontNumber=options.fontNumber)
|
||||
reader = ttf.reader
|
||||
tags = reader.keys()
|
||||
tags.sort()
|
||||
@ -163,7 +168,8 @@ def ttList(input, output, options):
|
||||
def ttDump(input, output, options):
|
||||
print 'Dumping "%s" to "%s"...' % (input, output)
|
||||
ttf = TTFont(input, 0, verbose=options.verbose, allowVID=options.allowVID,
|
||||
ignoreDecompileErrors=options.ignoreDecompileErrors)
|
||||
ignoreDecompileErrors=options.ignoreDecompileErrors,
|
||||
fontNumber=options.fontNumber)
|
||||
ttf.saveXML(output,
|
||||
tables=options.onlyTables,
|
||||
skipTables=options.skipTables,
|
||||
@ -224,6 +230,8 @@ def guessFileType(fileName):
|
||||
head = header[:4]
|
||||
if head == "OTTO":
|
||||
return "OTF"
|
||||
elif head == "ttcf":
|
||||
return "TTC"
|
||||
elif head in ("\0\1\0\0", "true"):
|
||||
return "TTF"
|
||||
elif head.lower() == "<?xm":
|
||||
@ -236,7 +244,7 @@ def guessFileType(fileName):
|
||||
|
||||
def parseOptions(args):
|
||||
try:
|
||||
rawOptions, files = getopt.getopt(args, "ld:vht:x:sim:bae")
|
||||
rawOptions, files = getopt.getopt(args, "ld:vht:x:sim:baey:")
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
|
||||
@ -248,7 +256,7 @@ def parseOptions(args):
|
||||
|
||||
for input in files:
|
||||
tp = guessFileType(input)
|
||||
if tp in ("OTF", "TTF"):
|
||||
if tp in ("OTF", "TTF", "TTC"):
|
||||
extension = ".ttx"
|
||||
if options.listTables:
|
||||
action = ttList
|
||||
|
Loading…
x
Reference in New Issue
Block a user