Skip to content

Rust Usage

Installation

sh
cargo add webfont-generator

Feature flags

FeatureDefaultDescription
(none)yesLibrary-only build
clinoBuilds the webfont-generator CLI binary (adds clap dependency)
napinoEnables Node.js NAPI bindings for use as a native addon

Async API

The primary entry point requires a tokio runtime:

rust
pub async fn generate(
    options: GenerateWebfontsOptions,
    rename: Option<RenameFn>,
) -> std::io::Result<GenerateWebfontsResult>

Example

rust
use webfont_generator::{GenerateWebfontsOptions, FontType};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let options = GenerateWebfontsOptions {
        dest: "output".to_owned(),
        files: vec![
            "icons/add.svg".to_owned(),
            "icons/remove.svg".to_owned(),
        ],
        font_name: Some("my-icons".to_owned()),
        types: Some(vec![FontType::Woff2, FontType::Woff]),
        ..Default::default()
    };

    let result = webfont_generator::generate(options, None).await?;

    if let Some(woff2) = result.woff2_bytes() {
        println!("Generated WOFF2: {} bytes", woff2.len());
    }

    Ok(())
}

Sync API

For contexts without a tokio runtime, generate_sync spawns one internally:

rust
pub fn generate_sync(
    options: GenerateWebfontsOptions,
    rename: Option<RenameFn>,
) -> std::io::Result<GenerateWebfontsResult>

Example

rust
use webfont_generator::{GenerateWebfontsOptions, FontType};

let options = GenerateWebfontsOptions {
    dest: "output".to_owned(),
    files: vec!["icons/add.svg".to_owned()],
    write_files: Some(false),
    ..Default::default()
};

let result = webfont_generator::generate_sync(options, None).unwrap();

if let Some(svg) = result.svg_string() {
    println!("SVG font length: {}", svg.len());
}

RenameFn

rust
pub type RenameFn = Box<dyn Fn(&str) -> String + Send + Sync>;

An optional callback that maps file paths to custom glyph names. When None, glyph names are derived from the file stem.

rust
let rename: webfont_generator::RenameFn = Box::new(|path| {
    // Use only the filename without extension, lowercased
    std::path::Path::new(path)
        .file_stem()
        .unwrap()
        .to_str()
        .unwrap()
        .to_lowercase()
});

let result = webfont_generator::generate_sync(options, Some(rename)).unwrap();

GenerateWebfontsOptions

All fields except dest and files are optional and implement Default.

FieldTypeDefaultDescription
destString--Output directory (required)
filesVec<String>--SVG file paths (required)
font_nameOption<String>"iconfont"Font family name
typesOption<Vec<FontType>>[Eot, Woff, Woff2]Font formats to generate
orderOption<Vec<FontType>>Filtered default order@font-face src order
cssOption<bool>trueGenerate CSS file
htmlOption<bool>falseGenerate HTML preview
write_filesOption<bool>trueWrite output to disk
css_templateOption<String>Built-in templateCustom Handlebars CSS template path
html_templateOption<String>Built-in templateCustom Handlebars HTML template path
css_fonts_urlOption<String>Relative pathURL prefix for fonts in CSS
css_destOption<String>dest/fontName.cssCSS output path
html_destOption<String>dest/fontName.htmlHTML output path
codepointsOption<HashMap<String, u32>>EmptyExplicit glyph codepoints
start_codepointOption<u32>0xF101Starting auto-codepoint
font_heightOption<f64>--Explicit font height
ascentOption<f64>--Font ascent
descentOption<f64>--Font descent
normalizeOption<bool>trueNormalize glyph heights
incrementalOption<bool>falseRetain parsed glyphs for regenerate
fixed_widthOption<bool>--Monospace font
center_horizontallyOption<bool>--Center glyphs horizontally
center_verticallyOption<bool>--Center glyphs vertically
ligatureOption<bool>trueEnable ligatures
roundOption<f64>--Path rounding precision
preserve_aspect_ratioOption<bool>--Preserve SVG aspect ratio
optimize_outputOption<bool>--Optimize SVG output
font_styleOption<String>--CSS font-style value
font_weightOption<String>--CSS font-weight value
format_optionsOption<FormatOptions>--Per-format options
template_optionsOption<Map<String, Value>>--Extra template context

FontType

rust
pub enum FontType {
    Svg,
    Ttf,
    Eot,
    Woff,
    Woff2,
}

Methods:

  • css_format() -> &'static str -- Returns the CSS format() value (e.g., "woff2", "truetype")
  • as_extension() -> &'static str -- Returns the file extension (e.g., "woff2", "ttf")

GenerateWebfontsResult

Font data getters

MethodReturn typeDescription
eot_bytes()Option<&[u8]>EOT font bytes
svg_string()Option<&str>SVG font XML string
ttf_bytes()Option<&[u8]>TTF font bytes
woff_bytes()Option<&[u8]>WOFF font bytes
woff2_bytes()Option<&[u8]>WOFF2 font bytes

Template methods

MethodReturn typeDescription
generate_css_pure(urls?)io::Result<String>Render CSS with optional URL overrides
generate_html_pure(urls?)io::Result<String>Render HTML preview with optional URL overrides

Both methods accept Option<HashMap<FontType, String>> for the urls parameter. Results are cached internally for repeated calls with the same arguments.

Incremental rebuild

MethodReturn typeDescription
regenerate(ordered_paths, changes)io::Result<()>Rebuild after known file changes, reusing unchanged glyphs
regenerate_all(ordered_paths)io::Result<()>Re-read/hash the full file set and infer added/changed/removed paths

Requires the result to have been generated with incremental: Some(true) (errors otherwise). ordered_paths: &[String] is the complete file set after the changes, in the order a fresh build would use (e.g. the glob result); the rebuilt glyphs are ordered to match it, so the result is byte-identical to a fresh build of that set — additions included, even when they sort before existing glyphs. Any path absent from ordered_paths is dropped. changes: &[(String, GlyphChange)] names the affected files: added/changed files are re-read from disk. Every format is refreshed in memory, and — when the result was built with write_files — refreshed fonts are written to disk too, while unchanged CSS/HTML companion files are skipped. Rendered CSS/HTML is reused when glyph names and codepoints are unchanged. Use regenerate_all when you have the fresh ordered file set but no reliable watcher change batch; existing glyph names are preserved, and added paths derive their glyph name from the file stem.

For Node.js results, regenerate() errors if the initial build used cssContext or htmlContext callbacks because the synchronous method cannot re-run JavaScript callbacks during the rebuild.

rust
pub enum GlyphChange {
    Added { name: Option<String> },   // new file; `name` overrides the file-stem glyph name
    Changed { name: Option<String> }, // content changed; `name` overrides the glyph name
    Removed,                          // file deleted
}

// result built with `incremental: Some(true)`
let files = vec!["icons/add.svg".to_owned(), "icons/remove.svg".to_owned()];
result.regenerate(&files, &[("icons/add.svg".to_owned(), GlyphChange::Changed { name: None })])?;
// Or re-diff the full set when watcher hints are unavailable/untrusted:
result.regenerate_all(&files)?;

Full API reference

For the complete API surface including all sub-types, see docs.rs/webfont-generator.

See also

Released under the MIT License.