Skip to main content

Font

Struct Font 

Source
pub struct Font {
    pub units_per_em: u16,
    pub num_glyphs: u16,
    pub ascent: i16,
    pub descent: i16,
    pub line_gap: i16,
    /* private fields */
}
Expand description

A parsed font, owning its backing bytes.

Fields§

§units_per_em: u16

Font design units per em (the coordinate scale; advances are in these).

§num_glyphs: u16

Number of glyphs in the font.

§ascent: i16

Typographic ascender (design units).

§descent: i16

Typographic descender (design units, usually negative).

§line_gap: i16

Recommended extra line gap (design units).

Implementations§

Source§

impl Font

Source

pub fn cff_outline(&self, gid: u16) -> Result<CffOutline, SubsetError>

Decode a CFF1 glyph, preserving exact cubic control points. No host APIs.

Examples found in repository?
examples/cff_probe.rs (line 7)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<_> = std::env::args().collect();
5    let font = Font::parse(std::fs::read(&args[1])?)?;
6    for gid in 0..font.num_glyphs {
7        let outline = font.cff_outline(gid)?;
8        println!("G {gid} {} {}", outline.advance, outline.lsb);
9        for c in outline.commands {
10            match c {
11                Command::Move(p) => println!("M {} {}", p.x, p.y),
12                Command::Line(p) => println!("L {} {}", p.x, p.y),
13                Command::Curve(a, b, c) => {
14                    println!("C {} {} {} {} {} {}", a.x, a.y, b.x, b.y, c.x, c.y)
15                }
16                Command::Close => println!("Z"),
17            }
18        }
19    }
20    if let Some(path) = args.get(2) {
21        let subset = font.try_subset_glyphs(&[1, 5, 73, 100, 500, 1000, 2000, 3000], &[])?;
22        std::fs::write(path, subset.bytes)?;
23    }
24    Ok(())
25}
Source§

impl Font

Source

pub fn glyph_outline(&self, gid: u16) -> Result<GlyphOutline, OutlineError>

Decode glyph gid to quadratic contours with phantom-point-correct metrics. Blank glyphs (space) succeed with empty contours.

§Errors

OutlineError::NoGlyfOutlines for CFF-only fonts, OutlineError::BadGlyphId for out-of-range ids, and OutlineError::Malformed / OutlineError::BudgetExceeded for structurally invalid or hostile glyph data.

Source§

impl Font

Source

pub fn shape( &self, text: &str, opts: &ShapeOptions<'_>, ) -> Result<ShapedRun, ShapeError>

Shape a single explicitly segmented run. See module docs for exact coverage.

Examples found in repository?
examples/shape_probe.rs (line 19)
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7    let args: Vec<_> = std::env::args().collect();
8    let f = Font::parse(std::fs::read(&args[1])?)?;
9    let arabic = args[2] == "arab";
10    let options = ShapeOptions {
11        script: if arabic { *b"arab" } else { *b"latn" },
12        direction: if arabic {
13            Direction::RightToLeft
14        } else {
15            Direction::LeftToRight
16        },
17        ..ShapeOptions::default()
18    };
19    let run = f.shape(&args[3], &options)?;
20    for g in run.glyphs {
21        println!(
22            "{} {} {} {} {} {} {}",
23            g.glyph_id,
24            g.cluster.start,
25            g.cluster.end,
26            g.x_advance,
27            g.y_advance,
28            g.x_offset,
29            g.y_offset
30        );
31    }
32    Ok(())
33}
Source§

impl Font

Source

pub fn try_subset(&self, keep: &[char]) -> Result<Subset, SubsetError>

Strict subset for browser embedding. Unlike the legacy Option API, invalid glyphs and malformed composites are refused, never repaired.

Source

pub fn try_subset_glyphs( &self, glyphs: &[u16], cmap_chars: &[char], ) -> Result<Subset, SubsetError>

Strict subset of a pre-shaped glyph set, with explicit embedding format.

Examples found in repository?
examples/cff_probe.rs (line 21)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<_> = std::env::args().collect();
5    let font = Font::parse(std::fs::read(&args[1])?)?;
6    for gid in 0..font.num_glyphs {
7        let outline = font.cff_outline(gid)?;
8        println!("G {gid} {} {}", outline.advance, outline.lsb);
9        for c in outline.commands {
10            match c {
11                Command::Move(p) => println!("M {} {}", p.x, p.y),
12                Command::Line(p) => println!("L {} {}", p.x, p.y),
13                Command::Curve(a, b, c) => {
14                    println!("C {} {} {} {} {} {}", a.x, a.y, b.x, b.y, c.x, c.y)
15                }
16                Command::Close => println!("Z"),
17            }
18        }
19    }
20    if let Some(path) = args.get(2) {
21        let subset = font.try_subset_glyphs(&[1, 5, 73, 100, 500, 1000, 2000, 3000], &[])?;
22        std::fs::write(path, subset.bytes)?;
23    }
24    Ok(())
25}
Source

