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