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}