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(
65 Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue, ToTyped,
66)]
67#[repr(u8)]
68pub enum Resize {
69 None,
70 Both,
71 Horizontal,
72 Vertical,
73}
74
75impl ToComputedValue for specified::Resize {
76 type ComputedValue = Resize;
77
78 #[inline]
79 fn to_computed_value(&self, context: &Context) -> Resize {
80 let is_vertical = context.style().writing_mode.is_vertical();
81 match self {
82 specified::Resize::Inline => {
83 context
84 .rule_cache_conditions
85 .borrow_mut()
86 .set_writing_mode_dependency(context.builder.writing_mode);
87 if is_vertical {
88 Resize::Vertical
89 } else {
90 Resize::Horizontal
91 }
92 },
93 specified::Resize::Block => {
94 context
95 .rule_cache_conditions
96 .borrow_mut()
97 .set_writing_mode_dependency(context.builder.writing_mode);
98 if is_vertical {
99 Resize::Horizontal
100 } else {
101 Resize::Vertical
102 }
103 },
104 specified::Resize::None => Resize::None,
105 specified::Resize::Both => Resize::Both,
106 specified::Resize::Horizontal => Resize::Horizontal,
107 specified::Resize::Vertical => Resize::Vertical,
108 }
109 }
110
111 #[inline]
112 fn from_computed_value(computed: &Resize) -> specified::Resize {
113 match computed {
114 Resize::None => specified::Resize::None,
115 Resize::Both => specified::Resize::Both,
116 Resize::Horizontal => specified::Resize::Horizontal,
117 Resize::Vertical => specified::Resize::Vertical,
118 }
119 }
120}
121
122#[derive(
124 Clone,
125 ComputeSquaredDistance,
126 Copy,
127 Debug,
128 MallocSizeOf,
129 PartialEq,
130 PartialOrd,
131 ToResolvedValue,
132 ToTyped,
133)]
134#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
135#[repr(C)]
136pub struct Zoom(f32);
137
138impl ToComputedValue for specified::Zoom {
139 type ComputedValue = Zoom;
140
141 #[inline]
142 fn to_computed_value(&self, _: &Context) -> Self::ComputedValue {
143 let n = match *self {
144 Self::Normal => return Zoom::ONE,
145 Self::Document => return Zoom::DOCUMENT,
146 Self::Value(ref n) => n.0.to_number().get(),
147 };
148 if n == 0.0 {
149 return Zoom::ONE;
151 }
152 Zoom(n)
153 }
154
155 #[inline]
156 fn from_computed_value(computed: &Self::ComputedValue) -> Self {
157 Self::new_number(computed.value())
158 }
159}
160
161impl ToCss for Zoom {
162 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
163 where
164 W: fmt::Write,
165 {
166 use std::fmt::Write;
167 if *self == Self::DOCUMENT {
168 return dest.write_str("document");
169 }
170 self.value().to_css(dest)
171 }
172}
173
174impl ToAnimatedValue for Zoom {
175 type AnimatedValue = Number;
176
177 #[inline]
178 fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
179 self.value()
180 }
181
182 #[inline]
183 fn from_animated_value(animated: Self::AnimatedValue) -> Self {
184 Zoom(animated.max(0.0))
185 }
186}
187
188impl Zoom {
189 pub const ONE: Zoom = Zoom(1.0);
191
192 pub const DOCUMENT: Zoom = Zoom(0.0);
195
196 #[inline]
198 pub fn is_one(self) -> bool {
199 self == Self::ONE
200 }
201
202 #[inline]
204 pub fn is_document(self) -> bool {
205 self == Self::DOCUMENT
206 }
207
208 #[inline]
210 pub fn inverted(&self) -> Option<Self> {
211 if self.0 == 0.0 {
212 return None;
213 }
214 Some(Self(1. / self.0))
215 }
216
217 #[inline]
219 pub fn value(&self) -> f32 {
220 self.0
221 }
222
223 pub fn compute_effective(self, specified: Self) -> Self {
225 if specified == Self::DOCUMENT {
226 return Self::ONE;
227 }
228 if self == Self::ONE {
229 return specified;
230 }
231 if specified == Self::ONE {
232 return self;
233 }
234 Zoom(self.0 * specified.0)
235 }
236
237 #[inline]
239 pub fn zoom(self, value: f32) -> f32 {
240 if self == Self::ONE {
241 return value;
242 }
243 value * self.value()
244 }
245
246 #[inline]
248 pub fn unzoom(self, value: f32) -> f32 {
249 if self == Self::ONE || self.0 == 0.0 {
251 return value;
252 }
253 value / self.value()
254 }
255}