babelfont

Crates.iobabelfont
lib.rsbabelfont
version0.1.1-pre
created_at2025-11-28 13:23:51.714349+00
updated_at2025-11-28 13:23:51.714349+00
descriptionA universal font format converter and processor
homepage
repositoryhttps://github.com/simoncozens/babelfont-rs
max_upload_size
id1955272
size5,532,711
Simon Cozens (simoncozens)

documentation

https://docs.rs/babelfont

README

Babelfont

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.

Features

  • Multi-format Support: Load and save fonts in UFO, DesignSpace, Glyphs, FontLab VFJ, and Babelfont's own JSON format
  • Format Conversion: Convert fonts between different editor formats seamlessly
  • Font Manipulation: Apply filters to subset, scale, or otherwise transform fonts
  • JSON Serialization: Full serialization/deserialization of Babelfont's internal representation
  • Variable Font Support: Full support for variable/multiple master fonts with axes, masters, and instances
  • Feature-based Compilation: Optional dependencies for specific format support

Status

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.

Installation

Add this to your Cargo.toml:

[dependencies]
babelfont = "0.1"

Feature Flags

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 formats
  • fontlab - Support for FontLab VFJ (JSON) format
  • fontra - Support for Fontra format
  • fontir - Enable compilation to binary font formats (.ttf)
  • cli - Command-line interface support
  • typescript - TypeScript type definition generation

Quick Start

Loading and Converting Fonts

use 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(())
}

Subsetting with Filters

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(())
}

Inspecting Font Metadata

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(())
}

Supported Formats

Input/Output Formats

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

JSON Serialization

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:

  • Convert any supported format to JSON and back without data loss
  • Use JSON as an intermediate format when converting between editor formats
  • Inspect the complete font structure in a human-readable format
  • Create programmatic workflows using standard JSON tools

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

Font Filters

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 axis
  • DropInstances - Remove named instances
  • DropKerning - Remove all kerning data
  • DropFeatures - Remove OpenType feature code
  • DropGuides - Remove all guidelines
  • DropSparseMasters - Convert sparse masters to associated layers
  • ResolveIncludes - Resolve feature file include statements
  • ScaleUpem - Scale the units-per-em value

Filters 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(())
}

Core Types

  • Font - The main font structure containing all font data
  • Glyph - A single glyph with its layers and metadata
  • Layer - A glyph's outline in a particular master
  • Master - A design master in a variable/multiple master font
  • Axis - A variation axis definition
  • Instance - A named instance (static font variant)
  • Features - OpenType feature code representation
  • Shape - A path or component in a glyph layer

Command-Line Interface

With 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

Related Projects

Babelfont is based on the Python babelfont library. Additional development is now happening here, rather than in the original Python version.

License

Babelfont is available under the MIT or Apache-2.0 licenses, at your option.

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues on GitHub.

Commit count: 0

cargo fmt