Manipulating Layer Data with Python in FontForge
Yes, you can fully manipulate layer data using Python in FontForge. FontForge provides robust Python bindings that expose both font-level layer definitions and individual glyph-level layer contents. This guide outlines how the layer architecture works, how to read and modify layer geometry directly, and how to programmatically transfer contours between different layers such as the Foreground and Background.
Understanding FontForge Layer Architecture
In FontForge, layers exist at two distinct levels:
- Font-Level Layers: Defined across the entire font, determining the layer names, spline types (Cubic or Quadratic), and whether a layer contains fill, stroke, or background data.
- Glyph-Level Layers: The actual vector contents (contours and references) present inside a specific glyph for a given layer.
FontForge accesses glyph layers primarily through the
glyph.layers tuple or convenience properties like
glyph.foreground and glyph.background.
Accessing Glyph Layers
Each element in glyph.layers is a
fontforge.layer object containing contours and references.
By default, index 0 corresponds to the Background layer and
index 1 corresponds to the Foreground layer.
import fontforge
# Open font and select a glyph
font = fontforge.open("MyFont.sfd")
glyph = font["A"]
# Access via properties
fg_layer = glyph.foreground
bg_layer = glyph.background
# Access via index
first_layer = glyph.layers[0]
# Inspect contents
print(f"Number of contours in foreground: {len(fg_layer)}")Modifying Layer Contours and Points
A fontforge.layer object acts like an iterable of
fontforge.contour objects. To modify layer geometry, you
extract the contours, alter their points, and assign the modified layer
back to the glyph.
import fontforge
font = fontforge.open("MyFont.sfd")
glyph = font["A"]
# Retrieve the foreground layer
layer = glyph.foreground
# Shift every point in the layer horizontally by 50 units
for contour in layer:
for point in contour:
point.x += 50
# Reassign the layer back to the glyph to apply changes
glyph.foreground = layer
font.save()When modifying points, changes are only committed to the font
database once the layer is reassigned to glyph.foreground,
glyph.background, or glyph.layers[index].
Copying Data Between Layers
A common task is duplicating geometry from one layer to another, such as backing up foreground outlines to the background before applying destructive transformations.
import fontforge
font = fontforge.open("MyFont.sfd")
glyph = font["A"]
# Copy foreground geometry to background
glyph.background = glyph.foreground.dup()
# Clear the foreground layer
glyph.foreground = fontforge.layer()
font.save()Adding and Configuring Custom Layers
You can create custom layers at the font level using the font's layer configuration methods.
import fontforge
font = fontforge.open("MyFont.sfd")
# Check existing font layers
for name in font.layer_cnt:
print(name)
# Enable multi-layer mode (needed for Type3 or SVG fonts with multiple colored layers)
font.multilayer = True
# Add a new cubic layer
new_layer_index = font.newLayer("Mask", False) # False indicates Cubic/PostScript
# Access the new layer inside a glyph
glyph = font["A"]
mask_layer = glyph.layers[new_layer_index]Key Considerations
- Layer Reassignment: Always reassign the layer
object back to the glyph (e.g.,
glyph.layers[i] = layer) after altering its contours; in-place mutations of point coordinates inside a retrieved layer do not automatically update the underlying font database. - Coordinate Types: Coordinate values
(
x,y) accept floating-point numbers during manipulation, but PostScript and TrueType font export requirements will dictate final integer rounding. - References: If a layer contains component
references (such as accents or composites), inspect
layer.referencesin addition to contour iteration.