|
@@ -1,4 +1,5 @@
|
|
|
use std::fmt::Display;
|
|
|
+use std::fmt::{Formatter, Error};
|
|
|
use std::io::Write;
|
|
|
|
|
|
/// An SVG document
|
|
@@ -7,6 +8,18 @@ pub struct SVG {
|
|
|
size: (f64, f64),
|
|
|
}
|
|
|
|
|
|
+#[derive(Copy, Clone)]
|
|
|
+pub struct Inches { amt: f64 }
|
|
|
+
|
|
|
+impl Display for Inches {
|
|
|
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
|
|
+ self.amt.fmt(f)?;
|
|
|
+ write!(f, "in")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+fn inches(amt: f64) -> Inches { Inches { amt } }
|
|
|
+
|
|
|
fn xml_tag(w: &mut Vec<u8>, name: &str, attrs: &[(&str, &dyn Display)]) {
|
|
|
write!(w, "<{}", name);
|
|
|
for (k, v) in attrs {
|
|
@@ -24,7 +37,7 @@ fn xml_open(w: &mut Vec<u8>, name: &str, attrs: &[(&str, &dyn Display)]) {
|
|
|
}
|
|
|
|
|
|
fn xml_close(w: &mut Vec<u8>, name: &str) {
|
|
|
- write!(w, "<{}/>", name);
|
|
|
+ write!(w, "</{}>", name);
|
|
|
}
|
|
|
|
|
|
/// Create a new empty SVG document of the specified width and height
|
|
@@ -52,13 +65,15 @@ impl SVG {
|
|
|
pub fn to_bytes(self) -> Vec<u8> {
|
|
|
let mut buf = Vec::new();
|
|
|
let (w, h) = self.size;
|
|
|
- writeln!(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
|
|
|
+ writeln!(buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
|
xml_open(
|
|
|
&mut buf, "svg",
|
|
|
&[("xmlns", &"http://www.w3.org/2000/svg"),
|
|
|
("version", &"1.1"),
|
|
|
- ("width", &w),
|
|
|
- ("height", &h),
|
|
|
+ ("width", &inches(w)),
|
|
|
+ ("height", &inches(h)),
|
|
|
+ ("viewBox", &format!("0 0 {} {}", w, h)),
|
|
|
+ ("stroke-width", &"0.0001in"),
|
|
|
],
|
|
|
);
|
|
|
for elem in self.stuff {
|
|
@@ -105,7 +120,7 @@ impl AsSVG for Line {
|
|
|
buf, "circle",
|
|
|
&[("cx", &x),
|
|
|
("cy", &y),
|
|
|
- ("r", &"0.5"),
|
|
|
+ ("r", &"0.01in"),
|
|
|
("fill", &"black"),
|
|
|
],
|
|
|
);
|
|
@@ -150,7 +165,7 @@ impl Line {
|
|
|
}
|
|
|
|
|
|
/// Draw a line segment from this point to another point
|
|
|
- pub fn draw_to(mut self, x: f64, y: f64) -> Line {
|
|
|
+ pub fn to(mut self, x: f64, y: f64) -> Line {
|
|
|
self.points.push((x, y));
|
|
|
self
|
|
|
}
|