Skip to main content

style/values/computed/
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//! Computed types for text properties.
6
7use crate::derives::*;
8use crate::values::computed::length::{Length, LengthPercentage};
9use crate::values::generics::text::{
10    GenericHyphenateLimitChars, GenericInitialLetter, GenericTextDecorationInset,
11    GenericTextDecorationLength, GenericTextIndent,
12};
13use crate::values::generics::NumberOrAuto;
14use crate::values::specified::text as specified;
15use crate::values::specified::text::{TextEmphasisFillMode, TextEmphasisShapeKeyword};
16use crate::values::{CSSFloat, CSSInteger};
17use crate::Zero;
18use std::fmt::{self, Write};
19use style_traits::{CssString, CssWriter, ToCss, ToTyped, TypedValue};
20
21pub use crate::values::specified::text::{
22    HyphenateCharacter, LineBreak, MozControlCharacterVisibility, OverflowWrap, RubyPosition,
23    TextAlignLast, TextAutospace, TextBoxEdge, TextBoxTrim, TextDecorationLine,
24    TextDecorationSkipInk, TextEmphasisPosition, TextJustify, TextOverflow, TextTransform,
25    TextUnderlinePosition, WordBreak,
26};
27
28/// A computed value for the `initial-letter` property.
29pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
30
31/// Implements type for `text-decoration-thickness` property.
32pub type TextDecorationLength = GenericTextDecorationLength<LengthPercentage>;
33
34/// Implements type for `text-decoration-inset` property.
35pub type TextDecorationInset = GenericTextDecorationInset<Length>;
36
37/// The computed value of `text-align`.
38pub type TextAlign = specified::TextAlignKeyword;
39
40/// The computed value of `text-indent`.
41pub type TextIndent = GenericTextIndent<LengthPercentage>;
42
43/// A computed value for the `hyphenate-character` property.
44pub type HyphenateLimitChars = GenericHyphenateLimitChars<CSSInteger>;
45
46impl HyphenateLimitChars {
47    /// Return the `auto` value, which has all three component values as `auto`.
48    #[inline]
49    pub fn auto() -> Self {
50        Self {
51            total_word_length: NumberOrAuto::Auto,
52            pre_hyphen_length: NumberOrAuto::Auto,
53            post_hyphen_length: NumberOrAuto::Auto,
54        }
55    }
56}
57
58/// A computed value for the `letter-spacing` property.
59#[repr(transparent)]
60#[derive(
61    Animate,
62    Clone,
63    ComputeSquaredDistance,
64    Copy,
65    Debug,
66    MallocSizeOf,
67    PartialEq,
68    ToAnimatedValue,
69    ToAnimatedZero,
70    ToResolvedValue,
71)]
72pub struct GenericLetterSpacing<L>(pub L);
73/// This is generic just to make the #[derive()] code do the right thing for lengths.
74pub type LetterSpacing = GenericLetterSpacing<LengthPercentage>;
75
76impl LetterSpacing {
77    /// Return the `normal` computed value, which is just zero.
78    #[inline]
79    pub fn normal() -> Self {
80        Self(LengthPercentage::zero())
81    }
82}
83
84impl ToCss for LetterSpacing {
85    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
86    where
87        W: Write,
88    {
89        // https://drafts.csswg.org/css-text/#propdef-letter-spacing
90        //
91        // For legacy reasons, a computed letter-spacing of zero yields a
92        // resolved value (getComputedStyle() return value) of normal.
93        if self.0.is_zero() {
94            return dest.write_str("normal");
95        }
96        self.0.to_css(dest)
97    }
98}
99
100impl ToTyped for LetterSpacing {
101    // XXX The specification does not currently define how this property should
102    // be reified into Typed OM. The current behavior follows existing WPT
103    // coverage (letter-spacing.html). We may file a spec issue once more data
104    // is collected to update the Property-specific Rules section to align with
105    // observed test expectations.
106    fn to_typed(&self) -> Option<TypedValue> {
107        if !self.0.has_percentage() && self.0.is_zero() {
108            return Some(TypedValue::Keyword(CssString::from("normal")));
109        }
110        self.0.to_typed()
111    }
112}
113
114/// A computed value for the `word-spacing` property.
115pub type WordSpacing = LengthPercentage;
116
117impl WordSpacing {
118    /// Return the `normal` computed value, which is just zero.
119    #[inline]
120    pub fn normal() -> Self {
121        LengthPercentage::zero()
122    }
123}
124
125/// Computed value for the text-emphasis-style property
126#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue, ToTyped)]
127#[allow(missing_docs)]
128#[repr(C, u8)]
129pub enum TextEmphasisStyle {
130    /// [ <fill> || <shape> ]
131    Keyword {
132        #[css(skip_if = "TextEmphasisFillMode::is_filled")]
133        fill: TextEmphasisFillMode,
134        shape: TextEmphasisShapeKeyword,
135    },
136    /// `none`
137    None,
138    /// `<string>` (of which only the first grapheme cluster will be used).
139    String(crate::OwnedStr),
140}