Пример #1
0
    def keys(self):
        """
        Return a list of all tables in the font. If a table order
        has been set manually or as the result of opening an existing
        WOFF file, the set table order will be in the list first.
        Tables not defined in an existing order will be sorted following
        the suggested ordering in the OTF/OFF specification.

        The first table listed in all cases is the GlyphOrder pseudo table.
        """
        tags = set(self.tables.keys())
        if self.reader is not None:
            tags = tags | set(self.reader.keys())
        tags = list(tags)
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        return ["GlyphOrder"] + sortedTagList(tags, self._tableOrder)
Пример #2
0
    def keys(self):
        """
        Return a list of all tables in the font. If a table order
        has been set manually or as the result of opening an existing
        WOFF file, the set table order will be in the list first.
        Tables not defined in an existing order will be sorted following
        the suggested ordering in the OTF/OFF specification.

        The first table listed in all cases is the GlyphOrder pseudo table.
        """
        tags = set(self.tables.keys())
        if self.reader is not None:
            tags = tags | set(self.reader.keys())
        tags = list(tags)
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        return ["GlyphOrder"] + sortedTagList(tags, self._tableOrder)
Пример #3
0
    def save(self,
             file,
             compressionLevel=9,
             recompressTables=False,
             reorderTables=True,
             recalculateHeadChecksum=True):
        """
        Save a WOFF into file a file object specifified by the
        file argument.. Optionally, file can be a path and a
        new file will be created at that location.

        compressionLevel is the compression level to be
        used with zlib. This must be an int between 1 and 9.
        The default is 9, the highest compression, but slowest
        compression time.

        Set recompressTables to True if you want any already
        compressed tables to be decompressed and then recompressed
        using the level specified by compressionLevel.

        If you want the tables in the WOFF reordered following
        the suggested optimal table orderings described in the
        OTF/OFF sepecification, set reorderTables to True.
        Tables cannot be reordered if a DSIG table is in the font.

        If you change any of the SFNT data or reorder the tables,
        the head table checkSumAdjustment must be recalculated.
        If you are not changing any of the SFNT data, you can set
        recalculateHeadChecksum to False to prevent the recalculation.
        This must be set to False if the font contains a DSIG table.
        """
        # if DSIG is to be written, the table order
        # must be completely specified. otherwise the
        # DSIG may not be valid after decoding the WOFF.
        tags = self.keys()
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        if "DSIG" in tags:
            if self._tableOrder is None or (set(self._tableOrder) !=
                                            set(tags)):
                raise WOFFLibError(
                    "A complete table order must be supplied when saving a font with a 'DSIG' table."
                )
            elif reorderTables:
                raise WOFFLibError(
                    "Tables can not be reordered when a 'DSIG' table is in the font. Set reorderTables to False."
                )
            elif recalculateHeadChecksum:
                raise WOFFLibError(
                    "The 'head' table checkSumAdjustment can not be recalculated when a 'DSIG' table is in the font."
                )
        # sort the tags if necessary
        if reorderTables:
            tags = sortedTagList(tags)
        # open a file if necessary
        closeStream = False
        if not hasattr(file, "write"):
            closeStream = True
            file = open(file, "wb")
        # write the table data
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        numTables = len(tags)
        writer = WOFFWriter(file,
                            numTables,
                            flavor=self.flavor,
                            majorVersion=self.majorVersion,
                            minorVersion=self.minorVersion,
                            compressionLevel=compressionLevel,
                            recalculateHeadChecksum=recalculateHeadChecksum,
                            verbose=self.verbose)
        for tag in tags:
            origData = None
            origLength = None
            origChecksum = None
            compLength = None
            # table is loaded
            if self.isLoaded(tag):
                origData = self.getTableData(tag)
            # table is in reader
            elif self.reader is not None:
                if recompressTables:
                    origData = self.getTableData(tag)
                else:
                    if self.verbose:
                        debugmsg("Reading '%s' table from disk" % tag)
                    origData, origLength, origChecksum, compLength = self.reader.getCompressedTableData(
                        tag)
            # add to writer
            writer.setTable(tag,
                            origData,
                            origLength=origLength,
                            origChecksum=origChecksum,
                            compLength=compLength)
        # write the metadata
        metadata = None
        metaOrigLength = None
        metaLength = None
        if hasattr(self, "metadata"):
            declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            tree = ElementTree.ElementTree(self.metadata)
            f = StringIO()
            tree.write(f, encoding="utf-8")
            metadata = f.getvalue()
            # make sure the metadata starts with the declaration
            if not metadata.startswith(declaration):
                metadata = declaration + metadata
            del f
        elif self.reader is not None:
            if recompressTables:
                metadata = self.reader.metadata
            else:
                metadata, metaOrigLength, metaLength = self.reader.getCompressedMetadata(
                )
        if metadata:
            writer.setMetadata(metadata,
                               metaOrigLength=metaOrigLength,
                               metaLength=metaLength)
        # write the private data
        privData = self.privateData
        if privData:
            writer.setPrivateData(privData)
        # close the writer
        writer.close()
        # close the file
        if closeStream:
            file.close()
