たくさんのSVG ファイルから画像の幅を取得しフォントごとに幅を設定後にフォントをバッチ処理で作成

準備

バッチファイル

md y:\input_svg
md y:\output_svg
md y:\input_png
md y:\output_png
call "D:\WinPython\scripts\env_for_icons.bat"

for /r y:\output_png %%f in (*.png) do (
"C:\app\ImageMagick\convert.exe"  "%%f" -strip -flatten -resize x1000   y:\input_png\%%~nf.bmp
"C:\app\potrace\potrace.exe" y:\input_png\%%~nf.bmp -o y:\input_png\%%~nf.svg --svg --flat --opttolerance 0.8 --alphamax 1.4 --blacklevel 0.5
rem 

scour -i y:\input_png\%%~nf.svg  -o y:\input_svg\%%~nf.svg
del y:\input_png\%%~nf.svg
del y:\input_png\%%~nf.bmp
)
"D:\app2\FontForgePortable\App\FontForge\bin\ffpython.exe" "D:\WinPython\notebooks\svgs2ttf\svgs2ttf3.py" 

プログラム

import svgelements

import sys
import os.path
import json
import fontforge
from datetime import datetime
from os.path import splitext

from psMat import compose, scale, translate

VERSION = "Version 0.1"
COPYRIGHT = """[]
SIL Open Font License Version 1.1 (http://scripts.sil.org/ofl)
Copyright eightban
"""

AUTHOR = 'eightban'
ATHR = '8ban'
FAMILY = 'eightban Font A'
STYLE = 'Regular'
WEIGHT = 'Book'
FULLNAME = FAMILY + ' ' + STYLE
FONTNAME = FULLNAME.replace(' ', '-')
FTNAME = FULLNAME.replace(' ', '')
ITALIC = 'Italic'
ITALIC_ANGLE = -10

ASCENT = 880
DESCENT = 120
FONT_ASCENT = ASCENT + 20
FONT_DESCENT = DESCENT + 80

ENCODING = 'UnicodeFull'

UNDERLINE_POS = -125
UNDERLINE_HEIGHT = 50
WIDTH = ASCENT + DESCENT

def new_font(font):
    font.sfnt_names = (
        (
            "English (US)",
            "License",
            "This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFL",
        ),
        ("English (US)", "License URL", "http://scripts.sil.org/OFL"),
        ("English (US)", "Family", f"{FAMILY}"),
        ("English (US)", "SubFamily", f"{STYLE}"),
        ("English (US)", "Fullname", f"{FULLNAME}"),
        ("English (US)", "Version", f"{VERSION}"),
        ("English (US)", "PostScriptName", f"{FTNAME}")
    )
    font.appendSFNTName('English (US)', 'UniqueID', ' : '.join([FAMILY,datetime.today().strftime('%d-%m-%Y')]))
    font.appendSFNTName('English (US)', 'Copyright', ' : '.join([AUTHOR,datetime.today().strftime('%d-%m-%Y')]))

    font.ascent = ASCENT
    font.descent = DESCENT

    # winascent & windescent is for setting the line height for Windows.
    font.os2_winascent = ASCENT
    font.os2_windescent = DESCENT
    # the `_add` version is for setting offsets.
    font.os2_winascent_add = 0
    font.os2_windescent_add = 0
    # hhea_ascent, hhea_descent is the macOS version for winascent &
    # windescent.
    font.hhea_ascent = ASCENT
    font.hhea_descent = -DESCENT
    font.hhea_ascent_add = 0
    font.hhea_descent_add = 0
    # typoascent, typodescent is generic version for above.
    font.os2_typoascent = ASCENT
    font.os2_typodescent = -DESCENT
    font.os2_typoascent_add = 0
    font.os2_typodescent_add = 0
    # linegap is for gap between lines.  The `hhea_` version is for macOS.
    font.os2_typolinegap = 0
    font.hhea_linegap = 0
    font.os2_typolinegap = 0
    font.italicangle = ITALIC_ANGLE
    font.upos = UNDERLINE_POS
    font.uwidth = UNDERLINE_HEIGHT

    font.familyname = FAMILY
    font.copyright = COPYRIGHT
    font.encoding = ENCODING
    font.fontname = FONTNAME
    font.fullname = FULLNAME
    font.version = VERSION
    font.weight = WEIGHT
    font.os2_weight = 400
    font.os2_width = 5  # Medium (w/h = 1.000)
    font.os2_fstype = 4  # Printable Document)
    font.os2_vendor = ATHR
    font.os2_family_class = 2057  # SS Typewriter Gothic
    font.os2_panose = (
        2,  # Latin: Text and Display
        11,  # Nomal Sans
        5,
        9,  # Monospaced
        2,  # None
        2,  # No Variation
        3,  # Straight Arms/Wedge
        2,
        2,  # Standard/Trimmed
        7,  # Ducking/Large
    )


IMPORT_OPTIONS = ('removeoverlap', 'correctdir')

try:
    unicode
except NameError:
    unicode = str

def addGlyphs(font, input_folder):

    # 
    for filename in os.listdir(input_folder):
        if filename.endswith(('.svg')):
            input_path = os.path.join(input_folder, filename)
            basename_without_ext = os.path.splitext(os.path.basename(filename))[0]
            g = font.createMappedChar(int(basename_without_ext, 0))
            g.importOutlines(input_path, IMPORT_OPTIONS)
            svg = svgelements.SVG.parse(input_path)
            g.width = int(svg.viewbox.width)

#
            sys.stderr.write("%s\n" % basename_without_ext )
            g.removeOverlap()


def space_glyphs(font):
    GLYPHS = [
    0x20, 0x3000,
    ]

    for i in GLYPHS:
        g = font.createMappedChar(i)
        g.width =int(WIDTH / 2)

        g.width = 648

def hankaku_glyphs(font):

    font.selection.none()
    font.selection.select(("ranges", "unicode"),0x20,0x7e)

#    for i in HANKAKU_GLYPHS:
#        font.selection.select(('more', 'unicode'), i)
    for glyph in font.selection.byGlyphs:
        glyph.width =int(WIDTH / 2)
        glyph.width = 648


def main():
    input_folder = 'y:/input_svg'
    output_file = 'y:/'+FONTNAME+'.ttf'

    font = fontforge.font()
    new_font(font)
    addGlyphs(font, input_folder)
    space_glyphs(font)

#    hankaku_glyphs(font)
    font.selection.all()
    # font.removeOverlap()
    font.autoHint()
    font.autoInstr()
    sys.stderr.write('Generating %s...\n' % output_file)
    font.generate(output_file)

#    font.generate(output_file, flags=('opentype',))
if __name__ == '__main__':
        main()

作成されたフォント

Created by potrace 1.16, written by Peter Selinger 2001-2019

SIL OPEN FONT LICENSE Version 1.1 – の ファイルを元に作成しました。そのためこのフォントも同じライセンスになります

font,Python

Posted by eightban