Check Contour Intersections in FontForge with Python

This article explains how to programmatically detect self-intersecting and overlapping contours in font glyphs using FontForge’s built-in Python scripting environment. You will learn how to use native methods like glyph.selfIntersects() to identify offending glyphs across an entire font file and generate automated validation reports without manually opening the graphic interface.

The selfIntersects() Method

FontForge exposes a Python API with built-in glyph analysis tools. The most direct method for checking whether a glyph contains intersecting contours—either a contour crossing itself or multiple contours overlapping one another—is the selfIntersects() method on a glyph object.

This method returns a boolean value:

  • True if any contour within the glyph intersects itself or another contour.
  • False if all contours are free of intersections.

Checking Intersections with a Python Script

To check every glyph in a font file for contour intersections, load the font using the fontforge module, iterate through the glyphs, and test each with selfIntersects().

Save the following script as check_intersections.py:

import fontforge
import sys

def check_font_intersections(font_path):
    # Open the font file
    try:
        font = fontforge.open(font_path)
    except Exception as e:
        print(f"Error loading font: {e}")
        return

    intersecting_glyphs = []

    # Iterate over all glyphs in the font
    for glyph in font.glyphs():
        # Check if the glyph has contours and self-intersects
        if glyph.layers[font.activeLayer]:
            if glyph.selfIntersects():
                intersecting_glyphs.append(glyph.glyphname)

    # Output results
    if intersecting_glyphs:
        print(f"Found {len(intersecting_glyphs)} glyphs with intersections:")
        for name in intersecting_glyphs:
            print(f" - {name}")
    else:
        print("No intersecting contours found in this font.")

    font.close()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: fontforge -script check_intersections.py <path-to-font>")
    else:
        check_font_intersections(sys.argv[1])

Running the Script

Because FontForge uses its own embedded Python interpreter with internal C-bindings, run the script via the FontForge command-line interface:

fontforge -script check_intersections.py /path/to/your-font.otf

Alternative: Checking via glyph.validate()

If you need deeper validation beyond just a boolean check, you can use glyph.validate(). This method checks for multiple font errors simultaneously and returns a bitmask integer where specific bits correspond to different geometric issues:

# Bit flag for self-intersection in FontForge
SELF_INTERSECTS_FLAG = 0x2

state = glyph.validate(True)
if state & SELF_INTERSECTS_FLAG:
    print(f"Glyph {glyph.glyphname} has self-intersecting contours.")

Using glyph.selfIntersects() is recommended for straightforward intersection detection, while glyph.validate() is preferable if you plan to incorporate checks for open contours, wrong direction paths, or missing extrema into the same automation pipeline.