From 6570f54adb2c6ef95c4702ccc588d54eff03e676 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 16:15:10 +0000 Subject: [PATCH 01/12] Failing complex percent tests --- ...grid_percent_nested_with_padding_margin.rs | 83 +++++++++++++ benches/generated/grid_percent_simple.rs | 60 ++++++++++ benches/generated/mod.rs | 8 ++ ...id_percent_nested_with_padding_margin.html | 22 ++++ test_fixtures/grid_percent_simple.html | 20 ++++ ...grid_percent_nested_with_padding_margin.rs | 113 ++++++++++++++++++ tests/generated/grid_percent_simple.rs | 85 +++++++++++++ tests/generated/mod.rs | 4 + 8 files changed, 395 insertions(+) create mode 100644 benches/generated/grid_percent_nested_with_padding_margin.rs create mode 100644 benches/generated/grid_percent_simple.rs create mode 100644 test_fixtures/grid_percent_nested_with_padding_margin.html create mode 100644 test_fixtures/grid_percent_simple.html create mode 100644 tests/generated/grid_percent_nested_with_padding_margin.rs create mode 100644 tests/generated/grid_percent_simple.rs diff --git a/benches/generated/grid_percent_nested_with_padding_margin.rs b/benches/generated/grid_percent_nested_with_padding_margin.rs new file mode 100644 index 000000000..d37dbcbec --- /dev/null +++ b/benches/generated/grid_percent_nested_with_padding_margin.rs @@ -0,0 +1,83 @@ +pub fn compute() { + #[allow(unused_imports)] + use taffy::prelude::*; + let mut taffy = taffy::Taffy::new(); + let node000 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node00 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node000], + ) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + min_size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.6f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + grid_template_rows: vec![flex(1f32), flex(4f32)], + size: taffy::geometry::Size { + width: taffy::style::Dimension::Points(200f32), + height: taffy::style::Dimension::Points(200f32), + }, + ..Default::default() + }, + &[node0, node1], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); +} diff --git a/benches/generated/grid_percent_simple.rs b/benches/generated/grid_percent_simple.rs new file mode 100644 index 000000000..338ba658a --- /dev/null +++ b/benches/generated/grid_percent_simple.rs @@ -0,0 +1,60 @@ +pub fn compute() { + #[allow(unused_imports)] + use taffy::prelude::*; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + grid_template_rows: vec![flex(1f32), flex(4f32)], + size: taffy::geometry::Size { + width: taffy::style::Dimension::Points(200f32), + height: taffy::style::Dimension::Points(200f32), + }, + ..Default::default() + }, + &[node0, node1], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); +} diff --git a/benches/generated/mod.rs b/benches/generated/mod.rs index f0d1949fc..e95ddbba3 100644 --- a/benches/generated/mod.rs +++ b/benches/generated/mod.rs @@ -405,6 +405,10 @@ mod grid_min_max_column_fixed_width_within_range; #[cfg(feature = "grid")] mod grid_out_of_order_items; #[cfg(feature = "grid")] +mod grid_percent_nested_with_padding_margin; +#[cfg(feature = "grid")] +mod grid_percent_simple; +#[cfg(feature = "grid")] mod grid_relayout_vertical_text; #[cfg(feature = "grid")] mod grid_size_child_fixed_tracks; @@ -906,6 +910,10 @@ fn benchmark(c: &mut Criterion) { #[cfg(feature = "grid")] grid_out_of_order_items::compute(); #[cfg(feature = "grid")] + grid_percent_nested_with_padding_margin::compute(); + #[cfg(feature = "grid")] + grid_percent_simple::compute(); + #[cfg(feature = "grid")] grid_relayout_vertical_text::compute(); #[cfg(feature = "grid")] grid_size_child_fixed_tracks::compute(); diff --git a/test_fixtures/grid_percent_nested_with_padding_margin.html b/test_fixtures/grid_percent_nested_with_padding_margin.html new file mode 100644 index 000000000..dfe30469f --- /dev/null +++ b/test_fixtures/grid_percent_nested_with_padding_margin.html @@ -0,0 +1,22 @@ + + + + + + + Test description + + + + +
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/test_fixtures/grid_percent_simple.html b/test_fixtures/grid_percent_simple.html new file mode 100644 index 000000000..9fa9f4b01 --- /dev/null +++ b/test_fixtures/grid_percent_simple.html @@ -0,0 +1,20 @@ + + + + + + + Test description + + + + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/tests/generated/grid_percent_nested_with_padding_margin.rs b/tests/generated/grid_percent_nested_with_padding_margin.rs new file mode 100644 index 000000000..786f53654 --- /dev/null +++ b/tests/generated/grid_percent_nested_with_padding_margin.rs @@ -0,0 +1,113 @@ +#[test] +fn grid_percent_nested_with_padding_margin() { + use slotmap::Key; + #[allow(unused_imports)] + use taffy::{layout::Layout, prelude::*}; + let mut taffy = taffy::Taffy::new(); + let node000 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node00 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node000], + ) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + min_size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.6f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + grid_template_rows: vec![flex(1f32), flex(4f32)], + size: taffy::geometry::Size { + width: taffy::style::Dimension::Points(200f32), + height: taffy::style::Dimension::Points(200f32), + }, + ..Default::default() + }, + &[node0, node1], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); + println!("\nComputed tree:"); + taffy::debug::print_tree(&taffy, node); + println!(); + let Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); + assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); + let Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 190f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 190f32, size.width); + assert_eq!(size.height, 41f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 41f32, size.height); + assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x); + assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y); + let Layout { size, location, .. } = taffy.layout(node00).unwrap(); + assert_eq!(size.width, 92f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 92f32, size.width); + assert_eq!(size.height, 25f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 25f32, size.height); + assert_eq!(location.x, 8f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 8f32, location.x); + assert_eq!(location.y, 8f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 8f32, location.y); + let Layout { size, location, .. } = taffy.layout(node000).unwrap(); + assert_eq!(size.width, 36f32, "width of node {:?}. Expected {}. Actual {}", node000.data(), 36f32, size.width); + assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node000.data(), 6f32, size.height); + assert_eq!(location.x, 10f32, "x of node {:?}. Expected {}. Actual {}", node000.data(), 10f32, location.x); + assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node000.data(), 10f32, location.y); + let Layout { size, location, .. } = taffy.layout(node1).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 200f32, size.width); + assert_eq!(size.height, 149f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 149f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x); + assert_eq!(location.y, 51f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 51f32, location.y); +} diff --git a/tests/generated/grid_percent_simple.rs b/tests/generated/grid_percent_simple.rs new file mode 100644 index 000000000..a8d30d052 --- /dev/null +++ b/tests/generated/grid_percent_simple.rs @@ -0,0 +1,85 @@ +#[test] +fn grid_percent_simple() { + use slotmap::Key; + #[allow(unused_imports)] + use taffy::{layout::Layout, prelude::*}; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + grid_template_rows: vec![flex(1f32), flex(4f32)], + size: taffy::geometry::Size { + width: taffy::style::Dimension::Points(200f32), + height: taffy::style::Dimension::Points(200f32), + }, + ..Default::default() + }, + &[node0, node1], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); + println!("\nComputed tree:"); + taffy::debug::print_tree(&taffy, node); + println!(); + let Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); + assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); + let Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 190f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 190f32, size.width); + assert_eq!(size.height, 30f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.height); + assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x); + assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y); + let Layout { size, location, .. } = taffy.layout(node00).unwrap(); + assert_eq!(size.width, 83f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 83f32, size.width); + assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height); + assert_eq!(location.x, 12f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 12f32, location.x); + assert_eq!(location.y, 12f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 12f32, location.y); + let Layout { size, location, .. } = taffy.layout(node1).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 200f32, size.width); + assert_eq!(size.height, 160f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 160f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x); + assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y); +} diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs index aa64bfe80..0d74b5de1 100644 --- a/tests/generated/mod.rs +++ b/tests/generated/mod.rs @@ -404,6 +404,10 @@ mod grid_min_max_column_fixed_width_within_range; #[cfg(feature = "grid")] mod grid_out_of_order_items; #[cfg(feature = "grid")] +mod grid_percent_nested_with_padding_margin; +#[cfg(feature = "grid")] +mod grid_percent_simple; +#[cfg(feature = "grid")] mod grid_relayout_vertical_text; #[cfg(feature = "grid")] mod grid_size_child_fixed_tracks; From af56f68fb21564a6f9fa273e50b425c5be448f09 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 17:08:29 +0000 Subject: [PATCH 02/12] Use available_grid_space rather than available_space in track sizing algorithm --- src/compute/grid/track_sizing.rs | 40 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs index 861c03bd1..714c9ff4f 100644 --- a/src/compute/grid/track_sizing.rs +++ b/src/compute/grid/track_sizing.rs @@ -171,7 +171,7 @@ pub(super) fn track_sizing_algorithm( ) { // 11.4 Initialise Track sizes // Initialize each track’s base size and growth limit. - initialize_track_sizes(axis_tracks, available_space.get(axis)); + initialize_track_sizes(axis_tracks, available_grid_space.get(axis)); // If all tracks have base_size = growth_limit, then skip the rest of this function. // Note: this can only happen both track sizing function have the same fixed track sizing function @@ -213,7 +213,7 @@ pub(super) fn track_sizing_algorithm( axis_tracks, other_axis_tracks, items, - available_space, + available_grid_space, get_track_size_estimate, ); @@ -272,7 +272,7 @@ fn flush_planned_growth_limit_increases(tracks: &mut [GridTrack], set_infinitely /// 11.4 Initialise Track sizes /// Initialize each track’s base size and growth limit. -fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_space: AvailableSpace) { +fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_grid_space: AvailableSpace) { let last_track_idx = axis_tracks.len() - 1; // First and last grid lines are always zero-sized. @@ -289,7 +289,7 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_space: A // Note: Indefinite lengths cannot occur, as they’re treated as auto. // - An intrinsic sizing function // Use an initial base size of zero. - track.base_size = track.min_track_sizing_function.definite_value(axis_available_space).unwrap_or(0.0); + track.base_size = track.min_track_sizing_function.definite_value(axis_available_grid_space).unwrap_or(0.0); // For each track, if the track’s max track sizing function is: // - A fixed sizing function @@ -299,7 +299,7 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_space: A // - A flexible sizing function // Use an initial growth limit of infinity. track.growth_limit = - track.max_track_sizing_function.definite_value(axis_available_space).unwrap_or(f32::INFINITY); + track.max_track_sizing_function.definite_value(axis_available_grid_space).unwrap_or(f32::INFINITY); // In all cases, if the growth limit is less than the base size, increase the growth limit to match the base size. if track.growth_limit < track.base_size { @@ -315,7 +315,7 @@ fn resolve_intrinsic_track_sizes( axis_tracks: &mut [GridTrack], other_axis_tracks: &mut [GridTrack], items: &mut [GridItem], - available_space: Size, + available_grid_space: Size, get_track_size_estimate: impl Fn(&GridTrack, AvailableSpace) -> Option, ) { // Step 1. Shim baseline-aligned items so their intrinsic size contributions reflect their baseline alignment. @@ -343,29 +343,37 @@ fn resolve_intrinsic_track_sizes( let known_dimensions = item.known_dimensions_cached( axis, other_axis_tracks, - available_space.get(axis.other()), + available_grid_space.get(axis.other()), &get_track_size_estimate, ); - let margin = item.margin.map(|m| m.resolve_or_zero(available_space.width.into_option())).sum_axes(); + let margin = item.margin.map(|m| m.resolve_or_zero(available_grid_space.width.into_option())).sum_axes(); + + dbg!(known_dimensions); + dbg!(available_grid_space.width); + dbg!(margin); let min_content_size = item.min_content_contribution_cached(tree, known_dimensions) + margin; let max_content_size = item.max_content_contribution_cached(tree, known_dimensions) + margin; let axis_minimum_size = - item.minimum_contribution_cached(tree, axis, axis_tracks, available_space, known_dimensions) + item.minimum_contribution_cached(tree, axis, axis_tracks, available_grid_space, known_dimensions) + margin.get(axis); + dbg!(axis_minimum_size); + dbg!(min_content_size.get(axis)); + dbg!(max_content_size.get(axis)); + (axis_minimum_size, min_content_size.get(axis), max_content_size.get(axis)) }; - let axis_available_space = available_space.get(axis); + let axis_available_grid_space = available_grid_space.get(axis); let mut batched_item_iterator = ItemBatcher::new(axis); while let Some((batch, is_flex)) = batched_item_iterator.next(items) { // 1. For intrinsic minimums: // First increase the base size of tracks with an intrinsic min track sizing function let has_intrinsic_min_track_sizing_function = move |track: &GridTrack| { - track.min_track_sizing_function.definite_value(available_space.get(axis)).is_none() + track.min_track_sizing_function.definite_value(available_grid_space.get(axis)).is_none() }; for item in batch.iter_mut() { let (axis_minimum_size, axis_min_content_size, _) = compute_item_sizes(item, axis_tracks); @@ -373,9 +381,9 @@ fn resolve_intrinsic_track_sizes( // ...by distributing extra space as needed to accommodate these items’ minimum contributions. // If the grid container is being sized under a min- or max-content constraint, use the items’ limited min-content contributions // in place of their minimum contributions here. - let space = match axis_available_space { + let space = match axis_available_grid_space { AvailableSpace::MinContent | AvailableSpace::MaxContent => { - let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_space); + let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_grid_space); axis_min_content_size.maybe_min(limit).max(axis_minimum_size) } AvailableSpace::Definite(_) => axis_minimum_size, @@ -421,14 +429,14 @@ fn resolve_intrinsic_track_sizes( // If the grid container is being sized under a max-content constraint, continue to increase the base size of tracks with // a min track sizing function of auto or max-content by distributing extra space as needed to account for these items' // limited max-content contributions. - if axis_available_space == AvailableSpace::MaxContent { + if axis_available_grid_space == AvailableSpace::MaxContent { let has_auto_or_max_content_min_track_sizing_function = move |track: &GridTrack| { use MinTrackSizingFunction::{Auto, MaxContent}; matches!(track.min_track_sizing_function, Auto | MaxContent) }; for item in batch.iter_mut() { let (_, _, axis_max_content_size) = compute_item_sizes(item, axis_tracks); - let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_space); + let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_grid_space); let space = axis_max_content_size.maybe_min(limit); let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)]; if space > 0.0 { @@ -477,7 +485,7 @@ fn resolve_intrinsic_track_sizes( // 5. For intrinsic maximums: Next increase the growth limit of tracks with an intrinsic max track sizing function by // distributing extra space as needed to account for these items' min-content contributions. let has_intrinsic_max_track_sizing_function = move |track: &GridTrack| { - track.max_track_sizing_function.definite_value(available_space.get(axis)).is_none() + track.max_track_sizing_function.definite_value(available_grid_space.get(axis)).is_none() }; for item in batch.iter_mut() { let (_, axis_min_content_size, _) = compute_item_sizes(item, axis_tracks); From cc0d92b78edd8ca8d00257d2dac3a63b0365fdb4 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 17:09:02 +0000 Subject: [PATCH 03/12] Return 0.0 for flex_fraction if free_space is negative --- src/compute/grid/track_sizing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs index 714c9ff4f..4b7fe79a8 100644 --- a/src/compute/grid/track_sizing.rs +++ b/src/compute/grid/track_sizing.rs @@ -695,7 +695,7 @@ fn expand_flexible_tracks( AvailableSpace::Definite(available_space) => { let used_space: f32 = axis_tracks.iter().map(|track| track.base_size).sum(); let free_space = available_space - used_space; - if free_space == 0.0 { + if free_space <= 0.0 { 0.0 } else { find_size_of_fr(axis_tracks, available_space) From 1891be3ad05d6d93f0c0f9d222ba03d5ca7b5421 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 17:09:46 +0000 Subject: [PATCH 04/12] Further simplify grid_percent_simple test --- benches/generated/grid_percent_simple.rs | 28 ++------------ test_fixtures/grid_percent_simple.html | 7 +--- tests/generated/grid_percent_simple.rs | 48 +++++------------------- 3 files changed, 15 insertions(+), 68 deletions(-) diff --git a/benches/generated/grid_percent_simple.rs b/benches/generated/grid_percent_simple.rs index 338ba658a..1d29d5684 100644 --- a/benches/generated/grid_percent_simple.rs +++ b/benches/generated/grid_percent_simple.rs @@ -2,7 +2,7 @@ pub fn compute() { #[allow(unused_imports)] use taffy::prelude::*; let mut taffy = taffy::Taffy::new(); - let node00 = taffy + let node0 = taffy .new_leaf(taffy::style::Style { size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, margin: taffy::geometry::Rect { @@ -20,16 +20,11 @@ pub fn compute() { ..Default::default() }) .unwrap(); - let node0 = taffy + let node = taffy .new_with_children( taffy::style::Style { display: taffy::style::Display::Grid, - margin: taffy::geometry::Rect { - left: taffy::style::LengthPercentageAuto::Points(5f32), - right: taffy::style::LengthPercentageAuto::Points(5f32), - top: taffy::style::LengthPercentageAuto::Points(5f32), - bottom: taffy::style::LengthPercentageAuto::Points(5f32), - }, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, padding: taffy::geometry::Rect { left: taffy::style::LengthPercentage::Points(3f32), right: taffy::style::LengthPercentage::Points(3f32), @@ -38,22 +33,7 @@ pub fn compute() { }, ..Default::default() }, - &[node00], - ) - .unwrap(); - let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); - let node = taffy - .new_with_children( - taffy::style::Style { - display: taffy::style::Display::Grid, - grid_template_rows: vec![flex(1f32), flex(4f32)], - size: taffy::geometry::Size { - width: taffy::style::Dimension::Points(200f32), - height: taffy::style::Dimension::Points(200f32), - }, - ..Default::default() - }, - &[node0, node1], + &[node0], ) .unwrap(); taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); diff --git a/test_fixtures/grid_percent_simple.html b/test_fixtures/grid_percent_simple.html index 9fa9f4b01..a28650d2e 100644 --- a/test_fixtures/grid_percent_simple.html +++ b/test_fixtures/grid_percent_simple.html @@ -9,11 +9,8 @@ -
-
-
-
-
+
+
diff --git a/tests/generated/grid_percent_simple.rs b/tests/generated/grid_percent_simple.rs index a8d30d052..cf1aae2da 100644 --- a/tests/generated/grid_percent_simple.rs +++ b/tests/generated/grid_percent_simple.rs @@ -4,7 +4,7 @@ fn grid_percent_simple() { #[allow(unused_imports)] use taffy::{layout::Layout, prelude::*}; let mut taffy = taffy::Taffy::new(); - let node00 = taffy + let node0 = taffy .new_leaf(taffy::style::Style { size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, margin: taffy::geometry::Rect { @@ -22,16 +22,11 @@ fn grid_percent_simple() { ..Default::default() }) .unwrap(); - let node0 = taffy + let node = taffy .new_with_children( taffy::style::Style { display: taffy::style::Display::Grid, - margin: taffy::geometry::Rect { - left: taffy::style::LengthPercentageAuto::Points(5f32), - right: taffy::style::LengthPercentageAuto::Points(5f32), - top: taffy::style::LengthPercentageAuto::Points(5f32), - bottom: taffy::style::LengthPercentageAuto::Points(5f32), - }, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, padding: taffy::geometry::Rect { left: taffy::style::LengthPercentage::Points(3f32), right: taffy::style::LengthPercentage::Points(3f32), @@ -40,22 +35,7 @@ fn grid_percent_simple() { }, ..Default::default() }, - &[node00], - ) - .unwrap(); - let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); - let node = taffy - .new_with_children( - taffy::style::Style { - display: taffy::style::Display::Grid, - grid_template_rows: vec![flex(1f32), flex(4f32)], - size: taffy::geometry::Size { - width: taffy::style::Dimension::Points(200f32), - height: taffy::style::Dimension::Points(200f32), - }, - ..Default::default() - }, - &[node0, node1], + &[node0], ) .unwrap(); taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); @@ -64,22 +44,12 @@ fn grid_percent_simple() { println!(); let Layout { size, location, .. } = taffy.layout(node).unwrap(); assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); - assert_eq!(size.height, 200f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.height); + assert_eq!(size.height, 31f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 31f32, size.height); assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); let Layout { size, location, .. } = taffy.layout(node0).unwrap(); - assert_eq!(size.width, 190f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 190f32, size.width); - assert_eq!(size.height, 30f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.height); - assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x); - assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y); - let Layout { size, location, .. } = taffy.layout(node00).unwrap(); - assert_eq!(size.width, 83f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 83f32, size.width); - assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height); - assert_eq!(location.x, 12f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 12f32, location.x); - assert_eq!(location.y, 12f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 12f32, location.y); - let Layout { size, location, .. } = taffy.layout(node1).unwrap(); - assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 200f32, size.width); - assert_eq!(size.height, 160f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 160f32, size.height); - assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x); - assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y); + assert_eq!(size.width, 87f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 87f32, size.width); + assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 6f32, size.height); + assert_eq!(location.x, 13f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 13f32, location.x); + assert_eq!(location.y, 13f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 13f32, location.y); } From 1685b4a15ecb76aa03daff8a1b4808d34fe66e63 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 17:10:01 +0000 Subject: [PATCH 05/12] Disable debug log of cache entries --- src/compute/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compute/mod.rs b/src/compute/mod.rs index c0c1ed9b5..427ab9754 100644 --- a/src/compute/mod.rs +++ b/src/compute/mod.rs @@ -199,8 +199,8 @@ fn compute_from_cache( ) -> Option> { for idx in 0..CACHE_SIZE { let entry = tree.cache_mut(node, idx); - #[cfg(feature = "debug")] - NODE_LOGGER.labelled_debug_log("cache_entry", &entry); + // #[cfg(feature = "debug")] + // NODE_LOGGER.labelled_debug_log("cache_entry", &entry); if let Some(entry) = entry { // Cached ComputeSize results are not valid if we are running in PerformLayout mode if entry.run_mode == RunMode::ComputeSize && run_mode == RunMode::PeformLayout { From f5e9139033bb77d6a50597d311783b7af5932aed Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Mon, 26 Dec 2022 18:00:31 +0000 Subject: [PATCH 06/12] Update percent sizing tests --- .../generated/grid_percent_nested_moderate.rs | 62 ++++++++++++++ ...le.rs => grid_percent_width_and_margin.rs} | 0 .../grid_percent_width_and_padding.rs | 28 +++++++ benches/generated/mod.rs | 12 ++- .../grid_percent_nested_moderate.html | 19 +++++ ...tml => grid_percent_width_and_margin.html} | 0 .../grid_percent_width_and_padding.html | 17 ++++ .../generated/grid_percent_nested_moderate.rs | 82 +++++++++++++++++++ ...le.rs => grid_percent_width_and_margin.rs} | 2 +- .../grid_percent_width_and_padding.rs | 43 ++++++++++ tests/generated/mod.rs | 6 +- 11 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 benches/generated/grid_percent_nested_moderate.rs rename benches/generated/{grid_percent_simple.rs => grid_percent_width_and_margin.rs} (100%) create mode 100644 benches/generated/grid_percent_width_and_padding.rs create mode 100644 test_fixtures/grid_percent_nested_moderate.html rename test_fixtures/{grid_percent_simple.html => grid_percent_width_and_margin.html} (100%) create mode 100644 test_fixtures/grid_percent_width_and_padding.html create mode 100644 tests/generated/grid_percent_nested_moderate.rs rename tests/generated/{grid_percent_simple.rs => grid_percent_width_and_margin.rs} (98%) create mode 100644 tests/generated/grid_percent_width_and_padding.rs diff --git a/benches/generated/grid_percent_nested_moderate.rs b/benches/generated/grid_percent_nested_moderate.rs new file mode 100644 index 000000000..901105b2d --- /dev/null +++ b/benches/generated/grid_percent_nested_moderate.rs @@ -0,0 +1,62 @@ +pub fn compute() { + #[allow(unused_imports)] + use taffy::prelude::*; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); +} diff --git a/benches/generated/grid_percent_simple.rs b/benches/generated/grid_percent_width_and_margin.rs similarity index 100% rename from benches/generated/grid_percent_simple.rs rename to benches/generated/grid_percent_width_and_margin.rs diff --git a/benches/generated/grid_percent_width_and_padding.rs b/benches/generated/grid_percent_width_and_padding.rs new file mode 100644 index 000000000..a145b5e86 --- /dev/null +++ b/benches/generated/grid_percent_width_and_padding.rs @@ -0,0 +1,28 @@ +pub fn compute() { + #[allow(unused_imports)] + use taffy::prelude::*; + let mut taffy = taffy::Taffy::new(); + let node0 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); +} diff --git a/benches/generated/mod.rs b/benches/generated/mod.rs index e95ddbba3..cad052e73 100644 --- a/benches/generated/mod.rs +++ b/benches/generated/mod.rs @@ -405,9 +405,13 @@ mod grid_min_max_column_fixed_width_within_range; #[cfg(feature = "grid")] mod grid_out_of_order_items; #[cfg(feature = "grid")] +mod grid_percent_nested_moderate; +#[cfg(feature = "grid")] mod grid_percent_nested_with_padding_margin; #[cfg(feature = "grid")] -mod grid_percent_simple; +mod grid_percent_width_and_margin; +#[cfg(feature = "grid")] +mod grid_percent_width_and_padding; #[cfg(feature = "grid")] mod grid_relayout_vertical_text; #[cfg(feature = "grid")] @@ -910,9 +914,13 @@ fn benchmark(c: &mut Criterion) { #[cfg(feature = "grid")] grid_out_of_order_items::compute(); #[cfg(feature = "grid")] + grid_percent_nested_moderate::compute(); + #[cfg(feature = "grid")] grid_percent_nested_with_padding_margin::compute(); #[cfg(feature = "grid")] - grid_percent_simple::compute(); + grid_percent_width_and_margin::compute(); + #[cfg(feature = "grid")] + grid_percent_width_and_padding::compute(); #[cfg(feature = "grid")] grid_relayout_vertical_text::compute(); #[cfg(feature = "grid")] diff --git a/test_fixtures/grid_percent_nested_moderate.html b/test_fixtures/grid_percent_nested_moderate.html new file mode 100644 index 000000000..9dd670f2f --- /dev/null +++ b/test_fixtures/grid_percent_nested_moderate.html @@ -0,0 +1,19 @@ + + + + + + + Test description + + + + +
+
+
+
+
+ + + \ No newline at end of file diff --git a/test_fixtures/grid_percent_simple.html b/test_fixtures/grid_percent_width_and_margin.html similarity index 100% rename from test_fixtures/grid_percent_simple.html rename to test_fixtures/grid_percent_width_and_margin.html diff --git a/test_fixtures/grid_percent_width_and_padding.html b/test_fixtures/grid_percent_width_and_padding.html new file mode 100644 index 000000000..224516037 --- /dev/null +++ b/test_fixtures/grid_percent_width_and_padding.html @@ -0,0 +1,17 @@ + + + + + + + Test description + + + + +
+
+
+ + + \ No newline at end of file diff --git a/tests/generated/grid_percent_nested_moderate.rs b/tests/generated/grid_percent_nested_moderate.rs new file mode 100644 index 000000000..19f0cbba1 --- /dev/null +++ b/tests/generated/grid_percent_nested_moderate.rs @@ -0,0 +1,82 @@ +#[test] +fn grid_percent_nested_moderate() { + use slotmap::Key; + #[allow(unused_imports)] + use taffy::{layout::Layout, prelude::*}; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); + println!("\nComputed tree:"); + taffy::debug::print_tree(&taffy, node); + println!(); + let Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); + assert_eq!(size.height, 42f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 42f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); + let Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 97f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 97f32, size.width); + assert_eq!(size.height, 26f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 26f32, size.height); + assert_eq!(location.x, 8f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.x); + assert_eq!(location.y, 8f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y); + let Layout { size, location, .. } = taffy.layout(node00).unwrap(); + assert_eq!(size.width, 38f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 38f32, size.width); + assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height); + assert_eq!(location.x, 10f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 10f32, location.x); + assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 10f32, location.y); +} diff --git a/tests/generated/grid_percent_simple.rs b/tests/generated/grid_percent_width_and_margin.rs similarity index 98% rename from tests/generated/grid_percent_simple.rs rename to tests/generated/grid_percent_width_and_margin.rs index cf1aae2da..4db83e269 100644 --- a/tests/generated/grid_percent_simple.rs +++ b/tests/generated/grid_percent_width_and_margin.rs @@ -1,5 +1,5 @@ #[test] -fn grid_percent_simple() { +fn grid_percent_width_and_margin() { use slotmap::Key; #[allow(unused_imports)] use taffy::{layout::Layout, prelude::*}; diff --git a/tests/generated/grid_percent_width_and_padding.rs b/tests/generated/grid_percent_width_and_padding.rs new file mode 100644 index 000000000..e9d8e0c0c --- /dev/null +++ b/tests/generated/grid_percent_width_and_padding.rs @@ -0,0 +1,43 @@ +#[test] +fn grid_percent_width_and_padding() { + use slotmap::Key; + #[allow(unused_imports)] + use taffy::{layout::Layout, prelude::*}; + let mut taffy = taffy::Taffy::new(); + let node0 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Grid, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); + println!("\nComputed tree:"); + taffy::debug::print_tree(&taffy, node); + println!(); + let Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); + assert_eq!(size.height, 12f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 12f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); + let Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width); + assert_eq!(size.height, 12f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 12f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y); +} diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs index 0d74b5de1..4e8786838 100644 --- a/tests/generated/mod.rs +++ b/tests/generated/mod.rs @@ -404,9 +404,13 @@ mod grid_min_max_column_fixed_width_within_range; #[cfg(feature = "grid")] mod grid_out_of_order_items; #[cfg(feature = "grid")] +mod grid_percent_nested_moderate; +#[cfg(feature = "grid")] mod grid_percent_nested_with_padding_margin; #[cfg(feature = "grid")] -mod grid_percent_simple; +mod grid_percent_width_and_margin; +#[cfg(feature = "grid")] +mod grid_percent_width_and_padding; #[cfg(feature = "grid")] mod grid_relayout_vertical_text; #[cfg(feature = "grid")] From 45513666376011740401a19635a5606892f85644 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 29 Dec 2022 21:23:32 +0000 Subject: [PATCH 07/12] Add moderate complexity percentage test for flexbox algorithm --- benches/generated/mod.rs | 2 + .../percentage_moderate_complexity.rs | 64 ++++++++++++++ .../percentage_moderate_complexity.html | 19 +++++ tests/generated/mod.rs | 1 + .../percentage_moderate_complexity.rs | 84 +++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 benches/generated/percentage_moderate_complexity.rs create mode 100644 test_fixtures/percentage_moderate_complexity.html create mode 100644 tests/generated/percentage_moderate_complexity.rs diff --git a/benches/generated/mod.rs b/benches/generated/mod.rs index cad052e73..ea7234c7d 100644 --- a/benches/generated/mod.rs +++ b/benches/generated/mod.rs @@ -520,6 +520,7 @@ mod percentage_flex_basis_main_max_height; mod percentage_flex_basis_main_max_width; mod percentage_flex_basis_main_min_width; mod percentage_margin_should_calculate_based_only_on_width; +mod percentage_moderate_complexity; mod percentage_multiple_nested_with_padding_margin_and_percentage_values; mod percentage_padding_should_calculate_based_only_on_width; mod percentage_position_bottom_right; @@ -1029,6 +1030,7 @@ fn benchmark(c: &mut Criterion) { percentage_flex_basis_main_max_width::compute(); percentage_flex_basis_main_min_width::compute(); percentage_margin_should_calculate_based_only_on_width::compute(); + percentage_moderate_complexity::compute(); percentage_multiple_nested_with_padding_margin_and_percentage_values::compute(); percentage_padding_should_calculate_based_only_on_width::compute(); percentage_position_bottom_right::compute(); diff --git a/benches/generated/percentage_moderate_complexity.rs b/benches/generated/percentage_moderate_complexity.rs new file mode 100644 index 000000000..cc733968b --- /dev/null +++ b/benches/generated/percentage_moderate_complexity.rs @@ -0,0 +1,64 @@ +pub fn compute() { + #[allow(unused_imports)] + use taffy::prelude::*; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Flex, + flex_direction: taffy::style::FlexDirection::Column, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Flex, + flex_direction: taffy::style::FlexDirection::Column, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); +} diff --git a/test_fixtures/percentage_moderate_complexity.html b/test_fixtures/percentage_moderate_complexity.html new file mode 100644 index 000000000..ce93de9ce --- /dev/null +++ b/test_fixtures/percentage_moderate_complexity.html @@ -0,0 +1,19 @@ + + + + + + + Test description + + + + +
+
+
+
+
+ + + \ No newline at end of file diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs index 4e8786838..30442ab48 100644 --- a/tests/generated/mod.rs +++ b/tests/generated/mod.rs @@ -519,6 +519,7 @@ mod percentage_flex_basis_main_max_height; mod percentage_flex_basis_main_max_width; mod percentage_flex_basis_main_min_width; mod percentage_margin_should_calculate_based_only_on_width; +mod percentage_moderate_complexity; mod percentage_multiple_nested_with_padding_margin_and_percentage_values; mod percentage_padding_should_calculate_based_only_on_width; mod percentage_position_bottom_right; diff --git a/tests/generated/percentage_moderate_complexity.rs b/tests/generated/percentage_moderate_complexity.rs new file mode 100644 index 000000000..87df70f35 --- /dev/null +++ b/tests/generated/percentage_moderate_complexity.rs @@ -0,0 +1,84 @@ +#[test] +fn percentage_moderate_complexity() { + use slotmap::Key; + #[allow(unused_imports)] + use taffy::{layout::Layout, prelude::*}; + let mut taffy = taffy::Taffy::new(); + let node00 = taffy + .new_leaf(taffy::style::Style { + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.45f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Percent(0.05f32), + right: taffy::style::LengthPercentageAuto::Percent(0.05f32), + top: taffy::style::LengthPercentageAuto::Percent(0.05f32), + bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }) + .unwrap(); + let node0 = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Flex, + flex_direction: taffy::style::FlexDirection::Column, + size: taffy::geometry::Size { width: taffy::style::Dimension::Percent(0.5f32), height: auto() }, + margin: taffy::geometry::Rect { + left: taffy::style::LengthPercentageAuto::Points(5f32), + right: taffy::style::LengthPercentageAuto::Points(5f32), + top: taffy::style::LengthPercentageAuto::Points(5f32), + bottom: taffy::style::LengthPercentageAuto::Points(5f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Percent(0.03f32), + right: taffy::style::LengthPercentage::Percent(0.03f32), + top: taffy::style::LengthPercentage::Percent(0.03f32), + bottom: taffy::style::LengthPercentage::Percent(0.03f32), + }, + ..Default::default() + }, + &[node00], + ) + .unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + display: taffy::style::Display::Flex, + flex_direction: taffy::style::FlexDirection::Column, + size: taffy::geometry::Size { width: taffy::style::Dimension::Points(200f32), height: auto() }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Points(3f32), + right: taffy::style::LengthPercentage::Points(3f32), + top: taffy::style::LengthPercentage::Points(3f32), + bottom: taffy::style::LengthPercentage::Points(3f32), + }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap(); + println!("\nComputed tree:"); + taffy::debug::print_tree(&taffy, node); + println!(); + let Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 200f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 200f32, size.width); + assert_eq!(size.height, 42f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 42f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y); + let Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 97f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 97f32, size.width); + assert_eq!(size.height, 26f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 26f32, size.height); + assert_eq!(location.x, 8f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.x); + assert_eq!(location.y, 8f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y); + let Layout { size, location, .. } = taffy.layout(node00).unwrap(); + assert_eq!(size.width, 38f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 38f32, size.width); + assert_eq!(size.height, 6f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height); + assert_eq!(location.x, 10f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 10f32, location.x); + assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 10f32, location.y); +} From 665c7f6bd907bc1f77c2c6a4b6409cbc0ec8dc23 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 29 Dec 2022 21:24:26 +0000 Subject: [PATCH 08/12] Introduce parent size parameter to layout algorithm + percentage sizing fixes --- src/compute/flexbox.rs | 77 +++++++++++++++++++---------- src/compute/grid/alignment.rs | 23 ++++++--- src/compute/grid/mod.rs | 53 ++++++++++++++------ src/compute/grid/track_sizing.rs | 41 +++++++++------ src/compute/grid/types/grid_item.rs | 7 ++- src/compute/leaf.rs | 11 +++-- src/compute/mod.rs | 18 +++++-- 7 files changed, 154 insertions(+), 76 deletions(-) diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs index 1c39fc3b0..a39871bc7 100644 --- a/src/compute/flexbox.rs +++ b/src/compute/flexbox.rs @@ -117,9 +117,12 @@ struct AlgoConstants { /// The align_items property of this node align_items: AlignItems, - /// The size of the internal node + /// The border-box size of the node being laid out (if known) + node_outer_size: Size>, + /// The content-box size of the node being laid out (if known) node_inner_size: Size>, - /// The size of the surrounding container + + /// The size of the virtual container containing the flex items. container_size: Size, /// The size of the internal container inner_container_size: Size, @@ -130,6 +133,7 @@ pub fn compute( tree: &mut impl LayoutTree, node: Node, known_dimensions: Size>, + parent_size: Size>, available_space: Size, run_mode: RunMode, ) -> Size { @@ -150,8 +154,8 @@ pub fn compute( let first_pass = compute_preliminary( tree, node, - // style.size.maybe_resolve(known_dimensions), known_dimensions.zip_map(clamped_style_size, |known, style| known.or(style)), + parent_size, available_space, RunMode::ComputeSize, ); @@ -162,13 +166,14 @@ pub fn compute( tree, node, known_dimensions.zip_map(clamped_first_pass_size, |known, first_pass| known.or_else(|| first_pass.into())), + parent_size, available_space, run_mode, ) } else { #[cfg(feature = "debug")] NODE_LOGGER.log("FLEX: single-pass"); - compute_preliminary(tree, node, known_dimensions.or(clamped_style_size), available_space, run_mode) + compute_preliminary(tree, node, known_dimensions.or(clamped_style_size), parent_size, available_space, run_mode) } } @@ -177,7 +182,8 @@ fn compute_preliminary( tree: &mut impl LayoutTree, node: Node, known_dimensions: Size>, - parent_size: Size, + parent_size: Size>, + available_space: Size, run_mode: RunMode, ) -> Size { // Define some general constants we will need for the remainder of the algorithm. @@ -197,7 +203,7 @@ fn compute_preliminary( // 2. Determine the available main and cross space for the flex items #[cfg(feature = "debug")] NODE_LOGGER.log("determine_available_space"); - let available_space = determine_available_space(known_dimensions, parent_size, &constants); + let available_space = determine_available_space(known_dimensions, available_space, &constants); let has_baseline_child = flex_items.iter().any(|child| child.align_self == AlignSelf::Baseline); @@ -362,6 +368,7 @@ fn compute_preliminary( tree, child, Size::NONE, + Size::NONE, Size::MAX_CONTENT, RunMode::PeformLayout, SizingMode::InherentSize, @@ -374,15 +381,19 @@ fn compute_preliminary( /// Compute constants that can be reused during the flexbox algorithm. #[inline] -fn compute_constants(style: &Style, node_size: Size>, parent_size: Size) -> AlgoConstants { +fn compute_constants( + style: &Style, + known_dimensions: Size>, + parent_size: Size>, +) -> AlgoConstants { let dir = style.flex_direction; let is_row = dir.is_row(); let is_column = dir.is_column(); let is_wrap_reverse = style.flex_wrap == FlexWrap::WrapReverse; - let margin = style.margin.resolve_or_zero(parent_size.width.into_option()); - let padding = style.padding.resolve_or_zero(parent_size.width.into_option()); - let border = style.border.resolve_or_zero(parent_size.width.into_option()); + let margin = style.margin.resolve_or_zero(parent_size.width); + let padding = style.padding.resolve_or_zero(parent_size.width); + let border = style.border.resolve_or_zero(parent_size.width); let align_items = style.align_items.unwrap_or(crate::style::AlignItems::Stretch); let padding_border = Rect { @@ -392,9 +403,18 @@ fn compute_constants(style: &Style, node_size: Size>, parent_size: S bottom: padding.bottom + border.bottom, }; + let node_outer_size = Size { + width: known_dimensions + .width + .or_else(|| style.size.width.maybe_resolve(parent_size.width).maybe_sub(margin.horizontal_axis_sum())), + height: known_dimensions + .height + .or_else(|| style.size.height.maybe_resolve(parent_size.height).maybe_sub(margin.vertical_axis_sum())), + }; + let node_inner_size = Size { - width: node_size.width.maybe_sub(padding_border.horizontal_axis_sum()), - height: node_size.height.maybe_sub(padding_border.vertical_axis_sum()), + width: node_outer_size.width.maybe_sub(padding_border.horizontal_axis_sum()), + height: node_outer_size.height.maybe_sub(padding_border.vertical_axis_sum()), }; let gap = style.gap.resolve_or_zero(node_inner_size.or(Size::zero())); @@ -411,6 +431,7 @@ fn compute_constants(style: &Style, node_size: Size>, parent_size: S gap, padding_border, align_items, + node_outer_size, node_inner_size, container_size, inner_container_size, @@ -580,7 +601,7 @@ fn determine_flex_base_size( let child_known_dimensions = { let mut ckd = child.size; if child.align_self == AlignSelf::Stretch && ckd.cross(constants.dir).is_none() { - ckd.set_cross(constants.dir, available_space.cross(constants.dir).into_option()); + ckd.set_cross(constants.dir, available_space.cross(constants.dir).into_option().maybe_sub(constants.margin.cross_axis_sum(constants.dir))); } ckd }; @@ -589,6 +610,7 @@ fn determine_flex_base_size( tree, child.node, child_known_dimensions, + constants.node_inner_size, available_space, RunMode::ComputeSize, SizingMode::ContentSize, @@ -603,18 +625,11 @@ fn determine_flex_base_size( child.inner_flex_basis = child.flex_basis - child.padding.main_axis_sum(constants.dir) - child.border.main_axis_sum(constants.dir); - let child_known_dimensions = { - let mut ckd = Size::NONE; - if child.align_self == AlignSelf::Stretch && ckd.cross(constants.dir).is_none() { - ckd.set_cross(constants.dir, available_space.cross(constants.dir).into_option()); - } - ckd - }; - let min_content_size = compute_node_layout( tree, child.node, - child_known_dimensions, // Should possibly also be Size::NONE + Size::NONE, + constants.node_inner_size, Size::MIN_CONTENT, RunMode::ComputeSize, SizingMode::ContentSize, @@ -953,6 +968,7 @@ fn determine_hypothetical_cross_size( width: if constants.is_row { child.target_size.width.into() } else { child_cross }, height: if constants.is_row { child_cross } else { child.target_size.height.into() }, }, + constants.node_inner_size, Size { width: if constants.is_row { constants.container_size.main(constants.dir).into() @@ -1016,6 +1032,7 @@ fn calculate_children_base_lines( child.target_size.height.into() }, }, + constants.node_inner_size, Size { width: if constants.is_row { constants.container_size.width.into() @@ -1436,12 +1453,14 @@ fn calculate_flex_item( total_offset_cross: f32, line_offset_cross: f32, container_size: Size, + node_inner_size: Size>, direction: FlexDirection, ) { let preliminary_size = compute_node_layout( tree, item.node, item.target_size.map(|s| s.into()), + node_inner_size, container_size.map(|s| s.into()), RunMode::PeformLayout, SizingMode::ContentSize, @@ -1479,6 +1498,7 @@ fn calculate_layout_line( line: &mut FlexLine, total_offset_cross: &mut f32, container_size: Size, + node_inner_size: Size>, padding_border: Rect, direction: FlexDirection, ) { @@ -1495,6 +1515,7 @@ fn calculate_layout_line( *total_offset_cross, line_offset_cross, container_size, + node_inner_size, direction, ); } @@ -1508,6 +1529,7 @@ fn calculate_layout_line( *total_offset_cross, line_offset_cross, container_size, + node_inner_size, direction, ); } @@ -1529,6 +1551,7 @@ fn final_layout_pass(tree: &mut impl LayoutTree, node: Node, flex_lines: &mut [F line, &mut total_offset_cross, constants.container_size, + constants.node_inner_size, constants.padding_border, constants.dir, ); @@ -1541,6 +1564,7 @@ fn final_layout_pass(tree: &mut impl LayoutTree, node: Node, flex_lines: &mut [F line, &mut total_offset_cross, constants.container_size, + constants.node_inner_size, constants.padding_border, constants.dir, ); @@ -1604,6 +1628,7 @@ fn perform_absolute_layout_on_absolute_children(tree: &mut impl LayoutTree, node tree, child, known_dimensions, + constants.node_inner_size, Size { width: AvailableSpace::Definite(container_width), height: AvailableSpace::Definite(container_height), @@ -1746,7 +1771,7 @@ mod tests { let node_id = tree.new_leaf(style.clone()).unwrap(); let node_size = Size::NONE; - let parent_size = Size::MAX_CONTENT; + let parent_size = Size::NONE; let constants = super::compute_constants(tree.style(node_id).unwrap(), node_size, parent_size); // let constants = super::compute_constants(&tree.nodes[node_id], node_size, parent_size); @@ -1756,13 +1781,13 @@ mod tests { assert!(constants.is_column == style.flex_direction.is_column()); assert!(constants.is_wrap_reverse == (style.flex_wrap == FlexWrap::WrapReverse)); - let margin = style.margin.resolve_or_zero(parent_size.into_options()); + let margin = style.margin.resolve_or_zero(parent_size); assert_eq!(constants.margin, margin); - let border = style.border.resolve_or_zero(parent_size.into_options()); + let border = style.border.resolve_or_zero(parent_size); assert_eq!(constants.border, border); - let padding = style.padding.resolve_or_zero(parent_size.into_options()); + let padding = style.padding.resolve_or_zero(parent_size); // TODO: Replace with something less hardcoded? let padding_border = Rect { diff --git a/src/compute/grid/alignment.rs b/src/compute/grid/alignment.rs index 28c9fb8af..ab5b822eb 100644 --- a/src/compute/grid/alignment.rs +++ b/src/compute/grid/alignment.rs @@ -12,6 +12,9 @@ use crate::style::{AlignContent, AlignItems, AlignSelf, AvailableSpace, Position use crate::sys::{f32_max, f32_min}; use crate::tree::LayoutTree; +#[cfg(feature = "debug")] +use crate::debug::NODE_LOGGER; + /// Align the grid tracks within the grid according to the align-content (rows) or /// justify-content (columns) property. This only does anything if the size of the /// grid is not equal to the size of the grid container in the axis being aligned. @@ -75,24 +78,24 @@ pub(super) fn align_and_position_item( node: Node, order: u32, grid_area: Rect, - container_content_box: Size, container_alignment_styles: InBothAbsAxis>, ) { let grid_area_size = Size { width: grid_area.right - grid_area.left, height: grid_area.bottom - grid_area.top }; + #[cfg(feature = "debug")] + NODE_LOGGER.labelled_debug_log("grid_area_size", grid_area_size); + let style = tree.style(node); let aspect_ratio = style.aspect_ratio; let justify_self = style.justify_self; let align_self = style.align_self; let position = style.position; - let inset_horizontal = - style.inset.horizontal_components().map(|size| size.resolve_to_option(container_content_box.width)); - let inset_vertical = - style.inset.vertical_components().map(|size| size.resolve_to_option(container_content_box.height)); - let inherent_size = style.size.maybe_resolve(container_content_box); - let min_size = style.min_size.maybe_resolve(container_content_box); - let max_size = style.max_size.maybe_resolve(container_content_box); + let inset_horizontal = style.inset.horizontal_components().map(|size| size.resolve_to_option(grid_area_size.width)); + let inset_vertical = style.inset.vertical_components().map(|size| size.resolve_to_option(grid_area_size.height)); + let inherent_size = style.size.maybe_resolve(grid_area_size); + let min_size = style.min_size.maybe_resolve(grid_area_size); + let max_size = style.max_size.maybe_resolve(grid_area_size); // Resolve default alignment styles if they are set on neither the parent or the node itself let alignment_styles = InBothAbsAxis { @@ -120,6 +123,9 @@ pub(super) fn align_and_position_item( height: grid_area_size.height.maybe_sub(margin.top).maybe_sub(margin.bottom), }; + #[cfg(feature = "debug")] + NODE_LOGGER.labelled_debug_log("grid_area_size", grid_area_minus_item_margins_size); + // If node is absolutely positioned and width is not set explicitly, then deduce it // from left, right and container_content_box if both are set. let width = inherent_size.width.or_else(|| { @@ -174,6 +180,7 @@ pub(super) fn align_and_position_item( tree, node, Size { width, height }, + grid_area_size.map(|s| Some(s)), grid_area_minus_item_margins_size.map(AvailableSpace::Definite), RunMode::PeformLayout, SizingMode::InherentSize, diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs index d6d390310..52c1aaa83 100644 --- a/src/compute/grid/mod.rs +++ b/src/compute/grid/mod.rs @@ -18,6 +18,9 @@ use track_sizing::{determine_if_item_crosses_flexible_tracks, resolve_item_track use types::{CellOccupancyMatrix, GridTrack}; use util::coordinates::css_grid_line_into_origin_zero_coords; +#[cfg(feature = "debug")] +use crate::debug::NODE_LOGGER; + use super::compute_node_layout; mod alignment; @@ -34,7 +37,13 @@ mod util; /// - Placing items (which also resolves the implicit grid) /// - Track (row/column) sizing /// - Alignment & Final item placement -pub fn compute(tree: &mut impl LayoutTree, node: Node, available_space: Size) -> Size { +pub fn compute( + tree: &mut impl LayoutTree, + node: Node, + known_dimensions: Size>, + parent_size: Size>, + available_space: Size, +) -> Size { let get_child_styles_iter = |node| tree.children(node).map(|child_node: &Node| tree.style(*child_node)); let style = tree.style(node).clone(); let child_styles_iter = get_child_styles_iter(node); @@ -92,11 +101,12 @@ pub fn compute(tree: &mut impl LayoutTree, node: Node, available_space: Size() @@ -229,14 +256,7 @@ pub fn compute(tree: &mut impl LayoutTree, node: Node, available_space: Size