Skip to content

Instantly share code, notes, and snippets.

@typoman
Last active November 10, 2024 22:58
Show Gist options
  • Save typoman/98353270a885ebcfecc867162443eb17 to your computer and use it in GitHub Desktop.
Save typoman/98353270a885ebcfecc867162443eb17 to your computer and use it in GitHub Desktop.
RoboFont script to fix contour direction for postscript curves (CFF/Cubic/OTF) on selected glyphs.
"""
RoboFont Script
based on:
https://gist.github.com/ryanbugden/a4ddf19cab034f837a51fb9d4f0db015
- Type: Mastering
- Purpose: To fix contour direction for postscript curves (CFF/Cubic/OTF) in selected glyphs.
- Specifications:
- Sorts contours by area and clusters them into contours that contain other contours
- Reverses the direction of contours in clusters where the largest contour is not clockwise
- Publish Date: 2024-11-08
- Author: Bahman Eskami
- License: MIT
"""
def fix_contour_direction(g):
"""
Fixes the contour direction for postscript curves (CFF/Cubic/OTF) in a given glyph.
Args:
g (fontParts.RGlyph): The glyph to fix contour direction for.
Returns:
bool: True if any contours were reversed, False otherwise.
"""
contours = list(sorted(g.contours, key=lambda c: -c.area)) # bigger contours first
clusters = [] # cluster are made of contours that contain other contours
for contour in contours:
added = False
for cluster in clusters:
for c in cluster:
if c.contourInside(contour):
# add the hole as part of the cluster
cluster.append(contour)
added = True
break
if not added:
clusters.append([contour, ])
changed = False
for contour_list in clusters:
if contour_list[0].clockwise:
for c in contour_list:
c.reverse()
changed = True
return changed
if __name__ == '__main__':
import fontgadgets.extensions.robofont.UI # requires fontgadgets extension
from mojo.UI import limitFontViewToGlyphSet
from mojo.UI import CurrentSelectedGlyphNames
for f in AllFonts():
gs = CurrentSelectedGlyphNames()
lv = set()
for gn in gs:
g = f[gn]
with g.undo():
if fix_contour_direction(g):
lv.add(gn)
limitFontViewToGlyphSet(lv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment