dioxuscut_paths/
transform.rs1use crate::parser::{parse_path, serialize_instructions};
4use crate::types::Instruction;
5
6pub fn translate_path(path: &str, dx: f64, dy: f64) -> String {
8 let mut instructions = match parse_path(path) {
9 Ok(insts) => insts,
10 Err(_) => return path.to_string(),
11 };
12
13 for inst in &mut instructions {
14 match inst {
15 Instruction::MoveTo { x, y } => {
16 *x += dx;
17 *y += dy;
18 }
19 Instruction::LineTo { x, y } => {
20 *x += dx;
21 *y += dy;
22 }
23 Instruction::CubicCurveTo {
24 x1,
25 y1,
26 x2,
27 y2,
28 x,
29 y,
30 } => {
31 *x1 += dx;
32 *y1 += dy;
33 *x2 += dx;
34 *y2 += dy;
35 *x += dx;
36 *y += dy;
37 }
38 Instruction::QuadCurveTo { x1, y1, x, y } => {
39 *x1 += dx;
40 *y1 += dy;
41 *x += dx;
42 *y += dy;
43 }
44 Instruction::ClosePath => {}
45 }
46 }
47
48 serialize_instructions(&instructions)
49}
50
51pub fn scale_path(path: &str, sx: f64, sy: f64) -> String {
53 let mut instructions = match parse_path(path) {
54 Ok(insts) => insts,
55 Err(_) => return path.to_string(),
56 };
57
58 for inst in &mut instructions {
59 match inst {
60 Instruction::MoveTo { x, y } => {
61 *x *= sx;
62 *y *= sy;
63 }
64 Instruction::LineTo { x, y } => {
65 *x *= sx;
66 *y *= sy;
67 }
68 Instruction::CubicCurveTo {
69 x1,
70 y1,
71 x2,
72 y2,
73 x,
74 y,
75 } => {
76 *x1 *= sx;
77 *y1 *= sy;
78 *x2 *= sx;
79 *y2 *= sy;
80 *x *= sx;
81 *y *= sy;
82 }
83 Instruction::QuadCurveTo { x1, y1, x, y } => {
84 *x1 *= sx;
85 *y1 *= sy;
86 *x *= sx;
87 *y *= sy;
88 }
89 Instruction::ClosePath => {}
90 }
91 }
92
93 serialize_instructions(&instructions)
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_translate_path() {
102 let path = "M 0 0 L 10 10 Z";
103 let res = translate_path(path, 5.0, 15.0);
104 assert_eq!(res, "M 5.0000 15.0000 L 15.0000 25.0000 Z");
105 }
106
107 #[test]
108 fn test_scale_path() {
109 let path = "M 10 20 L 30 40 Z";
110 let res = scale_path(path, 2.0, 0.5);
111 assert_eq!(res, "M 20.0000 10.0000 L 60.0000 20.0000 Z");
112 }
113}