use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// A font type (storing font family and font style and an optional preview URL) #[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)] pub struct Font { #[serde(rename = "fontFamily")] pub font_family: String, #[serde(rename = "fontStyle")] pub font_style: String, } impl Font { pub fn new(font_family: String, font_style: String) -> Self { Self { font_family, font_style } } } /// A cache of all loaded font data and preview urls along with the default font (send from `init_app` in `editor_api.rs`) #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct FontCache { /// Actual font file data used for rendering a font with ttf_parser and rustybuzz font_file_data: HashMap>, /// Web font preview URLs used for showing fonts when live editing preview_urls: HashMap, /// The default font (used as a fallback) default_font: Option, } impl FontCache { /// Returns the font family name if the font is cached, otherwise returns the default font family name if that is cached pub fn resolve_font<'a>(&'a self, font: &'a Font) -> Option<&'a Font> { if self.loaded_font(font) { Some(font) } else { self.default_font.as_ref().filter(|font| self.loaded_font(font)) } } /// Try to get the bytes for a font pub fn get<'a>(&'a self, font: &Font) -> Option<&'a Vec> { self.resolve_font(font).and_then(|font| self.font_file_data.get(font)) } /// Check if the font is already loaded pub fn loaded_font(&self, font: &Font) -> bool { self.font_file_data.contains_key(font) } /// Insert a new font into the cache pub fn insert(&mut self, font: Font, perview_url: String, data: Vec, is_default: bool) { if is_default { self.default_font = Some(font.clone()); } self.font_file_data.insert(font.clone(), data); self.preview_urls.insert(font, perview_url); } /// Checks if the font cache has a default font pub fn has_default(&self) -> bool { self.default_font.is_some() } /// Gets the preview URL for showing in text field when live editing pub fn get_preview_url(&self, font: &Font) -> Option<&String> { self.preview_urls.get(font) } }