Merge pull request #1053 from anthrotype/svg2glif-snippet
[Snippets] add script to convert SVG outlines to UFO GLIF
This commit is contained in:
commit
84a2de0fe6
126
Snippets/svg2glif.py
Executable file
126
Snippets/svg2glif.py
Executable file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
""" Convert SVG paths to UFO glyphs. """
|
||||
|
||||
from __future__ import print_function, absolute_import
|
||||
|
||||
__requires__ = ["FontTools", "ufoLib"]
|
||||
|
||||
from fontTools.misc.py23 import SimpleNamespace
|
||||
from fontTools.svgLib import SVGPath
|
||||
|
||||
from ufoLib.pointPen import SegmentToPointPen
|
||||
from ufoLib.glifLib import writeGlyphToString
|
||||
|
||||
|
||||
__all__ = ["svg2glif"]
|
||||
|
||||
|
||||
def svg2glif(svg, name, width=0, height=0, unicodes=None, transform=None,
|
||||
version=2):
|
||||
""" Convert an SVG outline to a UFO glyph with given 'name', advance
|
||||
'width' and 'height' (int), and 'unicodes' (list of int).
|
||||
Return the resulting string in GLIF format (default: version 2).
|
||||
If 'transform' is provided, apply a transformation matrix before the
|
||||
conversion (must be tuple of 6 floats, or a FontTools Transform object).
|
||||
"""
|
||||
glyph = SimpleNamespace(width=width, height=height, unicodes=unicodes)
|
||||
outline = SVGPath.fromstring(svg, transform=transform)
|
||||
|
||||
# writeGlyphToString takes a callable (usually a glyph's drawPoints
|
||||
# method) that accepts a PointPen, however SVGPath currently only has
|
||||
# a draw method that accepts a segment pen. We need to wrap the call
|
||||
# with a converter pen.
|
||||
def drawPoints(pointPen):
|
||||
pen = SegmentToPointPen(pointPen)
|
||||
outline.draw(pen)
|
||||
|
||||
return writeGlyphToString(name,
|
||||
glyphObject=glyph,
|
||||
drawPointsFunc=drawPoints,
|
||||
formatVersion=version)
|
||||
|
||||
|
||||
def parse_args(args):
|
||||
import argparse
|
||||
|
||||
def split(arg):
|
||||
return arg.replace(",", " ").split()
|
||||
|
||||
def unicode_hex_list(arg):
|
||||
try:
|
||||
return [int(unihex, 16) for unihex in split(arg)]
|
||||
except ValueError:
|
||||
msg = "Invalid unicode hexadecimal value: %r" % arg
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
|
||||
def transform_list(arg):
|
||||
try:
|
||||
return [float(n) for n in split(arg)]
|
||||
except ValueError:
|
||||
msg = "Invalid transformation matrix: %r" % arg
|
||||
raise argparse.ArgumentTypeError(msg)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Convert SVG outlines to UFO glyphs (.glif)")
|
||||
parser.add_argument(
|
||||
"infile", metavar="INPUT.svg", help="Input SVG file containing "
|
||||
'<path> elements with "d" attributes.')
|
||||
parser.add_argument(
|
||||
"outfile", metavar="OUTPUT.glif", help="Output GLIF file (default: "
|
||||
"print to stdout)", nargs='?')
|
||||
parser.add_argument(
|
||||
"-n", "--name", help="The glyph name (default: input SVG file "
|
||||
"basename, without the .svg extension)")
|
||||
parser.add_argument(
|
||||
"-w", "--width", help="The glyph advance width (default: 0)",
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
"-H", "--height", help="The glyph vertical advance (optional if "
|
||||
'"width" is defined)', type=int, default=0)
|
||||
parser.add_argument(
|
||||
"-u", "--unicodes", help="List of Unicode code points as hexadecimal "
|
||||
'numbers (e.g. -u "0041 0042")',
|
||||
type=unicode_hex_list)
|
||||
parser.add_argument(
|
||||
"-t", "--transform", help="Transformation matrix as a list of six "
|
||||
'float values (e.g. -t "0.1 0 0 -0.1 -50 200")', type=transform_list)
|
||||
parser.add_argument(
|
||||
"-f", "--format", help="UFO GLIF format version (default: 2)",
|
||||
type=int, choices=(1, 2), default=2)
|
||||
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
from io import open
|
||||
|
||||
options = parse_args(args)
|
||||
|
||||
svg_file = options.infile
|
||||
|
||||
if options.name:
|
||||
name = options.name
|
||||
else:
|
||||
import os
|
||||
name = os.path.splitext(os.path.basename(svg_file))[0]
|
||||
|
||||
with open(svg_file, "r", encoding="utf-8") as f:
|
||||
svg = f.read()
|
||||
|
||||
glif = svg2glif(svg, name,
|
||||
width=options.width,
|
||||
height=options.height,
|
||||
unicodes=options.unicodes,
|
||||
transform=options.transform,
|
||||
version=options.format)
|
||||
|
||||
if options.outfile is None:
|
||||
print(glif)
|
||||
else:
|
||||
with open(options.outfile, 'w', encoding='utf-8') as f:
|
||||
f.write(glif)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.exit(main())
|
Loading…
x
Reference in New Issue
Block a user