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