This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1use super::renderable::SVGRenderable; 2use crate::{ 3 graphics::canvas::Canvas, 4 rendering::{ 5 rasterization::{ 6 create_pixmap, pixmap_to_png_data, svg_to_usvg_tree, 7 usvg_tree_to_pixmap, write_png_data, 8 }, 9 svg, 10 }, 11}; 12use measure_time::debug_time; 13 14impl SVGRenderable for Canvas { 15 fn render_to_svg( 16 &self, 17 colormap: crate::ColorMapping, 18 cell_size: usize, 19 object_sizes: crate::graphics::objects::ObjectSizes, 20 _id: &str, 21 ) -> anyhow::Result<svg::Node> { 22 debug_time!("render_to_svg/canvas"); 23 let background_color = self.background.unwrap_or_default(); 24 let mut svg = svg::tag("svg").attr("xmlns", "http://www.w3.org/2000/svg"); 25 26 svg.add( 27 svg::tag("rect") 28 .attr("x", -(self.canvas_outer_padding as i32)) 29 .attr("y", -(self.canvas_outer_padding as i32)) 30 .attr("width", self.width()) 31 .attr("height", self.height()) 32 .attr("fill", background_color.render(&self.colormap)), 33 ); 34 35 for layer in self.layers.iter().filter(|layer| !layer.hidden).rev() { 36 svg.add(layer.render_to_svg( 37 colormap.clone(), 38 cell_size, 39 layer.object_sizes, 40 layer.name.as_str(), 41 )?); 42 } 43 44 let mut defs = svg::tag("defs"); 45 for filter in self.unique_filters() { 46 defs.add(filter.render_to_svg( 47 colormap.clone(), 48 cell_size, 49 object_sizes, 50 "", 51 )?); 52 } 53 54 for pattern_fill in self.unique_pattern_fills() { 55 if let Some(patterndef) = 56 pattern_fill.pattern_definition(&self.colormap) 57 { 58 defs.add(patterndef); 59 } 60 } 61 62 svg.add(defs); 63 64 Ok(svg 65 .attr( 66 "viewBox", 67 format!( 68 "{0} {0} {1} {2}", 69 -(self.canvas_outer_padding as i32), 70 self.width(), 71 self.height() 72 ), 73 ) 74 .attr("width", self.width()) 75 .attr("height", self.height()) 76 .into()) 77 } 78} 79 80impl Canvas { 81 pub fn svg_to_pixmap( 82 &self, 83 width: u32, 84 height: u32, 85 contents: &str, 86 ) -> anyhow::Result<tiny_skia::Pixmap> { 87 let mut pixmap = create_pixmap(width, height); 88 89 let parsed_svg = &svg_to_usvg_tree(contents, &self.fontdb)?; 90 91 usvg_tree_to_pixmap(self.dimensions(), pixmap.as_mut(), parsed_svg); 92 93 Ok(pixmap) 94 } 95 96 pub fn render_to_pixmap( 97 &mut self, 98 width: u32, 99 height: u32, 100 ) -> anyhow::Result<tiny_skia::Pixmap> { 101 let svg_contents = self 102 .render_to_svg( 103 self.colormap.clone(), 104 self.cell_size, 105 self.object_sizes, 106 "", 107 )? 108 .to_string(); 109 self.svg_to_pixmap(width, height, &svg_contents) 110 } 111 112 // 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 113 pub fn render_to_png( 114 &mut self, 115 at: &str, 116 resolution: u32, 117 ) -> anyhow::Result<()> { 118 debug_time!("render_to_png"); 119 let (width, height) = self.resolution_to_size(resolution); 120 121 self.render_to_pixmap(width, height).and_then(|pixmap| { 122 pixmap_to_png_data(pixmap).and_then(|data| write_png_data(data, at)) 123 }) 124 } 125 126 pub fn render_to_svg_string(&mut self) -> anyhow::Result<String> { 127 debug_time!("render_to_svg_string"); 128 129 let rendered = self.render_to_svg( 130 self.colormap.clone(), 131 self.cell_size, 132 self.object_sizes, 133 "", 134 )?; 135 136 Ok(rendered.to_string()) 137 } 138 139 pub fn render_to_svg_file(&mut self, at: &str) -> anyhow::Result<()> { 140 debug_time!("render_to_svg_file"); 141 142 std::fs::write(at, self.render_to_svg_string()?)?; 143 144 Ok(()) 145 } 146}