Add from impl to TaffyStyloStyle
1//! Conversion functions from Stylo types to Taffy types
2
3use servo_arc::Arc;
4
5// Module of type aliases so we can refer to stylo types with nicer names
6mod stylo {
7 pub(crate) use style::computed_values::align_content::T as AlignContent;
8 pub(crate) use style::computed_values::align_items::T as AlignItems;
9 pub(crate) use style::computed_values::align_self::T as AlignSelf;
10 pub(crate) use style::computed_values::flex_direction::T as FlexDirection;
11 pub(crate) use style::computed_values::flex_wrap::T as FlexWrap;
12 pub(crate) use style::computed_values::justify_content::T as JustifyContent;
13 // pub(crate) use style::computed_values::justify_items::T as JustifyItems;
14 // pub(crate) use style::computed_values::justify_self::T as JustifySelf;
15 pub(crate) use style::properties::longhands::aspect_ratio::computed_value::T as AspectRatio;
16 pub(crate) use style::properties::longhands::position::computed_value::T as Position;
17 // pub(crate) use style::properties::style_structs::{Margin, Padding};
18 pub(crate) use style::values::computed::LengthPercentage;
19 pub(crate) use style::values::generics::flex::GenericFlexBasis;
20 pub(crate) use style::values::generics::length::GenericLengthPercentageOrAuto;
21 pub(crate) use style::values::generics::length::GenericLengthPercentageOrNormal;
22 pub(crate) use style::values::generics::length::GenericMaxSize;
23 pub(crate) use style::values::generics::length::GenericSize;
24 pub(crate) use style::values::generics::position::PreferredRatio;
25 pub(crate) use style::values::generics::NonNegative;
26 pub(crate) use style::values::specified::box_::Display;
27 pub(crate) use style::values::specified::box_::DisplayInside;
28 pub(crate) use style::values::specified::box_::DisplayOutside;
29 pub(crate) use style::values::specified::box_::Overflow;
30 pub(crate) type LengthPercentageAuto = GenericLengthPercentageOrAuto<LengthPercentage>;
31 pub(crate) type Size = GenericSize<NonNegative<LengthPercentage>>;
32 pub(crate) type MaxSize = GenericMaxSize<NonNegative<LengthPercentage>>;
33 pub(crate) type FlexBasis = GenericFlexBasis<Size>;
34 pub(crate) type Gap = GenericLengthPercentageOrNormal<NonNegative<LengthPercentage>>;
35 pub(crate) use style::properties::generated::ComputedValues;
36}
37
38pub struct TaffyStyloStyle(pub Arc<stylo::ComputedValues>);
39
40impl From<Arc<stylo::ComputedValues>> for TaffyStyloStyle {
41 fn from(value: Arc<stylo::ComputedValues>) -> Self {
42 Self(Arc::clone(&value))
43 }
44}
45
46impl taffy::CoreStyle for TaffyStyloStyle {
47 #[inline]
48 fn box_generation_mode(&self) -> taffy::BoxGenerationMode {
49 t2s::box_generation_mode(self.0.get_box().display)
50 }
51
52 #[inline]
53 fn is_block(&self) -> bool {
54 t2s::is_block(self.0.get_box().display)
55 }
56
57 #[inline]
58 fn overflow(&self) -> taffy::Point<taffy::Overflow> {
59 let box_styles = self.0.get_box();
60 taffy::Point { x: t2s::overflow(box_styles.overflow_x), y: t2s::overflow(box_styles.overflow_y) }
61 }
62
63 #[inline]
64 fn scrollbar_width(&self) -> f32 {
65 0.0
66 }
67
68 #[inline]
69 fn position(&self) -> taffy::Position {
70 t2s::position(self.0.get_box().position)
71 }
72
73 #[inline]
74 fn inset(&self) -> taffy::Rect<taffy::LengthPercentageAuto> {
75 let position_styles = self.0.get_position();
76 taffy::Rect {
77 left: t2s::length_percentage_auto(&position_styles.left),
78 right: t2s::length_percentage_auto(&position_styles.right),
79 top: t2s::length_percentage_auto(&position_styles.top),
80 bottom: t2s::length_percentage_auto(&position_styles.bottom),
81 }
82 }
83
84 #[inline]
85 fn size(&self) -> taffy::Size<taffy::Dimension> {
86 let position_styles = self.0.get_position();
87 taffy::Size { width: t2s::dimension(&position_styles.width), height: t2s::dimension(&position_styles.height) }
88 }
89
90 #[inline]
91 fn min_size(&self) -> taffy::Size<taffy::Dimension> {
92 let position_styles = self.0.get_position();
93 taffy::Size {
94 width: t2s::dimension(&position_styles.min_width),
95 height: t2s::dimension(&position_styles.min_height),
96 }
97 }
98
99 #[inline]
100 fn max_size(&self) -> taffy::Size<taffy::Dimension> {
101 let position_styles = self.0.get_position();
102 taffy::Size {
103 width: t2s::max_size_dimension(&position_styles.max_width),
104 height: t2s::max_size_dimension(&position_styles.max_height),
105 }
106 }
107
108 #[inline]
109 fn aspect_ratio(&self) -> Option<f32> {
110 t2s::aspect_ratio(self.0.get_position().aspect_ratio)
111 }
112
113 #[inline]
114 fn margin(&self) -> taffy::Rect<taffy::LengthPercentageAuto> {
115 let margin_styles = self.0.get_margin();
116 taffy::Rect {
117 left: t2s::length_percentage_auto(&margin_styles.margin_left),
118 right: t2s::length_percentage_auto(&margin_styles.margin_right),
119 top: t2s::length_percentage_auto(&margin_styles.margin_top),
120 bottom: t2s::length_percentage_auto(&margin_styles.margin_bottom),
121 }
122 }
123
124 #[inline]
125 fn padding(&self) -> taffy::Rect<taffy::LengthPercentage> {
126 let padding_styles = self.0.get_padding();
127 taffy::Rect {
128 left: t2s::length_percentage(&padding_styles.padding_left.0),
129 right: t2s::length_percentage(&padding_styles.padding_right.0),
130 top: t2s::length_percentage(&padding_styles.padding_top.0),
131 bottom: t2s::length_percentage(&padding_styles.padding_bottom.0),
132 }
133 }
134
135 #[inline]
136 fn border(&self) -> taffy::Rect<taffy::LengthPercentage> {
137 let border_styles = self.0.get_border();
138 taffy::Rect {
139 left: taffy::LengthPercentage::Length(border_styles.border_left_width.to_f32_px()),
140 right: taffy::LengthPercentage::Length(border_styles.border_right_width.to_f32_px()),
141 top: taffy::LengthPercentage::Length(border_styles.border_top_width.to_f32_px()),
142 bottom: taffy::LengthPercentage::Length(border_styles.border_bottom_width.to_f32_px()),
143 }
144 }
145}
146
147impl taffy::FlexboxContainerStyle for TaffyStyloStyle {
148 #[inline]
149 fn flex_direction(&self) -> taffy::FlexDirection {
150 t2s::flex_direction(self.0.get_position().flex_direction)
151 }
152
153 #[inline]
154 fn flex_wrap(&self) -> taffy::FlexWrap {
155 t2s::flex_wrap(self.0.get_position().flex_wrap)
156 }
157
158 #[inline]
159 fn gap(&self) -> taffy::Size<taffy::LengthPercentage> {
160 let position_styles = self.0.get_position();
161 taffy::Size {
162 width: t2s::gap(&position_styles.column_gap),
163 height: taffy::LengthPercentage::Length(0.0), // TODO: enable row_gap in stylo
164 }
165 }
166
167 #[inline]
168 fn align_content(&self) -> Option<taffy::AlignContent> {
169 t2s::align_content(self.0.get_position().align_content)
170 }
171
172 #[inline]
173 fn align_items(&self) -> Option<taffy::AlignItems> {
174 t2s::align_items(self.0.get_position().align_items)
175 }
176
177 #[inline]
178 fn justify_content(&self) -> Option<taffy::JustifyContent> {
179 t2s::justify_content(self.0.get_position().justify_content)
180 }
181}
182
183impl taffy::FlexboxItemStyle for TaffyStyloStyle {
184 #[inline]
185 fn flex_basis(&self) -> taffy::Dimension {
186 t2s::flex_basis(&self.0.get_position().flex_basis)
187 }
188
189 #[inline]
190 fn flex_grow(&self) -> f32 {
191 self.0.get_position().flex_grow.0
192 }
193
194 #[inline]
195 fn flex_shrink(&self) -> f32 {
196 self.0.get_position().flex_grow.0
197 }
198
199 #[inline]
200 fn align_self(&self) -> Option<taffy::AlignSelf> {
201 t2s::align_self(self.0.get_position().align_self)
202 }
203}
204
205mod t2s {
206 use super::stylo;
207
208 #[inline]
209 pub(crate) fn length_percentage(val: &stylo::LengthPercentage) -> taffy::LengthPercentage {
210 if let Some(length) = val.to_length() {
211 taffy::LengthPercentage::Length(length.px())
212 } else if let Some(val) = val.to_percentage() {
213 taffy::LengthPercentage::Percent(val.0)
214 } else {
215 // TODO: Support calc
216 taffy::LengthPercentage::Percent(0.0)
217 }
218 }
219
220 #[inline]
221 pub(crate) fn length_percentage_auto(val: &stylo::LengthPercentageAuto) -> taffy::LengthPercentageAuto {
222 match val {
223 stylo::LengthPercentageAuto::Auto => taffy::LengthPercentageAuto::Auto,
224 stylo::LengthPercentageAuto::LengthPercentage(val) => length_percentage(val).into(),
225 }
226 }
227
228 #[inline]
229 pub(crate) fn dimension(val: &stylo::Size) -> taffy::Dimension {
230 match val {
231 stylo::Size::LengthPercentage(val) => length_percentage(&val.0).into(),
232 stylo::Size::Auto => taffy::Dimension::Auto,
233 // TODO: implement other values in Taffy (and servo configuration of stylo)
234 // _ => taffy::Dimension::Auto,
235 }
236 }
237
238 #[inline]
239 pub(crate) fn max_size_dimension(val: &stylo::MaxSize) -> taffy::Dimension {
240 match val {
241 stylo::MaxSize::LengthPercentage(val) => length_percentage(&val.0).into(),
242 stylo::MaxSize::None => taffy::Dimension::Auto,
243 // TODO: implement other values in Taffy (and servo configuration of stylo)
244 // _ => taffy::Dimension::Auto,
245 }
246 }
247
248 #[inline]
249 pub(crate) fn is_block(input: stylo::Display) -> bool {
250 matches!(input.outside(), stylo::DisplayOutside::Block)
251 // && matches!(input.inside(), stylo::DisplayInside::Flow | stylo::DisplayInside::FlowRoot)
252 }
253
254 #[inline]
255 pub(crate) fn box_generation_mode(input: stylo::Display) -> taffy::BoxGenerationMode {
256 match input.inside() {
257 stylo::DisplayInside::None => taffy::BoxGenerationMode::None,
258 // stylo::DisplayInside::Contents => display = taffy::BoxGenerationMode::Contents,
259 _ => taffy::BoxGenerationMode::Normal,
260 }
261 }
262
263 #[inline]
264 pub(crate) fn position(input: stylo::Position) -> taffy::Position {
265 match input {
266 // TODO: support position:static
267 stylo::Position::Relative => taffy::Position::Relative,
268 stylo::Position::Static => taffy::Position::Relative,
269
270 // TODO: support position:fixed and sticky
271 stylo::Position::Absolute => taffy::Position::Absolute,
272 stylo::Position::Fixed => taffy::Position::Absolute,
273 stylo::Position::Sticky => taffy::Position::Absolute,
274 }
275 }
276
277 #[inline]
278 pub(crate) fn overflow(input: stylo::Overflow) -> taffy::Overflow {
279 // TODO: Enable Overflow::Clip in servo configuration of stylo
280 match input {
281 stylo::Overflow::Visible => taffy::Overflow::Visible,
282 stylo::Overflow::Hidden => taffy::Overflow::Hidden,
283 stylo::Overflow::Scroll => taffy::Overflow::Scroll,
284 // TODO: Support Overflow::Auto in Taffy
285 stylo::Overflow::Auto => taffy::Overflow::Scroll,
286 }
287 }
288
289 #[inline]
290 pub(crate) fn aspect_ratio(input: stylo::AspectRatio) -> Option<f32> {
291 match input.ratio {
292 stylo::PreferredRatio::None => None,
293 stylo::PreferredRatio::Ratio(val) => Some(val.0 .0 / val.1 .0),
294 }
295 }
296
297 #[inline]
298 pub(crate) fn gap(input: &stylo::Gap) -> taffy::LengthPercentage {
299 match input {
300 // For Flexbox and CSS Grid the "normal" value is 0px. This may need to be updated
301 // if we ever implement multi-column layout.
302 stylo::Gap::Normal => taffy::LengthPercentage::Length(0.0),
303 stylo::Gap::LengthPercentage(val) => length_percentage(&val.0),
304 }
305 }
306
307 #[inline]
308 pub(crate) fn flex_basis(input: &stylo::FlexBasis) -> taffy::Dimension {
309 // TODO: Support flex-basis: content in Taffy
310 match input {
311 stylo::FlexBasis::Content => taffy::Dimension::Auto,
312 stylo::FlexBasis::Size(size) => dimension(&size).into(),
313 }
314 }
315
316 #[inline]
317 pub(crate) fn flex_direction(input: stylo::FlexDirection) -> taffy::FlexDirection {
318 match input {
319 stylo::FlexDirection::Row => taffy::FlexDirection::Row,
320 stylo::FlexDirection::RowReverse => taffy::FlexDirection::RowReverse,
321 stylo::FlexDirection::Column => taffy::FlexDirection::Column,
322 stylo::FlexDirection::ColumnReverse => taffy::FlexDirection::ColumnReverse,
323 }
324 }
325
326 #[inline]
327 pub(crate) fn flex_wrap(input: stylo::FlexWrap) -> taffy::FlexWrap {
328 match input {
329 stylo::FlexWrap::Wrap => taffy::FlexWrap::Wrap,
330 stylo::FlexWrap::WrapReverse => taffy::FlexWrap::WrapReverse,
331 stylo::FlexWrap::Nowrap => taffy::FlexWrap::NoWrap,
332 }
333 }
334
335 #[inline]
336 pub(crate) fn justify_content(input: stylo::JustifyContent) -> Option<taffy::JustifyContent> {
337 match input {
338 stylo::JustifyContent::Start => Some(taffy::JustifyContent::Start),
339 stylo::JustifyContent::End => Some(taffy::JustifyContent::End),
340 stylo::JustifyContent::FlexStart => Some(taffy::JustifyContent::FlexStart),
341 stylo::JustifyContent::FlexEnd => Some(taffy::JustifyContent::FlexEnd),
342 stylo::JustifyContent::Stretch => Some(taffy::JustifyContent::Stretch),
343 stylo::JustifyContent::Center => Some(taffy::JustifyContent::Center),
344 stylo::JustifyContent::SpaceBetween => Some(taffy::JustifyContent::SpaceBetween),
345 stylo::JustifyContent::SpaceAround => Some(taffy::JustifyContent::SpaceAround),
346 stylo::JustifyContent::SpaceEvenly => Some(taffy::JustifyContent::SpaceEvenly),
347 }
348 }
349
350 #[inline]
351 pub(crate) fn align_content(input: stylo::AlignContent) -> Option<taffy::AlignContent> {
352 match input {
353 stylo::AlignContent::Start => Some(taffy::AlignContent::Start),
354 stylo::AlignContent::End => Some(taffy::AlignContent::End),
355 stylo::AlignContent::FlexStart => Some(taffy::AlignContent::FlexStart),
356 stylo::AlignContent::FlexEnd => Some(taffy::AlignContent::FlexEnd),
357 stylo::AlignContent::Center => Some(taffy::AlignContent::Center),
358 stylo::AlignContent::Stretch => Some(taffy::AlignContent::Stretch),
359 stylo::AlignContent::SpaceBetween => Some(taffy::AlignContent::SpaceBetween),
360 stylo::AlignContent::SpaceAround => Some(taffy::AlignContent::SpaceAround),
361 stylo::AlignContent::SpaceEvenly => Some(taffy::AlignContent::SpaceEvenly),
362 }
363 }
364
365 #[inline]
366 pub(crate) fn align_items(input: stylo::AlignItems) -> Option<taffy::AlignItems> {
367 match input {
368 stylo::AlignItems::Stretch => Some(taffy::AlignItems::Stretch),
369 stylo::AlignItems::FlexStart => Some(taffy::AlignItems::FlexStart),
370 stylo::AlignItems::FlexEnd => Some(taffy::AlignItems::FlexEnd),
371 stylo::AlignItems::Center => Some(taffy::AlignItems::Center),
372 stylo::AlignItems::Baseline => Some(taffy::AlignItems::Baseline),
373 }
374 }
375
376 #[inline]
377 pub(crate) fn align_self(input: stylo::AlignSelf) -> Option<taffy::AlignSelf> {
378 match input {
379 stylo::AlignSelf::Auto => None,
380 stylo::AlignSelf::Stretch => Some(taffy::AlignSelf::Stretch),
381 stylo::AlignSelf::FlexStart => Some(taffy::AlignSelf::FlexStart),
382 stylo::AlignSelf::FlexEnd => Some(taffy::AlignSelf::FlexEnd),
383 stylo::AlignSelf::Center => Some(taffy::AlignSelf::Center),
384 stylo::AlignSelf::Baseline => Some(taffy::AlignSelf::Baseline),
385 }
386 }
387
388 // pub(crate) fn justify_items(input: stylo::JustifyItems) -> Option<taffy::JustifyItems> {
389 // match input {
390 // stylo::JustifyItems::Stretch => Some(taffy::JustifyItems::Stretch),
391 // stylo::JustifyItems::FlexStart => Some(taffy::JustifyItems::FlexStart),
392 // stylo::JustifyItems::FlexEnd => Some(taffy::JustifyItems::FlexEnd),
393 // stylo::JustifyItems::Center => Some(taffy::JustifyItems::Center),
394 // stylo::JustifyItems::Baseline => Some(taffy::JustifyItems::Baseline),
395 // }
396 // }
397
398 // pub(crate) fn justify_self(input: stylo::JustifySelf) -> Option<taffy::JustifySelf> {
399 // match input {
400 // stylo::JustifySelf::Auto => None,
401 // stylo::JustifySelf::Stretch => Some(taffy::JustifySelf::Stretch),
402 // stylo::JustifySelf::FlexStart => Some(taffy::JustifySelf::FlexStart),
403 // stylo::JustifySelf::FlexEnd => Some(taffy::JustifySelf::FlexEnd),
404 // stylo::JustifySelf::Center => Some(taffy::JustifySelf::Center),
405 // stylo::JustifySelf::Baseline => Some(taffy::JustifySelf::Baseline),
406 // }
407 // }
408}