lewp_css/domain/units/
font_relative_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::{conversions::FontRelativeLengthConversion, FontRelativeLength::*},
6    crate::{
7        domain::numbers::{CssNumber, CssNumberNewType},
8        serializers::serialize_dimension::serialize_dimension,
9    },
10    cssparser::ToCss,
11    std::{fmt, ops::*},
12};
13
14/// A font relative length.
15#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
16pub enum FontRelativeLength<Number: CssNumber> {
17    /// A "em" value: <https://drafts.csswg.org/css-values/#em>
18    em(Number),
19
20    /// A "ex" value: <https://drafts.csswg.org/css-values/#ex>
21    ex(Number),
22
23    /// A "ch" value: <https://drafts.csswg.org/css-values/#ch>
24    ch(Number),
25
26    /// A "rem" value: <https://drafts.csswg.org/css-values/#rem>
27    rem(Number),
28}
29
30impl<Number: CssNumber> ToCss for FontRelativeLength<Number> {
31    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
32        match *self {
33            em(length) => serialize_dimension(length, "em", dest),
34            ex(length) => serialize_dimension(length, "ex", dest),
35            ch(length) => serialize_dimension(length, "ch", dest),
36            rem(length) => serialize_dimension(length, "rem", dest),
37        }
38    }
39}
40
41impl<Number: CssNumber> Default for FontRelativeLength<Number> {
42    #[inline(always)]
43    fn default() -> Self {
44        FontRelativeLength::em(Number::default())
45    }
46}
47
48impl<Number: CssNumber> Add<Number> for FontRelativeLength<Number> {
49    type Output = Self;
50
51    #[inline(always)]
52    fn add(self, rhs: Number) -> Self::Output {
53        match self {
54            em(length) => em(length + rhs),
55            ex(length) => ex(length + rhs),
56            ch(length) => ch(length + rhs),
57            rem(length) => rem(length + rhs),
58        }
59    }
60}
61
62impl<Number: CssNumber> AddAssign<Number> for FontRelativeLength<Number> {
63    #[inline(always)]
64    fn add_assign(&mut self, rhs: Number) {
65        match *self {
66            em(ref mut length) => *length = *length + rhs,
67            ex(ref mut length) => *length = *length + rhs,
68            ch(ref mut length) => *length = *length + rhs,
69            rem(ref mut length) => *length = *length + rhs,
70        }
71    }
72}
73
74impl<Number: CssNumber> Sub<Number> for FontRelativeLength<Number> {
75    type Output = Self;
76
77    #[inline(always)]
78    fn sub(self, rhs: Number) -> Self::Output {
79        match self {
80            em(length) => em(length - rhs),
81            ex(length) => ex(length - rhs),
82            ch(length) => ch(length - rhs),
83            rem(length) => rem(length - rhs),
84        }
85    }
86}
87
88impl<Number: CssNumber> SubAssign<Number> for FontRelativeLength<Number> {
89    #[inline(always)]
90    fn sub_assign(&mut self, rhs: Number) {
91        match *self {
92            em(ref mut length) => *length = *length - rhs,
93            ex(ref mut length) => *length = *length - rhs,
94            ch(ref mut length) => *length = *length - rhs,
95            rem(ref mut length) => *length = *length - rhs,
96        }
97    }
98}
99
100impl<Number: CssNumber> Mul<Number> for FontRelativeLength<Number> {
101    type Output = Self;
102
103    #[inline(always)]
104    fn mul(self, rhs: Number) -> Self::Output {
105        match self {
106            em(length) => em(length * rhs),
107            ex(length) => ex(length * rhs),
108            ch(length) => ch(length * rhs),
109            rem(length) => rem(length * rhs),
110        }
111    }
112}
113
114impl<Number: CssNumber> MulAssign<Number> for FontRelativeLength<Number> {
115    #[inline(always)]
116    fn mul_assign(&mut self, rhs: Number) {
117        match *self {
118            em(ref mut length) => *length = *length * rhs,
119            ex(ref mut length) => *length = *length * rhs,
120            ch(ref mut length) => *length = *length * rhs,
121            rem(ref mut length) => *length = *length * rhs,
122        }
123    }
124}
125
126impl<Number: CssNumber> Div<Number> for FontRelativeLength<Number> {
127    type Output = Self;
128
129    #[inline(always)]
130    fn div(self, rhs: Number) -> Self::Output {
131        match self {
132            em(length) => em(length / rhs),
133            ex(length) => ex(length / rhs),
134            ch(length) => ch(length / rhs),
135            rem(length) => rem(length / rhs),
136        }
137    }
138}
139
140impl<Number: CssNumber> DivAssign<Number> for FontRelativeLength<Number> {
141    #[inline(always)]
142    fn div_assign(&mut self, rhs: Number) {
143        match *self {
144            em(ref mut length) => *length = *length / rhs,
145            ex(ref mut length) => *length = *length / rhs,
146            ch(ref mut length) => *length = *length / rhs,
147            rem(ref mut length) => *length = *length / rhs,
148        }
149    }
150}
151
152impl<Number: CssNumber> Rem<Number> for FontRelativeLength<Number> {
153    type Output = Self;
154
155    #[inline(always)]
156    fn rem(self, rhs: Number) -> Self::Output {
157        match self {
158            em(length) => em(length % rhs),
159            ex(length) => ex(length % rhs),
160            ch(length) => ch(length % rhs),
161            rem(length) => rem(length % rhs),
162        }
163    }
164}
165
166impl<Number: CssNumber> RemAssign<Number> for FontRelativeLength<Number> {
167    #[inline(always)]
168    fn rem_assign(&mut self, rhs: Number) {
169        match *self {
170            em(ref mut length) => *length = *length % rhs,
171            ex(ref mut length) => *length = *length % rhs,
172            ch(ref mut length) => *length = *length % rhs,
173            rem(ref mut length) => *length = *length % rhs,
174        }
175    }
176}
177
178impl<Number: CssNumber> Neg for FontRelativeLength<Number> {
179    type Output = Self;
180
181    #[inline(always)]
182    fn neg(self) -> Self::Output {
183        match self {
184            em(length) => em(-length),
185            ex(length) => ex(-length),
186            ch(length) => ch(-length),
187            rem(length) => rem(-length),
188        }
189    }
190}
191
192impl<Number: CssNumber> CssNumberNewType<Number>
193    for FontRelativeLength<Number>
194{
195    #[inline(always)]
196    fn to_f32(&self) -> f32 {
197        self.to_CssNumber().to_f32()
198    }
199
200    #[inline(always)]
201    fn as_CssNumber(&self) -> &Number {
202        match *self {
203            em(ref length) => length,
204            ex(ref length) => length,
205            ch(ref length) => length,
206            rem(ref length) => length,
207        }
208    }
209}
210
211impl<Number: CssNumber> FontRelativeLength<Number> {
212    /// Convert this into a pixel value.
213    #[inline(always)]
214    pub(crate) fn to_px(
215        self,
216        fontRelativeLengthConversion: &dyn FontRelativeLengthConversion<Number>,
217    ) -> Number {
218        match self {
219            em(length) => length * fontRelativeLengthConversion.em(),
220            ex(length) => length * fontRelativeLengthConversion.ex(),
221            ch(length) => length * fontRelativeLengthConversion.ch(),
222            rem(length) => length * fontRelativeLengthConversion.rem(),
223        }
224    }
225
226    /// Convert this into AppUnits.
227    #[inline]
228    pub fn to_app_units(
229        &self,
230        fontRelativeLengthConversion: &dyn FontRelativeLengthConversion<Number>,
231    ) -> Number {
232        self.to_px(fontRelativeLengthConversion) * Number::AppUnitsPerPX
233    }
234}