use std::collections::{BTreeMap, HashMap};
use std::sync::Arc;
use kurbo::BezPath;
use usvg::tiny_skia_path::Path as TinyPath;
use crate::input::LoadedSvgSource;
use crate::types::color::{ProcessedColorLayer, ResolvedColorSelection, ResolvedLayerPaint};
pub(crate) struct SvgOptions<'a> {
pub filesystem_free: bool,
pub color_selection: Option<&'a ResolvedColorSelection>,
pub ascent: Option<f64>,
pub center_horizontally: Option<bool>,
pub center_vertically: Option<bool>,
pub codepoints: &'a BTreeMap<String, u32>,
pub descent: Option<f64>,
pub fixed_width: Option<bool>,
pub font_height: Option<f64>,
pub font_id: Option<&'a str>,
pub font_name: &'a str,
pub font_style: Option<&'a str>,
pub font_weight: Option<&'a str>,
pub ligature: bool,
pub metadata: Option<&'a str>,
pub normalize: bool,
pub optimize_output: Option<bool>,
pub preserve_aspect_ratio: Option<bool>,
pub round: Option<f64>,
pub serialize_path: bool,
pub structure_path: bool,
}
impl SvgOptions<'_> {
pub(super) fn source_error(&self, id: &str, error: std::io::Error) -> std::io::Error {
if self.filesystem_free {
std::io::Error::new(error.kind(), format!("SVG source {id:?}: {error}"))
} else {
error
}
}
pub(crate) fn parser_options(&self) -> usvg::Options<'static> {
let mut options = usvg::Options::default();
if self.filesystem_free {
options.image_href_resolver.resolve_string = Box::new(|_, _| None);
}
options
}
pub fn selects_color(&self, name: &str) -> bool {
self.color_selection
.is_some_and(|selection| selection.contains(name))
}
}
#[derive(Debug)]
pub(crate) struct ParsedColorLayer {
pub path_index: usize,
pub paint: ResolvedLayerPaint,
pub fill_rule: usvg::FillRule,
}
#[derive(Clone)]
pub(crate) struct ParsedGlyph {
pub color_layers: Option<Arc<[ParsedColorLayer]>>,
pub codepoint: u32,
pub height: f64,
pub index: usize,
pub name: String,
pub paths: Vec<TinyPath>,
pub width: f64,
}
pub(crate) struct GlyphWorkItem<'a> {
pub codepoint: u32,
pub index: usize,
pub name: &'a str,
pub source_file: &'a LoadedSvgSource,
}
#[derive(Clone)]
pub(crate) struct ProcessedGlyph {
pub color_layers: Option<Arc<[ProcessedColorLayer]>>,
pub codepoint: u32,
pub height: f64,
pub index: usize,
pub name: String,
pub path_data: Arc<str>,
pub ttf_path: Option<Arc<BezPath>>,
pub ttf_path_hash: Option<u64>,
pub width: f64,
}
#[derive(Clone)]
pub(crate) struct CachedProcessedGlyph {
pub color_layers: Option<Arc<[ProcessedColorLayer]>>,
pub height: f64,
pub path_data: Arc<str>,
pub ttf_path: Option<Arc<BezPath>>,
pub ttf_path_hash: Option<u64>,
pub width: f64,
}
#[derive(Clone)]
pub(crate) struct PreparedSvgFont {
pub ascent: f64,
pub descent: f64,
pub font_height: f64,
pub font_id: String,
pub font_width: f64,
pub metadata: String,
pub processed_glyphs: Vec<ProcessedGlyph>,
}
pub(crate) struct PreparedVariantFamily {
pub ascent: f64,
pub descent: f64,
pub font_height: f64,
pub glyphs: Vec<ProcessedVariantGlyph>,
}
pub(crate) struct ProcessedVariantGlyph {
pub name: String,
pub codepoint: u32,
pub advance_width: f64,
pub outlines: Box<[Option<ProcessedGlyph>]>,
}
pub(crate) struct CachedGlyph {
pub color_layers: Option<Arc<[ParsedColorLayer]>>,
pub height: f64,
pub paths: Vec<TinyPath>,
pub width: f64,
}
#[derive(Clone, Default)]
pub(crate) struct GlyphCache {
pub entries: HashMap<String, Arc<CachedGlyph>>,
pub content_hashes: HashMap<String, [u8; 16]>,
pub by_content_hash: HashMap<[u8; 16], Arc<CachedGlyph>>,
pub processed_entries: HashMap<String, CachedProcessedGlyph>,
pub processed_signature: Option<[u8; 16]>,
#[cfg(test)]
pub parse_count: usize,
#[cfg(test)]
pub process_count: usize,
}