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