Beispiel #1
0
def defaultTestData(header=None, directory=None, collectionHeader=None, collectionDirectory=None, tableData=None, compressedData=None, metadata=None, privateData=None, flavor="cff", Base128Bug=False):
    isCollection = collectionDirectory is not None
    parts = []
    # setup the header
    if header is None:
        header = deepcopy(testDataWOFFHeader)
    parts.append(header)
    # setup the directory
    if directory is None:
        if flavor == "cff":
            directory = deepcopy(testCFFDataWOFFDirectory)
        else:
            directory = deepcopy(testTTFDataWOFFDirectory)
    parts.append(directory)
    if isCollection:
        if collectionHeader is None:
            collectionHeader = dict(version=0x00010000, numFonts=len(collectionDirectory))
        parts.append(collectionHeader)
        parts.append(collectionDirectory)
    # setup the table data
    if tableData is None:
        if flavor == "cff":
            tableData = deepcopy(sfntCFFTableData)
        else:
            tableData = deepcopy(sfntTTFTableData)
    if compressedData is None:
        if flavor == "cff":
            compressedData = deepcopy(sfntCFFCompressedData)
        else:
            compressedData = deepcopy(sfntTTFCompressedData)
    parts.append(compressedData)
    # sanity checks
    assert len(directory) == len(tableData)
    if not isCollection:
        assert set(tableData.keys()) == set([entry["tag"] for entry in directory])
    # apply the directory data to the header
    header["numTables"] = len(directory)
    if isCollection:
        header["flavor"] = "ttcf"
    elif "CFF " in tableData:
        header["flavor"] = "OTTO"
    else:
        header["flavor"] = "\000\001\000\000"
    # apply the table data to the directory and the header
    if isCollection:
        # TTC header
        header["totalSfntSize"] = 12 + 4 * collectionHeader["numFonts"]
        header["totalSfntSize"] += sfntDirectorySize * collectionHeader["numFonts"]
        for entry in collectionDirectory:
            header["totalSfntSize"] += sfntDirectoryEntrySize * entry["numTables"]
    else:
        header["totalSfntSize"] = sfntDirectorySize + (len(directory) * sfntDirectoryEntrySize)
    header["totalCompressedSize"] = len(compressedData)
    for i, entry in enumerate(directory):
        tag = entry["tag"]
        if isCollection:
            origData, transformData = tableData[i][1]
        else:
            origData, transformData = tableData[tag]
        entry["origLength"] = len(origData)
        entry["transformLength"] = len(transformData)
        if tag == "hmtx" and entry["origLength"] > entry["transformLength"]:
            entry["transformFlag"] = 1
        header["totalSfntSize"] += entry["origLength"]
        header["totalSfntSize"] += calcPaddingLength(header["totalSfntSize"])
    header["length"] = woffHeaderSize + len(packTestDirectory(directory, Base128Bug=Base128Bug))
    if isCollection:
        header["length"] += len(packTestCollectionHeader(collectionHeader))
        header["length"] += len(packTestCollectionDirectory(collectionDirectory))
    header["length"] += len(compressedData)
    header["length"] += calcPaddingLength(header["length"])
    # setup the metadata
    if metadata is not None:
        if isinstance(metadata, tuple):
            metadata, compMetadata = metadata
        else:
            compMetadata = None
        if compMetadata is None:
            compMetadata = brotli.compress(metadata, brotli.MODE_TEXT)
        header["metaOffset"] = header["length"]
        header["metaLength"] = len(compMetadata)
        header["metaOrigLength"] = len(metadata)
        header["length"] += len(compMetadata)
        if privateData is not None:
            header["length"] += calcPaddingLength(len(compMetadata))
        parts.append((metadata, compMetadata))
    # setup the private data
    if privateData is not None:
        header["privOffset"] = header["length"]
        header["privLength"] = len(privateData)
        header["length"] += len(privateData)
        parts.append(privateData)
    # return the parts
    return parts
