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

@ -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)),
);

@ -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<f64>) {
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<f64>) {
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>) {

Loading…
Cancel
Save