use egui::{Context, TextureHandle};
use std::sync::Arc;
use gled_model::asset::svg::Svg;
#[derive(Default)]
pub(crate) struct SvgRuntime {
rendered: Option<Arc<str>>,
texture: Option<TextureHandle>,
}
impl std::fmt::Debug for SvgRuntime {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SvgRuntime")
.field("rendered", &self.rendered.is_some())
.finish_non_exhaustive()
}
}
impl SvgRuntime {
pub(crate) fn texture(&mut self, svg: &Svg, context: &Context) -> Option<TextureHandle> {
let contents = svg.contents();
let current = self
.rendered
.as_ref()
.is_some_and(|rendered| Arc::ptr_eq(rendered, contents) || rendered == contents);
if !current {
self.rendered = Some(contents.clone());
self.texture = render_preview(contents, context);
}
self.texture.clone()
}
pub(crate) fn reset(&mut self) {
self.rendered = None;
self.texture = None;
}
}
fn render_preview(contents: &str, context: &Context) -> Option<TextureHandle> {
let svg = gled_svg::ParsedSvg::parse(contents).ok()?;
let rendered = svg.render().ok()?;
let image = egui::ColorImage::from_rgba_unmultiplied([rendered.size; 2], &rendered.rgba);
Some(context.load_texture("svg_preview", image, egui::TextureOptions::default()))
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn load_svg(path: &std::path::Path) -> std::io::Result<Svg> {
Ok(Svg::new(std::fs::read_to_string(path)?))
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn save_svg(svg: &Svg, path: &std::path::Path) -> std::io::Result<()> {
std::fs::write(path, svg.contents().as_bytes())
}