Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.9 kB · 168 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169use super::renderable::SVGRenderable;use crate::{ Object, graphics::canvas::Canvas, rendering::{ rasterization::{ create_pixmap, pixmap_to_png_data, svg_to_usvg_tree, usvg_tree_to_pixmap, write_png_data, }, svg, },};use measure_time::debug_time;use std::path::PathBuf;
impl SVGRenderable for Canvas { fn render_to_svg( &self, colormap: crate::ColorMapping, cell_size: usize, object_sizes: crate::graphics::objects::ObjectSizes, _id: &str, ) -> anyhow::Result<svg::Node> { debug_time!("render_to_svg/canvas"); let background_color = self.background.unwrap_or_default(); let mut svg = svg::tag("svg").attr("xmlns", "http://www.w3.org/2000/svg");
svg.add( svg::tag("rect") .attr("x", -(self.outer_padding as i32)) .attr("y", -(self.outer_padding as i32)) .attr("width", self.width()) .attr("height", self.height()) .attr("fill", background_color.render(&self.colormap)), );
for layer in self.layers.iter().filter(|layer| !layer.hidden).rev() { svg.add(layer.render_to_svg( colormap.clone(), cell_size, layer.object_sizes, layer.name.as_str(), )?); }
let mut defs = svg::tag("defs"); for filter in self.unique_filters() { defs.add(filter.render_to_svg( colormap.clone(), cell_size, object_sizes, "", )?); }
for pattern_fill in self.unique_pattern_fills() { if let Some(patterndef) = pattern_fill.pattern_definition(&self.colormap) { defs.add(patterndef); } }
for layer in self.layers.iter() { for Object { clip_to, .. } in layer.objects.values() { if let Some(region) = clip_to { defs.add( svg::tag("clipPath") .attr("id", region.clip_path_id()) .child( svg::tag("rect") .position(region.start, cell_size) .size(*region, cell_size) .node(), ), ); } } }
svg.add(defs);
Ok(svg .attr( "viewBox", format!( "{0} {0} {1} {2}", -(self.outer_padding as i32), self.width(), self.height() ), ) .attr("width", self.width()) .attr("height", self.height()) .into()) }}
impl Canvas { pub fn svg_to_pixmap( &self, width: u32, height: u32, contents: &str, ) -> anyhow::Result<tiny_skia::Pixmap> { let mut pixmap = create_pixmap(width, height);
let parsed_svg = &svg_to_usvg_tree(contents, &self.fontdb)?;
usvg_tree_to_pixmap(self.dimensions(), pixmap.as_mut(), parsed_svg);
Ok(pixmap) }
pub fn render_to_pixmap( &mut self, width: u32, height: u32, ) -> anyhow::Result<tiny_skia::Pixmap> { let svg_contents = self .render_to_svg( self.colormap.clone(), self.cell_size, self.object_sizes, "", )? .to_string(); self.svg_to_pixmap(width, height, &svg_contents) }
// previous_frame_at gives path to the previously rendered frame, which allows to copy on cache hits instead of having to re-write bytes again pub fn render_to_png( &mut self, at: &str, resolution: u32, ) -> anyhow::Result<()> { debug_time!("render_to_png"); let (width, height) = self.resolution_to_size(resolution);
self.render_to_pixmap(width, height).and_then(|pixmap| { pixmap_to_png_data(pixmap).and_then(|data| write_png_data(data, at)) }) }
pub fn render_to_svg_string(&mut self) -> anyhow::Result<String> { debug_time!("render_to_svg_string");
let rendered = self.render_to_svg( self.colormap.clone(), self.cell_size, self.object_sizes, "", )?;
Ok(rendered.to_string()) }
pub fn render_to_svg_file( &mut self, at: impl Into<PathBuf>, ) -> anyhow::Result<()> { debug_time!("render_to_svg_file");
std::fs::write(at.into(), self.render_to_svg_string()?)?;
Ok(()) }}