1use {
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#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
16pub enum FontRelativeLength<Number: CssNumber> {
17 em(Number),
19
20 ex(Number),
22
23 ch(Number),
25
26 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 #[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 #[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}