cranpose_render_common/
text_fonts.rs1use std::sync::Arc;
5
6use cranpose_text::{FontFamilyResolver, Typeface};
7
8#[cfg(feature = "embedded-default-font")]
10pub const DEFAULT_FONT_BYTES: &[u8] = include_bytes!("../assets/NotoSansMerged.ttf");
11
12pub fn default_typeface() -> Option<Typeface> {
15 #[cfg(feature = "embedded-default-font")]
16 {
17 Typeface::from_bytes(DEFAULT_FONT_BYTES).ok()
18 }
19 #[cfg(not(feature = "embedded-default-font"))]
20 {
21 None
22 }
23}
24
25#[derive(Clone, Default)]
28pub struct TextFonts {
29 typefaces: Arc<[Typeface]>,
30 #[cfg(feature = "installed-fonts")]
32 installed: usize,
33}
34
35impl TextFonts {
36 pub fn new(typefaces: Vec<Typeface>) -> Self {
38 Self {
39 typefaces: Arc::from(typefaces),
40 #[cfg(feature = "installed-fonts")]
41 installed: 0,
42 }
43 }
44
45 pub fn from_fonts_or_default(fonts: &[&'static [u8]]) -> Self {
48 let mut typefaces: Vec<Typeface> = fonts
49 .iter()
50 .filter_map(|bytes| Typeface::from_bytes(*bytes).ok())
51 .collect();
52 if typefaces.is_empty() {
53 typefaces.extend(default_typeface());
54 }
55 Self::new(typefaces)
56 }
57
58 pub fn typefaces(&self) -> &[Typeface] {
60 &self.typefaces
61 }
62
63 pub fn resolver(&self) -> FontFamilyResolver {
65 FontFamilyResolver::new(self.typefaces.iter().cloned())
66 }
67
68 #[cfg(feature = "installed-fonts")]
72 pub fn with_installed_faces(&self) -> Option<Self> {
73 if crate::installed_fonts::installed_font_generation() == self.installed {
74 return None;
75 }
76 let installed = crate::installed_fonts::installed_faces();
77 let own = &self.typefaces[..self.typefaces.len() - self.installed];
78 let mut typefaces = Vec::with_capacity(own.len() + installed.len());
79 typefaces.extend_from_slice(own);
80 typefaces.extend_from_slice(&installed);
81 Some(Self {
82 typefaces: Arc::from(typefaces),
83 installed: installed.len(),
84 })
85 }
86}