Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flexbox: pass correct cross-axis available space when computing an item's intrinsic main size (+misc fixes) #522

Merged
merged 5 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,24 @@ fn compute_preliminary(

// If container size is undefined, determine the container's main size
// and then re-resolve gaps based on newly determined size
#[cfg(feature = "debug")]
NODE_LOGGER.log("determine_container_main_size");
let original_gap = constants.gap;
if let Some(inner_main_size) = constants.node_inner_size.main(constants.dir) {
let outer_main_size = inner_main_size + constants.content_box_inset.main_axis_sum(constants.dir);
constants.inner_container_size.set_main(constants.dir, inner_main_size);
constants.container_size.set_main(constants.dir, outer_main_size);
} else {
// Sets constants.container_size and constants.outer_container_size
determine_container_main_size(tree, available_space.main(constants.dir), &mut flex_lines, &mut constants);
determine_container_main_size(tree, available_space, &mut flex_lines, &mut constants);
constants.node_inner_size.set_main(constants.dir, Some(constants.inner_container_size.main(constants.dir)));
constants.node_outer_size.set_main(constants.dir, Some(constants.container_size.main(constants.dir)));

#[cfg(feature = "debug")]
NODE_LOGGER.labelled_debug_log("constants.node_outer_size", constants.node_outer_size);
#[cfg(feature = "debug")]
NODE_LOGGER.labelled_debug_log("constants.node_inner_size", constants.node_inner_size);

// Re-resolve percentage gaps
let style = tree.style(node);
let inner_container_size = constants.inner_container_size.main(constants.dir);
Expand Down Expand Up @@ -689,7 +696,7 @@ fn determine_flex_base_size(
.cross(dir)
.into_option()
.maybe_clamp(child_min_cross, child_max_cross)
.maybe_sub(constants.margin.cross_axis_sum(dir)),
.maybe_sub(child.margin.cross_axis_sum(dir)),
);
}
ckd
Expand Down Expand Up @@ -848,14 +855,15 @@ fn collect_flex_lines<'a>(
/// Determine the container's main size (if not already known)
fn determine_container_main_size(
tree: &mut impl LayoutTree,
main_axis_available_space: AvailableSpace,
available_space: Size<AvailableSpace>,
lines: &mut Vec<FlexLine<'_>>,
constants: &mut AlgoConstants,
) {
let dir = constants.dir;
let main_content_box_inset = constants.content_box_inset.main_axis_sum(constants.dir);

let outer_main_size: f32 = constants.node_outer_size.main(constants.dir).unwrap_or_else(|| {
match main_axis_available_space {
match available_space.main(dir) {
AvailableSpace::Definite(main_axis_available_space) => {
let longest_line_length: f32 = lines
.iter()
Expand Down Expand Up @@ -940,14 +948,28 @@ fn determine_container_main_size(
// Else compute the min- or -max content size and apply the full formula for computing the
// min- or max- content contributuon
_ => {
// Parent size for child sizing
let cross_axis_parent_size = constants.node_inner_size.cross(dir);

// Available space for child sizing
let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
let child_min_cross = item.min_size.cross(dir).maybe_add(cross_axis_margin_sum);
let child_max_cross = item.max_size.cross(dir).maybe_add(cross_axis_margin_sum);
let cross_axis_available_space: AvailableSpace = available_space
.cross(dir)
.map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
.maybe_clamp(child_min_cross, child_max_cross);

let child_available_space = available_space.with_cross(dir, cross_axis_available_space);

// Either the min- or max- content size depending on which constraint we are sizing under.
// TODO: Optimise by using already computed values where available
let content_main_size = tree
.measure_child_size(
item.node,
Size::NONE,
constants.node_inner_size,
Size { width: main_axis_available_space, height: main_axis_available_space },
child_available_space,
SizingMode::InherentSize,
Line::FALSE,
)
Expand Down
13 changes: 9 additions & 4 deletions src/compute/leaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub fn compute(

// Note: both horizontal and vertical percentage padding/borders are resolved against the container's inline size (i.e. width).
// This is not a bug, but is how CSS is specified (see: https://developer.mozilla.org/en-US/docs/Web/CSS/padding#values)
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 padding_border = padding + border;
Expand Down Expand Up @@ -126,13 +127,17 @@ pub fn compute(
if let Some(measurable) = measurable {
// Compute available space
let available_space = Size {
width: available_space.width.maybe_set(node_size.width).maybe_set(node_max_size.width).map_definite_value(
|size| {
width: available_space
.width
.maybe_sub(margin.horizontal_axis_sum())
.maybe_set(node_size.width)
.maybe_set(node_max_size.width)
.map_definite_value(|size| {
size.maybe_clamp(node_min_size.width, node_max_size.width) - content_box_inset.horizontal_axis_sum()
},
),
}),
height: available_space
.height
.maybe_sub(margin.vertical_axis_sum())
.maybe_set(node_size.height)
.maybe_set(node_max_size.height)
.map_definite_value(|size| {
Expand Down
23 changes: 23 additions & 0 deletions test_fixtures/bevy_issue_9530.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
</head>
<body>

<div id="test-root" style="background: white; width: 300px; height: 300px; margin: auto; align-content: center; align-items: center; flex-direction: column;">
<div style="width: 100%; height: 20px; flex-direction: column; background: red;"></div>
<div style="width: 100%; flex-grow: 1; padding: 20px; margin: 20px; flex-direction: column; background: red;">
<div style="width: 100%; height: 50px;"></div>
<div style="/*width: 100%; */flex-grow: 1; align-content: center; align-items: center; justify-content: center; margin: 20px; background: blue;">HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH&ZeroWidthSpace;HHHH</div>
<div style="width: 100%; height: 50px;"></div>

</div>
</div>

</body>
</html>
19 changes: 19 additions & 0 deletions test_fixtures/bevy_issue_9530_reduced.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
</head>
<body>

<div id="test-root" style="flex-direction: column; width: 40px;">
<div style="flex-direction: column; flex-grow: 1;">
<div style="flex-grow: 1;">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
</div>
</div>

</body>
</html>
19 changes: 19 additions & 0 deletions test_fixtures/bevy_issue_9530_reduced2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
</head>
<body>

<div id="test-root" style="flex-direction: column;">
<div style="flex-direction: column; flex-grow: 1; width: 80px; margin: 0 20px;">
<div style="flex-grow: 1;">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
</div>
</div>

</body>
</html>
17 changes: 17 additions & 0 deletions test_fixtures/bevy_issue_9530_reduced3.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
</head>
<body>

<div id="test-root" style="flex-direction: column; width: 80px;">
<div style="flex-grow: 1; margin: 0 20px;">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
</div>

</body>
</html>
17 changes: 17 additions & 0 deletions test_fixtures/bevy_issue_9530_reduced4.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script src="../scripts/gentest/test_helper.js"></script>
<link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
<title>
Test description
</title>
</head>
<body>

<div id="test-root" style="flex-direction: column; width: 80px;">
<div style="margin: 20px;">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
</div>

</body>
</html>
Loading