1use crate::Zero;
8use std::fmt::{self, Write};
9use style_traits::{CssWriter, ToCss};
10
11#[derive(
13 Animate,
14 Clone,
15 ComputeSquaredDistance,
16 Copy,
17 Debug,
18 MallocSizeOf,
19 Parse,
20 PartialEq,
21 SpecifiedValueInfo,
22 ToAnimatedValue,
23 ToAnimatedZero,
24 ToComputedValue,
25 ToCss,
26 ToResolvedValue,
27 ToShmem,
28)]
29#[repr(C, u8)]
30pub enum NumberOrAuto<N> {
31 Auto,
33 Number(N),
35}
36
37#[derive(
39 Animate,
40 Clone,
41 ComputeSquaredDistance,
42 Debug,
43 MallocSizeOf,
44 PartialEq,
45 SpecifiedValueInfo,
46 ToAnimatedValue,
47 ToAnimatedZero,
48 ToComputedValue,
49 ToResolvedValue,
50 ToShmem,
51)]
52#[repr(C)]
53pub struct GenericHyphenateLimitChars<Integer> {
54 pub total_word_length: NumberOrAuto<Integer>,
56 pub pre_hyphen_length: NumberOrAuto<Integer>,
58 pub post_hyphen_length: NumberOrAuto<Integer>,
60}
61
62impl<Integer: ToCss + PartialEq> ToCss for GenericHyphenateLimitChars<Integer> {
63 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
64 where
65 W: Write,
66 {
67 self.total_word_length.to_css(dest)?;
68
69 if self.pre_hyphen_length != NumberOrAuto::Auto
70 || self.post_hyphen_length != self.pre_hyphen_length
71 {
72 dest.write_char(' ')?;
73 self.pre_hyphen_length.to_css(dest)?;
74 if self.post_hyphen_length != self.pre_hyphen_length {
75 dest.write_char(' ')?;
76 self.post_hyphen_length.to_css(dest)?;
77 }
78 }
79
80 Ok(())
81 }
82}
83
84#[derive(
86 Clone,
87 Copy,
88 Debug,
89 MallocSizeOf,
90 PartialEq,
91 SpecifiedValueInfo,
92 ToComputedValue,
93 ToResolvedValue,
94 ToShmem,
95)]
96#[repr(C)]
97pub struct GenericInitialLetter<Number, Integer> {
98 pub size: Number,
100 pub sink: Integer,
102}
103
104pub use self::GenericInitialLetter as InitialLetter;
105impl<N: Zero, I: Zero> InitialLetter<N, I> {
106 #[inline]
108 pub fn normal() -> Self {
109 InitialLetter {
110 size: N::zero(),
111 sink: I::zero(),
112 }
113 }
114}
115
116impl<N: ToCss + Zero, I: ToCss + Zero> ToCss for InitialLetter<N, I> {
117 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
118 where
119 W: Write,
120 {
121 if self.size.is_zero() {
122 return dest.write_str("normal");
123 }
124 self.size.to_css(dest)?;
125 if !self.sink.is_zero() {
126 dest.write_char(' ')?;
127 self.sink.to_css(dest)?;
128 }
129 Ok(())
130 }
131}
132
133#[repr(C, u8)]
138#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
139#[derive(
140 Animate,
141 Clone,
142 Copy,
143 ComputeSquaredDistance,
144 Debug,
145 Eq,
146 MallocSizeOf,
147 Parse,
148 PartialEq,
149 SpecifiedValueInfo,
150 ToAnimatedValue,
151 ToAnimatedZero,
152 ToComputedValue,
153 ToCss,
154 ToResolvedValue,
155 ToShmem,
156)]
157#[allow(missing_docs)]
158pub enum GenericTextDecorationLength<L> {
159 LengthPercentage(L),
160 Auto,
161 FromFont,
162}
163
164#[repr(C, u8)]
168#[derive(
169 Animate,
170 Clone,
171 ComputeSquaredDistance,
172 Debug,
173 Eq,
174 MallocSizeOf,
175 PartialEq,
176 SpecifiedValueInfo,
177 ToAnimatedValue,
178 ToAnimatedZero,
179 ToComputedValue,
180 ToResolvedValue,
181 ToShmem,
182)]
183pub enum GenericTextDecorationTrim<L> {
184 Auto,
186 #[allow(missing_docs)]
188 Length { start: L, end: L },
189}
190
191impl<L: Zero> GenericTextDecorationTrim<L> {
192 #[inline]
194 pub fn get_initial_value() -> Self {
195 GenericTextDecorationTrim::Length {
196 start: L::zero(),
197 end: L::zero(),
198 }
199 }
200}
201
202impl<L: ToCss + PartialEq> ToCss for GenericTextDecorationTrim<L> {
203 fn to_css<W>(&self, dst: &mut CssWriter<W>) -> fmt::Result
204 where
205 W: Write,
206 {
207 match self {
208 GenericTextDecorationTrim::Auto => dst.write_str("auto"),
209 GenericTextDecorationTrim::Length { start, end } => {
210 start.to_css(dst)?;
211 if start != end {
212 dst.write_char(' ')?;
213 end.to_css(dst)?;
214 }
215 Ok(())
216 },
217 }
218 }
219}
220
221#[repr(C)]
226#[derive(
227 Animate,
228 Clone,
229 ComputeSquaredDistance,
230 Debug,
231 Eq,
232 MallocSizeOf,
233 PartialEq,
234 SpecifiedValueInfo,
235 ToAnimatedValue,
236 ToAnimatedZero,
237 ToComputedValue,
238 ToCss,
239 ToResolvedValue,
240 ToShmem,
241)]
242pub struct GenericTextIndent<LengthPercentage> {
243 pub length: LengthPercentage,
245 #[animation(constant)]
247 #[css(represents_keyword)]
248 pub hanging: bool,
249 #[animation(constant)]
251 #[css(represents_keyword)]
252 pub each_line: bool,
253}
254
255impl<LengthPercentage: Zero> GenericTextIndent<LengthPercentage> {
256 pub fn zero() -> Self {
258 Self {
259 length: LengthPercentage::zero(),
260 hanging: false,
261 each_line: false,
262 }
263 }
264}