1use std::collections::HashMap;
2
3use ab_glyph::FontArc;
4use font_loader::system_fonts;
5
6const FONT_MAP: &[char] = &[
8 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
9 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
10];
11
12#[derive(Debug, Clone)]
17pub struct FontManager {
18 font_map: HashMap<String, String>,
20 font_index: HashMap<String, FontArc>,
22}
23
24impl Default for FontManager {
25 fn default() -> Self {
29 let mut current = Self {
30 font_map: HashMap::new(),
31 font_index: HashMap::new(),
32 };
33
34 let families = [
35 "Swiss 721",
36 "Helvetica",
37 "Roboto",
38 "Liberation Sans",
39 "DejaVu Sans",
40 "Arial",
41 ];
42
43 for family in families {
44 let prop = system_fonts::FontPropertyBuilder::new()
45 .family(family)
46 .build();
47 if let Some((data, _)) = system_fonts::get(&prop) {
48 let _ = current.register_font(family, &data, 'A', '9');
49 break;
50 }
51 }
52
53 current
54 }
55}
56
57impl FontManager {
58 pub fn get_font(&self, name: &str) -> Option<&FontArc> {
63 let font_name = self.font_map.get(name);
64 if let Some(font_name) = font_name {
65 self.font_index.get(font_name)
66 } else {
67 None
68 }
69 }
70
71 pub fn register_font(
82 &mut self,
83 name: &str,
84 bytes: &[u8],
85 from: char,
86 to: char,
87 ) -> Result<(), String> {
88 let font = FontArc::try_from_vec(bytes.to_vec()).map_err(|_| "Invalid font".to_string())?;
89 self.font_index.insert(name.to_string(), font);
90 self.assign_font(name, from, to);
91 Ok(())
92 }
93
94 fn assign_font(&mut self, name: &str, from: char, to: char) {
96 let from_idx = FONT_MAP.iter().position(|&x| x == from);
97 let to_idx = FONT_MAP.iter().position(|&x| x == to);
98
99 if from_idx.is_none() || to_idx.is_none() {
100 return;
101 }
102
103 if let (Some(start), Some(end)) = (from_idx, to_idx) {
104 if start <= end {
105 for key in &FONT_MAP[start..=end] {
106 self.font_map.insert(key.to_string(), name.to_string());
107 }
108 }
109 }
110 }
111}