1from __future__ import print_function, division, absolute_import
2from fontTools.misc.py23 import *
3from fontTools.ttLib.ttFont import TTFont
4from fontTools.ttLib.sfnt import readTTCHeader, writeTTCHeader
5import struct
6import logging
7
8log = logging.getLogger(__name__)
9
10
11class TTCollection(object):
12
13	"""Object representing a TrueType Collection / OpenType Collection.
14	The main API is self.fonts being a list of TTFont instances.
15
16	If shareTables is True, then different fonts in the collection
17	might point to the same table object if the data for the table was
18	the same in the font file.  Note, however, that this might result
19	in suprises and incorrect behavior if the different fonts involved
20	have different GlyphOrder.  Use only if you know what you are doing.
21	"""
22
23	def __init__(self, file=None, shareTables=False, **kwargs):
24		fonts = self.fonts = []
25		if file is None:
26			return
27
28		assert 'fontNumber' not in kwargs, kwargs
29
30		if not hasattr(file, "read"):
31			file = open(file, "rb")
32
33		tableCache = {} if shareTables else None
34
35		header = readTTCHeader(file)
36		for i in range(header.numFonts):
37			font = TTFont(file, fontNumber=i, _tableCache=tableCache, **kwargs)
38			fonts.append(font)
39
40	def save(self, file, shareTables=True):
41		"""Save the font to disk. Similarly to the constructor,
42		the 'file' argument can be either a pathname or a writable
43		file object.
44		"""
45		if not hasattr(file, "write"):
46			final = None
47			file = open(file, "wb")
48		else:
49			# assume "file" is a writable file object
50			# write to a temporary stream to allow saving to unseekable streams
51			final = file
52			file = BytesIO()
53
54		tableCache = {} if shareTables else None
55
56		offsets_offset = writeTTCHeader(file, len(self.fonts))
57		offsets = []
58		for font in self.fonts:
59			offsets.append(file.tell())
60			font._save(file, tableCache=tableCache)
61			file.seek(0,2)
62
63		file.seek(offsets_offset)
64		file.write(struct.pack(">%dL" % len(self.fonts), *offsets))
65
66		if final:
67			final.write(file.getvalue())
68		file.close()
69
70	def saveXML(self, fileOrPath, newlinestr=None, writeVersion=True, **kwargs):
71
72		from fontTools.misc import xmlWriter
73		writer = xmlWriter.XMLWriter(fileOrPath, newlinestr=newlinestr)
74
75		if writeVersion:
76			from fontTools import version
77			version = ".".join(version.split('.')[:2])
78			writer.begintag("ttCollection", ttLibVersion=version)
79		else:
80			writer.begintag("ttCollection")
81		writer.newline()
82		writer.newline()
83
84		for font in self.fonts:
85			font._saveXML(writer, writeVersion=False, **kwargs)
86			writer.newline()
87
88		writer.endtag("ttCollection")
89		writer.newline()
90
91		writer.close()
92
93
94	def __getitem__(self, item):
95		return self.fonts[item]
96
97	def __setitem__(self, item, value):
98		self.fonts[item] = values
99
100	def __delitem__(self, item):
101		return self.fonts[item]
102
103	def __len__(self):
104		return len(self.fonts)
105
106	def __iter__(self):
107		return iter(self.fonts)
108