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::Zero;
8use std::fmt::{self, Write};
9use style_traits::{CssWriter, ToCss};
10
11/// A generic value that is either a number or `auto`.
12#[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`
32    Auto,
33    /// `<number>`
34    Number(N),
35}
36
37/// A generic value for the `hyphenate-limit-chars` property.
38#[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    /// Required minimum number of characters in a hyphenated word.
55    pub total_word_length: NumberOrAuto<Integer>,
56    /// Required minumum number of characters before the hyphen.
57    pub pre_hyphen_length: NumberOrAuto<Integer>,
58    /// Required minumum number of characters after the hyphen.
59    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            dest.write_char(' ')?;
72            self.pre_hyphen_length.to_css(dest)?;
73            if self.post_hyphen_length != self.pre_hyphen_length {
74                dest.write_char(' ')?;
75                self.post_hyphen_length.to_css(dest)?;
76            }
77        }
78
79        Ok(())
80    }
81}
82
83/// A generic value for the `initial-letter` property.
84#[derive(
85    Clone,
86    Copy,
87    Debug,
88    MallocSizeOf,
89    PartialEq,
90    SpecifiedValueInfo,
91    ToComputedValue,
92    ToResolvedValue,
93    ToShmem,
94)]
95#[repr(C)]
96pub struct GenericInitialLetter<Number, Integer> {
97    /// The size, >=1, or 0 if `normal`.
98    pub size: Number,
99    /// The sink, >=1, if specified, 0 otherwise.
100    pub sink: Integer,
101}
102
103pub use self::GenericInitialLetter as InitialLetter;
104impl<N: Zero, I: Zero> InitialLetter<N, I> {
105    /// Returns `normal`.
106    #[inline]
107    pub fn normal() -> Self {
108        InitialLetter {
109            size: N::zero(),
110            sink: I::zero(),
111        }
112    }
113}
114
115impl<N: ToCss + Zero, I: ToCss + Zero> ToCss for InitialLetter<N, I> {
116    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
117    where
118        W: Write,
119    {
120        if self.size.is_zero() {
121            return dest.write_str("normal");
122        }
123        self.size.to_css(dest)?;
124        if !self.sink.is_zero() {
125            dest.write_char(' ')?;
126            self.sink.to_css(dest)?;
127        }
128        Ok(())
129    }
130}
131
132/// Implements type for text-decoration-thickness
133/// which takes the grammar of auto | from-font | <length> | <percentage>
134///
135/// https://drafts.csswg.org/css-text-decor-4/
136#[repr(C, u8)]
137#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
138#[derive(
139    Animate,
140    Clone,
141    Copy,
142    ComputeSquaredDistance,
143    Debug,
144    Eq,
145    MallocSizeOf,
146    Parse,
147    PartialEq,
148    SpecifiedValueInfo,
149    ToAnimatedValue,
150    ToAnimatedZero,
151    ToComputedValue,
152    ToCss,
153    ToResolvedValue,
154    ToShmem,
155)]
156#[allow(missing_docs)]
157pub enum GenericTextDecorationLength<L> {
158    LengthPercentage(L),
159    Auto,
160    FromFont,
161}
162
163/// Implements type for text-indent
164/// which takes the grammar of [<length-percentage>] && hanging? && each-line?
165///
166/// https://drafts.csswg.org/css-text/#propdef-text-indent
167#[repr(C)]
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    ToCss,
181    ToResolvedValue,
182    ToShmem,
183)]
184pub struct GenericTextIndent<LengthPercentage> {
185    /// The amount of indent to be applied to the inline-start of the first line.
186    pub length: LengthPercentage,
187    /// Apply indent to non-first lines instead of first.
188    #[animation(constant)]
189    #[css(represents_keyword)]
190    pub hanging: bool,
191    /// Apply to each line after a hard break, not only first in block.
192    #[animation(constant)]
193    #[css(represents_keyword)]
194    pub each_line: bool,
195}
196
197impl<LengthPercentage: Zero> GenericTextIndent<LengthPercentage> {
198    /// Return the initial zero value.
199    pub fn zero() -> Self {
200        Self {
201            length: LengthPercentage::zero(),
202            hanging: false,
203            each_line: false,
204        }
205    }
206}