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