pub fn try_subset_glyphs_with_lookup( &self, glyphs: &[u16], cmap_chars: &[char], ) -> Result<Subset, SubsetError>

Dense-map spelling for callers migrating from the legacy lookup API.

Source§

impl Font

Source

pub fn parse(data: Vec<u8>) -> Result<Self, FontError>

Parse a font from its raw bytes (e.g. an include_bytes! blob).

§Errors

Returns a FontError for a non-sfnt file, a missing required table, a truncated file, or the absence of a usable Unicode cmap.

Examples found in repository?
examples/shape_probe.rs (line 8)
6fn main() -> Result<(), Box<dyn std::error::Error>> {
7    let args: Vec<_> = std::env::args().collect();
8    let f = Font::parse(std::fs::read(&args[1])?)?;
9    let arabic = args[2] == "arab";
10    let options = ShapeOptions {
11        script: if arabic { *b"arab" } else { *b"latn" },
12        direction: if arabic {
13            Direction::RightToLeft
14        } else {
15            Direction::LeftToRight
16        },
17        ..ShapeOptions::default()
18    };
19    let run = f.shape(&args[3], &options)?;
20    for g in run.glyphs {
21        println!(
22            "{} {} {} {} {} {} {}",
23            g.glyph_id,
24            g.cluster.start,
25            g.cluster.end,
26            g.x_advance,
27            g.y_advance,
28            g.x_offset,
29            g.y_offset
30        );
31    }
32    Ok(())
33}
More examples
Hide additional examples
examples/cff_probe.rs (line 5)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4    let args: Vec<_> = std::env::args().collect();
5    let font = Font::parse(std::fs::read(&args[1])?)?;
6    for gid in 0..font.num_glyphs {
7        let outline = font.cff_outline(gid)?;
8        println!("G {gid} {} {}", outline.advance, outline.lsb);
9        for c in outline.commands {
10            match c {
11                Command::Move(p) => println!("M {} {}", p.x, p.y),
12                Command::Line(p) => println!("L {} {}", p.x, p.y),
13                Command::Curve(a, b, c) => {
14                    println!("C {} {} {} {} {} {}", a.x, a.y, b.x, b.y, c.x, c.y)
15                }
16                Command::Close => println!("Z"),
17            }
18        }
19    }
20    if let Some(path) = args.get(2) {
21        let subset = font.try_subset_glyphs(&[1, 5, 73, 100, 500, 1000, 2000, 3000], &[])?;
22        std::fs::write(path, subset.bytes)?;
23    }
24    Ok(())
25}
Source

pub fn has_glyf_outlines(&self) -> bool

True when the font carries TrueType (glyf) outlines we can read/subset.

Source

pub fn axes(&self) -> &[VariationAxis]

Variation axes from fvar, in table order. Empty for static fonts.

Source

pub fn named_instances(&self) -> &[NamedInstance]

Named instances from fvar. Empty when the table is absent or has none.

Source

pub fn instance_bounds(&self, tag: [u8; 4]) -> Option<AxisBounds>

User-space (min, default, max) for the axis whose tag is tag.

Source

pub fn normalized_axis(&self, tag: [u8; 4], user: f32) -> Option<f32>

Clamp user to the axis bounds, normalize to [-1, 1], then apply avar (identity when the table is absent or that axis has no maps).

Values below min and above max map to the corresponding endpoints (-1 / +1 after identity avar).

Source

pub fn instance(&self, weight: f32) -> Option<Font>

Instance this face at CSS font-weight weight on the wght axis.

Applies gvar tuple deltas (packed point numbers, packed deltas, IUP) and returns a static TrueType font: fvar/avar/gvar are dropped, glyf/loca hold the frozen outlines. None when the font has no wght axis, no TrueType outlines, or a table is unreadable.

The same weight twice yields identical bytes.

Source

pub fn as_sfnt(&self) -> &[u8] ⓘ

Current sfnt bytes. After Self::instance, this is the static instanced face (fvar/avar/gvar dropped).

Source

pub fn glyph_data(&self, gid: u16) -> Option<&[u8]>

Raw glyf bytes for glyph gid (for subset embedding), or None. An empty (zero-length) glyph yields Some(&[]).

Source

pub fn glyph_bbox(&self, gid: u16) -> Option<[i16; 4]>

