tooling: decompose and remove overlaps of SVG glyphs generated for the website
This commit is contained in:
parent
287f146a06
commit
c163658d67
1 changed files with 28 additions and 40 deletions
|
|
@ -18,9 +18,11 @@ from collections import OrderedDict
|
||||||
from math import ceil, floor
|
from math import ceil, floor
|
||||||
from defcon import Font
|
from defcon import Font
|
||||||
from svg import SVGPathPen
|
from svg import SVGPathPen
|
||||||
|
from ufo2ft.filters.decomposeComponents import DecomposeComponentsFilter
|
||||||
|
from ufo2ft.filters.removeOverlaps import RemoveOverlapsFilter
|
||||||
|
|
||||||
|
|
||||||
font = None # RFont
|
ufo = None
|
||||||
ufopath = ''
|
ufopath = ''
|
||||||
effectiveAscender = 0
|
effectiveAscender = 0
|
||||||
scale = 0.1
|
scale = 0.1
|
||||||
|
|
@ -30,31 +32,6 @@ def num(s):
|
||||||
return int(s) if s.find('.') == -1 else float(s)
|
return int(s) if s.find('.') == -1 else float(s)
|
||||||
|
|
||||||
|
|
||||||
def decomposeGlyph(font, glyph):
|
|
||||||
"""Moves the components of a glyph to its outline."""
|
|
||||||
if len(glyph.components):
|
|
||||||
deepCopyContours(font, glyph, glyph, (0, 0), (1, 1))
|
|
||||||
glyph.clearComponents()
|
|
||||||
|
|
||||||
|
|
||||||
def deepCopyContours(font, parent, component, offset, scale):
|
|
||||||
"""Copy contours to parent from component, including nested components."""
|
|
||||||
|
|
||||||
for nested in component.components:
|
|
||||||
deepCopyContours(
|
|
||||||
font, parent, font[nested.baseGlyph],
|
|
||||||
(offset[0] + nested.offset[0], offset[1] + nested.offset[1]),
|
|
||||||
(scale[0] * nested.scale[0], scale[1] * nested.scale[1]))
|
|
||||||
|
|
||||||
if component == parent:
|
|
||||||
return
|
|
||||||
for contour in component:
|
|
||||||
contour = contour.copy()
|
|
||||||
contour.scale(scale)
|
|
||||||
contour.move(offset)
|
|
||||||
parent.appendContour(contour)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def glyphToSVGPath(g, yMul):
|
def glyphToSVGPath(g, yMul):
|
||||||
pen = SVGPathPen(g.getParent(), yMul)
|
pen = SVGPathPen(g.getParent(), yMul)
|
||||||
|
|
@ -82,16 +59,16 @@ def glyphToSVG(g):
|
||||||
''' % {
|
''' % {
|
||||||
'name': g.name,
|
'name': g.name,
|
||||||
'width': int(ceil(width * scale)),
|
'width': int(ceil(width * scale)),
|
||||||
'height': int(ceil((effectiveAscender - font.info.descender) * scale)),
|
'height': int(ceil((effectiveAscender - ufo.info.descender) * scale)),
|
||||||
'xoffs': -(xoffs * scale),
|
'xoffs': -(xoffs * scale),
|
||||||
'yoffs': effectiveAscender * scale,
|
'yoffs': effectiveAscender * scale,
|
||||||
# 'leftMargin': g.leftMargin * scale,
|
# 'leftMargin': g.leftMargin * scale,
|
||||||
# 'rightMargin': g.rightMargin * scale,
|
# 'rightMargin': g.rightMargin * scale,
|
||||||
'glyphSVGPath': glyphToSVGPath(g, -1),
|
'glyphSVGPath': glyphToSVGPath(g, -1),
|
||||||
# 'ascender': font.info.ascender * scale,
|
# 'ascender': ufo.info.ascender * scale,
|
||||||
# 'descender': font.info.descender * scale,
|
# 'descender': ufo.info.descender * scale,
|
||||||
# 'baselineOffset': (font.info.unitsPerEm + font.info.descender) * scale,
|
# 'baselineOffset': (ufo.info.unitsPerEm + ufo.info.descender) * scale,
|
||||||
# 'unitsPerEm': font.info.unitsPerEm,
|
# 'unitsPerEm': ufo.info.unitsPerEm,
|
||||||
'scale': scale,
|
'scale': scale,
|
||||||
|
|
||||||
# 'margin': [g.leftMargin * scale, g.rightMargin * scale],
|
# 'margin': [g.leftMargin * scale, g.rightMargin * scale],
|
||||||
|
|
@ -173,7 +150,7 @@ def findGlifFile(glyphname):
|
||||||
usedSVGNames = set()
|
usedSVGNames = set()
|
||||||
|
|
||||||
def genGlyph(glyphName):
|
def genGlyph(glyphName):
|
||||||
g = font[glyphName]
|
g = ufo[glyphName]
|
||||||
return glyphToSVG(g)
|
return glyphToSVG(g)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -188,11 +165,11 @@ def genGlyphIDs(glyphnames):
|
||||||
return nameToIdMap, idToNameMap
|
return nameToIdMap, idToNameMap
|
||||||
|
|
||||||
|
|
||||||
def genKerningInfo(font, glyphnames, nameToIdMap):
|
def genKerningInfo(ufo, glyphnames, nameToIdMap):
|
||||||
kerning = font.kerning
|
kerning = ufo.kerning
|
||||||
|
|
||||||
# load groups
|
# load groups
|
||||||
filename = os.path.join(font.path, 'groups.plist')
|
filename = os.path.join(ufo.path, 'groups.plist')
|
||||||
groups = plistlib.readPlist(filename)
|
groups = plistlib.readPlist(filename)
|
||||||
|
|
||||||
pairs = []
|
pairs = []
|
||||||
|
|
@ -269,16 +246,27 @@ if len(args.scale):
|
||||||
|
|
||||||
ufopath = args.ufopath.rstrip('/')
|
ufopath = args.ufopath.rstrip('/')
|
||||||
|
|
||||||
font = Font(ufopath)
|
ufo = Font(ufopath)
|
||||||
effectiveAscender = max(font.info.ascender, font.info.unitsPerEm)
|
effectiveAscender = max(ufo.info.ascender, ufo.info.unitsPerEm)
|
||||||
|
|
||||||
# print('\n'.join(font.keys()))
|
print('preprocessing glyphs')
|
||||||
|
filters = [
|
||||||
|
DecomposeComponentsFilter(),
|
||||||
|
RemoveOverlapsFilter(backend=RemoveOverlapsFilter.Backend.SKIA_PATHOPS),
|
||||||
|
]
|
||||||
|
glyphSet = {g.name: g for g in ufo}
|
||||||
|
for func in filters:
|
||||||
|
func(ufo, glyphSet)
|
||||||
|
|
||||||
|
print('generating SVGs and metrics data')
|
||||||
|
|
||||||
|
# print('\n'.join(ufo.keys()))
|
||||||
# sys.exit(0)
|
# sys.exit(0)
|
||||||
|
|
||||||
deleteNames.add('.notdef')
|
deleteNames.add('.notdef')
|
||||||
deleteNames.add('.null')
|
deleteNames.add('.null')
|
||||||
|
|
||||||
glyphnames = args.glyphs if len(args.glyphs) else font.keys()
|
glyphnames = args.glyphs if len(args.glyphs) else ufo.keys()
|
||||||
glyphnameSet = set(glyphnames)
|
glyphnameSet = set(glyphnames)
|
||||||
|
|
||||||
glyphnames = [gn for gn in glyphnames if gn not in deleteNames]
|
glyphnames = [gn for gn in glyphnames if gn not in deleteNames]
|
||||||
|
|
@ -321,7 +309,7 @@ if startPos == -1 or endPos == -1:
|
||||||
print(msg % relfilename, file=sys.stderr)
|
print(msg % relfilename, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
kerning = genKerningInfo(font, glyphnames, nameToIdMap)
|
kerning = genKerningInfo(ufo, glyphnames, nameToIdMap)
|
||||||
metaJson = '{\n'
|
metaJson = '{\n'
|
||||||
metaJson += '"nameids":' + fmtJsonDict(idToNameMap) + ',\n'
|
metaJson += '"nameids":' + fmtJsonDict(idToNameMap) + ',\n'
|
||||||
metaJson += '"metrics":' + fmtJsonDict(glyphMetrics) + ',\n'
|
metaJson += '"metrics":' + fmtJsonDict(glyphMetrics) + ',\n'
|
||||||
|
|
|
||||||
Reference in a new issue