Skip to content

Commit

Permalink
Improve SVG stingification
Browse files Browse the repository at this point in the history
  • Loading branch information
staticintlucas committed May 30, 2024
1 parent 297cdc1 commit c17fd05
Showing 1 changed file with 33 additions and 19 deletions.
52 changes: 33 additions & 19 deletions keyset-drawing/src/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,24 @@ use svg::Document;

use super::{Drawing, KeyDrawing, KeyPath};

macro_rules! fmt_num {
($fmt:literal, $($args:expr),*) => {
format!($fmt, $(($args * 1e5).round() / 1e5),*)
macro_rules! float {
($arg:expr $(,)?) => {
format!("{}", float!(@round $arg))
};
($arg0:expr, $($args:expr),+ $(,)?) => {
format!("{}{}", float!(@round $arg0), float!(@inner $($args),+))
};
(@inner $arg:expr $(,)?) => {
format_args!("{}", float!(@format $arg))
};
(@inner $arg0:expr, $($args:expr),+ $(,)?) => {
format_args!("{}{}", float!(@format $arg0), float!(@inner $($args),+))
};
(@format $arg:expr) => {
format_args!("{}{}", if $arg.is_sign_positive() { " " } else { "" }, float!(@round $arg))
};
(@round $arg:expr) => {
($arg * 1e3).round() / 1e3
};
}

Expand All @@ -15,12 +30,11 @@ pub fn draw(drawing: &Drawing) -> String {
let view_box = drawing.bounds * DOT_PER_UNIT; // Use 1000 user units per key

let document = Document::new()
.set("width", fmt_num!("{}mm", size.width))
.set("height", fmt_num!("{}mm", size.height))
.set("width", format!("{}mm", float!(size.width)))
.set("height", format!("{}mm", float!(size.height)))
.set(
"viewBox",
fmt_num!(
"{} {} {} {}",
float!(
view_box.min.x,
view_box.min.y,
view_box.size().width,
Expand All @@ -41,7 +55,7 @@ fn draw_key(key: &KeyDrawing) -> Group {
let origin = key.origin * DOT_PER_UNIT;
let group = Group::new().set(
"transform",
fmt_num!("translate({},{})", origin.x, origin.y),
format!("translate({},{})", float!(origin.x), float!(origin.y)),
);
key.paths.iter().map(draw_path).fold(group, Group::add)
}
Expand All @@ -51,13 +65,13 @@ fn draw_path(path: &KeyPath) -> SvgPath {
.data
.iter()
.map(|el| match *el {
PathSegment::Move(p) => fmt_num!("M{} {}", p.x, p.y),
PathSegment::Line(d) => fmt_num!("l{} {}", d.x, d.y),
PathSegment::Move(p) => format!("M{}", float!(p.x, p.y)),
PathSegment::Line(d) => format!("l{}", float!(d.x, d.y)),
PathSegment::CubicBezier(c1, c2, d) => {
fmt_num!("c{} {} {} {} {} {}", c1.x, c1.y, c2.x, c2.y, d.x, d.y)
format!("c{}", float!(c1.x, c1.y, c2.x, c2.y, d.x, d.y))
}
// GRCOV_EXCL_START - no quads in example
PathSegment::QuadraticBezier(c1, d) => fmt_num!("q{} {} {} {}", c1.x, c1.y, d.x, d.y),
PathSegment::QuadraticBezier(c1, d) => format!("q{}", float!(c1.x, c1.y, d.x, d.y)),
// GRCOV_EXCL_STOP
PathSegment::Close => "z".into(),
})
Expand All @@ -71,7 +85,7 @@ fn draw_path(path: &KeyPath) -> SvgPath {
if let Some(outline) = path.outline {
svg_path
.set("stroke", format!("{:x}", outline.color))
.set("stroke-width", fmt_num!("{}", outline.width.get()))
.set("stroke-width", float!(outline.width.get()))
} else {
svg_path.set("stroke", "none")
}
Expand Down Expand Up @@ -102,13 +116,13 @@ mod tests {
r##"
<svg height="19.05mm" viewBox="0 0 1000 1000" width="19.05mm" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0,0)">
<path d="M25 90c0 -35.89851 29.10149 -65.00001 64.99999 -65.00001l820 0c35.89851 0 65 29.10149 65 65l0 820c0 35.89851 -29.1015 65 -65 65l-820 0c-35.89851 0 -64.99999 -29.1015 -64.99999 -65.00001z" fill="#cccccc" stroke="#aeaeae" stroke-width="10"/>
<path d="M170 120c0 -35.89851 29.10149 -65.00001 64.99999 -65.00001l530 0c35.89851 0 65 29.10149 65 65l0 605c0 35.89851 -29.1015 65 -65 65l-530 0c-35.89851 0 -64.99999 -29.1015 -64.99999 -65.00001z" fill="#cccccc" stroke="#aeaeae" stroke-width="10"/>
<path d="M25 90c0-35.899 29.101-65 65-65l820 0c35.899 0 65 29.101 65 65l0 820c0 35.899-29.101 65-65 65l-820 0c-35.899 0-65-29.101-65-65z" fill="#cccccc" stroke="#aeaeae" stroke-width="10"/>
<path d="M170 120c0-35.899 29.101-65 65-65l530 0c35.899 0 65 29.101 65 65l0 605c0 35.899-29.101 65-65 65l-530 0c-35.899 0-65-29.101-65-65z" fill="#cccccc" stroke="#aeaeae" stroke-width="10"/>
<path d="M220 105l560 0l0 635l-560 0z" fill="none" stroke="#ff0000" stroke-width="5"/>
<path d="M220 299.44446l0 -194.44444l126.36166 0l0 194.44444l-126.36166 -0zM235.52287 270.30502l37.03704 -68.08279l-37.03704 -68.08279l0 136.16557zM244.23747 120.52289l38.94336 69.98911l38.94336 -69.98911l-77.88671 -0zM330.83878 134.13945l-37.03704 68.08279l37.03704 68.08279l0 -136.16557zM322.12418 283.92157l-38.94336 -69.98911l-38.94336 69.98911l77.88671 0z" fill="#000000" stroke="none"/>
<path d="M653.6383 299.44446l0 -194.44444l126.36166 0l0 194.44444l-126.36166 -0zM669.1612 270.30502l37.03704 -68.08279l-37.03704 -68.08279l0 136.16557zM677.87573 120.52289l38.94336 69.98911l38.94336 -69.98911l-77.88671 -0zM764.4771 134.13945l-37.03704 68.08279l37.03704 68.08279l0 -136.16557zM755.76245 283.92157l-38.94336 -69.98911l-38.94336 69.98911l77.88671 0z" fill="#000000" stroke="none"/>
<path d="M220 740l0 -194.44444l126.36166 0l0 194.44444l-126.36166 -0zM235.52287 710.86053l37.03704 -68.08279l-37.03704 -68.08279l0 136.16557zM244.23747 561.0784l38.94336 69.98911l38.94336 -69.98911l-77.88671 -0zM330.83878 574.695l-37.03704 68.08279l37.03704 68.08279l0 -136.16557zM322.12418 724.4771l-38.94336 -69.98911l-38.94336 69.98911l77.88671 0z" fill="#000000" stroke="none"/>
<path d="M653.6383 740l0 -194.44444l126.36166 0l0 194.44444l-126.36166 -0zM669.1612 710.86053l37.03704 -68.08279l-37.03704 -68.08279l0 136.16557zM677.87573 561.0784l38.94336 69.98911l38.94336 -69.98911l-77.88671 -0zM764.4771 574.695l-37.03704 68.08279l37.03704 68.08279l0 -136.16557zM755.76245 724.4771l-38.94336 -69.98911l-38.94336 69.98911l77.88671 0z" fill="#000000" stroke="none"/>
<path d="M220 299.444l0-194.444l126.362 0l0 194.444l-126.362-0zM235.523 270.305l37.037-68.083l-37.037-68.083l0 136.166zM244.237 120.523l38.943 69.989l38.943-69.989l-77.887-0zM330.839 134.139l-37.037 68.083l37.037 68.083l0-136.166zM322.124 283.922l-38.943-69.989l-38.943 69.989l77.887 0z" fill="#000000" stroke="none"/>
<path d="M653.638 299.444l0-194.444l126.362 0l0 194.444l-126.362-0zM669.161 270.305l37.037-68.083l-37.037-68.083l0 136.166zM677.876 120.523l38.943 69.989l38.943-69.989l-77.887-0zM764.477 134.139l-37.037 68.083l37.037 68.083l0-136.166zM755.763 283.922l-38.943-69.989l-38.943 69.989l77.887 0z" fill="#000000" stroke="none"/>
<path d="M220 740l0-194.444l126.362 0l0 194.444l-126.362-0zM235.523 710.861l37.037-68.083l-37.037-68.083l0 136.166zM244.237 561.078l38.943 69.989l38.943-69.989l-77.887-0zM330.839 574.695l-37.037 68.083l37.037 68.083l0-136.166zM322.124 724.477l-38.943-69.989l-38.943 69.989l77.887 0z" fill="#000000" stroke="none"/>
<path d="M653.638 740l0-194.444l126.362 0l0 194.444l-126.362-0zM669.161 710.861l37.037-68.083l-37.037-68.083l0 136.166zM677.876 561.078l38.943 69.989l38.943-69.989l-77.887-0zM764.477 574.695l-37.037 68.083l37.037 68.083l0-136.166zM755.763 724.477l-38.943-69.989l-38.943 69.989l77.887 0z" fill="#000000" stroke="none"/>
</g>
</svg>"##
)
Expand Down

0 comments on commit c17fd05

Please sign in to comment.