Last active
May 10, 2023 13:42
-
-
Save anthrotype/b775d84e23e053a24502775d5aafa4fd to your computer and use it in GitHub Desktop.
script to remove overlaps from TTF with fonttools and skia-pathops
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
# Example script to remove overlaps in TTF using skia-pathops | |
import sys | |
from fontTools.ttLib import TTFont | |
from fontTools.pens.recordingPen import DecomposingRecordingPen | |
from fontTools.pens.ttGlyphPen import TTGlyphPen | |
try: | |
import pathops | |
except ImportError: | |
sys.exit( | |
"This script requires the skia-pathops module. " | |
"`pip install skia-pathops` and then retry." | |
) | |
def skpath_from_simple_glyph(glyphName, glyphSet): | |
path = pathops.Path() | |
pathPen = path.getPen() | |
glyphSet[glyphName].draw(pathPen) | |
return path | |
def skpath_from_composite_glyph(glyphName, glyphSet): | |
# record TTGlyph outlines without components | |
dcPen = DecomposingRecordingPen(glyphSet) | |
glyphSet[glyphName].draw(dcPen) | |
# replay recording onto a skia-pathops Path | |
path = pathops.Path() | |
pathPen = path.getPen() | |
dcPen.replay(pathPen) | |
return path | |
def tt_glyph_from_skpath(path): | |
ttPen = TTGlyphPen(None) | |
path.draw(ttPen) | |
return ttPen.glyph() | |
def main(): | |
if len(sys.argv) != 3: | |
print("usage: remove-overlaps.py fontfile.ttf outfile.ttf") | |
sys.exit(1) | |
src = sys.argv[1] | |
dst = sys.argv[2] | |
with TTFont(src) as f: | |
glyfTable = f["glyf"] | |
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] = tt_glyph_from_skpath(path2) | |
f.save(dst) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment