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 FontThe loaded font.
metrics: Metrics<'a>Metrics derived from it, for the layout engine.
Implementations§
Source§impl TextFont<'_>
impl TextFont<'_>
Sourcepub fn encode(&self, code: u32) -> Vec<u8> ⓘ
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");Sourcepub fn char_width(font: &Font, code: u32) -> i32
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);Sourcepub fn metrics_of<'a>(
font: &'a Font,
width: &'a dyn Fn(u32) -> i32,
) -> Metrics<'a>
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);