1#![cfg(feature = "svg")]
14
15use std::fmt::Write;
16use std::marker::PhantomData;
17
18use crate::render::{Canvas as RenderCanvas, Pixel};
19use crate::types::Color as ModuleColor;
20
21#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct Color<'a>(pub &'a str);
24
25impl<'a> Pixel for Color<'a> {
26 type Image = String;
27 type Canvas = Canvas<'a>;
28
29 fn default_color(color: ModuleColor) -> Self {
30 Color(color.select("#000", "#fff"))
31 }
32}
33
34#[doc(hidden)]
35pub struct Canvas<'a> {
36 svg: String,
37 marker: PhantomData<Color<'a>>,
38}
39
40impl<'a> RenderCanvas for Canvas<'a> {
41 type Pixel = Color<'a>;
42 type Image = String;
43
44 fn new(width: u32, height: u32, dark_pixel: Color<'a>, light_pixel: Color<'a>) -> Self {
45 Canvas {
46 svg: format!(
47 concat!(
48 r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>"#,
49 r#"<svg xmlns="http://www.w3.org/2000/svg""#,
50 r#" version="1.1" width="{w}" height="{h}""#,
51 r#" viewBox="0 0 {w} {h}" shape-rendering="crispEdges">"#,
52 r#"<rect x="0" y="0" width="{w}" height="{h}" fill="{bg}"/>"#,
53 r#"<path fill="{fg}" d=""#,
54 ),
55 w = width,
56 h = height,
57 fg = dark_pixel.0,
58 bg = light_pixel.0
59 ),
60 marker: PhantomData,
61 }
62 }
63
64 fn draw_dark_pixel(&mut self, x: u32, y: u32) {
65 self.draw_dark_rect(x, y, 1, 1);
66 }
67
68 fn draw_dark_rect(&mut self, left: u32, top: u32, width: u32, height: u32) {
69 write!(self.svg, "M{left} {top}h{width}v{height}H{left}V{top}").unwrap();
70 }
71
72 fn into_image(mut self) -> String {
73 self.svg.push_str(r#""/></svg>"#);
74 self.svg
75 }
76}