Skip to main content

Font

Enum Font 

Source
pub enum Font {
    Simple(Box<SimpleFont>),
    Type0(Box<Type0Font>),
    Type3(Box<Type3Font>),
}
Expand description

A loaded PDF font, ready to decode strings and produce glyphs.

Three variants, because PDF has three genuinely different kinds of font and they share almost nothing below the surface: a simple font maps one byte to one glyph through a name, a Type0 font maps a multi-byte code through a CMap to a CID and then to a glyph, and a Type3 font has no glyphs at all — its “glyphs” are content streams the page layer executes.

Variants§

§

Simple(Box<SimpleFont>)

Type1, MMType1, TrueType, or a font whose /Subtype was missing or unrecognised — PDFium’s dispatch sends all of those here.

§

Type0(Box<Type0Font>)

A composite font: /Type0 with a CID-keyed descendant.

§

Type3(Box<Type3Font>)

A font whose glyph procedures are content streams.

Implementations§

Source§

impl Font

Source

pub fn decode<'a>(&'a self, s: &'a [u8]) -> impl Iterator<Item = CharItem> + 'a

Decode a string into one CharItem per character code.

The one text-decoding entry point rendering and extraction share, so they cannot disagree about where one character ends and the next begins — which for a Type0 font is a question only the CMap’s codespace can answer.

Source

pub fn glyph_path(&self, gid: Gid) -> Option<BezPath>

A glyph’s outline in 1000/em text space.

None for a missing or degenerate outline, and always for a Type3 font, whose glyphs are content streams rather than outlines.

This is the uncached path. A renderer drawing many glyphs should go through crate::GlyphCache instead, which keys on the substitution parameters that change the outline for a Multiple-Master face.

Source

pub fn hinted_glyph_path(&self, gid: Gid) -> Option<BezPath>

A glyph’s outline in 1000/em text space, grid-fitted at 64 ppem.

The same space Self::glyph_path returns, so a caller can substitute one for the other without touching its matrices — which is what a renderer rasterizing a glyph bitmap does, since hinting applies to that path and not to the outline one.

None for every font that is not hinted: a face with no table directory (every bare CFF and every Type 1 program, so every base-14 substitution), a Type 3 font, and a face whose own programs the interpreter refuses. In all of them the caller falls back to Self::glyph_path rather than drawing nothing.

Uncached, and expensive: it builds a hinting instance and runs the face’s bytecode. A renderer should call it only on a bitmap-cache miss.

Source

pub fn is_vertical(&self) -> bool

Is this a vertical-writing font? Only a Type0 font with a -V CMap is.

Source

pub fn is_embedded(&self) -> bool

Does the font carry its own program, rather than being substituted?

Consulted far more widely than it looks: PDFium’s per-glyph fallback, its glyph-spacing heuristic and its all-caps aliasing all branch on it, and a program that failed to parse counts as not embedded.

Source

pub fn is_unicode_compatible(&self) -> bool

Whether character codes can be turned into Unicode at all, which text extraction uses to decide a font is worth reading.

Source

pub fn font_bbox(&self) -> Rect

The font bounding box in 1000/em text space, after the derivation of the former working note has filled in whatever the PDF failed to declare.

Source

pub fn ascent(&self) -> f32

The ascent in 1000/em text space.

Source

pub fn descent(&self) -> f32

The descent in 1000/em text space, normally negative.

Source

pub fn type3(&self) -> Option<&Type3Font>

The Type3 font, when this is one. Its glyph procedures are raw /CharProcs streams that pdfrum-page executes.

Source

pub fn base_font_name(&self) -> &[u8]

The base font name, with any subset prefix already stripped.

Source

pub fn id(&self) -> FontId

This font’s identity within a FontCache, for glyph-cache keys.

Source

pub fn subst(&self) -> Option<&SubstFont>

The substitution record, when the font was substituted rather than embedded. Carries the synthetic skew and embolden levels a renderer applies.

Source

pub fn char_width(&self, code: CharCode) -> f32

The width of one character code in 1000/em text space.

Source

pub fn applies_glyph_spacing(&self) -> bool

Whether this font’s glyphs take the glyph-spacing correction.

Reads the font’s five relevant facts and asks the glyph-spacing rule, where the reasoning lives.

Source

pub fn glyph_advance(&self, gid: Gid) -> i32

One glyph’s own advance width, in 1000/em units, as the face declares it — not as the PDF does.

Zero when there is no face or the glyph has no advance, which callers treat as “unknown” rather than as a genuine zero-width glyph.

Source

pub fn char_bbox(&self, code: CharCode) -> Rect

The bounding box of one character code’s glyph, in 1000/em text space and y-up: Rect::new(left, bottom, right, top) with bottom <= top.

