use crate::{ color::Color, font_cache::FamilyId, json::{json, ToJson}, text_layout::RunStyle, FontCache, }; use anyhow::{anyhow, Result}; pub use font_kit::{ metrics::Metrics, properties::{Properties, Stretch, Style, Weight}, }; use ordered_float::OrderedFloat; use refineable::Refineable; use schemars::JsonSchema; use serde::{de, Deserialize, Serialize}; use serde_json::Value; use std::{cell::RefCell, sync::Arc}; #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, JsonSchema)] pub struct FontId(pub usize); pub type GlyphId = u32; #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct Features { pub calt: Option, pub case: Option, pub cpsp: Option, pub frac: Option, pub liga: Option, pub onum: Option, pub ordn: Option, pub pnum: Option, pub ss01: Option, pub ss02: Option, pub ss03: Option, pub ss04: Option, pub ss05: Option, pub ss06: Option, pub ss07: Option, pub ss08: Option, pub ss09: Option, pub ss10: Option, pub ss11: Option, pub ss12: Option, pub ss13: Option, pub ss14: Option, pub ss15: Option, pub ss16: Option, pub ss17: Option, pub ss18: Option, pub ss19: Option, pub ss20: Option, pub subs: Option, pub sups: Option, pub swsh: Option, pub titl: Option, pub tnum: Option, pub zero: Option, } #[derive(Clone, Debug, JsonSchema)] pub struct TextStyle { pub color: Color, pub font_family_name: Arc, pub font_family_id: FamilyId, pub font_id: FontId, pub font_size: f32, #[schemars(with = "PropertiesDef")] pub font_properties: Properties, pub underline: Underline, pub soft_wrap: bool, } impl TextStyle { pub fn for_color(color: Color) -> Self { Self { color, ..Default::default() } } } impl TextStyle { pub fn refine( &mut self, refinement: &TextStyleRefinement, font_cache: &FontCache, ) -> Result<()> { if let Some(font_size) = refinement.font_size { self.font_size = font_size; } if let Some(color) = refinement.color { self.color = color; } if let Some(underline) = refinement.underline { self.underline = underline; } let mut update_font_id = false; if let Some(font_family) = refinement.font_family.clone() { self.font_family_id = font_cache.load_family(&[&font_family], &Default::default())?; self.font_family_name = font_family; update_font_id = true; } if let Some(font_weight) = refinement.font_weight { self.font_properties.weight = font_weight; update_font_id = true; } if let Some(font_style) = refinement.font_style { self.font_properties.style = font_style; update_font_id = true; } if update_font_id { self.font_id = font_cache.select_font(self.font_family_id, &self.font_properties)?; } Ok(()) } } #[derive(Clone, Debug, Default)] pub struct TextStyleRefinement { pub color: Option, pub font_family: Option>, pub font_size: Option, pub font_weight: Option, pub font_style: Option