Beispiel #1
0
def processFonts(font_paths_list, hex_colors_list, outputFolderPath, options):
    glyphSetsList = []
    allGlyphNamesList = []

    # Load the fonts and collect their glyph sets
    for fontPath in font_paths_list:
        font = ttLib.TTFont(fontPath)
        gSet = font.getGlyphSet()
        glyphSetsList.append(gSet)
        allGlyphNamesList.append(gSet.keys())
        font.close()

    if not glyphSetsList:
        raise AssertionError("No glyph sets.")

    # Define the list of glyph names to convert to SVG
    if options.gnames_to_generate:
        glyphNamesList = sorted(options.gnames_to_generate)
    else:
        if options.glyphsets_union:
            glyphNamesList = sorted(
                list(set.union(*map(set, allGlyphNamesList))))
        else:
            glyphNamesList = sorted(
                list(set.intersection(*map(set, allGlyphNamesList))))
            # Extend the list with additional glyph names
            if options.gnames_to_add:
                glyphNamesList.extend(options.gnames_to_add)
                # Remove any duplicates and sort
                glyphNamesList = sorted(list(set(glyphNamesList)))

    # Confirm that there's something to process
    if not glyphNamesList:
        print("The fonts and options provided can't produce any SVG files.",
              file=sys.stdout)
        return

    # Define the list of glyph names to skip
    glyphNamesToSkipList = [".notdef"]
    if options.gnames_to_exclude:
        glyphNamesToSkipList.extend(options.gnames_to_exclude)

    # Determine which glyph names need to be saved in a nested folder
    glyphNamesToSaveInNestedFolder = get_gnames_to_save_in_nested_folder(
        glyphNamesList)

    # Gather the fonts' UPM. For simplicity, it's assumed that all fonts have
    # the same UPM value. If fetching the UPM value fails, default to 1000.
    try:
        upm = ttLib.TTFont(font_paths_list[0])['head'].unitsPerEm
    except KeyError:
        upm = 1000

    nestedFolderPath = None
    filesSaved = 0

    # Generate the SVGs
    for gName in glyphNamesList:
        svgStr = (u"""<svg xmlns="http://www.w3.org/2000/svg" """
                  u"""viewBox="0 -{} {} {}">\n""".format(upm, upm, upm))

        for index, gSet in enumerate(glyphSetsList):
            # Skip glyphs that don't exist in the current font,
            # or that were requested to be skipped
            if gName not in gSet.keys() or gName in glyphNamesToSkipList:
                continue

            pen = SVGPen(gSet)
            tpen = TransformPen(pen, (1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
            glyph = gSet[gName]
            glyph.draw(tpen)
            d = pen.d
            # Skip glyphs with no contours
            if not len(d):
                continue

            hex_str = hex_colors_list[index]
            opc = ''
            if len(hex_str) != 6:
                opcHex = hex_str[6:]
                hex_str = hex_str[:6]
                if opcHex.lower() != 'ff':
                    opc = ' opacity="{:.2f}"'.format(int(opcHex, 16) / 255)

            svgStr += u'\t<path{} fill="#{}" d="{}"/>\n'.format(
                opc, hex_str, d)
        svgStr += u'</svg>'

        # Skip saving files that have no paths
        if '<path' not in svgStr:
            continue

        # Create the output folder.
        # This may be necessary if the folder was not provided.
        # The folder is made this late in the process because
        # only now it's clear that's needed.
        create_folder(outputFolderPath)

        # Create the nested folder, if there are conflicting glyph names.
        if gName in glyphNamesToSaveInNestedFolder:
            folderPath = create_nested_folder(nestedFolderPath,
                                              outputFolderPath)
        else:
            folderPath = outputFolderPath

        svgFilePath = os.path.join(folderPath, gName + '.svg')
        write_file(svgFilePath, svgStr)
        filesSaved += 1

    font.close()
    final_message(filesSaved)
Beispiel #2
0
def processFont(fontPath, outputFolderPath, options):
    font = ttLib.TTFont(fontPath)
    glyphOrder = font.getGlyphOrder()
    svgTag = 'SVG '

    if svgTag not in font:
        print("ERROR: The font does not have the {} table.".format(
            svgTag.strip()),
              file=sys.stderr)
        sys.exit(1)

    svgTable = font[svgTag]

    if not len(svgTable.docList):
        print("ERROR: The {} table has no data that can be output.".format(
            svgTag.strip()),
              file=sys.stderr)
        sys.exit(1)

    # Define the list of glyph names to convert to SVG
    if options.gnames_to_generate:
        glyphNamesList = sorted(options.gnames_to_generate)
    else:
        glyphNamesList = sorted(glyphOrder)

    # Confirm that there's something to process
    if not glyphNamesList:
        print("The fonts and options provided can't produce any SVG files.",
              file=sys.stdout)
        return

    # Define the list of glyph names to skip
    glyphNamesToSkipList = [".notdef"]
    if options.gnames_to_exclude:
        glyphNamesToSkipList.extend(options.gnames_to_exclude)

    # Determine which glyph names need to be saved in a nested folder
    glyphNamesToSaveInNestedFolder = get_gnames_to_save_in_nested_folder(
        glyphNamesList)

    nestedFolderPath = None
    filesSaved = 0
    unnamedNum = 1

    # Write the SVG files by iterating over the entries in the SVG table.
    # The process assumes that each SVG document contains only one 'id' value,
    # i.e. the artwork for two or more glyphs is not included in a single SVG.
    for svgItemsList in svgTable.docList:
        svgItemData, startGID, endGID = svgItemsList

        if options.reset_viewbox:
            svgItemData = resetViewBox(svgItemData)

        while (startGID != endGID + 1):
            try:
                gName = glyphOrder[startGID]
            except IndexError:
                gName = "_unnamed{}".format(unnamedNum)
                glyphNamesList.append(gName)
                unnamedNum += 1
                print("WARNING: The SVG table references a glyph ID (#{}) "
                      "which the font does not contain.\n"
                      "         The artwork will be saved as '{}.svg'.".format(
                          startGID, gName),
                      file=sys.stderr)

            if gName not in glyphNamesList or gName in glyphNamesToSkipList:
                startGID += 1
                continue

            # Create the output folder.
            # This may be necessary if the folder was not provided.
            # The folder is made this late in the process because
            # only now it's clear that's needed.
            create_folder(outputFolderPath)

            # Create the nested folder, if there are conflicting glyph names.
            if gName in glyphNamesToSaveInNestedFolder:
                folderPath = create_nested_folder(nestedFolderPath,
                                                  outputFolderPath)
            else:
                folderPath = outputFolderPath

            svgFilePath = os.path.join(folderPath, gName + '.svg')
            write_file(svgFilePath, svgItemData)
            filesSaved += 1
            startGID += 1

    font.close()
    final_message(filesSaved)
 def test_read_write_file(self):
     content = '1st line\n2nd line\n3rd line'
     with tempfile.NamedTemporaryFile(delete=False) as tmp:
         shared_utils.write_file(tmp.name, content)
         result = shared_utils.read_file(tmp.name)
         self.assertEqual(result.splitlines()[1], '2nd line')