open_sesame/platform/
fonts.rs1use fontconfig::Fontconfig;
7use std::path::PathBuf;
8
9pub struct ResolvedFont {
11 pub path: PathBuf,
13 pub family: String,
15}
16
17pub fn resolve_font(family: &str) -> Option<ResolvedFont> {
24 let fc = Fontconfig::new()?;
25
26 if let Some(font) = fc.find(family, None) {
28 tracing::debug!(
29 "fontconfig: resolved '{}' to '{}'",
30 family,
31 font.path.display()
32 );
33 return Some(ResolvedFont {
34 path: font.path,
35 family: font.name,
36 });
37 }
38
39 if family != "sans"
41 && let Some(font) = fc.find("sans", None)
42 {
43 tracing::info!(
44 "fontconfig: '{}' not found, falling back to sans ({})",
45 family,
46 font.path.display()
47 );
48 return Some(ResolvedFont {
49 path: font.path,
50 family: font.name,
51 });
52 }
53
54 tracing::error!("fontconfig: no fonts available");
55 None
56}
57
58pub fn resolve_sans() -> Option<ResolvedFont> {
60 resolve_font("sans")
61}
62
63pub fn resolve_font_with_style(family: &str, style: &str) -> Option<ResolvedFont> {
65 let fc = Fontconfig::new()?;
66
67 let pattern = format!("{}:style={}", family, style);
69 if let Some(font) = fc.find(&pattern, None) {
70 return Some(ResolvedFont {
71 path: font.path,
72 family: font.name,
73 });
74 }
75
76 resolve_font(family)
78}
79
80pub fn fontconfig_available() -> bool {
82 Fontconfig::new()
83 .and_then(|fc| fc.find("sans", None))
84 .is_some()
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_fontconfig_available() {
93 assert!(fontconfig_available(), "fontconfig should have sans font");
94 }
95
96 #[test]
97 fn test_resolve_sans() {
98 let font = resolve_sans().expect("Should resolve sans font");
99 assert!(font.path.exists(), "Font path should exist");
100 println!(
101 "Resolved sans to: {} ({})",
102 font.family,
103 font.path.display()
104 );
105 }
106
107 #[test]
108 fn test_resolve_open_sans() {
109 if let Some(font) = resolve_font("Open Sans") {
110 println!(
111 "Resolved Open Sans to: {} ({})",
112 font.family,
113 font.path.display()
114 );
115 } else {
116 println!("Open Sans not installed, fallback would be used");
117 }
118 }
119}