Beispiel #2
0
def getWOFFCollectionData(pathOrFiles, MismatchGlyfLoca=False, reverseNames=False):
    from defaultData import defaultTestData

    tableChecksums = []
    tableData = []
    tableOrder = []
    collectionDirectory = []
    locaIndices = []

    fonts = [TTFont(pathOrFile) for pathOrFile in pathOrFiles]
    for i, font in enumerate(fonts):
        index = i
        if reverseNames:
            index = len(fonts) - i - 1

        # Make the name table unique
        name = font["name"]
        for namerecord in name.names:
            nameID = namerecord.nameID
            string = namerecord.toUnicode()
            if nameID == 1:
                namerecord.string = "%s %d" % (string, index)
            elif nameID == 4:
                namerecord.string = string.replace("Regular", "%d Regular" % index)
            elif nameID == 6:
                namerecord.string = string.replace("-", "%d-" % index)

        tags = [i for i in sorted(font.keys()) if len(i) == 4]
        if "glyf" in tags:
            glyf = tags.index("glyf")
            loca = tags.index("loca")
            tags.insert(glyf + 1, tags.pop(loca))
        tableIndices = OrderedDict()
        for tag in tags:
            data = transformTable(font, tag)
            if MismatchGlyfLoca and tag in ("glyf", "loca"):
                tableData.append([tag, data])
                tableChecksums.append([tag, font.reader.tables[tag].checkSum])
                tableOrder.append(tag)
                tableIndex = len(tableData) - 1
                tableIndices[tag] = tableIndex
                if tag == "loca":
                    locaIndices.append(tableIndex)
            else:
                if [tag, data] not in tableData:
                    tableData.append([tag, data])
                    tableChecksums.append([tag, font.reader.tables[tag].checkSum])
                    tableOrder.append(tag)
                tableIndices[tag] = tableData.index([tag, data])
        collectionDirectory.append(dict(numTables=len(tableIndices), flavor=font.sfntVersion, index=tableIndices))
        font.close()
        del font

    if MismatchGlyfLoca:
        locaIndices.reverse()
        for i, entry in enumerate(collectionDirectory):
            entry["index"]["loca"] = locaIndices[i]
    totalData = "".join([data[1][1] for data in tableData])
    compData = brotli.compress(totalData, brotli.MODE_FONT)
    if len(compData) >= len(totalData):
        compData = totalData

    directory = [dict(tag=tag, origLength=0, transformLength=0, transformFlag=0) for tag in tableOrder]

    header, directory, collectionHeader, collectionDirectory, tableData = defaultTestData(directory=directory,
            tableData=tableData, compressedData=compData, collectionDirectory=collectionDirectory)

    data = packTestHeader(header)
    data += packTestDirectory(directory, isCollection=True)
    data += packTestCollectionHeader(collectionHeader)
    data += packTestCollectionDirectory(collectionDirectory)
    data += tableData

    data = padData(data)

    return data
Beispiel #3
0
def defaultTestData(header=None,
                    directory=None,
                    collectionHeader=None,
                    collectionDirectory=None,
                    tableData=None,
                    compressedData=None,
                    metadata=None,
                    privateData=None,
                    flavor="cff",
                    Base128Bug=False):
    isCollection = collectionDirectory is not None
    parts = []
    # setup the header
    if header is None:
        header = deepcopy(testDataWOFFHeader)
    parts.append(header)
    # setup the directory
    if directory is None:
        if flavor == "cff":
            directory = deepcopy(testCFFDataWOFFDirectory)
        else:
            directory = deepcopy(testTTFDataWOFFDirectory)
    parts.append(directory)
    if isCollection:
        if collectionHeader is None:
            collectionHeader = dict(version=0x00010000,
                                    numFonts=len(collectionDirectory))
        parts.append(collectionHeader)
        parts.append(collectionDirectory)
    # setup the table data
    if tableData is None:
        if flavor == "cff":
            tableData = deepcopy(sfntCFFTableData)
        else:
            tableData = deepcopy(sfntTTFTableData)
    if compressedData is None:
        if flavor == "cff":
            compressedData = deepcopy(sfntCFFCompressedData)
        else:
            compressedData = deepcopy(sfntTTFCompressedData)
    parts.append(compressedData)
    # sanity checks
    assert len(directory) == len(tableData)
    if not isCollection:
        assert set(tableData.keys()) == set(
            [entry["tag"] for entry in directory])
    # apply the directory data to the header
    header["numTables"] = len(directory)
    if isCollection:
        header["flavor"] = "ttcf"
    elif "CFF " in tableData:
        header["flavor"] = "OTTO"
    else:
        header["flavor"] = "\000\001\000\000"
    # apply the table data to the directory and the header
    if isCollection:
        # TTC header
        header["totalSfntSize"] = 12 + 4 * collectionHeader["numFonts"]
        header["totalSfntSize"] += sfntDirectorySize * collectionHeader[
            "numFonts"]
        for entry in collectionDirectory:
            header[
                "totalSfntSize"] += sfntDirectoryEntrySize * entry["numTables"]
    else:
        header["totalSfntSize"] = sfntDirectorySize + (len(directory) *
                                                       sfntDirectoryEntrySize)
    header["totalCompressedSize"] = len(compressedData)
    for i, entry in enumerate(directory):
        tag = entry["tag"]
        if isCollection:
            origData, transformData = tableData[i][1]
        else:
            origData, transformData = tableData[tag]
        entry["origLength"] = len(origData)
        entry["transformLength"] = len(transformData)
        header["totalSfntSize"] += entry["origLength"]
        header["totalSfntSize"] += calcPaddingLength(header["totalSfntSize"])
    header["length"] = woffHeaderSize + len(
        packTestDirectory(directory, Base128Bug=Base128Bug))
    if isCollection:
        header["length"] += len(packTestCollectionHeader(collectionHeader))
        header["length"] += len(
            packTestCollectionDirectory(collectionDirectory))
    header["length"] += len(compressedData)
    header["length"] += calcPaddingLength(header["length"])
    # setup the metadata
    if metadata is not None:
        if isinstance(metadata, tuple):
            metadata, compMetadata = metadata
        else:
            compMetadata = None
        if compMetadata is None:
            compMetadata = brotli.compress(metadata, brotli.MODE_TEXT)
        header["metaOffset"] = header["length"]
        header["metaLength"] = len(compMetadata)
        header["metaOrigLength"] = len(metadata)
        header["length"] += len(compMetadata)
        if privateData is not None:
            header["length"] += calcPaddingLength(len(compMetadata))
        parts.append((metadata, compMetadata))
    # setup the private data
    if privateData is not None:
        header["privOffset"] = header["length"]
        header["privLength"] = len(privateData)
        header["length"] += len(privateData)
        parts.append(privateData)
    # return the parts
    return parts