Пример #4
0
    def save(self, file, compressionLevel=9, recompressTables=False, reorderTables=True, recalculateHeadChecksum=True):
        """
        Save a WOFF into file a file object specifified by the
        file argument.. Optionally, file can be a path and a
        new file will be created at that location.

        compressionLevel is the compression level to be
        used with zlib. This must be an int between 1 and 9.
        The default is 9, the highest compression, but slowest
        compression time.

        Set recompressTables to True if you want any already
        compressed tables to be decompressed and then recompressed
        using the level specified by compressionLevel.

        If you want the tables in the WOFF reordered following
        the suggested optimal table orderings described in the
        OTF/OFF sepecification, set reorderTables to True.
        Tables cannot be reordered if a DSIG table is in the font.

        If you change any of the SFNT data or reorder the tables,
        the head table checkSumAdjustment must be recalculated.
        If you are not changing any of the SFNT data, you can set
        recalculateHeadChecksum to False to prevent the recalculation.
        This must be set to False if the font contains a DSIG table.
        """
        # if DSIG is to be written, the table order
        # must be completely specified. otherwise the
        # DSIG may not be valid after decoding the WOFF.
        tags = self.keys()
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        if "DSIG" in tags:
            if self._tableOrder is None or (set(self._tableOrder) != set(tags)):
                raise WOFFLibError("A complete table order must be supplied when saving a font with a 'DSIG' table.")
            elif reorderTables:
                raise WOFFLibError("Tables can not be reordered when a 'DSIG' table is in the font. Set reorderTables to False.")
            elif recalculateHeadChecksum:
                raise WOFFLibError("The 'head' table checkSumAdjustment can not be recalculated when a 'DSIG' table is in the font.")
        # sort the tags if necessary
        if reorderTables:
            tags = sortedTagList(tags)
        # open a file if necessary
        closeStream = False
        if not hasattr(file, "write"):
            closeStream = True
            file = open(file, "wb")
        # write the table data
        if "GlyphOrder" in tags:
            tags.remove("GlyphOrder")
        numTables = len(tags)
        writer = WOFFWriter(file, numTables, flavor=self.flavor,
            majorVersion=self.majorVersion, minorVersion=self.minorVersion,
            compressionLevel=compressionLevel, recalculateHeadChecksum=recalculateHeadChecksum,
            verbose=self.verbose)
        for tag in tags:
            origData = None
            origLength = None
            origChecksum = None
            compLength = None
            # table is loaded
            if self.isLoaded(tag):
                origData = self.getTableData(tag)
            # table is in reader
            elif self.reader is not None:
                if recompressTables:
                    origData = self.getTableData(tag)
                else:
                    if self.verbose:
                        debugmsg("Reading '%s' table from disk" % tag)
                    origData, origLength, origChecksum, compLength = self.reader.getCompressedTableData(tag)
            # add to writer
            writer.setTable(tag, origData, origLength=origLength, origChecksum=origChecksum, compLength=compLength)
        # write the metadata
        metadata = None
        metaOrigLength = None
        metaLength = None
        if hasattr(self, "metadata"):
            declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            tree = ElementTree.ElementTree(self.metadata)
            f = StringIO()
            tree.write(f, encoding="utf-8")
            metadata = f.getvalue()
            # make sure the metadata starts with the declaration
            if not metadata.startswith(declaration):
                metadata = declaration + metadata
            del f
        elif self.reader is not None:
            if recompressTables:
                metadata = self.reader.metadata
            else:
                metadata, metaOrigLength, metaLength = self.reader.getCompressedMetadata()
        if metadata:
            writer.setMetadata(metadata, metaOrigLength=metaOrigLength, metaLength=metaLength)
        # write the private data
        privData = self.privateData
        if privData:
            writer.setPrivateData(privData)
        # close the writer
        writer.close()
        # close the file
        if closeStream:
            file.close()