termcinema_engine/core/
font.rs

1/// Metadata descriptor for an embeddable font.
2///
3/// Each embedded font includes a path to the TTF file and
4/// a CSS `font-family` name used during SVG rendering.
5pub struct EmbeddedFont {
6    /// Path to the font file (relative to project root).
7    pub path: &'static str,
8
9    /// CSS font-family name to inject via `@font-face`.
10    pub css_family: &'static str,
11}
12
13/// Built-in embedded font list, ordered by priority.
14///
15/// Fonts in this list will be embedded into SVG if matched by name.
16/// These fonts offer reliable layout and aesthetics across platforms.
17pub static EMBEDDED_FONTS: &[EmbeddedFont] = &[
18    EmbeddedFont {
19        path: "assets/fonts/PxPlus_IBM_VGA_8x16.ttf",
20        css_family: "PxPlus IBM VGA8", // Classic VGA pixel font, highly aligned, retro feel.
21    },
22    EmbeddedFont {
23        path: "assets/fonts/JetBrainsMono-Regular.ttf",
24        css_family: "JetBrains Mono", // Modern monospace font by JetBrains, great for code output.
25    },
26    EmbeddedFont {
27        path: "assets/fonts/FiraCode-Regular.ttf",
28        css_family: "Fira Code", // Ligature-friendly, stylish monospace font.
29    },
30    EmbeddedFont {
31        path: "assets/fonts/SourceCodePro-Regular.ttf",
32        css_family: "Source Code Pro", // Clean, well-balanced font from Adobe.
33    },
34    EmbeddedFont {
35        path: "assets/fonts/CascadiaMono-Regular.ttf",
36        css_family: "Cascadia Mono", // Default font for Windows Terminal, modern look.
37    },
38];
39
40/// Resolve a font by its CSS `font-family` name.
41///
42/// Returns the matching embedded font metadata if the name
43/// exactly matches any of the available `css_family` entries.
44///
45/// Used during style patching and font validation.
46pub fn resolve_embedded_font(user_input: &str) -> Option<&'static EmbeddedFont> {
47    let trimmed = user_input.trim();
48    EMBEDDED_FONTS
49        .iter()
50        .find(|font| font.css_family == trimmed)
51}
52
53/// Returns a list of all embeddable CSS `font-family` names.
54///
55/// Useful for validation, autocomplete, and UI dropdowns.
56pub fn list_embeddable_font_families() -> Vec<&'static str> {
57    EMBEDDED_FONTS.iter().map(|f| f.css_family).collect()
58}
59
60/// Returns a whitelist of system fonts considered monospace-safe.
61///
62/// These are not embedded but may be used as fallback options.
63/// Each entry includes an optional comment describing platform behavior.
64pub fn list_builtin_system_fonts() -> Vec<(&'static str, Option<&'static str>)> {
65    vec![
66        (
67            "Monospace",
68            Some("Generic fallback: macOS → Menlo, Windows → Consolas, Linux → DejaVu Sans Mono"),
69        ),
70        ("Courier New", None),      // Win/macOS
71        ("Menlo", None),            // macOS
72        ("Consolas", None),         // Windows
73        ("Lucida Console", None),   // Windows legacy
74        ("DejaVu Sans Mono", None), // Linux
75        ("Ubuntu Mono", None),      // Ubuntu
76    ]
77}
78
79/// Suggest recommended fonts based on the current operating system.
80///
81/// Returns a prioritized list combining system fonts and known embedded fonts.
82/// Can be used to prefill default font-family selections.
83pub fn recommended_fonts_for_current_os() -> Vec<&'static str> {
84    match std::env::consts::OS {
85        "macos" => vec!["Menlo", "Courier New", "JetBrains Mono"],
86        "windows" => vec!["Consolas", "Courier New", "JetBrains Mono"],
87        "linux" => vec!["DejaVu Sans Mono", "Ubuntu Mono", "JetBrains Mono"],
88        _ => vec!["Monospace", "JetBrains Mono"],
89    }
90}