pdf_canvas/
fontmetrics.rs

1use crate::fontsource::BuiltinFont;
2use std::collections::BTreeMap;
3use std::fs::File;
4use std::io::{self, BufRead};
5
6/// Relevant data that can be loaded from an AFM (Adobe Font Metrics) file.
7/// A FontMetrics object is specific to a given encoding.
8#[derive(Debug, Hash, PartialEq, Eq, Clone)]
9pub struct FontMetrics {
10    widths: BTreeMap<u8, u16>,
11}
12
13impl FontMetrics {
14    /// Create a FontMetrics by reading an .afm file.
15    pub fn parse(source: File) -> io::Result<FontMetrics> {
16        let source = io::BufReader::new(source);
17        let mut result = FontMetrics {
18            widths: BTreeMap::new(),
19        };
20        for line in source.lines() {
21            let line = line.unwrap();
22            let words: Vec<&str> = line.split_whitespace().collect();
23            if words[0] == "C" && words[3] == "WX" {
24                if let (Ok(c), Ok(w)) =
25                    (words[1].parse::<u8>(), words[4].parse::<u16>())
26                {
27                    result.widths.insert(c, w);
28                }
29            }
30        }
31        Ok(result)
32    }
33
34    /// Create a FontMetrics from a slice of (char, width) pairs.
35    fn from_slice(data: &[(u8, u16)]) -> Self {
36        let mut widths = BTreeMap::new();
37        for &(c, w) in data {
38            widths.insert(c, w);
39        }
40        FontMetrics { widths }
41    }
42
43    /// Get the width of a specific character.
44    /// The character is given in the encoding of the FontMetrics object.
45    pub fn get_width(&self, char: u8) -> Option<u16> {
46        self.widths.get(&char).cloned()
47    }
48}
49
50include!(concat!(env!("OUT_DIR"), "/metrics_data.rs"));