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
diff --git a/Lib/fontTools/ttLib/sfnt.py b/Lib/fontTools/ttLib/sfnt.py
index db90c7a..c0d8ff1 100644
--- a/Lib/fontTools/ttLib/sfnt.py
+++ b/Lib/fontTools/ttLib/sfnt.py
@@ -20,7 +20,7 @@
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 @@
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 @@
# -- 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