Beispiel #4
0
def getWOFFCollectionData(pathOrFiles, MismatchGlyfLoca=False):
    from defaultData import defaultTestData

    tableChecksums = []
    tableData = []
    tableOrder = []
    collectionDirectory = []
    locaIndices = []

    for i, pathOrFile in enumerate(pathOrFiles):
        font = TTFont(pathOrFile)

        # Make the name table unique
        name = font["name"]
        for namerecord in name.names:
            nameID = namerecord.nameID
            string = namerecord.toUnicode()
            if nameID == 1:
                namerecord.string = "%s %d" % (string, i)
            elif nameID == 4:
                namerecord.string = string.replace("Regular", "%d Regular" % i)
            elif nameID == 6:
                namerecord.string = string.replace("-", "%d-" % i)

        tags = [i for i in sorted(font.keys()) if len(i) == 4]
        if "glyf" in tags:
            glyf = tags.index("glyf")
            loca = tags.index("loca")
            tags.insert(glyf + 1, tags.pop(loca))
        tableIndices = OrderedDict()
        for tag in tags:
            data = transformTable(font, tag)
            if MismatchGlyfLoca and tag in ("glyf", "loca"):
                tableData.append([tag, data])
                tableChecksums.append([tag, font.reader.tables[tag].checkSum])
                tableOrder.append(tag)
                tableIndex = len(tableData) - 1
                tableIndices[tag] = tableIndex
                if tag == "loca":
                    locaIndices.append(tableIndex)
            else:
                if [tag, data] not in tableData:
                    tableData.append([tag, data])
                    tableChecksums.append(
                        [tag, font.reader.tables[tag].checkSum])
                    tableOrder.append(tag)
                tableIndices[tag] = tableData.index([tag, data])
        collectionDirectory.append(
            dict(numTables=len(tableIndices),
                 flavor=font.sfntVersion,
                 index=tableIndices))
        font.close()
        del font

    if MismatchGlyfLoca:
        locaIndices.reverse()
        for i, entry in enumerate(collectionDirectory):
            entry["index"]["loca"] = locaIndices[i]
    totalData = "".join([data[1][1] for data in tableData])
    compData = brotli.compress(totalData, brotli.MODE_FONT)
    if len(compData) >= len(totalData):
        compData = totalData

    directory = [
        dict(tag=tag, origLength=0, transformLength=0) for tag in tableOrder
    ]

    header, directory, collectionHeader, collectionDirectory, tableData = defaultTestData(
        directory=directory,
        tableData=tableData,
        compressedData=compData,
        collectionDirectory=collectionDirectory)

    data = packTestHeader(header)
    data += packTestDirectory(directory, isCollection=True)
    data += packTestCollectionHeader(collectionHeader)
    data += packTestCollectionDirectory(collectionDirectory)
    data += tableData

    data = padData(data)

    return data