Files
aoostar-rs/src/font.rs
T
Markus Zehnder 1756e1f919 initial commit
2025-07-25 17:31:37 +02:00

65 lines
1.8 KiB
Rust

// SPDX-License-Identifier: MIT OR Apache-2.0
// SPDX-FileCopyrightText: Copyright (c) 2025 Markus Zehnder
use ab_glyph::{FontArc, FontRef, FontVec};
use anyhow::{Context, anyhow};
use log::warn;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
static DEFAULT_TTF_FONT: Lazy<FontArc> = Lazy::new(|| {
FontArc::new(
FontRef::try_from_slice(include_bytes!("../fonts/DejaVuSans.ttf"))
.expect("Failed to load default font"),
)
});
pub struct FontHandler {
ttf_path: PathBuf,
ttf_cache: HashMap<String, FontArc>,
}
impl FontHandler {
pub fn new(ttf_path: impl Into<PathBuf>) -> Self {
Self {
ttf_path: ttf_path.into(),
ttf_cache: Default::default(),
}
}
pub fn default_font() -> FontArc {
DEFAULT_TTF_FONT.clone()
}
pub fn get_ttf_font_or_default(&mut self, name: &str) -> FontArc {
self.get_ttf_font(name).unwrap_or_else(|e| {
warn!("Failed to load font: {e}. Using default");
FontHandler::default_font()
})
}
pub fn get_ttf_font(&mut self, name: &str) -> anyhow::Result<FontArc> {
if let Some(font) = self.ttf_cache.get(name) {
return Ok(font.clone());
}
let mut path = self.ttf_path.join(name);
path.set_extension("ttf");
if !path.exists() {
return Err(anyhow!("{name}.ttf not found"));
}
let data = fs::read(path).with_context(|| format!("Error reading font {name}.ttf"))?;
let font = FontArc::new(
FontVec::try_from_vec(data)
.with_context(|| format!("Error parsing font {name}.ttf"))?,
);
self.ttf_cache.insert(name.to_string(), font.clone());
Ok(font)
}
}