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