lewp_css/domain/units/
absolute_length.rs

1// This file is part of css. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/css/master/COPYRIGHT. No part of predicator, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
2// Copyright © 2017 The developers of css. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/css/master/COPYRIGHT.
3
4use {
5    super::AbsoluteLength::*,
6    crate::{
7        domain::numbers::{CssNumber, CssNumberNewType},
8        serializers::serialize_dimension::serialize_dimension,
9    },
10    cssparser::ToCss,
11    std::{fmt, ops::*},
12};
13
14/// Represents an absolute length with its unit
15#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
16pub enum AbsoluteLength<Number: CssNumber> {
17    /// An absolute length in pixels (px)
18    px(Number),
19
20    /// An absolute length in inches (in)
21    in_(Number),
22
23    /// An absolute length in centimeters (cm)
24    cm(Number),
25
26    /// An absolute length in millimeters (mm)
27    mm(Number),
28
29    /// An absolute length in quarter-millimeters (q)
30    q(Number),
31
32    /// An absolute length in points (pt)
33    pt(Number),
34
35    /// An absolute length in pica (pc)
36    pc(Number),
37}
38
39impl<Number: CssNumber> ToCss for AbsoluteLength<Number> {
40    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
41        match *self {
42            px(length) => serialize_dimension(length, "px", dest),
43            in_(length) => serialize_dimension(length, "in", dest),
44            cm(length) => serialize_dimension(length, "cm", dest),
45            mm(length) => serialize_dimension(length, "mm", dest),
46            q(length) => serialize_dimension(length, "q", dest),
47            pt(length) => serialize_dimension(length, "pt", dest),
48            pc(length) => serialize_dimension(length, "pc", dest),
49        }
50    }
51}
52
53impl<Number: CssNumber> Default for AbsoluteLength<Number> {
54    #[inline(always)]
55    fn default() -> Self {
56        AbsoluteLength::px(Number::default())
57    }
58}
59
60impl<Number: CssNumber> Add<Number> for AbsoluteLength<Number> {
61    type Output = AbsoluteLength<Number>;
62
63    #[inline(always)]
64    fn add(self, rhs: Number) -> Self::Output {
65        match self {
66            px(length) => px(length + rhs),
67            in_(length) => in_(length + rhs),
68            cm(length) => cm(length + rhs),
69            mm(length) => mm(length + rhs),
70            q(length) => q(length + rhs),
71            pt(length) => pt(length + rhs),
72            pc(length) => pc(length + rhs),
73        }
74    }
75}
76
77impl<Number: CssNumber> AddAssign<Number> for AbsoluteLength<Number> {
78    #[inline(always)]
79    fn add_assign(&mut self, rhs: Number) {
80        match *self {
81            px(ref mut length) => *length = *length + rhs,
82            in_(ref mut length) => *length = *length + rhs,
83            cm(ref mut length) => *length = *length + rhs,
84            mm(ref mut length) => *length = *length + rhs,
85            q(ref mut length) => *length = *length + rhs,
86            pt(ref mut length) => *length = *length + rhs,
87            pc(ref mut length) => *length = *length + rhs,
88        }
89    }
90}
91
92impl<Number: CssNumber> Sub<Number> for AbsoluteLength<Number> {
93    type Output = AbsoluteLength<Number>;
94
95    #[inline(always)]
96    fn sub(self, rhs: Number) -> Self::Output {
97        match self {
98            px(length) => px(length - rhs),
99            in_(length) => in_(length - rhs),
100            cm(length) => cm(length - rhs),
101            mm(length) => mm(length - rhs),
102            q(length) => q(length - rhs),
103            pt(length) => pt(length - rhs),
104            pc(length) => pc(length - rhs),
105        }
106    }
107}
108
109impl<Number: CssNumber> SubAssign<Number> for AbsoluteLength<Number> {
110    #[inline(always)]
111    fn sub_assign(&mut self, rhs: Number) {
112        match *self {
113            px(ref mut length) => *length = *length - rhs,
114            in_(ref mut length) => *length = *length - rhs,
115            cm(ref mut length) => *length = *length - rhs,
116            mm(ref mut length) => *length = *length - rhs,
117            q(ref mut length) => *length = *length - rhs,
118            pt(ref mut length) => *length = *length - rhs,
119            pc(ref mut length) => *length = *length - rhs,
120        }
121    }
122}
123
124impl<Number: CssNumber> Mul<Number> for AbsoluteLength<Number> {
125    type Output = AbsoluteLength<Number>;
126
127    #[inline(always)]
128    fn mul(self, rhs: Number) -> Self::Output {
129        match self {
130            px(length) => px(length * rhs),
131            in_(length) => in_(length * rhs),
132            cm(length) => cm(length * rhs),
133            mm(length) => mm(length * rhs),
134            q(length) => q(length * rhs),
135            pt(length) => pt(length * rhs),
136            pc(length) => pc(length * rhs),
137        }
138    }
139}
140
141impl<Number: CssNumber> MulAssign<Number> for AbsoluteLength<Number> {
142    #[inline(always)]
143    fn mul_assign(&mut self, rhs: Number) {
144        match *self {
145            px(ref mut length) => *length = *length * rhs,
146            in_(ref mut length) => *length = *length * rhs,
147            cm(ref mut length) => *length = *length * rhs,
148            mm(ref mut length) => *length = *length * rhs,
149            q(ref mut length) => *length = *length * rhs,
150            pt(ref mut length) => *length = *length * rhs,
151            pc(ref mut length) => *length = *length * rhs,
152        }
153    }
154}
155
156impl<Number: CssNumber> Div<Number> for AbsoluteLength<Number> {
157    type Output = AbsoluteLength<Number>;
158
159    #[inline(always)]
160    fn div(self, rhs: Number) -> Self::Output {
161        match self {
162            px(length) => px(length / rhs),
163            in_(length) => in_(length / rhs),
164            cm(length) => cm(length / rhs),
165            mm(length) => mm(length / rhs),
166            q(length) => q(length / rhs),
167            pt(length) => pt(length / rhs),
168            pc(length) => pc(length / rhs),
169        }
170    }
171}
172
173impl<Number: CssNumber> DivAssign<Number> for AbsoluteLength<Number> {
174    #[inline(always)]
175    fn div_assign(&mut self, rhs: Number) {
176        match *self {
177            px(ref mut length) => *length = *length / rhs,
178            in_(ref mut length) => *length = *length / rhs,
179            cm(ref mut length) => *length = *length / rhs,
180            mm(ref mut length) => *length = *length / rhs,
181            q(ref mut length) => *length = *length / rhs,
182            pt(ref mut length) => *length = *length / rhs,
183            pc(ref mut length) => *length = *length / rhs,
184        }
185    }
186}
187
188impl<Number: CssNumber> Rem<Number> for AbsoluteLength<Number> {
189    type Output = AbsoluteLength<Number>;
190
191    #[inline(always)]
192    fn rem(self, rhs: Number) -> Self::Output {
193        match self {
194            px(length) => px(length % rhs),
195            in_(length) => in_(length % rhs),
196            cm(length) => cm(length % rhs),
197            mm(length) => mm(length % rhs),
198            q(length) => q(length % rhs),
199            pt(length) => pt(length % rhs),
200            pc(length) => pc(length % rhs),
201        }
202    }
203}
204
205impl<Number: CssNumber> RemAssign<Number> for AbsoluteLength<Number> {
206    #[inline(always)]
207    fn rem_assign(&mut self, rhs: Number) {
208        match *self {
209            px(ref mut length) => *length = *length % rhs,
210            in_(ref mut length) => *length = *length % rhs,
211            cm(ref mut length) => *length = *length % rhs,
212            mm(ref mut length) => *length = *length % rhs,
213            q(ref mut length) => *length = *length % rhs,
214            pt(ref mut length) => *length = *length % rhs,
215            pc(ref mut length) => *length = *length % rhs,
216        }
217    }
218}
219
220impl<Number: CssNumber> Neg for AbsoluteLength<Number> {
221    type Output = AbsoluteLength<Number>;
222
223    #[inline(always)]
224    fn neg(self) -> Self::Output {
225        match self {
226            px(length) => px(-length),
227            in_(length) => in_(-length),
228            cm(length) => cm(-length),
229            mm(length) => mm(-length),
230            q(length) => q(-length),
231            pt(length) => pt(-length),
232            pc(length) => pc(-length),
233        }
234    }
235}
236
237impl<Number: CssNumber> CssNumberNewType<Number> for AbsoluteLength<Number> {
238    #[inline(always)]
239    fn to_f32(&self) -> f32 {
240        self.to_CssNumber().to_f32()
241    }
242
243    #[inline(always)]
244    fn as_CssNumber(&self) -> &Number {
245        match *self {
246            px(ref length) => length,
247            in_(ref length) => length,
248            cm(ref length) => length,
249            mm(ref length) => length,
250            q(ref length) => length,
251            pt(ref length) => length,
252            pc(ref length) => length,
253        }
254    }
255}
256
257impl<Number: CssNumber> AbsoluteLength<Number> {
258    /// Convert this into a pixel value.
259    #[inline]
260    pub fn to_px(&self) -> Number {
261        match *self {
262            px(value) => value,
263            in_(value) => {
264                value * (Number::AppUnitsPerIN / Number::AppUnitsPerPX)
265            }
266            cm(value) => {
267                value * (Number::AppUnitsPerCM / Number::AppUnitsPerPX)
268            }
269            mm(value) => {
270                value * (Number::AppUnitsPerMM / Number::AppUnitsPerPX)
271            }
272            q(value) => value * (Number::AppUnitsPerQ / Number::AppUnitsPerPX),
273            pt(value) => {
274                value * (Number::AppUnitsPerPT / Number::AppUnitsPerPX)
275            }
276            pc(value) => {
277                value * (Number::AppUnitsPerPC / Number::AppUnitsPerPX)
278            }
279        }
280    }
281
282    /// Convert this into AppUnits.
283    #[inline]
284    pub fn to_app_units(&self) -> Number {
285        match *self {
286            px(value) => value * Number::AppUnitsPerPX,
287            in_(value) => value * Number::AppUnitsPerIN,
288            cm(value) => value * Number::AppUnitsPerCM,
289            mm(value) => value * Number::AppUnitsPerMM,
290            q(value) => value * Number::AppUnitsPerQ,
291            pt(value) => value * Number::AppUnitsPerPT,
292            pc(value) => value * Number::AppUnitsPerPC,
293        }
294    }
295}