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