gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definitions

⎇ 4e1c35c5d40729fdaafc40afeea863aa12ed1d5a benches/yoga_helpers.rs Rust · 154 lines · 6.2 KB History Who touched what raw

Implement head-to-head benchmarks against Yoga (#337) 4e1c35c5d · Nico Burns ·

1use slotmap::{DefaultKey, SlotMap};
2
3pub mod yg {
4    pub use ordered_float::OrderedFloat;
5    use slotmap::{DefaultKey, SlotMap};
6    pub use yoga::types::*;
7    pub use yoga::Node;
8
9    pub type YogaTree = SlotMap<DefaultKey, Node>;
10}
11mod tf {
12    pub use taffy::prelude::*;
13}
14
15pub fn new_with_children(
16    tree: &mut SlotMap<DefaultKey, yg::Node>,
17    style: &tf::Style,
18    children: Vec<DefaultKey>,
19) -> DefaultKey {
20    let mut node = yg::Node::new();
21    apply_taffy_style(&mut node, style);
22    for (i, child) in children.into_iter().enumerate() {
23        node.insert_child(&mut tree[child], i as u32);
24    }
25    tree.insert(node)
26}
27
28fn into_yg_units(dim: impl Into<tf::Dimension>) -> yg::StyleUnit {
29    match dim.into() {
30        tf::Dimension::Auto => yg::StyleUnit::Auto,
31        tf::Dimension::Points(val) => yg::StyleUnit::Point(yg::OrderedFloat(val)),
32        tf::Dimension::Percent(val) => yg::StyleUnit::Percent(yg::OrderedFloat(val)),
33    }
34}
35
36fn into_pixels(dim: impl Into<tf::Dimension>) -> f32 {
37    dim.into().into_option().unwrap_or(0.0)
38}
39
40fn items_into_align(align: Option<tf::AlignSelf>) -> yg::Align {
41    match align {
42        None => yg::Align::Auto,
43        Some(tf::AlignSelf::FlexStart) => yg::Align::FlexStart,
44        Some(tf::AlignSelf::FlexEnd) => yg::Align::FlexEnd,
45        Some(tf::AlignSelf::Center) => yg::Align::Center,
46        Some(tf::AlignSelf::Baseline) => yg::Align::Baseline,
47        Some(tf::AlignSelf::Stretch) => yg::Align::Stretch,
48        Some(tf::AlignSelf::Start) => unimplemented!(),
49        Some(tf::AlignSelf::End) => unimplemented!(),
50    }
51}
52
53fn content_into_align(align: Option<tf::AlignContent>) -> yg::Align {
54    match align {
55        None => yg::Align::Auto,
56        Some(tf::AlignContent::FlexStart) => yg::Align::FlexStart,
57        Some(tf::AlignContent::Start) => yg::Align::FlexStart,
58        Some(tf::AlignContent::FlexEnd) => yg::Align::FlexEnd,
59        Some(tf::AlignContent::End) => yg::Align::FlexEnd,
60        Some(tf::AlignContent::Center) => yg::Align::Center,
61        Some(tf::AlignContent::Stretch) => yg::Align::Stretch,
62        Some(tf::AlignContent::SpaceBetween) => yg::Align::SpaceBetween,
63        Some(tf::AlignContent::SpaceAround) => yg::Align::SpaceAround,
64        Some(tf::AlignContent::SpaceEvenly) => unimplemented!(),
65    }
66}
67
68fn content_into_justify(align: Option<tf::JustifyContent>) -> yg::Justify {
69    match align {
70        None => yg::Justify::FlexStart,
71        Some(tf::JustifyContent::FlexStart) => yg::Justify::FlexStart,
72        Some(tf::JustifyContent::Start) => yg::Justify::FlexStart,
73        Some(tf::JustifyContent::FlexEnd) => yg::Justify::FlexEnd,
74        Some(tf::JustifyContent::End) => yg::Justify::FlexEnd,
75        Some(tf::JustifyContent::Center) => yg::Justify::Center,
76        Some(tf::JustifyContent::SpaceBetween) => yg::Justify::SpaceBetween,
77        Some(tf::JustifyContent::SpaceAround) => yg::Justify::SpaceAround,
78        Some(tf::JustifyContent::Stretch) => unimplemented!(),
79        Some(tf::JustifyContent::SpaceEvenly) => unimplemented!(),
80    }
81}
82
83pub fn apply_taffy_style(node: &mut yg::Node, style: &tf::Style) {
84    // display
85    node.set_display(match style.display {
86        tf::Display::Flex => yg::Display::Flex,
87        tf::Display::Grid => panic!("Yoga does not support CSS Grid"),
88        tf::Display::None => yg::Display::None,
89    });
90
91    // position
92    node.set_position_type(match style.position {
93        tf::Position::Relative => yg::PositionType::Relative,
94        tf::Position::Absolute => yg::PositionType::Absolute,
95    });
96    // inset
97    node.set_position(yg::Edge::Left, into_yg_units(style.inset.left));
98    node.set_position(yg::Edge::Right, into_yg_units(style.inset.right));
99    node.set_position(yg::Edge::Top, into_yg_units(style.inset.top));
100    node.set_position(yg::Edge::Bottom, into_yg_units(style.inset.bottom));
101
102    // sizes
103    node.set_width(into_yg_units(style.size.width));
104    node.set_height(into_yg_units(style.size.height));
105    node.set_min_width(into_yg_units(style.min_size.width));
106    node.set_min_height(into_yg_units(style.min_size.height));
107    node.set_max_width(into_yg_units(style.max_size.width));
108    node.set_max_height(into_yg_units(style.max_size.height));
109
110    // aspect_ratio
111    if let Some(aspect_ratio) = style.aspect_ratio {
112        node.set_aspect_ratio(aspect_ratio);
113    }
114
115    // spacing
116    node.set_padding(yg::Edge::Left, into_yg_units(style.padding.left));
117    node.set_padding(yg::Edge::Right, into_yg_units(style.padding.right));
118    node.set_padding(yg::Edge::Top, into_yg_units(style.padding.top));
119    node.set_padding(yg::Edge::Bottom, into_yg_units(style.padding.bottom));
120    node.set_margin(yg::Edge::Left, into_yg_units(style.margin.left));
121    node.set_margin(yg::Edge::Right, into_yg_units(style.margin.right));
122    node.set_margin(yg::Edge::Top, into_yg_units(style.margin.top));
123    node.set_margin(yg::Edge::Bottom, into_yg_units(style.margin.bottom));
124    node.set_border(yg::Edge::Left, into_pixels(style.border.left));
125    node.set_border(yg::Edge::Right, into_pixels(style.border.right));
126    node.set_border(yg::Edge::Top, into_pixels(style.border.top));
127    node.set_border(yg::Edge::Bottom, into_pixels(style.border.bottom));
128
129    // alignment
130    node.set_align_items(items_into_align(style.align_items));
131    node.set_align_self(items_into_align(style.align_self));
132    node.set_align_content(content_into_align(style.align_content));
133    node.set_justify_content(content_into_justify(style.justify_content));
134
135    // gap
136    node.set_column_gap(into_pixels(style.gap.width));
137    node.set_row_gap(into_pixels(style.gap.height));
138
139    // flex
140    node.set_flex_direction(match style.flex_direction {
141        tf::FlexDirection::Row => yg::FlexDirection::Row,
142        tf::FlexDirection::Column => yg::FlexDirection::Column,
143        tf::FlexDirection::RowReverse => yg::FlexDirection::RowReverse,
144        tf::FlexDirection::ColumnReverse => yg::FlexDirection::ColumnReverse,
145    });
146    node.set_flex_wrap(match style.flex_wrap {
147        tf::FlexWrap::NoWrap => yg::Wrap::NoWrap,
148        tf::FlexWrap::Wrap => yg::Wrap::Wrap,
149        tf::FlexWrap::WrapReverse => yg::Wrap::WrapReverse,
150    });
151    node.set_flex_basis(into_yg_units(style.flex_basis));
152    node.set_flex_grow(style.flex_grow);
153    node.set_flex_shrink(style.flex_shrink);
154}