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