From 7d9ba355d1dbe19878c85bf5eb7607a31d9e340c Mon Sep 17 00:00:00 2001 From: Sameer Puri Date: Thu, 25 Apr 2019 19:41:48 -0500 Subject: [PATCH] Add viewbox handling, fix ellipse handling for large_arc case --- README.md | 1 + src/main.rs | 14 ++++++++++---- src/turtle.rs | 13 +++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 59430a5..4ca700c 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,4 @@ Convert any SVG 1.1 path to gcode for a pen plotter, laser engraver, etc. - [ ] Smooth curves should not use the control point when the previous curve is not of the same type (quadratic -> smooth cubic, cubic -> smooth quadratic) - [x] Image coordinates mirrored in the y-axis because SVGs uses upper left corner as (0,0) while GCode uses lower left as (0,0) - [x] Close path command connects back to (0.0, 0.0) instead of the last move +- [ ] Ellipse paths are dubious -- large_arc, sweep may need to be inverted diff --git a/src/main.rs b/src/main.rs index a4dfb6b..d8bfa07 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ use std::env; use std::fs::File; use std::io::{self, Read}; -use lyon_geom::{math, euclid}; +use lyon_geom::{euclid, math}; use svgdom::{AttributeId, AttributeValue, ElementId, ElementType, PathSegment}; mod code; @@ -123,16 +123,22 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> P }; let attrs = node.attributes(); if let (ElementId::Svg, true) = (id, is_start) { + if let Some(&AttributeValue::ViewBox(vbox)) = attrs.get_value(AttributeId::ViewBox) { + t.stack_scaling( + euclid::Transform2D::create_scale(1. / vbox.w, 1. / vbox.h) + .post_translate(math::vector(vbox.x, vbox.y)), + ); + } if let (Some(&AttributeValue::Length(width)), Some(&AttributeValue::Length(height))) = ( attrs.get_value(AttributeId::Width), attrs.get_value(AttributeId::Height), ) { let width_in_mm = length_to_mm(width, opts.dpi); let height_in_mm = length_to_mm(height, opts.dpi); - t.set_scaling( + t.stack_scaling( euclid::Transform2D::create_scale( - width_in_mm / width.num, - -height_in_mm / height.num, + width_in_mm, + -height_in_mm, ) .post_translate(math::vector(0.0, height_in_mm)), ); diff --git a/src/turtle.rs b/src/turtle.rs index e671329..1be7b21 100644 --- a/src/turtle.rs +++ b/src/turtle.rs @@ -328,7 +328,7 @@ impl Turtle { radians: x_axis_rotation, }, flags: ArcFlags { - large_arc: large_arc, + large_arc: !large_arc, sweep: sweep, }, }; @@ -353,12 +353,13 @@ impl Turtle { .collect() } - pub fn set_scaling(&mut self, scaling: Transform2D) { - if let Some(ref old_scaling) = self.scaling { - self.curtran = self.curtran.post_mul(&old_scaling.inverse().unwrap()); - } - self.scaling = Some(scaling); + pub fn stack_scaling(&mut self, scaling: Transform2D) { self.curtran = self.curtran.post_mul(&scaling); + if let Some(ref current_scaling) = self.scaling { + self.scaling = Some(current_scaling.post_mul(&scaling)); + } else { + self.scaling = Some(scaling); + } } pub fn push_transform(&mut self, trans: Transform2D) {