Add viewbox handling, fix ellipse handling for large_arc case

master
Sameer Puri 6 years ago
parent b774e63c8a
commit 7d9ba355d1

@ -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) - [ ] 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] 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 - [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

@ -10,7 +10,7 @@ use std::env;
use std::fs::File; use std::fs::File;
use std::io::{self, Read}; use std::io::{self, Read};
use lyon_geom::{math, euclid}; use lyon_geom::{euclid, math};
use svgdom::{AttributeId, AttributeValue, ElementId, ElementType, PathSegment}; use svgdom::{AttributeId, AttributeValue, ElementId, ElementType, PathSegment};
mod code; mod code;
@ -123,16 +123,22 @@ fn svg2program(doc: &svgdom::Document, opts: ProgramOptions, mach: Machine) -> P
}; };
let attrs = node.attributes(); let attrs = node.attributes();
if let (ElementId::Svg, true) = (id, is_start) { 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))) = ( if let (Some(&AttributeValue::Length(width)), Some(&AttributeValue::Length(height))) = (
attrs.get_value(AttributeId::Width), attrs.get_value(AttributeId::Width),
attrs.get_value(AttributeId::Height), attrs.get_value(AttributeId::Height),
) { ) {
let width_in_mm = length_to_mm(width, opts.dpi); let width_in_mm = length_to_mm(width, opts.dpi);
let height_in_mm = length_to_mm(height, opts.dpi); let height_in_mm = length_to_mm(height, opts.dpi);
t.set_scaling( t.stack_scaling(
euclid::Transform2D::create_scale( euclid::Transform2D::create_scale(
width_in_mm / width.num, width_in_mm,
-height_in_mm / height.num, -height_in_mm,
) )
.post_translate(math::vector(0.0, height_in_mm)), .post_translate(math::vector(0.0, height_in_mm)),
); );

@ -328,7 +328,7 @@ impl Turtle {
radians: x_axis_rotation, radians: x_axis_rotation,
}, },
flags: ArcFlags { flags: ArcFlags {
large_arc: large_arc, large_arc: !large_arc,
sweep: sweep, sweep: sweep,
}, },
}; };
@ -353,12 +353,13 @@ impl Turtle {
.collect() .collect()
} }
pub fn set_scaling(&mut self, scaling: Transform2D<f64>) { pub fn stack_scaling(&mut self, scaling: Transform2D<f64>) {
if let Some(ref old_scaling) = self.scaling {
self.curtran = self.curtran.post_mul(&old_scaling.inverse().unwrap());
}
self.scaling = Some(scaling);
self.curtran = self.curtran.post_mul(&scaling); 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<f64>) { pub fn push_transform(&mut self, trans: Transform2D<f64>) {

Loading…
Cancel
Save