qr_code_styling/figures/corner_square/
drawer.rs1use crate::figures::traits::{rotate_transform, svg_path};
4use crate::types::CornerSquareType;
5
6pub struct QRCornerSquare {
8 square_type: CornerSquareType,
9}
10
11impl QRCornerSquare {
12 pub fn new(square_type: CornerSquareType) -> Self {
14 Self { square_type }
15 }
16
17 pub fn draw(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
19 match self.square_type {
20 CornerSquareType::Square => self.draw_square(x, y, size, rotation),
21 CornerSquareType::Dot => self.draw_dot(x, y, size, rotation),
22 CornerSquareType::ExtraRounded => self.draw_extra_rounded(x, y, size, rotation),
23 }
24 }
25
26 fn basic_dot(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
28 let transform = rotate_transform(x, y, size, rotation);
29 let dot_size = size / 7.0;
30 let half_size = size / 2.0;
31 let inner_radius = half_size - dot_size;
32
33 let d = format!(
35 "M {} {} a {} {} 0 1 0 0.1 0 z m 0 {} a {} {} 0 1 1 -0.1 0 Z",
36 x + half_size,
37 y,
38 half_size,
39 half_size,
40 dot_size,
41 inner_radius,
42 inner_radius
43 );
44
45 svg_path(&d, Some("evenodd"), transform.as_deref())
46 }
47
48 fn basic_square(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
50 let transform = rotate_transform(x, y, size, rotation);
51 let dot_size = size / 7.0;
52
53 let d = format!(
55 "M {} {} v {} h {} v {} z M {} {} h {} v {} h {} z",
56 x, y,
57 size, size, -size,
58 x + dot_size, y + dot_size,
59 size - 2.0 * dot_size,
60 size - 2.0 * dot_size,
61 -(size - 2.0 * dot_size)
62 );
63
64 svg_path(&d, Some("evenodd"), transform.as_deref())
65 }
66
67 fn basic_extra_rounded(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
69 let transform = rotate_transform(x, y, size, rotation);
70 let dot_size = size / 7.0;
71
72 let outer = format!(
74 "M {} {} v {} a {} {} 0 0 0 {} {} h {} a {} {} 0 0 0 {} {} v {} a {} {} 0 0 0 {} {} h {} a {} {} 0 0 0 {} {}",
75 x, y + 2.5 * dot_size,
76 2.0 * dot_size,
77 2.5 * dot_size, 2.5 * dot_size, 2.5 * dot_size, 2.5 * dot_size,
78 2.0 * dot_size,
79 2.5 * dot_size, 2.5 * dot_size, 2.5 * dot_size, -2.5 * dot_size,
80 -2.0 * dot_size,
81 2.5 * dot_size, 2.5 * dot_size, -2.5 * dot_size, -2.5 * dot_size,
82 -2.0 * dot_size,
83 2.5 * dot_size, 2.5 * dot_size, -2.5 * dot_size, 2.5 * dot_size
84 );
85
86 let inner = format!(
88 "M {} {} h {} a {} {} 0 0 1 {} {} v {} a {} {} 0 0 1 {} {} h {} a {} {} 0 0 1 {} {} v {} a {} {} 0 0 1 {} {}",
89 x + 2.5 * dot_size, y + dot_size,
90 2.0 * dot_size,
91 1.5 * dot_size, 1.5 * dot_size, 1.5 * dot_size, 1.5 * dot_size,
92 2.0 * dot_size,
93 1.5 * dot_size, 1.5 * dot_size, -1.5 * dot_size, 1.5 * dot_size,
94 -2.0 * dot_size,
95 1.5 * dot_size, 1.5 * dot_size, -1.5 * dot_size, -1.5 * dot_size,
96 -2.0 * dot_size,
97 1.5 * dot_size, 1.5 * dot_size, 1.5 * dot_size, -1.5 * dot_size
98 );
99
100 let d = format!("{} {}", outer, inner);
101 svg_path(&d, Some("evenodd"), transform.as_deref())
102 }
103
104 fn draw_dot(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
105 self.basic_dot(x, y, size, rotation)
106 }
107
108 fn draw_square(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
109 self.basic_square(x, y, size, rotation)
110 }
111
112 fn draw_extra_rounded(&self, x: f64, y: f64, size: f64, rotation: f64) -> String {
113 self.basic_extra_rounded(x, y, size, rotation)
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_draw_square() {
123 let drawer = QRCornerSquare::new(CornerSquareType::Square);
124 let svg = drawer.draw(0.0, 0.0, 70.0, 0.0);
125 assert!(svg.contains("path"));
126 assert!(svg.contains("evenodd"));
127 }
128
129 #[test]
130 fn test_draw_dot() {
131 let drawer = QRCornerSquare::new(CornerSquareType::Dot);
132 let svg = drawer.draw(0.0, 0.0, 70.0, 0.0);
133 assert!(svg.contains("path"));
134 assert!(svg.contains("evenodd"));
135 }
136
137 #[test]
138 fn test_draw_extra_rounded() {
139 let drawer = QRCornerSquare::new(CornerSquareType::ExtraRounded);
140 let svg = drawer.draw(0.0, 0.0, 70.0, 0.0);
141 assert!(svg.contains("path"));
142 }
143}