svgcleaner/task/paths/
apply_transform.rs1use svgdom::{
20 Transform,
21 FuzzyEq,
22};
23use svgdom::path::{
24 Path,
25 SegmentData,
26};
27
28pub fn apply_transform(path: &mut Path, ts: &Transform) {
29 let (sx, sy) = ts.get_scale();
30
31 debug_assert!(sx.fuzzy_eq(&sy));
33
34 for seg in &mut path.d {
35 match *seg.data_mut() {
36 SegmentData::MoveTo { ref mut x, ref mut y }
37 | SegmentData::LineTo { ref mut x, ref mut y }
38 | SegmentData::SmoothQuadratic { ref mut x, ref mut y } => {
39 ts.apply_ref(x, y);
40 }
41
42 SegmentData::HorizontalLineTo { ref mut x } => {
43 ts.apply_ref(x, &mut 0.0);
44 }
45
46 SegmentData::VerticalLineTo { ref mut y } => {
47 ts.apply_ref(&mut 0.0, y);
48 }
49
50 SegmentData::CurveTo { ref mut x1, ref mut y1, ref mut x2, ref mut y2,
51 ref mut x, ref mut y } => {
52 ts.apply_ref(x1, y1);
53 ts.apply_ref(x2, y2);
54 ts.apply_ref(x, y);
55 }
56
57 SegmentData::SmoothCurveTo { ref mut x2, ref mut y2, ref mut x, ref mut y } => {
58 ts.apply_ref(x2, y2);
59 ts.apply_ref(x, y);
60 }
61
62 SegmentData::Quadratic { ref mut x1, ref mut y1, ref mut x, ref mut y } => {
63 ts.apply_ref(x1, y1);
64 ts.apply_ref(x, y);
65 }
66
67 SegmentData::EllipticalArc { ref mut rx, ref mut ry, ref mut x, ref mut y, .. } => {
68 *rx *= sx;
69 *ry *= sx;
70
71 ts.apply_ref(x, y);
72 }
73
74 SegmentData::ClosePath => {}
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use std::str::FromStr;
82
83 use super::*;
84 use svgdom::path::Path;
85 use svgdom::Transform;
86
87 macro_rules! test {
88 ($name:ident, $in_path:expr, $in_ts:expr, $out_text:expr) => (
89 #[test]
90 fn $name() {
91 let mut path = Path::from_str($in_path).unwrap();
92 path.conv_to_absolute();
93
94 let ts = Transform::from_str($in_ts).unwrap();
95
96 apply_transform(&mut path, &ts);
97 assert_eq_text!(path.to_string(), $out_text);
98 }
99 )
100 }
101
102 test!(apply_1, "M 10 20 L 30 40", "translate(10 20)",
103 "M 20 40 L 40 60");
104}