Subset a Font from a Text File with FontForge Python
Yes, you can generate a font subset based on a text file using FontForge's Python module. This process works by extracting unique characters from your source text file, opening the target font in FontForge, selecting only the glyphs corresponding to those characters, removing all unused glyphs, and exporting the reduced font file. This is an effective way to drastically reduce font file sizes for web performance or embedded systems.
Prerequisites
To use FontForge with Python, you must run your script through
FontForge's embedded Python interpreter. FontForge provides a standalone
binary that can execute Python scripts directly using the
-script flag:
fontforge -script subset.pyAlternatively, on Linux distributions, you can install the
system-level Python bindings (often packaged as
python3-fontforge).
The Subsetting Script
Below is a complete Python script that reads unique characters from
input.txt, extracts them from SourceFont.ttf,
and outputs a subsetted font named SubsetFont.ttf.
import sys
import fontforge
def subset_font(font_path, text_path, output_path):
# Step 1: Read unique characters from the text file
with open(text_path, 'r', encoding='utf-8') as f:
text_content = f.read()
unique_chars = set(text_content)
# Step 2: Open the target font
font = fontforge.open(font_path)
# Step 3: Deselect all glyphs to start with a clean slate
font.selection.none()
# Step 4: Select only the glyphs present in the text file
for char in unique_chars:
codepoint = ord(char)
# Verify the glyph exists in the font before selecting
if codepoint in font:
font.selection.select(("more",), codepoint)
# Step 5: Always retain the .notdef glyph (undefined character box)
if ".notdef" in font:
font.selection.select(("more",), ".notdef")
# Step 6: Invert the selection and clear all unused glyphs
font.selection.invert()
font.clear()
# Step 7: Generate the optimized subset font
font.generate(output_path)
font.close()
if __name__ == "__main__":
subset_font("SourceFont.ttf", "input.txt", "SubsetFont.ttf")How the Script Works
- Character Extraction: The script opens the plain
text file using UTF-8 encoding and places all characters into a Python
set, eliminating duplicates. - Glyph Selection: It converts each character to its
Unicode codepoint via
ord(char)and verifies if the font contains that encoding. The("more",)flag appends the character to the active selection without resetting previous selections. - Preserving Critical Glyphs: Retaining standard
fallback glyphs like
.notdefis critical to prevent font rendering errors when an unmapped character is encountered in runtime environments. - Inversion and Removal:
font.selection.invert()flips the selection so that all unused characters are highlighted, andfont.clear()wipes them entirely from the font database. - Generation:
font.generate()exports the subsetted font into modern formats like TTF, OTF, or WOFF depending on the specified file extension.