# Source code for fontTools.ttLib.ttCollection

    from fontTools.ttLib.ttFont import TTFont
    from fontTools.ttLib.sfnt import readTTCHeader, writeTTCHeader
    from io import BytesIO
    import struct
    import logging

    log = logging.getLogger(__name__)

    class TTCollection(object):
        """Object representing a TrueType Collection / OpenType Collection.
        The main API is self.fonts being a list of TTFont instances.

        If shareTables is True, then different fonts in the collection
        might point to the same table object if the data for the table was
        the same in the font file.  Note, however, that this might result
        in suprises and incorrect behavior if the different fonts involved
        have different GlyphOrder.  Use only if you know what you are doing.
        """

        def __init__(self, file=None, shareTables=False, **kwargs):
            fonts = self.fonts = []
            if file is None:
                return

            assert "fontNumber" not in kwargs, kwargs

            closeStream = False
            if not hasattr(file, "read"):
                file = open(file, "rb")
                closeStream = True

            tableCache = {} if shareTables else None

            header = readTTCHeader(file)
            for i in range(header.numFonts):
                font = TTFont(file, fontNumber=i, _tableCache=tableCache, **kwargs)
                fonts.append(font)

            # don't close file if lazy=True, as the TTFont hold a reference to the original
            # file; the file will be closed once the TTFonts are closed in the
            # TTCollection.close(). We still want to close the file if lazy is None or
            # False, because in that case the TTFont no longer need the original file
            # and we want to avoid 'ResourceWarning: unclosed file'.
            if not kwargs.get("lazy") and closeStream:
                file.close()

        def __enter__(self):
            return self

        def __exit__(self, type, value, traceback):
            self.close()

        def close(self):
            for font in self.fonts:
                font.close()

        def save(self, file, shareTables=True):
            """Save the font to disk. Similarly to the constructor,
            the 'file' argument can be either a pathname or a writable
            file object.
            """
            if not hasattr(file, "write"):
                final = None
                file = open(file, "wb")
            else:
                # assume "file" is a writable file object
                # write to a temporary stream to allow saving to unseekable streams
                final = file
                file = BytesIO()

            tableCache = {} if shareTables else None

            offsets_offset = writeTTCHeader(file, len(self.fonts))
            offsets = []
            for font in self.fonts:
                offsets.append(file.tell())
                font._save(file, tableCache=tableCache)
                file.seek(0, 2)

            file.seek(offsets_offset)
            file.write(struct.pack(">%dL" % len(self.fonts), *offsets))

            if final:
                final.write(file.getvalue())
            file.close()

        def saveXML(self, fileOrPath, newlinestr="\n", writeVersion=True, **kwargs):
            from fontTools.misc import xmlWriter

            writer = xmlWriter.XMLWriter(fileOrPath, newlinestr=newlinestr)

            if writeVersion:
                from fontTools import version

                version = ".".join(version.split(".")[:2])
                writer.begintag("ttCollection", ttLibVersion=version)
            else:
                writer.begintag("ttCollection")
            writer.newline()
            writer.newline()

            for font in self.fonts:
                font._saveXML(writer, writeVersion=False, **kwargs)
                writer.newline()

            writer.endtag("ttCollection")
            writer.newline()

            writer.close()

        def __getitem__(self, item):
            return self.fonts[item]

        def __setitem__(self, item, value):
            self.fonts[item] = value

        def __delitem__(self, item):
            return self.fonts[item]

        def __len__(self):
            return len(self.fonts)

        def __iter__(self):
            return iter(self.fonts)