swc_css_minifier/compressor/
length.rs1use swc_atoms::atom;
2use swc_css_ast::*;
3
4use super::Compressor;
5
6impl Compressor {
7 fn convert_length(&mut self, value: f64, from_unit: &str, to_unit: &str) -> f64 {
8 match to_unit {
9 "cm" => match from_unit {
10 "cm" => value,
11 "mm" => value / 10.0,
12 "q" => value / 40.0,
13 "in" => 2.54 * value,
14 "pc" => 2.54 / 6.0 * value,
15 "pt" => 2.54 / 72.0 * value,
16 "px" => 2.54 / 96.0 * value,
17 _ => {
18 unreachable!()
19 }
20 },
21 "mm" => match from_unit {
22 "cm" => 10.0 * value,
23 "mm" => value,
24 "q" => value / 4.0,
25 "in" => 25.4 * value,
26 "pc" => 25.4 / 6.0 * value,
27 "pt" => 25.4 / 72.0 * value,
28 "px" => 25.4 / 96.0 * value,
29 _ => {
30 unreachable!()
31 }
32 },
33 "q" => match from_unit {
34 "cm" => 40.0 * value,
35 "mm" => 4.0 * value,
36 "q" => value,
37 "in" => 101.6 * value,
38 "pc" => 101.6 / 6.0 * value,
39 "pt" => 101.6 / 72.0 * value,
40 "px" => 101.6 / 96.0 * value,
41 _ => {
42 unreachable!()
43 }
44 },
45 "in" => match from_unit {
46 "cm" => value / 2.54,
47 "mm" => value / 25.4,
48 "q" => value / 101.6,
49 "in" => value,
50 "pc" => value / 6.0,
51 "pt" => value / 72.0,
52 "px" => value / 96.0,
53 _ => {
54 unreachable!()
55 }
56 },
57 "pc" => match from_unit {
58 "cm" => 6.0 / 2.54 * value,
59 "mm" => 6.0 / 25.4 * value,
60 "q" => 6.0 / 101.6 * value,
61 "in" => 6.0 * value,
62 "pc" => value,
63 "pt" => 6.0 / 72.0 * value,
64 "px" => 6.0 / 96.0 * value,
65 _ => {
66 unreachable!()
67 }
68 },
69 "pt" => match from_unit {
70 "cm" => 72.0 / 2.54 * value,
71 "mm" => 72.0 / 25.4 * value,
72 "q" => 72.0 / 101.6 * value,
73 "in" => 72.0 * value,
74 "pc" => 12.0 * value,
75 "pt" => value,
76 "px" => 0.75 * value,
77 _ => {
78 unreachable!()
79 }
80 },
81 "px" => match from_unit {
82 "cm" => 96.0 / 2.54 * value,
83 "mm" => 96.0 / 25.4 * value,
84 "q" => 96.0 / 101.6 * value,
85 "in" => 96.0 * value,
86 "pc" => 16.0 * value,
87 "pt" => 96.0 / 72.0 * value,
88 "px" => value,
89 _ => {
90 unreachable!()
91 }
92 },
93 _ => {
94 unreachable!()
95 }
96 }
97 }
98}
99
100impl Compressor {
101 pub(super) fn length_to_zero(&mut self, n: &mut Length) -> Option<Number> {
102 match &n {
103 Length {
104 value:
105 Number {
106 value: number_value,
107 ..
108 },
109 span,
110 ..
111 } if *number_value == 0.0 => Some(Number {
112 span: *span,
113 value: 0.0,
114 raw: None,
115 }),
116 _ => None,
117 }
118 }
119
120 pub(super) fn compress_component_value_for_length(&mut self, n: &mut ComponentValue) {
121 if self.ctx.in_math_function {
122 return;
123 }
124
125 let length = match n {
126 ComponentValue::Dimension(dimension) => dimension.as_mut_length(),
127 ComponentValue::LengthPercentage(length_percentage) => {
128 length_percentage.as_mut_length()
129 }
130 _ => None,
131 };
132
133 let Some(number) = length.and_then(|length| self.length_to_zero(length)) else {
134 return;
135 };
136
137 *n = ComponentValue::Number(Box::new(number));
138 }
139
140 pub(super) fn compress_length(&mut self, length: &mut Length) {
141 let value = length.value.value;
142
143 match &*length.unit.value {
144 "cm" => {
145 if value % 2.54 == 0.0 {
146 let new_value = self.convert_length(value, &length.unit.value, "in");
147
148 length.value = Number {
149 span: length.value.span,
150 value: new_value,
151 raw: None,
152 };
153 length.unit = Ident {
154 span: length.unit.span,
155 value: atom!("in"),
156 raw: None,
157 };
158 } else if value <= 0.1 {
159 let new_value = self.convert_length(value, &length.unit.value, "mm");
160
161 length.value = Number {
162 span: length.value.span,
163 value: new_value,
164 raw: None,
165 };
166 length.unit = Ident {
167 span: length.unit.span,
168 value: atom!("mm"),
169 raw: None,
170 };
171 }
172 }
173 "mm" => {
174 if value % 25.4 == 0.0 {
175 let new_value = self.convert_length(value, &length.unit.value, "in");
176
177 length.value = Number {
178 span: length.value.span,
179 value: new_value,
180 raw: None,
181 };
182 length.unit = Ident {
183 span: length.unit.span,
184 value: atom!("in"),
185 raw: None,
186 };
187 } else if value % 10.0 == 0.0 {
188 let new_value = self.convert_length(value, &length.unit.value, "cm");
189
190 length.value = Number {
191 span: length.value.span,
192 value: new_value,
193 raw: None,
194 };
195 length.unit = Ident {
196 span: length.unit.span,
197 value: atom!("cm"),
198 raw: None,
199 };
200 }
201 }
202 "q" => {
203 if value > 80.0 && value % 40.0 == 0.0 {
204 let new_value = self.convert_length(value, &length.unit.value, "cm");
205
206 length.value = Number {
207 span: length.value.span,
208 value: new_value,
209 raw: None,
210 };
211 length.unit = Ident {
212 span: length.unit.span,
213 value: atom!("cm"),
214 raw: None,
215 };
216 } else if value % 101.6 == 0.0 {
217 let new_value = self.convert_length(value, &length.unit.value, "in");
218
219 length.value = Number {
220 span: length.value.span,
221 value: new_value,
222 raw: None,
223 };
224 length.unit = Ident {
225 span: length.unit.span,
226 value: atom!("in"),
227 raw: None,
228 };
229 }
230 }
231 "pc" => {
232 if value % 6.0 == 0.0 {
233 let new_value = self.convert_length(value, &length.unit.value, "in");
234
235 length.value = Number {
236 span: length.value.span,
237 value: new_value,
238 raw: None,
239 };
240 length.unit = Ident {
241 span: length.unit.span,
242 value: atom!("in"),
243 raw: None,
244 };
245 }
246 }
247 "pt" => {
248 if value % 72.0 == 0.0 {
249 let new_value = self.convert_length(value, &length.unit.value, "in");
250
251 length.value = Number {
252 span: length.value.span,
253 value: new_value,
254 raw: None,
255 };
256 length.unit = Ident {
257 span: length.unit.span,
258 value: atom!("in"),
259 raw: None,
260 };
261 } else if value % 12.0 == 0.0 {
262 let new_value = self.convert_length(value, &length.unit.value, "pc");
263
264 length.value = Number {
265 span: length.value.span,
266 value: new_value,
267 raw: None,
268 };
269 length.unit = Ident {
270 span: length.unit.span,
271 value: atom!("pc"),
272 raw: None,
273 };
274 } else if value % 0.75 == 0.0 {
275 let new_value = self.convert_length(value, &length.unit.value, "px");
276
277 length.value = Number {
278 span: length.value.span,
279 value: new_value,
280 raw: None,
281 };
282 length.unit = Ident {
283 span: length.unit.span,
284 value: atom!("px"),
285 raw: None,
286 };
287 }
288 }
289 _ => {}
290 }
291 }
292}