tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Sutichaykuna

⎇ cb3aee042ccb9a1b88b99247e08048ad3cb9a4ff taffy_stylo/src/lib.rs Rust · 408 siq'ikuna · 16.5 KB Ñawpa willay Pi imata llamkarqan ch'uya

Add from impl to TaffyStyloStyle c472dbf31 · Nico Burns ·

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}