tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 717HTML 669Markdown 12TOML 62372 Sutichaykuna

⎇ 9915b967e9809dc57f210de8fe5f7510e66806d6 taffy_stylo/src/convert.rs Rust · 312 siq'ikuna · 13.4 KB Ñawpa willay Pi imata llamkarqan ch'uya

Stylo integration (#693) 9915b967e · Nico Burns ·

1// Module of type aliases so we can refer to stylo types with nicer names
2mod stylo {
3    pub(crate) use style::computed_values::flex_direction::T as FlexDirection;
4    pub(crate) use style::computed_values::flex_wrap::T as FlexWrap;
5    pub(crate) use style::computed_values::grid_auto_flow::T as GridAutoFlow;
6    pub(crate) use style::properties::generated::longhands::box_sizing::computed_value::T as BoxSizing;
7    pub(crate) use style::properties::longhands::aspect_ratio::computed_value::T as AspectRatio;
8    pub(crate) use style::properties::longhands::position::computed_value::T as Position;
9    pub(crate) use style::values::specified::align::AlignFlags;
10    pub(crate) use style::values::specified::align::ContentDistribution;
11    // pub(crate) use style::properties::style_structs::{Margin, Padding};
12    pub(crate) use style::values::computed::GridLine;
13    pub(crate) use style::values::computed::GridTemplateComponent;
14    pub(crate) use style::values::computed::ImplicitGridTracks;
15    pub(crate) use style::values::computed::LengthPercentage;
16    pub(crate) use style::values::generics::flex::GenericFlexBasis;
17    pub(crate) use style::values::generics::grid::RepeatCount;
18    pub(crate) use style::values::generics::grid::TrackBreadth;
19    pub(crate) use style::values::generics::grid::TrackListValue;
20    pub(crate) use style::values::generics::grid::TrackSize;
21    pub(crate) use style::values::generics::length::GenericLengthPercentageOrAuto;
22    pub(crate) use style::values::generics::length::GenericLengthPercentageOrNormal;
23    pub(crate) use style::values::generics::length::GenericMaxSize;
24    pub(crate) use style::values::generics::length::GenericSize;
25    pub(crate) use style::values::generics::position::PreferredRatio;
26    pub(crate) use style::values::generics::NonNegative;
27    pub(crate) use style::values::specified::box_::Display;
28    pub(crate) use style::values::specified::box_::DisplayInside;
29    pub(crate) use style::values::specified::box_::DisplayOutside;
30    pub(crate) use style::values::specified::box_::Overflow;
31    pub(crate) use style::values::specified::GenericGridTemplateComponent;
32    pub(crate) type LengthPercentageAuto = GenericLengthPercentageOrAuto<LengthPercentage>;
33    pub(crate) type Size = GenericSize<NonNegative<LengthPercentage>>;
34    pub(crate) type MaxSize = GenericMaxSize<NonNegative<LengthPercentage>>;
35    pub(crate) type FlexBasis = GenericFlexBasis<Size>;
36    pub(crate) type Gap = GenericLengthPercentageOrNormal<NonNegative<LengthPercentage>>;
37}
38
39#[inline]
40pub(crate) fn length_percentage(val: &stylo::LengthPercentage) -> taffy::LengthPercentage {
41    if let Some(length) = val.to_length() {
42        taffy::LengthPercentage::Length(length.px())
43    } else if let Some(val) = val.to_percentage() {
44        taffy::LengthPercentage::Percent(val.0)
45    } else {
46        // TODO: Support calc
47        taffy::LengthPercentage::Percent(0.0)
48    }
49}
50
51#[inline]
52pub(crate) fn length_percentage_auto(val: &stylo::LengthPercentageAuto) -> taffy::LengthPercentageAuto {
53    match val {
54        stylo::LengthPercentageAuto::Auto => taffy::LengthPercentageAuto::Auto,
55        stylo::LengthPercentageAuto::LengthPercentage(val) => length_percentage(val).into(),
56    }
57}
58
59#[inline]
60pub(crate) fn dimension(val: &stylo::Size) -> taffy::Dimension {
61    match val {
62        stylo::Size::LengthPercentage(val) => length_percentage(&val.0).into(),
63        stylo::Size::Auto => taffy::Dimension::Auto,
64        // TODO: implement other values in Taffy (and servo configuration of stylo)
65        // _ => taffy::Dimension::Auto,
66    }
67}
68
69#[inline]
70pub(crate) fn max_size_dimension(val: &stylo::MaxSize) -> taffy::Dimension {
71    match val {
72        stylo::MaxSize::LengthPercentage(val) => length_percentage(&val.0).into(),
73        stylo::MaxSize::None => taffy::Dimension::Auto,
74        // TODO: implement other values in Taffy (and servo configuration of stylo)
75        // _ => taffy::Dimension::Auto,
76    }
77}
78
79#[inline]
80pub(crate) fn is_block(input: stylo::Display) -> bool {
81    matches!(input.outside(), stylo::DisplayOutside::Block)
82        && matches!(input.inside(), stylo::DisplayInside::Flow | stylo::DisplayInside::FlowRoot)
83}
84
85#[inline]
86pub(crate) fn box_generation_mode(input: stylo::Display) -> taffy::BoxGenerationMode {
87    match input.inside() {
88        stylo::DisplayInside::None => taffy::BoxGenerationMode::None,
89        // stylo::DisplayInside::Contents => display = taffy::BoxGenerationMode::Contents,
90        _ => taffy::BoxGenerationMode::Normal,
91    }
92}
93
94#[inline]
95pub(crate) fn box_sizing(input: stylo::BoxSizing) -> taffy::BoxSizing {
96    match input {
97        stylo::BoxSizing::BorderBox => taffy::BoxSizing::BorderBox,
98        stylo::BoxSizing::ContentBox => taffy::BoxSizing::ContentBox,
99    }
100}
101
102#[inline]
103pub(crate) fn position(input: stylo::Position) -> taffy::Position {
104    match input {
105        // TODO: support position:static
106        stylo::Position::Relative => taffy::Position::Relative,
107        stylo::Position::Static => taffy::Position::Relative,
108
109        // TODO: support position:fixed and sticky
110        stylo::Position::Absolute => taffy::Position::Absolute,
111        stylo::Position::Fixed => taffy::Position::Absolute,
112        stylo::Position::Sticky => taffy::Position::Absolute,
113    }
114}
115
116#[inline]
117pub(crate) fn overflow(input: stylo::Overflow) -> taffy::Overflow {
118    // TODO: Enable Overflow::Clip in servo configuration of stylo
119    match input {
120        stylo::Overflow::Visible => taffy::Overflow::Visible,
121        stylo::Overflow::Hidden => taffy::Overflow::Hidden,
122        stylo::Overflow::Scroll => taffy::Overflow::Scroll,
123        // TODO: Support Overflow::Auto in Taffy
124        stylo::Overflow::Auto => taffy::Overflow::Scroll,
125    }
126}
127
128#[inline]
129pub(crate) fn aspect_ratio(input: stylo::AspectRatio) -> Option<f32> {
130    match input.ratio {
131        stylo::PreferredRatio::None => None,
132        stylo::PreferredRatio::Ratio(val) => Some(val.0 .0 / val.1 .0),
133    }
134}
135
136#[inline]
137pub(crate) fn gap(input: &stylo::Gap) -> taffy::LengthPercentage {
138    match input {
139        // For Flexbox and CSS Grid the "normal" value is 0px. This may need to be updated
140        // if we ever implement multi-column layout.
141        stylo::Gap::Normal => taffy::LengthPercentage::Length(0.0),
142        stylo::Gap::LengthPercentage(val) => length_percentage(&val.0),
143    }
144}
145
146#[inline]
147pub(crate) fn flex_basis(input: &stylo::FlexBasis) -> taffy::Dimension {
148    // TODO: Support flex-basis: content in Taffy
149    match input {
150        stylo::FlexBasis::Content => taffy::Dimension::Auto,
151        stylo::FlexBasis::Size(size) => dimension(size),
152    }
153}
154
155#[inline]
156pub(crate) fn flex_direction(input: stylo::FlexDirection) -> taffy::FlexDirection {
157    match input {
158        stylo::FlexDirection::Row => taffy::FlexDirection::Row,
159        stylo::FlexDirection::RowReverse => taffy::FlexDirection::RowReverse,
160        stylo::FlexDirection::Column => taffy::FlexDirection::Column,
161        stylo::FlexDirection::ColumnReverse => taffy::FlexDirection::ColumnReverse,
162    }
163}
164
165#[inline]
166pub(crate) fn flex_wrap(input: stylo::FlexWrap) -> taffy::FlexWrap {
167    match input {
168        stylo::FlexWrap::Wrap => taffy::FlexWrap::Wrap,
169        stylo::FlexWrap::WrapReverse => taffy::FlexWrap::WrapReverse,
170        stylo::FlexWrap::Nowrap => taffy::FlexWrap::NoWrap,
171    }
172}
173
174#[inline]
175pub(crate) fn content_alignment(input: stylo::ContentDistribution) -> Option<taffy::AlignContent> {
176    match input.primary().value() {
177        stylo::AlignFlags::NORMAL => None,
178        stylo::AlignFlags::AUTO => None,
179        stylo::AlignFlags::START => Some(taffy::AlignContent::Start),
180        stylo::AlignFlags::END => Some(taffy::AlignContent::End),
181        stylo::AlignFlags::FLEX_START => Some(taffy::AlignContent::FlexStart),
182        stylo::AlignFlags::STRETCH => Some(taffy::AlignContent::Stretch),
183        stylo::AlignFlags::FLEX_END => Some(taffy::AlignContent::FlexEnd),
184        stylo::AlignFlags::CENTER => Some(taffy::AlignContent::Center),
185        stylo::AlignFlags::SPACE_BETWEEN => Some(taffy::AlignContent::SpaceBetween),
186        stylo::AlignFlags::SPACE_AROUND => Some(taffy::AlignContent::SpaceAround),
187        stylo::AlignFlags::SPACE_EVENLY => Some(taffy::AlignContent::SpaceEvenly),
188        // Should never be hit. But no real reason to panic here.
189        _ => None,
190    }
191}
192
193#[inline]
194pub(crate) fn item_alignment(input: stylo::AlignFlags) -> Option<taffy::AlignItems> {
195    match input.value() {
196        stylo::AlignFlags::NORMAL => None,
197        stylo::AlignFlags::AUTO => None,
198        stylo::AlignFlags::STRETCH => Some(taffy::AlignItems::Stretch),
199        stylo::AlignFlags::FLEX_START => Some(taffy::AlignItems::FlexStart),
200        stylo::AlignFlags::FLEX_END => Some(taffy::AlignItems::FlexEnd),
201        stylo::AlignFlags::START => Some(taffy::AlignItems::Start),
202        stylo::AlignFlags::END => Some(taffy::AlignItems::End),
203        stylo::AlignFlags::CENTER => Some(taffy::AlignItems::Center),
204        stylo::AlignFlags::BASELINE => Some(taffy::AlignItems::Baseline),
205        // Should never be hit. But no real reason to panic here.
206        _ => None,
207    }
208}
209
210#[inline]
211pub(crate) fn grid_auto_flow(input: stylo::GridAutoFlow) -> taffy::GridAutoFlow {
212    let is_row = input.contains(stylo::GridAutoFlow::ROW);
213    let is_dense = input.contains(stylo::GridAutoFlow::DENSE);
214
215    match (is_row, is_dense) {
216        (true, false) => taffy::GridAutoFlow::Row,
217        (true, true) => taffy::GridAutoFlow::RowDense,
218        (false, false) => taffy::GridAutoFlow::Column,
219        (false, true) => taffy::GridAutoFlow::ColumnDense,
220    }
221}
222
223#[inline]
224pub(crate) fn grid_line(input: &stylo::GridLine) -> taffy::GridPlacement {
225    if input.is_auto() {
226        taffy::GridPlacement::Auto
227    } else if input.is_span {
228        taffy::style_helpers::span(input.line_num.try_into().unwrap())
229    } else if input.line_num == 0 {
230        taffy::GridPlacement::Auto
231    } else {
232        taffy::style_helpers::line(input.line_num.try_into().unwrap())
233    }
234}
235
236#[inline]
237pub(crate) fn grid_template_tracks(input: &stylo::GridTemplateComponent) -> Vec<taffy::TrackSizingFunction> {
238    match input {
239        stylo::GenericGridTemplateComponent::None => Vec::new(),
240        stylo::GenericGridTemplateComponent::TrackList(list) => list
241            .values
242            .iter()
243            .map(|track| match track {
244                stylo::TrackListValue::TrackSize(size) => taffy::TrackSizingFunction::Single(track_size(size)),
245                stylo::TrackListValue::TrackRepeat(repeat) => taffy::TrackSizingFunction::Repeat(
246                    track_repeat(repeat.count),
247                    repeat.track_sizes.iter().map(track_size).collect(),
248                ),
249            })
250            .collect(),
251
252        // TODO: Implement subgrid and masonry
253        stylo::GenericGridTemplateComponent::Subgrid(_) => Vec::new(),
254        stylo::GenericGridTemplateComponent::Masonry => Vec::new(),
255    }
256}
257
258#[inline]
259pub(crate) fn grid_auto_tracks(input: &stylo::ImplicitGridTracks) -> Vec<taffy::NonRepeatedTrackSizingFunction> {
260    input.0.iter().map(track_size).collect()
261}
262
263#[inline]
264pub(crate) fn track_repeat(input: stylo::RepeatCount<i32>) -> taffy::GridTrackRepetition {
265    match input {
266        stylo::RepeatCount::Number(val) => taffy::GridTrackRepetition::Count(val.try_into().unwrap()),
267        stylo::RepeatCount::AutoFill => taffy::GridTrackRepetition::AutoFill,
268        stylo::RepeatCount::AutoFit => taffy::GridTrackRepetition::AutoFit,
269    }
270}
271
272#[inline]
273pub(crate) fn track_size(input: &stylo::TrackSize<stylo::LengthPercentage>) -> taffy::NonRepeatedTrackSizingFunction {
274    match input {
275        stylo::TrackSize::Breadth(breadth) => taffy::MinMax { min: min_track(breadth), max: max_track(breadth) },
276        stylo::TrackSize::Minmax(min, max) => taffy::MinMax { min: min_track(min), max: max_track(max) },
277        stylo::TrackSize::FitContent(limit) => taffy::MinMax {
278            min: taffy::MinTrackSizingFunction::Auto,
279            max: taffy::MaxTrackSizingFunction::FitContent(match limit {
280                stylo::TrackBreadth::Breadth(lp) => length_percentage(lp),
281
282                // Are these valid? Taffy doesn't support this in any case
283                stylo::TrackBreadth::Fr(_) => unreachable!(),
284                stylo::TrackBreadth::Auto => unreachable!(),
285                stylo::TrackBreadth::MinContent => unreachable!(),
286                stylo::TrackBreadth::MaxContent => unreachable!(),
287            }),
288        },
289    }
290}
291
292#[inline]
293pub(crate) fn min_track(input: &stylo::TrackBreadth<stylo::LengthPercentage>) -> taffy::MinTrackSizingFunction {
294    match input {
295        stylo::TrackBreadth::Breadth(lp) => taffy::MinTrackSizingFunction::Fixed(length_percentage(lp)),
296        stylo::TrackBreadth::Fr(_) => taffy::MinTrackSizingFunction::Auto,
297        stylo::TrackBreadth::Auto => taffy::MinTrackSizingFunction::Auto,
298        stylo::TrackBreadth::MinContent => taffy::MinTrackSizingFunction::MinContent,
299        stylo::TrackBreadth::MaxContent => taffy::MinTrackSizingFunction::MaxContent,
300    }
301}
302
303#[inline]
304pub(crate) fn max_track(input: &stylo::TrackBreadth<stylo::LengthPercentage>) -> taffy::MaxTrackSizingFunction {
305    match input {
306        stylo::TrackBreadth::Breadth(lp) => taffy::MaxTrackSizingFunction::Fixed(length_percentage(lp)),
307        stylo::TrackBreadth::Fr(val) => taffy::MaxTrackSizingFunction::Fraction(*val),
308        stylo::TrackBreadth::Auto => taffy::MaxTrackSizingFunction::Auto,
309        stylo::TrackBreadth::MinContent => taffy::MaxTrackSizingFunction::MinContent,
310        stylo::TrackBreadth::MaxContent => taffy::MaxTrackSizingFunction::MaxContent,
311    }
312}