Create a Font from Scratch Using FontForge Python

You can build a complete, production-ready font from scratch using only Python scripting in FontForge. FontForge provides a dedicated Python module that exposes virtually all of its core functionality, allowing you to generate new font files, define font metadata, draw vector outlines, set advance widths and kerning, and export finalized formats such as OpenType (OTF) or TrueType (TTF) entirely without using the graphical user interface.

How FontForge Python Scripting Works

FontForge embeds an internal Python interpreter and can also be imported as a standalone Python module (import fontforge) in supported environments. When run in headless mode using the command fontforge -script your_script.py, the engine can execute complex mathematical algorithms to create typography purely from code.

Every component required for a functional digital font is accessible through this API:

  • Font Properties: Set font names, weights, family names, versioning, and copyright metadata.
  • Glyph Outlines: Construct vector paths using points, beziers, and standard drawing commands (such as the FontForge Pen API).
  • Metrics and Kerning: Programmatically set advance widths, left side bearings (LSB), right side bearings (RSB), and OpenType kerning pairs.
  • File Export: Compile vector data into OTF, TTF, WOFF, or SVG font formats with full hinting support.

Step-by-Step Implementation

Building a font from scratch in Python involves five distinct steps:

1. Initialize the Font and Define Metadata

Create a new font object and set the primary identification fields so operating systems can parse and display the font family correctly:

import fontforge

# Create a new font
font = fontforge.font()

# Set general font metadata
font.fontname = "CodeSans-Regular"
font.familyname = "CodeSans"
font.fullname = "CodeSans Regular"
font.weight = "Regular"
font.version = "1.0"
font.copyright = "Copyright (c) 2026 by Designer"

# Define standard dimensions
font.ascent = 800
font.descent = 200
font.em = 1000

2. Create and Draw Glyphs

FontForge allows you to create an empty glyph container at a specific Unicode code point or glyph name, then trace coordinates onto its outline layer:

# Create the glyph for the letter 'I'
glyph = font.createChar(ord('I'), "I")

# Open a drawing pen on the glyph
pen = glyph.glyphPen()

# Draw a simple rectangle
pen.moveTo((100, 0))
pen.lineTo((100, 700))
pen.lineTo((200, 700))
pen.lineTo((200, 0))
pen.closePath()

# Close the pen to finalize coordinates
pen = None

3. Set Metrics

Without explicitly defined metrics, glyphs will overlap when rendered in text editors:

# Set the horizontal advance width
glyph.width = 300

4. Build Curves and Complex Shapes

For curved glyphs like 'O' or 'S', use cubic or quadratic bezier commands (pen.curveTo()) to add smooth contours. You can also construct multi-contour paths (e.g., the counter/hole inside an 'O') by drawing an outer path clockwise and an inner path counter-clockwise, ensuring correct path direction.

5. Validate and Generate the Font File

Before compiling, ensure the contours are corrected for overlap and direction, then save the font to disk:

# Clean up paths across all glyphs
font.selection.all()
font.correctDirection()
font.removeOverlap()

# Generate the output font file
font.generate("CodeSans-Regular.otf")
font.close()

Practical Uses for Pure Python Font Creation

Scripting a font from scratch is particularly valuable for:

  • Procedural and Generative Typography: Generating experimental glyph designs using mathematical formulas.
  • Custom Icon and Symbol Fonts: Automatically compiling SVG icons exported from design tools into a unified web font.
  • Automated CI/CD Pipelines: Rebuilding and testing fonts automatically within software development environments.