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
|
import sys
|
||||||
@ -70,7 +70,8 @@ class TTFont:
|
|||||||
|
|
||||||
def __init__(self, file=None, res_name_or_index=None,
|
def __init__(self, file=None, res_name_or_index=None,
|
||||||
sfntVersion="\000\001\000\000", checkChecksums=0,
|
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.
|
"""The constructor can be called with a few different arguments.
|
||||||
When reading a font from disk, 'file' should be either a pathname
|
When reading a font from disk, 'file' should be either a pathname
|
||||||
@ -152,7 +153,7 @@ class TTFont:
|
|||||||
file = open(file, "rb")
|
file = open(file, "rb")
|
||||||
else:
|
else:
|
||||||
pass # assume "file" is a readable file object
|
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
|
self.sfntVersion = self.reader.sfntVersion
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
@ -20,7 +20,7 @@ import os
|
|||||||
|
|
||||||
class SFNTReader:
|
class SFNTReader:
|
||||||
|
|
||||||
def __init__(self, file, checkChecksums=1):
|
def __init__(self, file, checkChecksums=1, fontNumber=-1):
|
||||||
self.file = file
|
self.file = file
|
||||||
self.checkChecksums = checkChecksums
|
self.checkChecksums = checkChecksums
|
||||||
data = self.file.read(sfntDirectorySize)
|
data = self.file.read(sfntDirectorySize)
|
||||||
@ -28,6 +28,19 @@ class SFNTReader:
|
|||||||
from fontTools import ttLib
|
from fontTools import ttLib
|
||||||
raise ttLib.TTLibError, "Not a TrueType or OpenType font (not enough data)"
|
raise ttLib.TTLibError, "Not a TrueType or OpenType font (not enough data)"
|
||||||
sstruct.unpack(sfntDirectoryFormat, data, self)
|
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"):
|
if self.sfntVersion not in ("\000\001\000\000", "OTTO", "true"):
|
||||||
from fontTools import ttLib
|
from fontTools import ttLib
|
||||||
raise ttLib.TTLibError, "Not a TrueType or OpenType font (bad sfntVersion)"
|
raise ttLib.TTLibError, "Not a TrueType or OpenType font (bad sfntVersion)"
|
||||||
@ -165,6 +178,19 @@ class SFNTWriter:
|
|||||||
|
|
||||||
# -- sfnt directory helpers and cruft
|
# -- 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 = """
|
sfntDirectoryFormat = """
|
||||||
> # big endian
|
> # big endian
|
||||||
sfntVersion: 4s
|
sfntVersion: 4s
|
||||||
|
@ -41,6 +41,8 @@ usage: ttx [options] inputfile1 [... inputfileN]
|
|||||||
file smaller.
|
file smaller.
|
||||||
-e Don't ignore decompilation errors, but show a full traceback
|
-e Don't ignore decompilation errors, but show a full traceback
|
||||||
and abort.
|
and abort.
|
||||||
|
-y <number> Select font number for TrueTrue Collection,
|
||||||
|
starting from 0.
|
||||||
|
|
||||||
Compile options:
|
Compile options:
|
||||||
-m Merge with TrueType-input-file: specify a TrueType or OpenType
|
-m Merge with TrueType-input-file: specify a TrueType or OpenType
|
||||||
@ -99,6 +101,7 @@ class Options:
|
|||||||
def __init__(self, rawOptions, numFiles):
|
def __init__(self, rawOptions, numFiles):
|
||||||
self.onlyTables = []
|
self.onlyTables = []
|
||||||
self.skipTables = []
|
self.skipTables = []
|
||||||
|
self.fontNumber = -1
|
||||||
for option, value in rawOptions:
|
for option, value in rawOptions:
|
||||||
# general options
|
# general options
|
||||||
if option == "-h":
|
if option == "-h":
|
||||||
@ -122,6 +125,8 @@ class Options:
|
|||||||
self.splitTables = 1
|
self.splitTables = 1
|
||||||
elif option == "-i":
|
elif option == "-i":
|
||||||
self.disassembleInstructions = 0
|
self.disassembleInstructions = 0
|
||||||
|
elif option == "-y":
|
||||||
|
self.fontNumber = int(value)
|
||||||
# compile options
|
# compile options
|
||||||
elif option == "-m":
|
elif option == "-m":
|
||||||
self.mergeFile = value
|
self.mergeFile = value
|
||||||
@ -141,7 +146,7 @@ class Options:
|
|||||||
|
|
||||||
def ttList(input, output, options):
|
def ttList(input, output, options):
|
||||||
import string
|
import string
|
||||||
ttf = TTFont(input)
|
ttf = TTFont(input, fontNumber=options.fontNumber)
|
||||||
reader = ttf.reader
|
reader = ttf.reader
|
||||||
tags = reader.keys()
|
tags = reader.keys()
|
||||||
tags.sort()
|
tags.sort()
|
||||||
@ -163,7 +168,8 @@ def ttList(input, output, options):
|
|||||||
def ttDump(input, output, options):
|
def ttDump(input, output, options):
|
||||||
print 'Dumping "%s" to "%s"...' % (input, output)
|
print 'Dumping "%s" to "%s"...' % (input, output)
|
||||||
ttf = TTFont(input, 0, verbose=options.verbose, allowVID=options.allowVID,
|
ttf = TTFont(input, 0, verbose=options.verbose, allowVID=options.allowVID,
|
||||||
ignoreDecompileErrors=options.ignoreDecompileErrors)
|
ignoreDecompileErrors=options.ignoreDecompileErrors,
|
||||||
|
fontNumber=options.fontNumber)
|
||||||
ttf.saveXML(output,
|
ttf.saveXML(output,
|
||||||
tables=options.onlyTables,
|
tables=options.onlyTables,
|
||||||
skipTables=options.skipTables,
|
skipTables=options.skipTables,
|
||||||
@ -224,6 +230,8 @@ def guessFileType(fileName):
|
|||||||
head = header[:4]
|
head = header[:4]
|
||||||
if head == "OTTO":
|
if head == "OTTO":
|
||||||
return "OTF"
|
return "OTF"
|
||||||
|
elif head == "ttcf":
|
||||||
|
return "TTC"
|
||||||
elif head in ("\0\1\0\0", "true"):
|
elif head in ("\0\1\0\0", "true"):
|
||||||
return "TTF"
|
return "TTF"
|
||||||
elif head.lower() == "<?xm":
|
elif head.lower() == "<?xm":
|
||||||
@ -236,7 +244,7 @@ def guessFileType(fileName):
|
|||||||
|
|
||||||
def parseOptions(args):
|
def parseOptions(args):
|
||||||
try:
|
try:
|
||||||
rawOptions, files = getopt.getopt(args, "ld:vht:x:sim:bae")
|
rawOptions, files = getopt.getopt(args, "ld:vht:x:sim:baey:")
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
usage()
|
usage()
|
||||||
|
|
||||||
@ -248,7 +256,7 @@ def parseOptions(args):
|
|||||||
|
|
||||||
for input in files:
|
for input in files:
|
||||||
tp = guessFileType(input)
|
tp = guessFileType(input)
|
||||||
if tp in ("OTF", "TTF"):
|
if tp in ("OTF", "TTF", "TTC"):
|
||||||
extension = ".ttx"
|
extension = ".ttx"
|
||||||
if options.listTables:
|
if options.listTables:
|
||||||
action = ttList
|
action = ttList
|
||||||
|
Loading…
x
Reference in New Issue
Block a user