This commit is contained in:
elvis
2025-11-14 02:44:01 +01:00
parent 41ceea2bcc
commit 87cdc97987
2 changed files with 79 additions and 4 deletions

View File

@ -1839,6 +1839,49 @@ impl eframe::App for AppHandle {
println!("Could not save file: {e}"), println!("Could not save file: {e}"),
} }
ui.close();
}
if ui.button("Save without cache…").clicked()
&& let Some(path) = rfd::FileDialog::new()
.add_filter("ron", &["ron"])
.save_file()
{
let state =
match ron::ser::to_string(&self.state) {
| Ok(value) => value,
| Err(e) => {
println!("Error serializing: {e}");
panic!()
},
};
let translator =
match ron::ser::to_string(&self.translator)
{
| Ok(value) => value,
| Err(e) => {
println!("Error serializing: {e}");
panic!()
},
};
let cache =
match ron::ser::to_string(&OutputsCache::default()) {
| Ok(value) => value,
| Err(e) => {
println!("Error serializing: {e}");
panic!()
},
};
match write_state(
&state,
&translator,
&cache,
&path,
) {
| Ok(_) => {},
| Err(e) =>
println!("Could not save file: {e}"),
}
ui.close(); ui.close();
} }
}); });

View File

@ -5,6 +5,7 @@ use std::sync::{Arc, Mutex};
use eframe::egui; use eframe::egui;
use layout::backends::svg::SVGWriter; use layout::backends::svg::SVGWriter;
use layout::gv::{self, GraphBuilder}; use layout::gv::{self, GraphBuilder};
use resvg::tiny_skia;
#[cfg_attr( #[cfg_attr(
feature = "persistence", feature = "persistence",
@ -27,6 +28,7 @@ impl Svg {
let mut fontdb = fontdb::Database::new(); let mut fontdb = fontdb::Database::new();
fontdb.load_system_fonts(); fontdb.load_system_fonts();
// parse the string to dot
let mut parser = gv::DotParser::new(dot_str); let mut parser = gv::DotParser::new(dot_str);
let g = match parser.process() { let g = match parser.process() {
| Ok(g) => g, | Ok(g) => g,
@ -35,34 +37,64 @@ impl Svg {
return Err("Could not parse dot string.".into()), return Err("Could not parse dot string.".into()),
}; };
// from the graph create the svg
let mut gb = GraphBuilder::new(); let mut gb = GraphBuilder::new();
gb.visit_graph(&g); gb.visit_graph(&g);
let mut graph = gb.get(); let mut graph = gb.get();
let mut svg = SVGWriter::new(); let mut svg = SVGWriter::new();
graph.do_it(false, false, false, &mut svg); graph.do_it(false, false, false, &mut svg);
// convert svg to string
let content = svg.finalize(); let content = svg.finalize();
// parse the string into an svg tree (different library)
let svg_tree = let svg_tree =
match resvg::usvg::Tree::from_str(&content, &resvg::usvg::Options { match resvg::usvg::Tree::from_str(&content, &resvg::usvg::Options {
dpi: 92., dpi: 92.,
font_family: "Andale Mono".into(), // font_family: "Andale Mono".into(),
fontdb: Arc::new(fontdb), fontdb: Arc::new(fontdb),
default_size: resvg::tiny_skia::Size::from_wh(100., 100.).unwrap(),
..Default::default() ..Default::default()
}) { }) {
| Ok(svg) => svg, | Ok(svg) => svg,
| Err(err) => return Err(format!("{}", err)), | Err(err) => return Err(format!("{}", err)),
}; };
let svg_size = let (svg_size, scaling) = {
egui::vec2(svg_tree.size().width(), svg_tree.size().height()); let width = svg_tree.size().width() as u32;
let height = svg_tree.size().height() as u32;
let max = std::cmp::max(width, height);
let larger = if max >= 2_u32.pow(14) { 2_u32.pow(14) } else { max };
let (smaller, scale) = {
let min = std::cmp::min(width, height);
if max >= 2_u32.pow(14) {
((2_u32.pow(14) * min) / max, 2_f32.powf(14.) / max as f32)
} else {
(min, 1.)
}
};
if width == max {
(egui::vec2(larger as f32, smaller as f32), scale)
} else {
(egui::vec2(smaller as f32, larger as f32), scale)
}
// (egui::vec2(svg_tree.size().width(), svg_tree.size().height()), 1.)
};
// create the pixel map to render the svg in
let mut pixmap = let mut pixmap =
resvg::tiny_skia::Pixmap::new(svg_size.x as _, svg_size.y as _) resvg::tiny_skia::Pixmap::new(svg_size.x as _, svg_size.y as _)
.expect("Could not allocate svg"); .expect("Could not allocate svg");
let pixmap_mut = &mut pixmap.as_mut(); let pixmap_mut = &mut pixmap.as_mut();
resvg::render(&svg_tree, Default::default(), pixmap_mut);
// render the tree inside the pixel map
resvg::render(&svg_tree,
// scaling is compleately ignored by the library
tiny_skia::Transform::from_scale(scaling, scaling),
pixmap_mut);
let pixmap = pixmap_mut.to_owned(); let pixmap = pixmap_mut.to_owned();
// create a color image that will be converted to texture for egui to
// display (and cache)
let image = egui::ColorImage::from_rgba_unmultiplied( let image = egui::ColorImage::from_rgba_unmultiplied(
[pixmap.width() as _, pixmap.height() as _], [pixmap.width() as _, pixmap.height() as _],
pixmap.data(), pixmap.data(),