Skip to main content

style/values/generics/
text.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Generic types for text properties.
6
7use crate::derives::*;
8use crate::Zero;
9use std::fmt::{self, Write};
10use style_traits::{CssWriter, ToCss};
11
12/// A generic value that is either a number or `auto`.
13#[derive(
14    Animate,
15    Clone,
16    ComputeSquaredDistance,
17    Copy,
18    Debug,
19    MallocSizeOf,
20    Parse,
21    PartialEq,
22    SpecifiedValueInfo,
23    ToAnimatedValue,
24    ToAnimatedZero,
25    ToComputedValue,
26    ToCss,
27    ToResolvedValue,
28    ToShmem,
29)]
30#[repr(C, u8)]
31pub enum NumberOrAuto<N> {
32    /// `auto`
33    Auto,
34    /// `<number>`
35    Number(N),
36}
37
38/// A generic value for the `hyphenate-limit-chars` property.
39#[derive(
40    Animate,
41    Clone,
42    ComputeSquaredDistance,
43    Debug,
44    MallocSizeOf,
45    PartialEq,
46    SpecifiedValueInfo,
47    ToAnimatedValue,
48    ToAnimatedZero,
49    ToComputedValue,
50    ToResolvedValue,
51    ToShmem,
52    ToTyped,
53)]
54#[repr(C)]
55#[typed(todo_derive_fields)]
56pub struct GenericHyphenateLimitChars<Integer> {
57    /// Required minimum number of characters in a hyphenated word.
58    pub total_word_length: NumberOrAuto<Integer>,
59    /// Required minumum number of characters before the hyphen.
60    pub pre_hyphen_length: NumberOrAuto<Integer>,
61    /// Required minumum number of characters after the hyphen.
62    pub post_hyphen_length: NumberOrAuto<Integer>,
63}
64
65impl<Integer: ToCss + PartialEq> ToCss for GenericHyphenateLimitChars<Integer> {
66    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
67    where
68        W: Write,
69    {
70        self.total_word_length.to_css(dest)?;
71
72        if self.pre_hyphen_length != NumberOrAuto::Auto
73            || self.post_hyphen_length != self.pre_hyphen_length
74        {
75            dest.write_char(' ')?;
76            self.pre_hyphen_length.to_css(dest)?;
77            if self.post_hyphen_length != self.pre_hyphen_length {
78                dest.write_char(' ')?;
79                self.post_hyphen_length.to_css(dest)?;
80            }
81        }
82
83        Ok(())
84    }
85}
86
87/// A generic value for the `initial-letter` property.
88#[derive(
89    Clone,
90    Copy,
91    Debug,
92    MallocSizeOf,
93    PartialEq,
94    SpecifiedValueInfo,
95    ToComputedValue,
96    ToResolvedValue,
97    ToShmem,
98    ToTyped,
99)]
100#[repr(C)]
101pub struct GenericInitialLetter<Number, Integer> {
102    /// The size, >=1, or 0 if `normal`.
103    pub size: Number,
104    /// The sink, >=1, if specified, 0 otherwise.
105    pub sink: Integer,
106}
107
108pub use self::GenericInitialLetter as InitialLetter;
109impl<N: Zero, I: Zero> InitialLetter<N, I> {
110    /// Returns `normal`.
111    #[inline]
112    pub fn normal() -> Self {
113        InitialLetter {
114            size: N::zero(),
115            sink: I::zero(),
116        }
117    }
118}
119
120impl<N: ToCss + Zero, I: ToCss + Zero> ToCss for InitialLetter<N, I> {
121    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
122    where
123        W: Write,
124    {
125        if self.size.is_zero() {
126            return dest.write_str("normal");
127        }
128        self.size.to_css(dest)?;
129        if !self.sink.is_zero() {
130            dest.write_char(' ')?;
131            self.sink.to_css(dest)?;
132        }
133        Ok(())
134    }
135}
136
137/// Implements type for text-decoration-thickness
138/// which takes the grammar of auto | from-font | <length> | <percentage>
139///
140/// https://drafts.csswg.org/css-text-decor-4/
141#[repr(C, u8)]
142#[derive(
143    Animate,
144    Clone,
145    Copy,
146    ComputeSquaredDistance,
147    Debug,
148    Deserialize,
149    Eq,
150    MallocSizeOf,
151    Parse,
152    PartialEq,
153    Serialize,
154    SpecifiedValueInfo,
155    ToAnimatedValue,
156    ToAnimatedZero,
157    ToComputedValue,
158    ToCss,
159    ToResolvedValue,
160    ToShmem,
161    ToTyped,
162)]
163#[allow(missing_docs)]
164pub enum GenericTextDecorationLength<L> {
165    LengthPercentage(L),
166    Auto,
167    FromFont,
168}
169
170/// Text decoration inset values.
171///
172/// https://drafts.csswg.org/css-text-decor-4/#text-decoration-skip-inset-property
173#[repr(C, u8)]
174#[derive(
175    Clone,
176    Debug,
177    Eq,
178    MallocSizeOf,
179    PartialEq,
180    SpecifiedValueInfo,
181    ToComputedValue,
182    ToResolvedValue,
183    ToShmem,
184    ToTyped,
185)]
186pub enum GenericTextDecorationInset<LP> {
187    /// `auto` value
188    Auto,
189    /// Start and end length values.
190    #[allow(missing_docs)]
191    LengthPercentage { start: LP, end: LP },
192}
193
194impl<L: Zero> GenericTextDecorationInset<L> {
195    /// Gets the initial value (zero)
196    #[inline]
197    pub fn get_initial_value() -> Self {
198        GenericTextDecorationInset::LengthPercentage {
199            start: L::zero(),
200            end: L::zero(),
201        }
202    }
203}
204
205impl<L: ToCss + PartialEq> ToCss for GenericTextDecorationInset<L> {
206    fn to_css<W>(&self, dst: &mut CssWriter<W>) -> fmt::Result
207    where
208        W: Write,
209    {
210        match self {
211            GenericTextDecorationInset::Auto => dst.write_str("auto"),
212            GenericTextDecorationInset::LengthPercentage { start, end } => {
213                start.to_css(dst)?;
214                if start != end {
215                    dst.write_char(' ')?;
216                    end.to_css(dst)?;
217                }
218                Ok(())
219            },
220        }
221    }
222}
223
224/// Implements type for text-indent
225/// which takes the grammar of [<length-percentage>] && hanging? && each-line?
226///
227/// https://drafts.csswg.org/css-text/#propdef-text-indent
228#[repr(C)]
229#[derive(
230    Animate,
231    Clone,
232    ComputeSquaredDistance,
233    Debug,
234    Eq,
235    MallocSizeOf,
236    PartialEq,
237    SpecifiedValueInfo,
238    ToAnimatedValue,
239    ToAnimatedZero,
240    ToComputedValue,
241    ToCss,
242    ToResolvedValue,
243    ToShmem,
244    ToTyped,
245)]
246pub struct GenericTextIndent<LengthPercentage> {
247    /// The amount of indent to be applied to the inline-start of the first line.
248    pub length: LengthPercentage,
249    /// Apply indent to non-first lines instead of first.
250    #[animation(constant)]
251    #[css(represents_keyword)]
252    pub hanging: bool,
253    /// Apply to each line after a hard break, not only first in block.
254    #[animation(constant)]
255    #[css(represents_keyword)]
256    pub each_line: bool,
257}
258
259impl<LengthPercentage: Zero> GenericTextIndent<LengthPercentage> {
260    /// Return the initial zero value.
261    pub fn zero() -> Self {
262        Self {
263            length: LengthPercentage::zero(),
264            hanging: false,
265            each_line: false,
266        }
267    }
268}