Glyph bounding box [xMin, yMin, xMax, yMax] (design units), or None for an empty glyph / no outlines.

Source

pub fn is_composite(&self, gid: u16) -> bool

True when glyph gid is a composite (built from component glyphs).

Source

pub fn glyph_components(&self, gid: u16) -> Vec<u16>

Component glyph ids referenced by a composite glyph (for transitive subsetting). Empty for simple or empty glyphs.

Source

pub fn advance_width(&self, gid: u16) -> u16

The advance width of glyph gid in design units. Glyphs past the hmtx metric run share the last advance (monospaced trailing run).

Source

pub fn left_side_bearing(&self, gid: u16) -> i16

The left side bearing of glyph gid in design units. Glyphs past the long-metric run share the last advance but keep their own trailing LSB.

Source

pub fn glyph_index(&self, ch: char) -> u16

The glyph id for a character, or 0 (.notdef) if unmapped.

Source

pub fn advance_1000(&self, ch: char) -> u32

Advance width of ch in 1/1000 em (PDF text-space units). An unmapped ch resolves to glyph 0 (.notdef) and reserves that glyph’s advance (so a tofu box still occupies its natural width); only an unparsable face with units_per_em == 0 yields 0.

Source

pub fn kerning_between_glyphs(&self, left: u16, right: u16) -> i16

Kerning adjustment between two glyph ids in design units.

Unsupported or absent kerning tables return zero. This currently supports legacy TrueType/Microsoft kern table version 0, format 0, horizontal pairs. GPOS pair positioning is tracked separately.

Source

pub fn kerning(&self, left: char, right: char) -> i16

Kerning adjustment between two characters in design units.

Source

pub fn kerning_1000(&self, left: char, right: char) -> i32

Kerning adjustment between two characters in 1/1000 em units.

Source

pub fn subset(&self, keep: &[char]) -> Option<Vec<u8>>

Build a new, minimal, valid TrueType (glyf) font containing glyph 0 (.notdef) plus exactly the glyphs needed to render keep (mapped through the original cmap), transitively closing over composite components. Returns a fresh sfnt (0x00010000) suitable for a PDF FontFile2, or None on any failure (missing glyf/loca/required table, or a malformed read).

Source

pub fn subset_glyphs( &self, glyphs: &[u16], cmap_chars: &[char], ) -> Option<(Vec<u8>, BTreeMap<u16, u16>)>

Subset to an explicit glyph set (the closure still pulls in composite components), building the cmap from cmap_chars. Returns the font bytes plus the old->new glyph id remap — for callers that pre-shaped a glyph sequence (e.g. GSUB ligatures) and must emit the renumbered ids.

The map is the ordered projection of Font::subset_glyphs_with_lookup; prefer that method when a dense lookup table is more useful than an ordered map (same font bytes, no per-glyph tree nodes).

§Errors

Returns None for a font without glyf/loca outlines or on a malformed read (same conditions as Font::subset).

Source

pub fn subset_glyphs_with_lookup( &self, glyphs: &[u16], cmap_chars: &[char], ) -> Option<(Vec<u8>, Vec<u16>)>

Subset to an explicit glyph set (same closure and cmap construction as Font::subset_glyphs), returning the font bytes plus the subsetter’s own dense old->new lookup: lookup[old] is the glyph’s renumbered id in the subset, or MISSING_GLYPH_REMAP when old is not part of it. The vector has max(num_glyphs, 1) entries indexed by old gid — the exact table the subsetter builds internally, so callers translating pre-shaped glyph runs need neither an ordered map nor a rebuild of this very vector. Font bytes are identical to Font::subset_glyphs.

§Errors

Returns None for a font without glyf/loca outlines or on a malformed read (same conditions as Font::subset).

Source§

impl Font

Source

pub fn gpos_kerning(&self) -> Kerning

Parses the GPOS kern feature once into a Kerning structure.

Returns an empty Kerning (every pair() -> 0) when the font has no GPOS table, no kern feature, or the relevant offsets are malformed.

Source§

impl Font

Source

pub fn gsub_ligatures(&self) -> Ligatures

Parse the GSUB liga standard-ligature substitutions once.

Returns empty Ligatures when the font has no GSUB / no liga feature or the relevant offsets are malformed.

Trait Implementations§

Source§

impl Clone for Font

Source§

fn clone(&self) -> Font

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Font

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Font

§

impl RefUnwindSafe for Font

§

impl Send for Font

§

impl Sync for Font

§

impl Unpin for Font

§

impl UnsafeUnpin for Font

§

impl UnwindSafe for Font

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.