1use crate::values::animated::{Animate, Procedure, ToAnimatedValue};
8use crate::values::computed::length::{LengthPercentage, NonNegativeLength};
9use crate::values::computed::{Context, Integer, Number, ToComputedValue};
10use crate::values::generics::box_::{
11 GenericContainIntrinsicSize, GenericLineClamp, GenericPerspective, GenericVerticalAlign,
12};
13use crate::values::specified::box_ as specified;
14use std::fmt;
15use style_traits::{CssWriter, ToCss};
16
17pub use crate::values::specified::box_::{
18 Appearance, BaselineSource, BreakBetween, BreakWithin, Clear, Contain, ContainerName,
19 ContainerType, ContentVisibility, Display, Float, Overflow, OverflowAnchor, OverflowClipBox,
20 OverscrollBehavior, PositionProperty, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStop,
21 ScrollSnapStrictness, ScrollSnapType, ScrollbarGutter, TouchAction, WillChange,
22 WritingModeProperty,
23};
24
25pub type VerticalAlign = GenericVerticalAlign<LengthPercentage>;
27
28pub type ContainIntrinsicSize = GenericContainIntrinsicSize<NonNegativeLength>;
30
31impl ContainIntrinsicSize {
32 pub fn add_auto_if_needed(&self) -> Option<Self> {
34 Some(match *self {
35 Self::None => Self::AutoNone,
36 Self::Length(ref l) => Self::AutoLength(*l),
37 Self::AutoNone | Self::AutoLength(..) => return None,
38 })
39 }
40}
41
42pub type LineClamp = GenericLineClamp<Integer>;
44
45impl Animate for LineClamp {
46 #[inline]
47 fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
48 if self.is_none() != other.is_none() {
49 return Err(());
50 }
51 if self.is_none() {
52 return Ok(Self::none());
53 }
54 Ok(Self(self.0.animate(&other.0, procedure)?.max(1)))
55 }
56}
57
58pub type Perspective = GenericPerspective<NonNegativeLength>;
60
61#[allow(missing_docs)]
63#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
64#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue)]
65#[repr(u8)]
66pub enum Resize {
67 None,
68 Both,
69 Horizontal,
70 Vertical,
71}
72
73impl ToComputedValue for specified::Resize {
74 type ComputedValue = Resize;
75
76 #[inline]
77 fn to_computed_value(&self, context: &Context) -> Resize {
78 let is_vertical = context.style().writing_mode.is_vertical();
79 match self {
80 specified::Resize::Inline => {
81 context
82 .rule_cache_conditions
83 .borrow_mut()
84 .set_writing_mode_dependency(context.builder.writing_mode);
85 if is_vertical {
86 Resize::Vertical
87 } else {
88 Resize::Horizontal
89 }
90 },
91 specified::Resize::Block => {
92 context
93 .rule_cache_conditions
94 .borrow_mut()
95 .set_writing_mode_dependency(context.builder.writing_mode);
96 if is_vertical {
97 Resize::Horizontal
98 } else {
99 Resize::Vertical
100 }
101 },
102 specified::Resize::None => Resize::None,
103 specified::Resize::Both => Resize::Both,
104 specified::Resize::Horizontal => Resize::Horizontal,
105 specified::Resize::Vertical => Resize::Vertical,
106 }
107 }
108
109 #[inline]
110 fn from_computed_value(computed: &Resize) -> specified::Resize {
111 match computed {
112 Resize::None => specified::Resize::None,
113 Resize::Both => specified::Resize::Both,
114 Resize::Horizontal => specified::Resize::Horizontal,
115 Resize::Vertical => specified::Resize::Vertical,
116 }
117 }
118}
119
120#[derive(
122 Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToResolvedValue,
123)]
124#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
125#[repr(C)]
126pub struct Zoom(f32);
127
128impl ToComputedValue for specified::Zoom {
129 type ComputedValue = Zoom;
130
131 #[inline]
132 fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
133 let n = match *self {
134 Self::Normal => return Zoom::ONE,
135 Self::Document => return Zoom::DOCUMENT,
136 Self::Value(ref n) => n.0.to_number().get(),
137 };
138 if n == 0.0 {
139 return Zoom::ONE;
141 }
142 Zoom(n)
143 }
144
145 #[inline]
146 fn from_computed_value(computed: &Self::ComputedValue) -> Self {
147 Self::new_number(computed.value())
148 }
149}
150
151impl ToCss for Zoom {
152 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
153 where
154 W: fmt::Write,
155 {
156 use std::fmt::Write;
157 if *self == Self::DOCUMENT {
158 return dest.write_str("document");
159 }
160 self.value().to_css(dest)
161 }
162}
163
164impl ToAnimatedValue for Zoom {
165 type AnimatedValue = Number;
166
167 #[inline]
168 fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
169 self.value()
170 }
171
172 #[inline]
173 fn from_animated_value(animated: Self::AnimatedValue) -> Self {
174 Zoom(animated.max(0.0))
175 }
176}
177
178impl Zoom {
179 pub const ONE: Zoom = Zoom(1.0);
181
182 pub const DOCUMENT: Zoom = Zoom(0.0);
185
186 #[inline]
188 pub fn is_one(self) -> bool {
189 self == Self::ONE
190 }
191
192 #[inline]
194 pub fn is_document(self) -> bool {
195 self == Self::DOCUMENT
196 }
197
198 #[inline]
200 pub fn inverted(&self) -> Option<Self> {
201 if self.0 == 0.0 {
202 return None;
203 }
204 Some(Self(1. / self.0))
205 }
206
207 #[inline]
209 pub fn value(&self) -> f32 {
210 self.0
211 }
212
213 pub fn compute_effective(self, specified: Self) -> Self {
215 if specified == Self::DOCUMENT {
216 return Self::ONE;
217 }
218 if self == Self::ONE {
219 return specified;
220 }
221 if specified == Self::ONE {
222 return self;
223 }
224 Zoom(self.0 * specified.0)
225 }
226
227 #[inline]
229 pub fn zoom(self, value: f32) -> f32 {
230 if self == Self::ONE {
231 return value;
232 }
233 value * self.value()
234 }
235
236 #[inline]
238 pub fn unzoom(self, value: f32) -> f32 {
239 if self == Self::ONE || self.0 == 0.0 {
241 return value;
242 }
243 value / self.value()
244 }
245}