fonts-rs-generator - Build-Time Pipeline
The fonts-rs-generator crate provides the build-time pipeline for exporting
glyphs from TTF/OTF font files, generating codepoint maps, compiling
GResource bundles, and producing Rust source constants. It is used as a
build-dependency by every font family crate.
ExportConfig<X: FontFamilyConfig>
Runtime configuration for glyph export, decoupled from FontDefinition.
Enables variant-specific parameters at build time without a separate
FontDefinition impl per variant.
#![allow(unused)]
fn main() {
pub struct ExportConfig<X: FontFamilyConfig> {
pub gresource_prefix: String,
pub glyph_name_prefix: String,
pub axes: AxisValues,
pub name_filter: Option<fn(&str) -> bool>,
pub family_display_name: String,
_marker: PhantomData<X>,
}
}
Constructors
ExportConfig::new()- without a variant, usesX::GRESOURCE_PREFIXandX::FONT_FAMILY_NAMEExportConfig::with_variant(variant)- with a variant, constructsgresource_prefixas{X::GRESOURCE_PREFIX}/{variant_slug}andglyph_name_prefixas{X::FONT_FAMILY_NAME}-{variant}
Methods
export_glyphs(font_path, output_dir)- standard export: iterates over all glyph IDs, normalizes names to{glyph_name_prefix}-{kebab}, renders SVGs with axis locationexport_glyphs_by_name_map(font_path, output_dir, name_map)- export via external name→codepoint map (e.g. SMuFLglyphnames.json): for fonts without PostScript glyph nameswrite_variant_info()- writesOUT_DIR/variant.rswithGRESOURCE_PREFIXandGLYPH_PREFIXconstantsgenerate_gresource_xml(entries, path)- generatesicons.gresource.xmlwithquick-xmlserialization
export_glyphs() (Two Variants)
There are two distinct export_glyphs methods in the framework:
FontDefinition::export_glyphs (trait default method)
Uses Self::normalize_name for type-safe glyph names. Iterates over all
glyph IDs, calls should_skip and normalize_name, renders SVGs without
axis location (default location).
ExportConfig::export_glyphs (struct method)
Uses normalize_to_kebab + glyph_name_prefix for string-based names.
Renders SVGs with axis location (glyph_to_svg_full_height_at).
Supports name_filter for custom glyph filtering.
Output
Both produce:
<output_dir>/scalable/{context}/*.svg<output_dir>/metadata.json<output_dir>/icons.gresource.xml
write_variant_info()
Writes OUT_DIR/variant.rs with two constants:
#![allow(unused)]
fn main() {
pub const GRESOURCE_PREFIX: &str = "/io/smearor/fonts/doto/regular_medium";
pub const GLYPH_PREFIX: &str = "doto-regular-medium";
}
Included by lib.rs via include!(concat!(env!("OUT_DIR"), "/variant.rs")).
Enables the runtime API to construct GResource paths and glyph names with
the active variant prefix.
detect_and_get_active_variant()
On VariantList<X: FontFamilyConfig>:
#![allow(unused)]
fn main() {
pub fn detect_and_get_active_variant(&self, default_index: usize) -> miette::Result<&'a FontVariant>
}
Scans CARGO_FEATURE_{NAME} environment variables for each variant.
Returns the active variant or default_index if none is active. Returns
an error if more than one variant is active. Uses X::FAMILY_DISPLAY_NAME
for diagnostic messages.
FontBuild (Builder)
Builder for the common build.rs pipeline. Handles hash-based change
detection, conditional glyph export, GResource compilation, and code
generator invocation.
#![allow(unused)]
fn main() {
FontBuild::new(&font_path)
.extra_hash(entry.as_str()) // for variable font variants
.compile_font_gresource() // optional: font.gresource
.rerun_if_changed(path) // additional cargo:rerun-if-changed
.additional_gresource(xml, out) // additional GResource bundles
.run(|font_path, resources_dir| {
config.export_glyphs(font_path, resources_dir)
})
.map_err(|e| miette::miette!("{e}"))?;
}
Builder Methods
extra_hash: Additional hash component (e.g. variant name) - forces re-export on variant change even if the font file is unchangedcompile_font_gresource: Also compilefont.gresourcein addition toicons.gresourcererun_if_changed: Add extracargo:rerun-if-changedpathsadditional_gresource: Register additional GResource bundles to compile
Run Methods
run: Export closure + default code generation (CodemapGenerator+RustConstantsGenerator)run_with: Export closure + custom code generation closure- Hash is computed as FNV-1a of the font file and stored in
resources/.hash
impl_font_loader! Macro
Generates a font() -> Option<&'static ab_glyph::FontVec> function that
loads a TTF font file and caches it in a OnceLock.
Two variants:
#![allow(unused)]
fn main() {
// Literal: relative to resources/
fonts_rs_generator::impl_font_loader!("Doto.ttf");
// Env var: absolute path set by build.rs via cargo:rustc-env
fonts_rs_generator::impl_font_loader!(env: "DOTO_FONT_PATH");
}
With the embed-fonts feature, include_bytes! is used; otherwise
std::fs::read.
MetadataGenerator (Trait)
Trait for generating phf::Map metadata tables (keywords, categories,
aliases) at build time.
#![allow(unused)]
fn main() {
pub trait MetadataGenerator {
type Name: AsRef<str>;
fn keywords_for(&self, entry: &GlyphEntry<Self::Name>) -> Vec<String>;
fn categories_for(&self, entry: &GlyphEntry<Self::Name>) -> Vec<String>;
fn aliases(&self) -> Vec<(String, String)> { Vec::new() }
fn deduplicate_statics() -> bool { false }
fn generate_keywords(&self, entries: &[GlyphEntry<Self::Name>]) -> String { ... }
fn generate_categories(&self, entries: &[GlyphEntry<Self::Name>]) -> String { ... }
fn generate_aliases(&self) -> String { ... }
fn run(&self, entries: &[GlyphEntry<Self::Name>]) -> Result<(), std::io::Error> { ... }
}
}
deduplicate_statics() = true: Extracts repeated value lists intostaticconstants (e.g.static KW_0: &[GlyphKeyword] = &[...]) - reduces binary size for large maps with many duplicatesrun(): Writeskeywords.rs,categories.rs,aliases.rstoOUT_DIR
Example implementation: NotoEmojiMetadataGenerator in
fonts-rs-noto-emoji-generator uses CodePointKeywordMap and
CodePointCategoryMap as data sources.
VariantList<X: FontFamilyConfig>
A typed list of font variants, generic over the font family config. Provides methods to detect the active variant from Cargo features.
#![allow(unused)]
fn main() {
const VARIANTS: VariantList<DotoConfig> = VariantList::new(&[
FontVariant::axes("regular-medium", &[AxisValue::new("wght", 500.0), AxisValue::new("ROND", 50.0)]),
FontVariant::axes("bold-dot", &[AxisValue::new("wght", 700.0), AxisValue::new("ROND", 100.0)]),
]);
let entry = VARIANTS.detect_and_get_active_variant(0)?;
}
FontVariantExt (Extension Trait)
Extension trait providing a method to get the font file path from a
FontVariant, handling errors if no font file is associated.
set_font_path_env() Helper
Sets cargo:rustc-env with the absolute font path for include_bytes!
in lib.rs. Constructs the absolute path from CARGO_MANIFEST_DIR and
the given relative font path.
#![allow(unused)]
fn main() {
set_font_path_env("DOTO_FONT_PATH", &font_path)?;
}
build_constants Module
Provides common constants for build scripts:
RESOURCES_DIR- theresources/directory pathMETADATA_PATH- path toresources/metadata.jsonHASH_PATH- path toresources/.hashICONS_GRESOURCE_XML- path toresources/icons.gresource.xmlICONS_GRESOURCE- path to compiledicons.gresourceFONT_GRESOURCE_XML- path toresources/font.gresource.xmlFONT_GRESOURCE- path to compiledfont.gresource