webfont_generator/types.rs
1use std::collections::HashMap;
2
3use serde_json::{Map, Value};
4
5/// What happened to a file, for [`crate::GenerateWebfontsResult::regenerate`]. `name` is the
6/// caller-resolved glyph name (the `rename` callback, if any, is applied by the caller).
7pub enum GlyphChange {
8 /// A new file. `name` overrides the file-stem glyph name when `Some`.
9 Added { name: Option<String> },
10 /// An existing file's contents changed. `name` overrides the glyph name when `Some`.
11 Changed { name: Option<String> },
12 /// The file was deleted.
13 Removed,
14}
15
16/// One entry in the `changes` array passed to the Node binding's `regenerate`. The complete
17/// ordered file list passed alongside it controls final glyph order; this only describes which
18/// files need re-reading, renaming, or removal.
19pub struct GlyphChangeEntry {
20 /// Path of the changed file.
21 pub path: String,
22 /// What happened to the file.
23 pub change_type: String,
24 /// Resolved glyph name (with the caller's `rename` already applied). Optional for `'added'`
25 /// and `'changed'` (defaults to the file stem/current name); ignored for `'removed'`.
26 pub name: Option<String>,
27}
28
29/// Complete ordered input membership for a regeneration operation. The case must match the
30/// result's generation mode. Synchronous methods borrow this value; async methods consume it.
31pub enum RegenerationFiles {
32 /// Single-design font inputs, in the order a fresh generation would use.
33 Single(Vec<String>),
34 /// Complete file sets for every configured variant, each named exactly once. The order of
35 /// these entries does not change configured design order. Paths can be shared between
36 /// designs; each design's file list independently determines its membership and order.
37 Variants(Vec<VariantFileSet>),
38}
39
40/// Complete file set for one configured variant during regeneration.
41pub struct VariantFileSet {
42 /// Existing variant name. Full re-diff requires every configured variant exactly once.
43 pub variant: String,
44 /// Complete ordered file set for this variant.
45 pub files: Vec<String>,
46}
47
48/// Font output format. Used in the `types` and `order` options to control which
49/// formats are generated and the order they appear in the CSS `@font-face`
50/// `src:` descriptor.
51#[cfg_attr(feature = "cli", derive(clap::ValueEnum))]
52#[derive(Clone, Copy, PartialEq, Eq, Hash)]
53#[cfg_attr(
54 feature = "cli",
55 derive(serde::Deserialize),
56 serde(rename_all = "lowercase")
57)]
58pub enum FontType {
59 /// SVG font (`.svg`). Legacy format; intermediate representation that all
60 /// other formats are derived from.
61 Svg,
62 /// TrueType font (`.ttf`).
63 Ttf,
64 /// Embedded OpenType (`.eot`). Legacy format for older Internet Explorer.
65 Eot,
66 /// Web Open Font Format 1.0 (`.woff`).
67 Woff,
68 /// Web Open Font Format 2.0 (`.woff2`). Best compression; preferred for
69 /// modern browsers.
70 Woff2,
71}
72
73/// One named SVG design in a multi-variant icon family.
74#[derive(Clone)]
75#[cfg_attr(
76 feature = "cli",
77 derive(serde::Deserialize),
78 serde(rename_all = "camelCase", deny_unknown_fields)
79)]
80pub struct FontVariant {
81 /// User-facing variant name, used to derive CSS modifier classes.
82 pub name: String,
83 /// SVG files that belong to this variant.
84 pub files: Vec<String>,
85 /// Optional explicit CSS weight coordinate in the range 1 through 1000. Automatic weights
86 /// resolve outward from the default in steps of 100, or evenly when an interval is crowded.
87 pub weight: Option<u16>,
88 /// Whether this is the family's default variant. Exactly one variant must set this to `true`.
89 pub default: Option<bool>,
90}
91
92/// Family-wide behavior when a logical glyph is absent from a variant.
93#[derive(Clone, Copy, PartialEq, Eq)]
94#[cfg_attr(
95 feature = "cli",
96 derive(serde::Deserialize),
97 serde(rename_all = "lowercase")
98)]
99pub enum MissingGlyphBehavior {
100 /// Use an empty outline while retaining the logical glyph's advance.
101 Blank,
102 /// Reject generation and report every missing variant/glyph pair.
103 Error,
104 /// Reuse the outline from the named fallback variant, which must contain every logical glyph.
105 Fallback,
106}
107
108/// Family-wide missing-glyph policy for multi-variant generation.
109#[derive(Clone)]
110#[cfg_attr(
111 feature = "cli",
112 derive(serde::Deserialize),
113 serde(rename_all = "camelCase", deny_unknown_fields)
114)]
115pub struct MissingGlyphOptions {
116 /// Missing-glyph behavior. Variant mode defaults to [`MissingGlyphBehavior::Blank`] when this
117 /// object is omitted.
118 pub behavior: MissingGlyphBehavior,
119 /// Fallback variant name. Required only when `behavior` is `fallback`; the named variant must
120 /// contain every logical glyph in the family.
121 pub variant: Option<String>,
122}
123
124impl FontType {
125 /// Returns the CSS `format()` value (e.g., "truetype", "woff2").
126 #[inline]
127 pub fn css_format(self) -> &'static str {
128 match self {
129 FontType::Svg => "svg",
130 FontType::Ttf => "truetype",
131 FontType::Eot => "embedded-opentype",
132 FontType::Woff => "woff",
133 FontType::Woff2 => "woff2",
134 }
135 }
136
137 /// Returns the file extension (e.g., "svg", "ttf", "woff2").
138 #[inline]
139 pub fn as_extension(self) -> &'static str {
140 match self {
141 FontType::Svg => "svg",
142 FontType::Ttf => "ttf",
143 FontType::Eot => "eot",
144 FontType::Woff => "woff",
145 FontType::Woff2 => "woff2",
146 }
147 }
148}
149
150/// SVG-format–specific options for the intermediate SVG font and the per-glyph
151/// path processing that feeds every other format.
152#[derive(Clone, Default)]
153#[cfg_attr(
154 feature = "cli",
155 derive(serde::Deserialize),
156 serde(rename_all = "camelCase", deny_unknown_fields)
157)]
158pub struct SvgFormatOptions {
159 /// SVG-format override of the top-level `centerVertically` option. When set,
160 /// it wins over the top-level value; centers each glyph vertically inside
161 /// the em-square based on its bounding box.
162 pub center_vertically: Option<bool>,
163 /// Value of the SVG font's `id` attribute. Defaults to `fontName` when
164 /// omitted.
165 pub font_id: Option<String>,
166 /// Content embedded inside the generated SVG font's `<metadata>` element.
167 pub metadata: Option<String>,
168 /// SVG-format override of the top-level `optimizeOutput` option. When set,
169 /// it wins over the top-level value; runs an SVG path optimizer over each
170 /// glyph, trading a small amount of build time for smaller output bytes.
171 pub optimize_output: Option<bool>,
172 /// SVG-format override of the top-level `preserveAspectRatio` option. When
173 /// set, it wins over the top-level value; preserves the source viewBox
174 /// aspect ratio when scaling glyphs into the em-square.
175 pub preserve_aspect_ratio: Option<bool>,
176}
177
178/// TTF-format–specific options. Populates fields in the generated TTF `name`
179/// and `head` tables.
180#[derive(Clone)]
181#[cfg_attr(
182 feature = "cli",
183 derive(serde::Deserialize),
184 serde(rename_all = "camelCase", deny_unknown_fields)
185)]
186pub struct TtfFormatOptions {
187 /// Copyright string written to the TTF `name` table (record id 0).
188 pub copyright: Option<String>,
189 /// Description string written to the TTF `name` table (record id 10).
190 pub description: Option<String>,
191 /// Unix timestamp in seconds used for the `created` and `modified` fields
192 /// in the TTF `head` table. Pin to a fixed value to produce byte-stable
193 /// reproducible builds.
194 pub ts: Option<i64>,
195 /// Manufacturer URL written to the TTF `name` table (record id 11).
196 pub url: Option<String>,
197 /// Version string written to the TTF `name` table (record id 5).
198 pub version: Option<String>,
199}
200
201/// WOFF-format–specific options. Affects only WOFF1 output; WOFF2 ignores these.
202#[derive(Clone)]
203#[cfg_attr(
204 feature = "cli",
205 derive(serde::Deserialize),
206 serde(rename_all = "camelCase", deny_unknown_fields)
207)]
208pub struct WoffFormatOptions {
209 /// XML string embedded in the WOFF1 metadata block.
210 pub metadata: Option<String>,
211}
212
213/// WOFF2-format–specific options. Affects only WOFF2 output.
214#[derive(Clone)]
215#[cfg_attr(
216 feature = "cli",
217 derive(serde::Deserialize),
218 serde(rename_all = "camelCase", deny_unknown_fields)
219)]
220pub struct Woff2FormatOptions {
221 /// Brotli compression quality used when encoding WOFF2, from `0` (fastest,
222 /// largest output) to `11` (slowest, smallest output). This tunes compression
223 /// effort only and never changes glyph fidelity — the decompressed font is
224 /// identical at every level. Defaults to `11` for the smallest output; lower it
225 /// (e.g. to `10`) for faster encoding at a marginal size cost. Must be between
226 /// `0` and `11`; other values are rejected.
227 pub compression_quality: Option<u8>,
228}
229
230/// Per-format configuration object. Each field carries options that only apply
231/// to the corresponding output format.
232#[derive(Clone, Default)]
233#[cfg_attr(
234 feature = "cli",
235 derive(serde::Deserialize),
236 serde(rename_all = "camelCase", deny_unknown_fields)
237)]
238pub struct FormatOptions {
239 /// SVG-format options.
240 pub svg: Option<SvgFormatOptions>,
241 /// TTF-format options.
242 pub ttf: Option<TtfFormatOptions>,
243 /// WOFF1-format options.
244 pub woff: Option<WoffFormatOptions>,
245 /// WOFF2-format options.
246 pub woff2: Option<Woff2FormatOptions>,
247}
248
249/// Resolved variant metadata supplied to CSS and HTML template callbacks.
250#[derive(Clone)]
251pub struct TemplateVariant {
252 /// User-provided variant name.
253 pub name: String,
254 /// Resolved CSS weight coordinate.
255 pub weight: u32,
256 /// Whether this is the family's default design.
257 pub default: bool,
258 /// Unescaped modifier class for use in HTML.
259 pub class_name: String,
260 /// CSS-escaped modifier class identifier, without a leading dot.
261 pub selector: String,
262}
263
264/// Fields supplied to a `cssContext` callback. Additional keys from
265/// user-supplied `templateOptions` are merged into the same object at runtime,
266/// so the JS-side type widens this with an open-ended index signature.
267#[derive(Clone)]
268pub struct CssContext {
269 /// Name of the generated font, mirroring the `fontName` option.
270 pub font_name: String,
271 /// Pre-rendered value for the CSS `@font-face` `src:` descriptor — a
272 /// comma-separated list of `url(...) format(...)` entries derived from the
273 /// configured `types`, `order`, and `cssFontsUrl`.
274 pub src: String,
275 /// Map from glyph name to its assigned codepoint as a hex-encoded string
276 /// (e.g. `"add" -> "f101"`), suitable for use inside CSS `content`
277 /// declarations like `content: "\f101"`.
278 pub codepoints: HashMap<String, String>,
279 /// Ordered resolved variants; absent in ordinary mode unless supplied by template options.
280 /// The mode-independent Node declaration is unknown because ordinary template data is arbitrary.
281 pub variants: Option<Vec<TemplateVariant>>,
282 /// Modifier class prefix, supplied in variant mode.
283 pub variant_class_prefix: Option<String>,
284 /// Resolved default weight, supplied in variant mode.
285 pub default_weight: Option<u32>,
286 /// Resolved font style, supplied in variant mode.
287 pub font_style: Option<String>,
288}
289
290/// Fields supplied to an `htmlContext` callback. Additional keys
291/// from user-supplied `templateOptions` are merged into the same object at
292/// runtime, so the JS-side type widens this with an open-ended index signature.
293#[derive(Clone)]
294pub struct HtmlContext {
295 /// Name of the generated font, mirroring the `fontName` option.
296 pub font_name: String,
297 /// Glyph names in declaration order, after any `rename` callback has been
298 /// applied. Useful for iterating over icons in a preview template.
299 pub names: Vec<String>,
300 /// Pre-rendered CSS (the same string the engine writes to the `.css`
301 /// output) so HTML templates can embed it inline for self-contained
302 /// previews without an external stylesheet reference.
303 pub styles: String,
304 /// Map from glyph name to its assigned codepoint as a numeric value
305 /// (e.g. `"add" -> 0xF101`). Use the CSS context's hex form if you need a
306 /// string for embedding into CSS `content` declarations.
307 pub codepoints: HashMap<String, u32>,
308 /// Ordered resolved variants; absent in ordinary mode unless supplied by template options.
309 /// The mode-independent Node declaration is unknown because ordinary template data is arbitrary.
310 pub variants: Option<Vec<TemplateVariant>>,
311 /// Modifier class prefix, supplied in variant mode.
312 pub variant_class_prefix: Option<String>,
313 /// Resolved default weight, supplied in variant mode.
314 pub default_weight: Option<u32>,
315 /// Resolved font style, supplied in variant mode.
316 pub font_style: Option<String>,
317}
318
319/// Top-level options controlling webfont generation. `dest` and exactly one source, ordinary
320/// `files` or `variants`, are required. Every other field has a sensible default.
321/// With the `cli` feature, options deserialize from camelCase JSON with unknown fields rejected.
322#[derive(Clone, Default)]
323#[cfg_attr(
324 feature = "cli",
325 derive(serde::Deserialize),
326 serde(rename_all = "camelCase", deny_unknown_fields)
327)]
328pub struct GenerateWebfontsOptions {
329 /// Font ascent in font units. Overrides the value computed from the source
330 /// glyphs.
331 pub ascent: Option<f64>,
332 /// When `true`, centers each glyph horizontally inside the em-square based
333 /// on its bounding box.
334 pub center_horizontally: Option<bool>,
335 /// When `true`, centers each glyph vertically inside the em-square based
336 /// on its bounding box. Convenience alias for
337 /// `formatOptions.svg.centerVertically`.
338 pub center_vertically: Option<bool>,
339 /// Whether to generate a CSS file. Defaults to `true`.
340 pub css: Option<bool>,
341 /// Output path for the generated CSS file. Defaults to
342 /// `path.join(dest, fontName + '.css')`.
343 pub css_dest: Option<String>,
344 /// Path to a custom Handlebars template for CSS generation. The template
345 /// receives the `cssContext` shape plus any `templateOptions` keys.
346 pub css_template: Option<String>,
347 /// Explicit Unicode codepoints for specific glyphs, keyed by glyph name.
348 /// Glyphs not listed here are auto-assigned starting at `startCodepoint`.
349 pub codepoints: Option<HashMap<String, u32>>,
350 /// URL prefix for font files in the generated CSS. Defaults to the
351 /// relative path from `cssDest` to `dest`.
352 pub css_fonts_url: Option<String>,
353 /// Font descent in font units. Overrides the value computed from the
354 /// source glyphs.
355 pub descent: Option<f64>,
356 /// Output directory for generated font files. Required.
357 pub dest: String,
358 /// Paths to the SVG files to include in an ordinary font. Must be empty when `variants` is set.
359 #[cfg_attr(feature = "cli", serde(default))]
360 pub files: Vec<String>,
361 /// When `true`, produces a monospace font sized to the widest glyph.
362 pub fixed_width: Option<bool>,
363 /// Per-format option overrides. See `FormatOptions`.
364 pub format_options: Option<FormatOptions>,
365 /// Whether to generate an HTML preview file. Defaults to `false`.
366 pub html: Option<bool>,
367 /// Output path for the generated HTML preview file. Defaults to
368 /// `path.join(dest, fontName + '.html')`.
369 pub html_dest: Option<String>,
370 /// Path to a custom Handlebars template for HTML preview generation.
371 pub html_template: Option<String>,
372 /// Retain parsed glyph data on the result so `regenerate` can rebuild after file changes
373 /// without re-parsing unchanged glyphs. Defaults to `false`; enable for watch/dev. One-shot
374 /// builds (CLI, production) should leave it off to avoid holding the parsed geometry in memory.
375 /// Multi-variant results retain per-design parse/process caches. Pass
376 /// `RegenerationFiles::Variants` to the same regeneration methods for these results.
377 pub incremental: Option<bool>,
378 /// Explicit output font height in units per em. Overrides the height
379 /// computed from the source glyphs.
380 pub font_height: Option<f64>,
381 /// Name of the generated font family; also used as the base name for
382 /// output files. Defaults to `'iconfont'`.
383 pub font_name: Option<String>,
384 /// CSS `font-style` value for the generated `@font-face` rule.
385 pub font_style: Option<String>,
386 /// CSS `font-weight` value for the generated `@font-face` rule.
387 pub font_weight: Option<String>,
388 /// Enable ligature support so each glyph can be referenced by its name as
389 /// a text ligature. Defaults to `true`.
390 pub ligature: Option<bool>,
391 /// Family-wide missing-glyph policy for multi-variant generation. Defaults to `blank` and is
392 /// invalid without `variants`.
393 pub missing_glyphs: Option<MissingGlyphOptions>,
394 /// Scale icons to the height of the tallest icon. Defaults to `true`.
395 pub normalize: Option<bool>,
396 /// Order of `@font-face` `src:` entries in the generated CSS. Every entry
397 /// must also appear in `types`. Defaults to
398 /// `['eot', 'woff2', 'woff', 'ttf', 'svg']` filtered to the requested
399 /// `types`.
400 pub order: Option<Vec<FontType>>,
401 /// Run an SVG path optimizer over each glyph, trading a small amount of
402 /// build time for smaller output bytes. Convenience alias for
403 /// `formatOptions.svg.optimizeOutput`.
404 pub optimize_output: Option<bool>,
405 /// Preserve the source viewBox aspect ratio when scaling glyphs into the
406 /// em-square. Convenience alias for `formatOptions.svg.preserveAspectRatio`.
407 pub preserve_aspect_ratio: Option<bool>,
408 /// SVG path coordinate rounding precision.
409 pub round: Option<f64>,
410 /// Starting codepoint for auto-assigned glyphs. Defaults to `0xF101`.
411 pub start_codepoint: Option<u32>,
412 /// Additional key-value pairs merged into the Handlebars template
413 /// context for both CSS and HTML rendering. Typical home for
414 /// `classPrefix` and `baseSelector`.
415 pub template_options: Option<Map<String, Value>>,
416 /// Font formats to generate. Ordinary mode defaults to `['eot', 'woff', 'woff2']`;
417 /// variant mode defaults to `['woff', 'woff2']` and rejects SVG and EOT.
418 pub types: Option<Vec<FontType>>,
419 /// Prefix for generated variant modifier classes. Defaults to `icon--` in variant mode and is
420 /// invalid without `variants`.
421 pub variant_class_prefix: Option<String>,
422 /// Ordered named SVG designs for one logical icon family. Variant generation emits shared
423 /// variable TTF/WOFF/WOFF2 fonts. SVG and EOT output are unsupported in variant mode.
424 /// Default CSS emits exact-weight faces sharing those fonts, with modifier classes and no
425 /// synthetic weights. CSS/HTML companions are written when enabled; HTML uses one default grid.
426 /// Template contexts include ordered `variants`, `variantClassPrefix`, `defaultWeight`, and
427 /// `fontStyle`. The SCSS mixin uses each family's default weight and style.
428 pub variants: Option<Vec<FontVariant>>,
429 /// Whether to write generated files to disk. Set to `false` for
430 /// in-memory usage. Defaults to `true`.
431 pub write_files: Option<bool>,
432}