| Crates.io | babelfont |
| lib.rs | babelfont |
| version | 0.1.1-pre |
| created_at | 2025-11-28 13:23:51.714349+00 |
| updated_at | 2025-11-28 13:23:51.714349+00 |
| description | A universal font format converter and processor |
| homepage | |
| repository | https://github.com/simoncozens/babelfont-rs |
| max_upload_size | |
| id | 1955272 |
| size | 5,532,711 |
Babelfont is a Rust library for working with font source files from different font editing software. It provides a unified interface to load, examine, manipulate, and convert fonts between various formats, abstracting over the differences between font editors' native representations.
Babelfont is currently in early development. While the core architecture and many features are implemented, some format support and filters are still works in progress.
Glyphs file format: Mostly complete for reading and writing Glyphs 2 and Glyphs 3 files.
UFO/DesignSpace: Reading support is implemented; writing support is in progress.
FontLab VFJ: Very basic reading support is implemented; writing support is planned.
Fontra: Basic reading and writing support is implemented.
Add this to your Cargo.toml:
[dependencies]
babelfont = "0.1"
By default, all major format support is enabled. You can customize which formats are supported:
[dependencies]
babelfont = { version = "0.1", default-features = false, features = ["glyphs", "ufo"] }
Available features:
glyphs - Support for Glyphs 2 and Glyphs 3 files (.glyphs and .glyphspackage)ufo - Support for UFO and DesignSpace formatsfontlab - Support for FontLab VFJ (JSON) formatfontra - Support for Fontra formatfontir - Enable compilation to binary font formats (.ttf)cli - Command-line interface supporttypescript - TypeScript type definition generationuse babelfont::{load, BabelfontError};
fn main() -> Result<(), BabelfontError> {
// Load a font from any supported format
let font = load("MyFont.designspace")?;
// Convert to Glyphs format
font.save("MyFont.glyphs")?;
// Or save as JSON
font.save("MyFont.babelfont")?;
Ok(())
}
use babelfont::{load, BabelfontError};
use babelfont::filters::{FontFilter, RetainGlyphs};
fn main() -> Result<(), BabelfontError> {
// Load a DesignSpace file
let mut font = load("MyFont.designspace")?;
// Create a filter to retain only certain glyphs
let filter = RetainGlyphs::new(vec![
"A".to_string(),
"B".to_string(),
"C".to_string(),
"space".to_string(),
]);
// Apply the filter
filter.apply(&mut font)?;
// Save as a Glyphs file
font.save("MyFont-Subset.glyphs")?;
Ok(())
}
use babelfont::load;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let font = load("MyFont.ufo")?;
// Access font metadata
println!("Font family: {}", font.names.family_name);
println!("Units per em: {}", font.upm);
println!("Number of glyphs: {}", font.glyphs.len());
// Iterate over axes in a variable font
for axis in &font.axes {
println!("Axis: {} ({} to {})", axis.name, axis.min, axis.max);
}
// Access specific glyphs
if let Some(glyph) = font.glyphs.get("A") {
println!("Glyph 'A' has {} layers", glyph.layers.len());
for layer in &glyph.layers {
println!(" Layer: {:?}", layer.id);
}
}
Ok(())
}
| Format | Extension | Read | Write | Feature Flag |
|---|---|---|---|---|
| UFO | .ufo |
✓ | ✗ | ufo |
| DesignSpace | .designspace |
✓ | ✓ | ufo |
| Glyphs 2/3 | .glyphs |
✓ | ✓ | glyphs |
| Glyphs Package | .glyphspackage |
✓ | ✗ | glyphs |
| FontLab VFJ | .vfj |
✓ | ✗ | fontlab |
| Babelfont JSON | .babelfont |
✓ | ✓ | (always) |
| TrueType | .ttf |
✗ | ✓ | fontir |
One of Babelfont's unique features is its ability to serialize and deserialize its internal representation to and from JSON. This provides a format-agnostic way to store and exchange font data.
The JSON format is complete and lossless, meaning you can:
Example:
use babelfont::load;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load from Glyphs
let font = load("MyFont.glyphs")?;
// Save as JSON
font.save("MyFont.babelfont")?;
// Load from JSON
let font2 = load("MyFont.babelfont")?;
// Convert to DesignSpace
font2.save("MyFont.designspace")?;
Ok(())
}
To generate TypeScript type definitions for the JSON format, run:
$ cargo run --example dump-typescript --features=typescript
Babelfont includes several built-in filters for font manipulation:
RetainGlyphs - Keep only specified glyphs, removing all others. Components referencing removed glyphs are automatically decomposed.DropAxis - Remove a variable font axisDropInstances - Remove named instancesDropKerning - Remove all kerning dataDropFeatures - Remove OpenType feature codeDropGuides - Remove all guidelinesDropSparseMasters - Convert sparse masters to associated layersResolveIncludes - Resolve feature file include statementsScaleUpem - Scale the units-per-em valueFilters can be chained together:
use babelfont::{load, filters::*};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut font = load("MyFont.glyphs")?;
// Apply multiple filters
RetainGlyphs::new(vec!["A".into(), "B".into()]).apply(&mut font)?;
DropGuides.apply(&mut font)?;
DropKerning.apply(&mut font)?;
font.save("MyFont-Filtered.glyphs")?;
Ok(())
}
Font - The main font structure containing all font dataGlyph - A single glyph with its layers and metadataLayer - A glyph's outline in a particular masterMaster - A design master in a variable/multiple master fontAxis - A variation axis definitionInstance - A named instance (static font variant)Features - OpenType feature code representationShape - A path or component in a glyph layerWith the cli feature enabled, Babelfont also provides a command-line tool:
# Convert between formats
babelfont MyFont.glyphs --output MyFont.babelfont
# Apply filters
babelfont MyFont.babelfont --filter dropaxis=wdth --filter retainglyphs=A,B,C --output Subset.babelfont
# Compile to TTF
babelfont Subset.babelfont --output Subset.ttf
Compile the CLI with:
$ cargo build --release --bin babelfont --features=cli
Babelfont is based on the Python babelfont library. Additional development is now happening here, rather than in the original Python version.
Babelfont is available under the MIT or Apache-2.0 licenses, at your option.
Contributions are welcome! Please feel free to submit pull requests or open issues on GitHub.