Skip to main content

TtfFontStore

Struct TtfFontStore 

Source
pub struct TtfFontStore { /* private fields */ }
Expand description

Owns the raw bytes of every distinct font file that was loaded, plus a FontKey(0/1/2) -> file lookup that lets bold/oblique fall back to the regular face without duplicating its bytes in memory (and, in the PDF writer, without embedding the same font file twice).

Face ownership: rather than caching a ttf_parser::Face<'a> alongside the Vec<u8> it borrows from (which needs either unsafe self-referential storage or a crate like owned-ttf-parser), each accessor reparses a Face on demand from the stored bytes. Face::parse only walks the sfnt table directory and a few small required tables (head, hhea, maxp, OS/2, …); it does not touch glyph outlines, so its cost does not scale with document size and is cheap at the milestone’s scale (a handful of pages, one parse per glyph lookup). This keeps TtfFontStore a plain, safe struct.

Implementations§

Source§

impl TtfFontStore

Source

pub fn load( regular: &Path, bold: Option<&Path>, oblique: Option<&Path>, ) -> Result<Self, FontError>

Load up to three faces. bold/oblique fall back to regular when not given.

Source

pub fn from_bytes( regular: Vec<u8>, bold: Option<Vec<u8>>, oblique: Option<Vec<u8>>, label: &str, ) -> Result<Self, FontError>

Self::load for bytes that never came from a path.

The WebAssembly build is why this exists: a browser has no filesystem, so a font supplied by the user arrives as bytes from a file picker. label names the source in a FontError::Parse — a file name, a URL, whatever the caller can show the user — since there is no path to report.

bold/oblique fall back to regular when absent, exactly as Self::load does, and the bytes are shared rather than duplicated.

Source

pub fn file_index(&self, font: FontKey) -> usize

The physical-file index backing font (after bold/oblique fallback). Used by the CID embedder to dedup: two FontKeys that resolve to the same file are embedded (and their Type0 font object shared) once.

pub rather than pub(crate) because rustyfi-html needs it too, to key its @font-face set by physical file the same way — a one-way dependency, since rustyfi-pdf does not depend back on it.

Source

pub fn num_files(&self) -> usize

Source

pub fn file_bytes(&self, file_index: usize) -> &[u8]

Raw bytes of a physical file, for FontFile2 embedding.

Source

pub fn file_family_name(&self, file_index: usize) -> Option<String>

The typographic family name a physical file declares in its name table (English where the font offers it, since that is what a CSS font-family has to match), or None for a file with no usable family record.

pub for rustyfi-html’s reflow backend, which NAMES fonts rather than embedding them: a reflowed document is explicitly not metric-faithful, so paying several megabytes of base64 to pin the exact face would buy nothing it wants and cost the reader everything (fonts::reflow_font_stack). The faithful backend still embeds.

Source

pub fn abbrev_key(&self, abbrev: &str) -> Option<FontKey>

Resolve a registry abbrev (“ipaexm”, “Junicode-b”, …) to its allocated FontKey, or None if the store has no such abbrev (either it wasn’t configured, or the store came from a bare load).

Source

pub fn script_default(&self, script: usize) -> Option<(FontKey, f64, f64)>

See the script_defaults field doc.

Source

pub fn face(&self, font: FontKey) -> Option<Face<'_>>

Parse the face for a given font key. See the struct doc for why this reparses on every call instead of caching a Face.

Trait Implementations§

Source§

impl FontMetrics for TtfFontStore

Source§

fn math_script_variant( &self, font: FontKey, c: char, size: Length, ) -> Option<MathVariantGlyph>

ssty (Math Script Style): the GSUB feature a math font uses to swap in purpose-drawn exponent/index forms — upstream’s FontFormat.get_math_script_variant (fontFormat.ml:2216-2241).

Two divergences from upstream’s fold, neither reachable in the math fonts this port ships or tests against:

  • upstream reaches ssty through a SCRIPT and its default langsys (fontFormat.ml:2185-2194); this scans the feature LIST by tag, so a font whose ssty differs per script would diverge;
  • an Alternate substitution takes the FIRST alternate — upstream’s gidorgto :: _ verbatim, where OpenType would index it by script LEVEL. Matching upstream is the point.

Upstream substitutes ssty BEFORE looking for a MathVariants vertical variant (fontInfo.ml:379-401); this port applies it in push_char_glyph only, so a big operator inside a script keeps its unsubstituted vertical variant. The two coverages are disjoint in the fonts here, so the orders agree.

Source§

fn math_vertical_variant( &self, font: FontKey, c: char, size: Length, policy: VertVariantPolicy, ) -> Option<MathVariantGlyph>

Pick a vertically-grown MATH variant (MathVariants) of c per policy and report its real per-glyph ink metrics at size. Assembly-only constructions (variants.len() == 0, big enough stretchy delimiters in some fonts) return None here — they are math_vertical_assembly’s job.

Source§

fn math_vertical_assembly( &self, font: FontKey, c: char, size: Length, target: Length, ) -> Option<Vec<(u16, Length, Length)>>

