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#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
69#[derive(
70 Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue, ToTyped,
71)]
72#[repr(u8)]
73pub enum Resize {
74 None,
75 Both,
76 Horizontal,
77 Vertical,
78}
79
80impl ToComputedValue for specified::Resize {
81 type ComputedValue = Resize;
82
83 #[inline]
84 fn to_computed_value(&self, context: &Context) -> Resize {
85 let is_vertical = context.style().writing_mode.is_vertical();
86 match self {
87 specified::Resize::Inline => {
88 context
89 .rule_cache_conditions
90 .borrow_mut()
91 .set_writing_mode_dependency(context.builder.writing_mode);
92 if is_vertical {
93 Resize::Vertical
94 } else {
95 Resize::Horizontal
96 }
97 },
98 specified::Resize::Block => {
99 context
100 .rule_cache_conditions
101 .borrow_mut()
102 .set_writing_mode_dependency(context.builder.writing_mode);
103 if is_vertical {
104 Resize::Horizontal
105 } else {
106 Resize::Vertical
107 }
108 },
109 specified::Resize::None => Resize::None,
110 specified::Resize::Both => Resize::Both,
111 specified::Resize::Horizontal => Resize::Horizontal,
112 specified::Resize::Vertical => Resize::Vertical,
113 }
114 }
115
116 #[inline]
117 fn from_computed_value(computed: &Resize) -> specified::Resize {
118 match computed {
119 Resize::None => specified::Resize::None,
120 Resize::Both => specified::Resize::Both,
121 Resize::Horizontal => specified::Resize::Horizontal,
122 Resize::Vertical => specified::Resize::Vertical,
123 }
124 }
125}
126
127#[derive(
129 Clone,
130 ComputeSquaredDistance,
131 Copy,
132 Debug,
133 MallocSizeOf,
134 PartialEq,
135 PartialOrd,
136 ToResolvedValue,
137 ToTyped,
138)]
139#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
140#[repr(C)]
141pub struct Zoom(f32);
142
143impl ToComputedValue for specified::Zoom {
144 type ComputedValue = Zoom;
145
146 #[inline]
147 fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
148 let c = match *self {
149 Self::Normal => return Zoom::ONE,
150 Self::Document => return Zoom::DOCUMENT,
151 Self::Value(ref n) => n.0.to_computed_value(context),
152 };
153 let n = match c {
154 super::NumberOrPercentage::Percentage(p) => p.0,
155 super::NumberOrPercentage::Number(n) => n,
156 };
157 if n == 0.0 {
158 return Zoom::ONE;
160 }
161 Zoom(n)
162 }
163
164 #[inline]
165 fn from_computed_value(computed: &Self::ComputedValue) -> Self {
166 Self::new_number(computed.value())
167 }
168}
169
170impl ToCss for Zoom {
171 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
172 where
173 W: fmt::Write,
174 {
175 use std::fmt::Write;
176 if *self == Self::DOCUMENT {
177 return dest.write_str("document");
178 }
179 self.value().to_css(dest)
180 }
181}
182
183impl ToAnimatedValue for Zoom {
184 type AnimatedValue = Number;
185
186 #[inline]
187 fn to_animated_value(self, _: &crate::values::animated::Context) -> Self::AnimatedValue {
188 self.value()
189 }
190
191 #[inline]
192 fn from_animated_value(animated: Self::AnimatedValue) -> Self {
193 Zoom(animated.max(0.0))
194 }
195}
196
197impl Zoom {
198 pub const ONE: Zoom = Zoom(1.0);
200
201 pub const DOCUMENT: Zoom = Zoom(0.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 == 0.0 {
221 return None;
222 }
223 Some(Self(1. / self.0))
224 }
225
226 #[inline]
228 pub fn value(&self) -> f32 {
229 self.0
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 == 0.0 {
260 return value;
261 }
262 value / self.value()
263 }
264}