factor out remove_overlaps routine, add typing annotations

This commit is contained in:
Cosimo Lupo 2020-09-23 17:48:11 +01:00
parent 19f5915f2e
commit 8bbc3d509b
No known key found for this signature in database
GPG Key ID: 179A8F0895A02F4F

View File

@ -5,7 +5,9 @@
import sys import sys
from fontTools.ttLib import TTFont from typing import Iterable, Optional, Mapping
from fontTools.ttLib import ttFont
from fontTools.ttLib.tables import _g_l_y_f
from fontTools.pens.recordingPen import DecomposingRecordingPen from fontTools.pens.recordingPen import DecomposingRecordingPen
from fontTools.pens.ttGlyphPen import TTGlyphPen from fontTools.pens.ttGlyphPen import TTGlyphPen
@ -17,15 +19,19 @@ except ImportError:
"`pip install skia-pathops` and then retry." "`pip install skia-pathops` and then retry."
) )
_TTGlyphMapping = Mapping[str, ttFont._TTGlyph]
def skpath_from_simple_glyph(glyphName, glyphSet):
def skpath_from_simple_glyph(glyphName: str, glyphSet: _TTGlyphMapping) -> pathops.Path:
path = pathops.Path() path = pathops.Path()
pathPen = path.getPen() pathPen = path.getPen()
glyphSet[glyphName].draw(pathPen) glyphSet[glyphName].draw(pathPen)
return path return path
def skpath_from_composite_glyph(glyphName, glyphSet): def skpath_from_composite_glyph(
glyphName: str, glyphSet: _TTGlyphMapping
) -> pathops.Path:
# record TTGlyph outlines without components # record TTGlyph outlines without components
dcPen = DecomposingRecordingPen(glyphSet) dcPen = DecomposingRecordingPen(glyphSet)
glyphSet[glyphName].draw(dcPen) glyphSet[glyphName].draw(dcPen)
@ -36,7 +42,7 @@ def skpath_from_composite_glyph(glyphName, glyphSet):
return path return path
def simple_glyph_from_skpath(path): def simple_glyph_from_skpath(path: pathops.Path) -> _g_l_y_f.Glyph:
# Skia paths have no 'components', no need for glyphSet # Skia paths have no 'components', no need for glyphSet
ttPen = TTGlyphPen(glyphSet=None) ttPen = TTGlyphPen(glyphSet=None)
path.draw(ttPen) path.draw(ttPen)
@ -47,39 +53,48 @@ def simple_glyph_from_skpath(path):
return glyph return glyph
def main(): def remove_overlaps(
if len(sys.argv) != 3: font: ttFont.TTFont, glyphNames: Optional[Iterable[str]] = None
print("usage: remove-overlaps.py fontfile.ttf outfile.ttf") ) -> None:
if glyphNames is None:
glyphNames = font.getGlyphOrder()
glyfTable = font["glyf"]
hmtxTable = font["hmtx"]
glyphSet = font.getGlyphSet()
for glyphName in glyphNames:
if glyfTable[glyphName].isComposite():
path = skpath_from_composite_glyph(glyphName, glyphSet)
else:
path = skpath_from_simple_glyph(glyphName, glyphSet)
# duplicate path
path2 = pathops.Path(path)
# remove overlaps
path2.simplify()
# replace TTGlyph if simplified copy is different
if path2 != path:
glyfTable[glyphName] = glyph = simple_glyph_from_skpath(path2)
# also ensure hmtx LSB == glyph.xMin so glyph origin is at x=0
width, lsb = hmtxTable[glyphName]
if lsb != glyph.xMin:
hmtxTable[glyphName] = (width, glyph.xMin)
def main() -> None:
if len(sys.argv) < 3:
print("usage: remove-overlaps.py fontfile.ttf outfile.ttf [GLYPHNAMES ...]")
sys.exit(1) sys.exit(1)
src = sys.argv[1] src = sys.argv[1]
dst = sys.argv[2] dst = sys.argv[2]
glyphNames = sys.argv[3:] or None
with TTFont(src) as f: with ttFont.TTFont(src) as f:
glyfTable = f["glyf"] remove_overlaps(f, glyphNames)
hmtxTable = f["hmtx"]
glyphSet = f.getGlyphSet()
for glyphName in glyphSet.keys():
if glyfTable[glyphName].isComposite():
path = skpath_from_composite_glyph(glyphName, glyphSet)
else:
path = skpath_from_simple_glyph(glyphName, glyphSet)
# duplicate path
path2 = pathops.Path(path)
# remove overlaps
path2.simplify()
# replace TTGlyph if simplified copy is different
if path2 != path:
glyfTable[glyphName] = glyph = simple_glyph_from_skpath(path2)
# also ensure hmtx LSB == glyph.xMin so glyph origin is at x=0
width, lsb = hmtxTable[glyphName]
if lsb != glyph.xMin:
hmtxTable[glyphName] = (width, glyph.xMin)
f.save(dst) f.save(dst)