Skip to main content

TextFont

Struct TextFont 

Source
pub struct TextFont<'a> {
    pub font: &'a Font,
    pub metrics: Metrics<'a>,
}
Expand description

The font a text-bearing generator sets its text with.

Threaded in rather than loaded here, because loading one needs a font cache the caller already owns, and because the layout engine is a pure function of these numbers — which is what lets it be tested against a stub.

use pdfrum_doc::ap::FormFonts;
use pdfrum_object::{Dict, NoResolve};

// A catalog with no `/AcroForm` still yields the stock fallback face.
let mut ctx = pdfrum_page::BuildContext::new();
let fonts = FormFonts::load(&Dict::default(), &NoResolve, &mut ctx);
use pdfrum_doc::ap::TextFont;

let font = fonts.face(b"Helv").expect("the fallback face");
let width = |code: u32| TextFont::char_width(font, code);
let text = fonts.text_font(b"Helv", &width).expect("a face to set text with");

// The ascent the layout engine stacks lines by.
assert!(text.metrics.ascent > 0);

Fields§

§font: &'a Font

The loaded font.

§metrics: Metrics<'a>

Metrics derived from it, for the layout engine.

Implementations§

Source§

impl TextFont<'_>

Source

pub fn encode(&self, code: u32) -> Vec<u8> ⓘ

How one code point is written into a content stream.

A Symbol or ZapfDingbats font takes the code point’s low byte verbatim, relying on the font’s built-in encoding: there is no named-glyph table and no /Encoding consultation anywhere in this path. Anything else goes through the reverse ToUnicode mapping.

A code point the font cannot represent is still written, as its own value taken for a character code. The glyph that draws is whatever that code happens to name in the chosen face and is usually wrong — but the text object exists, occupies the layout, and is what a reader sees. Dropping the character instead loses the object entirely, which on bug_725389 — three Hebrew characters in a /DA naming Times-Roman — is the difference between six text objects and three.

use pdfrum_doc::ap::FormFonts;
use pdfrum_object::{Dict, NoResolve};

// A catalog with no `/AcroForm` still yields the stock fallback face.
let mut ctx = pdfrum_page::BuildContext::new();
let fonts = FormFonts::load(&Dict::default(), &NoResolve, &mut ctx);
use pdfrum_doc::ap::TextFont;

let font = fonts.face(b"Helv").expect("the fallback face");
let width = |code: u32| TextFont::char_width(font, code);
let text = fonts.text_font(b"Helv", &width).expect("a face");

// `A` writes as one byte in a simple font.
assert_eq!(text.encode(u32::from('A')), b"A");
Source

pub fn char_width(font: &Font, code: u32) -> i32

One code point’s width, in thousandths of an em.

The width is the one the face gives whatever Self::encode wrote, so an unrepresentable code point measures the glyph its raw value names rather than nothing — the two have to agree or the layout advances past characters the stream still contains, and the line comes out the wrong length.

A free function rather than a method because Self::metrics_of wants it as a &dyn Fn borrowed for the same lifetime as the font, which a closure over self cannot supply before self exists.

use pdfrum_doc::ap::FormFonts;
use pdfrum_object::{Dict, NoResolve};

// A catalog with no `/AcroForm` still yields the stock fallback face.
let mut ctx = pdfrum_page::BuildContext::new();
let fonts = FormFonts::load(&Dict::default(), &NoResolve, &mut ctx);
use pdfrum_doc::ap::TextFont;

let font = fonts.face(b"Helv").expect("the fallback face");
// Thousandths of an em, for whatever `encode` wrote.
assert!(TextFont::char_width(font, u32::from('A')) > 0);
Source

pub fn metrics_of<'a>( font: &'a Font, width: &'a dyn Fn(u32) -> i32, ) -> Metrics<'a>

The layout metrics a loaded font supplies.

use pdfrum_doc::ap::FormFonts;
use pdfrum_object::{Dict, NoResolve};

// A catalog with no `/AcroForm` still yields the stock fallback face.
let mut ctx = pdfrum_page::BuildContext::new();
let fonts = FormFonts::load(&Dict::default(), &NoResolve, &mut ctx);
use pdfrum_doc::ap::TextFont;

let font = fonts.face(b"Helv").expect("the fallback face");
let width = |code: u32| TextFont::char_width(font, code);
let metrics = TextFont::metrics_of(font, &width);
assert!(metrics.ascent > metrics.descent);

Trait Implementations§

Source§

impl Debug for TextFont<'_>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for TextFont<'a>

§

impl<'a> !Send for TextFont<'a>

§

impl<'a> !Sync for TextFont<'a>

§

impl<'a> !UnwindSafe for TextFont<'a>

§

impl<'a> Freeze for TextFont<'a>

§

impl<'a> Unpin for TextFont<'a>

§

impl<'a> UnsafeUnpin for TextFont<'a>

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.