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 render_synth(&self, xx: i32, xy: i32) -> Option<SynthGlyph>

The synthetic italic and embolden the glyph-bitmap side applies, resolved against the device matrix’s two horizontal components.

The bitmap side is a second call site with its own two levels (CFX_Face::RenderGlyph, cfx_face.cpp:769-778 and :806-816), not the path side’s, which is why it cannot simply reuse the outline the glyph cache already adjusted: the render-path embolden level depends on the device matrix, which only the renderer knows, and the render-path skew is the effective one rather than the plain one.

xx and xy are the oracle’s own 16.16 quantities — matrix.a / 64 * 65536 and matrix.c / 64 * 65536 (cfx_face.cpp:766-767) — because the embolden table’s / 36655 is calibrated to that scale and nothing else. The SynthGlyph that comes back is therefore in device pixels, and belongs on an outline already mapped into that space.

None where the C++ returns a negative level and RenderGlyph bails out with a null bitmap (cfx_face.cpp:809-811): a substitution weight of 1400 or more, which is past the table. A caller draws nothing.

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);
Source

pub fn should_use_own_glyph(&self, gid: Option<Gid>) -> bool

Whether this character’s glyph is drawn from this font (ShouldUseFont).

A Type 3 font has no glyph indices and never takes GetCharPosList, so it always answers true: there is no Arial stand-in for a content stream.

Source

pub fn glyph_fallback(&self) -> Option<&GlyphFallback>

The Arial stand-in GetCharPosList draws when Self::should_use_own_glyph fails. Created on first miss; None if even Arial failed to load.

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.