Rect::ZERO when there is no glyph, and always for a Type 3 font, whose glyph boxes are a property of the content streams the page layer executes rather than of the font.

Text extraction reads this per code — not per decoded string — when it builds a character’s tight box and when its width ladder has run out of better answers.

Source

pub fn japan1_transform(&self, code: CharCode) -> Option<CidTransform>

The Adobe-Japan1 per-CID transform a character takes, when one applies.

Only a non-embedded Japan1 CID font has one, and only for the hundred and fifty-four CIDs the table lists. It moves the glyph within its em box without touching the advance, so a renderer applies it to the drawing origin alone — the pen walks on as if it were not there.

Non-Japan1, embedded and non-CID fonts all answer None — those three tests are the whole gate, and there is no fourth.

Source

pub fn string_width(&self, bytes: &[u8]) -> f32

The width of a string of character codes, decoded through this font’s own encoding and summed.

Not the same as summing char_width over the codes a caller already has: the string is re-decoded, so a code that does not round-trip through append_char — a simple font’s code above 255, say — comes back as a different code and contributes a different width. That difference is the whole point of the rung this serves in text extraction’s width ladder.

Source

pub fn type_ascent(&self) -> i32

The typographic ascent, truncated to an integer as the C++ stores it.

Source

pub fn type_descent(&self) -> i32

The typographic descent, truncated to an integer, normally negative.

Source

pub fn cid_from_charcode(&self, code: CharCode) -> Option<Cid>

The CID a character code maps to, for a composite font only.

Source

pub fn vert_origin(&self, code: CharCode) -> Option<(f32, f32)>

The vertical origin of a character code, in 1000/em units, for a composite font only.

Source

pub fn vert_width(&self, code: CharCode) -> Option<f32>

The vertical advance of a character code, in 1000/em units, for a composite font only. Normally negative.

Source

pub fn unicode_from_charcode(&self, code: CharCode) -> SmallVec<[char; 2]>

The Unicode a character code stands for, /ToUnicode first.

Source

pub fn char_code_from_unicode(&self, unicode: char) -> Option<CharCode>

The character code that produces unicode, or None.

The inverse of unicode_from_charcode, and the direction appearance generation needs: to write a string with a font the document already carries, a caller has to turn characters back into the codes that font understands.

None means the font cannot express that character at all, which is the caller’s signal to pick a different font rather than to emit a code that will draw the wrong glyph.

use pdfrum_common::{Diagnostics, Limits};
use pdfrum_font::{CharCode, Font, FontCache, StandardFont};

let font = Font::load_standard(StandardFont::Helvetica, &FontCache::new());
assert_eq!(font.char_code_from_unicode('A'), Some(CharCode(u32::from(b'A'))));
// A character no Latin encoding carries.
assert_eq!(font.char_code_from_unicode('\u{4e00}'), None);
Source

pub fn append_char(&self, out: &mut Vec<u8>, code: CharCode)

Append one character code to a string being built, in the font’s own byte encoding.

A simple font writes one byte; a composite font writes as many as its CMap’s codespace says, which is the whole reason this is a method rather than a cast at the call site. Pairs with char_code_from_unicode to turn text into a string a content stream can show.

use pdfrum_font::{CharCode, Font, FontCache, StandardFont};

let font = Font::load_standard(StandardFont::Helvetica, &FontCache::new());
let mut out = Vec::new();
for ch in "Hi".chars() {
    if let Some(code) = font.char_code_from_unicode(ch) {
        font.append_char(&mut out, code);
    }
}
assert_eq!(out, b"Hi");
Source

pub fn load_standard(which: StandardFont, cache: &FontCache) -> Self

Build one of the fourteen standard fonts, with no document behind it.

Every reader must supply these faces, so a caller that needs to draw text of its own — an annotation’s appearance stream, say — can have one without inventing a font dictionary. The result is exactly what synthesizing /Type /Font /Subtype /Type1 /BaseFont <name> /Encoding /WinAnsiEncoding would produce, which is how PDFium’s own stock-font path builds them.

use pdfrum_font::{CharCode, Font, FontCache, StandardFont};

let cache = FontCache::new();
let helvetica = Font::load_standard(StandardFont::Helvetica, &cache);
assert_eq!(helvetica.base_font_name(), b"Helvetica");

// The Couriers are fixed-pitch: every glyph is 600 units wide.
let courier = Font::load_standard(StandardFont::Courier, &cache);
assert_eq!(courier.char_width(CharCode(u32::from(b'i'))), 600.0);
assert_eq!(courier.char_width(CharCode(u32::from(b'W'))), 600.0);

Trait Implementations§

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> 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 = !

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.