pdf_canvas/fontref.rs
1use crate::encoding::Encoding;
2use crate::fontmetrics::FontMetrics;
3use std::fmt;
4use std::sync::Arc;
5
6/// A font ready to be used in a TextObject.
7///
8/// The way to get FontRef is to call
9/// [Canvas::get_font](struct.Canvas.html#method.get_font) with a
10/// [FontSource](trait.FontSource.html).
11/// In PDF terms, a FontSource is everything needed to build a font
12/// dictionary, while a FontRef is the name that can be used in a page
13/// stream to use a font.
14/// Calling Canvas::get_font will make sure the font dictionary is
15/// created in the file, associate it with a name in the page
16/// resources and return a FontRef representing that name.
17///
18/// The `serif` variable in
19/// [the TextObject example](struct.TextObject.html#example) is a FontRef.
20#[derive(Debug, PartialEq, Eq, Hash, Clone)]
21pub struct FontRef {
22 n: usize,
23 encoding: Encoding,
24 metrics: Arc<FontMetrics>,
25}
26
27impl FontRef {
28 // Hidden from user code by not beeing a constructor method of FontRef.
29 pub(crate) fn new(
30 n: usize,
31 encoding: Encoding,
32 metrics: Arc<FontMetrics>,
33 ) -> Self {
34 FontRef {
35 n,
36 encoding,
37 metrics,
38 }
39 }
40
41 /// Get the encoding used by the referenced font.
42 pub fn get_encoding(&self) -> &Encoding {
43 &self.encoding
44 }
45
46 /// Get the width of the given text in this font at given size.
47 pub fn get_width(&self, size: f32, text: &str) -> f32 {
48 size * self.get_width_raw(text) as f32 / 1000.0
49 }
50
51 /// Get the width of the given text in thousands of unit of text
52 /// space.
53 /// This unit is what is used in some places internally in pdf files
54 /// and in some methods on a [TextObject](struct.TextObject.html).
55 pub fn get_width_raw(&self, text: &str) -> u32 {
56 text.chars().fold(0, |result, char| {
57 result
58 + u32::from(
59 self.encoding
60 .encode_char(char)
61 .and_then(|ch| self.metrics.get_width(ch))
62 .unwrap_or(100),
63 )
64 })
65 }
66}
67
68impl fmt::Display for FontRef {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 write!(f, "/F{}", self.n)
71 }
72}