This repository has no description
1use itertools::Itertools;
2use resvg::usvg;
3use std::path::PathBuf;
4
5use crate::Canvas;
6
7#[derive(Default, Debug, Clone)]
8pub struct FontOptions {
9 pub skip_system_fonts: bool,
10 pub font_files: Vec<PathBuf>,
11 pub font_dirs: Vec<PathBuf>,
12 pub serif_family: Option<String>,
13 pub sans_serif_family: Option<String>,
14 pub cursive_family: Option<String>,
15 pub fantasy_family: Option<String>,
16 pub monospace_family: Option<String>,
17}
18
19pub fn load_fonts(args: &FontOptions) -> anyhow::Result<usvg::Options<'_>> {
20 let mut usvg = usvg::Options {
21 font_family: args.sans_serif_family.clone().unwrap_or("Arial".into()),
22 ..Default::default()
23 };
24 let fontdb = usvg.fontdb_mut();
25
26 if !args.skip_system_fonts {
27 fontdb.load_system_fonts();
28 }
29
30 for path in &args.font_files {
31 if let Err(e) = fontdb.load_font_file(path) {
32 log::warn!("Failed to load '{}' cause {}.", path.display(), e);
33 }
34 }
35
36 for path in &args.font_dirs {
37 fontdb.load_fonts_dir(path);
38 }
39
40 fontdb.set_serif_family(
41 args.serif_family.as_deref().unwrap_or("Times New Roman"),
42 );
43 fontdb.set_sans_serif_family(
44 args.sans_serif_family.as_deref().unwrap_or("Arial"),
45 );
46 fontdb.set_cursive_family(
47 args.cursive_family.as_deref().unwrap_or("Comic Sans MS"),
48 );
49 fontdb.set_fantasy_family(args.fantasy_family.as_deref().unwrap_or("Impact"));
50 fontdb.set_monospace_family(
51 args.monospace_family.as_deref().unwrap_or("Courier New"),
52 );
53
54 Ok(usvg)
55}
56
57impl Canvas {
58 pub fn show_available_fonts(&self) -> () {
59 match self.fontdb {
60 Some(ref fontdb) => println!(
61 "Available fonts: {:?}",
62 fontdb
63 .faces()
64 .flat_map(|f| f.families.iter().map(|(name, _)| name))
65 .unique()
66 .collect::<Vec<_>>()
67 ),
68 None => println!(
69 "No font database available, using default font loading strategy"
70 ),
71 };
72 }
73}