Stretch c (via OpenType MATH GlyphAssembly) beyond the largest discrete MathVariants record by stacking the assembly’s GlyphParts vertically, repeating extender parts to reach target. Faithful to the OpenType “assembling glyphs” recipe (and math.ml’s MathVariants/GlyphConstruction reader): parts are listed bottom-to-top; every non-extender part is placed exactly once, and all extender parts are repeated the same number of times r (the smallest r whose stacked extent, at the minimum min_connector_overlap overlap, covers target). Each connection overlaps by exactly min_connector_overlap design units (the smallest legal overlap, which yields the LONGEST assembly for a given part count — so the result always covers target). Returns (gid, dy, advance) per placed part with dy the y-up box-local baseline offset (bottom part at dy = 0, each next part raised by the previous part’s advance minus the overlap) and advance the part’s full_advance scaled to size.

Source§

fn font_abbrev(&self, key: FontKey) -> Option<String>

Reverse scan of abbrevs. Linear, but that map holds one row per configured font (tens at most) and get-font is called a handful of times per document, so a second index would cost more than it saves.

Source§

fn advance(&self, font: FontKey, c: char, size: Length) -> Option<Length>

Horizontal advance of c at size, or None if the font has no glyph for it.
Source§

fn ascender(&self, font: FontKey, size: Length) -> Length

Height above the baseline at size.
Source§

fn descender(&self, font: FontKey, size: Length) -> Length

Depth below the baseline at size (a positive value).
Source§

fn glyph_vextent( &self, font: FontKey, c: char, size: Length, ) -> Option<(Length, Length)>

One glyph’s vertical extent from its ACTUAL bounding box — (height above baseline = ymax, depth below baseline = -ymin), both in size units. None when the provider has no per-glyph bbox (base-14 / test stubs), in which case run_vextent falls back to ascender/descender. This is how SATySFi measures glyphs (fontFormat.ml’s get_glyph_metrics: hgt = ymax, dpt = ymin).
Source§

fn math_constants(&self, font: FontKey) -> Option<MathConstants>

The font’s OpenType MATH MathConstants table, or None when the font has no MATH table (every base-14/non-math provider). Lang-side math layout (MathC resolver) falls back to the pre-MATH-table fixed constants whenever this is None, so a provider that never overrides it (like Base14Metrics) keeps today’s fixtures byte-identical.
Source§

fn italic_correction( &self, font: FontKey, c: char, size: Length, ) -> Option<Length>

The italic correction of c at size (OpenType MATH MathItalicsCorrectionInfo), or None when the font has no MATH table or no entry for this glyph.
Source§

fn math_kern( &self, font: FontKey, c: char, size: Length, corner: MathCorner, corr: Length, ) -> Option<Length>

The OpenType MATH per-glyph corner kern of c at size, sampled at correction height corr (MathKernInfo/MathKern), or None when the font has no MATH table or no kern data for this glyph/corner.
Source§

fn resolve_font_abbrev(&self, abbrev: &str) -> Option<FontKey>

Resolve a registry abbrev ("ipaexm", "Junicode-b", …) to its FontKey. None means either “no such abbrev in this provider’s registry” or “this provider has no registry at all” (every provider that predates the registry, Base14Metrics) — the caller then falls back to the milestone-1 3-face name heuristic (resolve_font_abbrev free fn, rustyfi-lang), keeping every existing set-font call byte-identical.
Source§

fn default_script_font(&self, script: Script) -> Option<(FontKey, f64, f64)>

The configured default (font, ratio, rising) for script, from default-font.satysfi-hash’s scripts block. None means “no scheme configured for this script” — the caller then falls back to (ctx.font, 1.0, 0.0), i.e. today’s single-font behavior.
Source§

fn default_math_font(&self) -> Option<FontKey>

The configured default math font, from default-font.satysfi-hash’s optional "math" abbrev. None means “no math default configured” — the caller (get-initial-context) then leaves Context::math_font at its Context::initial seed (FontKey(0), the regular text face), i.e. today’s behavior. Every provider that predates this math-default support (Base14Metrics, a bare TtfFontStore::load, a registry with no "math" entry) returns None here, so this is purely additive.
Source§

fn run_vextent( &self, font: FontKey, text: &str, size: Length, ) -> (Length, Length)

A text run’s (height, depth) the way SATySFi’s get_metrics_of_word (fontInfo.ml:192) computes it: the MAX glyph ymax and MAX -ymin over the run’s actual glyph bounding boxes — NOT the font-level ascender/descender. Starting the folds at zero clamps a run with no descenders (Japanese, digits, TOC leader dots) to depth 0, matching SATySFi’s much tighter inter-line advance for such content. Falls back to ascender/descender when no glyph exposes a bbox.
Source§

fn text_width(&self, font: FontKey, text: &str, size: Length) -> Option<Length>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Finish for T

Source§

fn finish(self)

Does nothing but move self, equivalent to drop.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.