tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 497HTML 254C 19JavaScript 81329 Definiciones

random small fixes

fd45f4e4404ac1d2ddb53b182c589cd53b15f615 · por Emil Sjölander · (hace 7 años) · padre b8e1c8fd3 · ver el árbol en este commit

Delta semántico · 9

src/algo.rs

9 archivos · +159 −86

diff --git a/src/algo.rs b/src/algo.rs
index 0cc1729c7..12c087ea6 100644
--- a/src/algo.rs
+++ b/src/algo.rs
@@ -34,6 +34,7 @@ struct FlexItem<'a> {
     hypothetical_inner_main_size: f32,
     hypothetical_outer_main_size: f32,
     target_main_size: f32,
+    outer_target_main_size: f32,
     violation: f32,
     frozen: bool,
 
@@ -209,6 +210,7 @@ fn compute_internal(
             hypothetical_inner_main_size: 0.0,
             hypothetical_outer_main_size: 0.0,
             target_main_size: 0.0,
+            outer_target_main_size: 0.0,
             violation: 0.0,
             frozen: false,
 
@@ -428,6 +430,9 @@ fn compute_internal(
 
         for child in line.items.iter_mut() {
             child.target_main_size = child.hypothetical_inner_main_size;
+            child.outer_target_main_size = child.target_main_size
+                + child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0)
+                + child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
 
             if (child.node.flex_grow == 0.0 && child.node.flex_shrink == 0.0)
                 || (growing && child.flex_basis > child.hypothetical_inner_main_size)
@@ -553,6 +558,9 @@ fn compute_internal(
                 child.violation = clamped - child.target_main_size;
                 total_violation += child.violation;
                 child.target_main_size = clamped;
+                child.outer_target_main_size = child.target_main_size
+                    + child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0)
+                    + child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
             }
 
             // e. Freeze over-flexed items. The total violation is the sum of the adjustments
@@ -589,13 +597,15 @@ fn compute_internal(
         let mut longest_line = f32::MIN;
 
         for line in &flex_lines {
-            let length: f32 = line.items.iter().map(|item| item.target_main_size).sum();
+            let length: f32 = line.items.iter().map(|item| item.outer_target_main_size).sum();
             longest_line = if length > longest_line { length } else { longest_line };
         }
 
         (longest_line + padding_main + border_main)
     };
 
+    let inner_container_main_size = container_main_size - padding_main - border_main;
+
     // 9.4. Cross Size Determination
 
     // 7. Determine the hypothetical cross size of each item by performing layout with the
@@ -725,15 +735,15 @@ fn compute_internal(
             }
 
             if is_stretch {
-                // TODO use result somehow
-                compute_internal(
+                let size = compute_internal(
                     child.node,
                     if node.flex_direction.is_row() { child.target_main_size } else { child.target_cross_size },
                     if node.flex_direction.is_row() { child.target_cross_size } else { child.target_main_size },
                     if node.flex_direction.is_row() { container_main_size } else { available_cross },
                     if node.flex_direction.is_row() { available_cross } else { container_main_size },
                     percent_calc_base_child,
-                );
+                ).size;
+                child.target_cross_size = size.cross(node.flex_direction);
             }
         }
     }
@@ -747,8 +757,16 @@ fn compute_internal(
     //     2. Align the items along the main-axis per justify-content.
 
     for line in &mut flex_lines {
-        let used_space: f32 = line.items.iter().map(|child| child.target_main_size).sum();
-        let free_space = available_main - used_space;
+        let used_space: f32 = line.items.iter().map(|child| child.outer_target_main_size).sum();
+        let free_space = inner_container_main_size - used_space;
+
+        // TODO does not make a ton of sense to have this here but we want to have this somewhere.
+        for child in &mut line.items {
+            child.main_margin_start =
+                child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+            child.main_margin_end =
+                child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+        }
 
         if free_space > 0.0 {
             let mut num_auto_margins = 0;
@@ -778,11 +796,6 @@ fn compute_internal(
                 let mut is_first = true;
 
                 for child in &mut line.items {
-                    child.main_margin_start =
-                        child.node.main_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-                    child.main_margin_end =
-                        child.node.main_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-
                     child.offset_main = match node.justify_content {
                         style::JustifyContent::FlexStart => 0.0,
                         style::JustifyContent::Center => if is_first {
@@ -826,6 +839,12 @@ fn compute_internal(
 
     for line in &mut flex_lines {
         for child in &mut line.items {
+            // TODO probably move this somewhere else, as with main margin resolution. Only auto margins should be resolved here.
+            child.cross_margin_start =
+                child.node.cross_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+            child.cross_margin_end =
+                child.node.cross_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
+
             if child.target_cross_size < line.cross_size {
                 let free_space = line.cross_size - child.target_cross_size;
 
@@ -839,11 +858,6 @@ fn compute_internal(
                 } else if child.node.cross_margin_end(node.flex_direction) == style::Dimension::Auto {
                     child.cross_margin_end = free_space;
                 } else {
-                    child.cross_margin_start =
-                        child.node.cross_margin_start(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-                    child.cross_margin_end =
-                        child.node.cross_margin_end(node.flex_direction).resolve(percent_calc_base_child, 0.0);
-
                     // 14. Align all flex items along the cross-axis per align-self, if neither of the item’s
                     //     cross-axis margins are auto.
 
@@ -881,10 +895,11 @@ fn compute_internal(
     let total_cross_size: f32 = flex_lines.iter().map(|line| line.cross_size).sum();
     let container_cross_size =
         if node_cross.is_finite() { node_cross } else { (total_cross_size + padding_cross + border_cross) };
+    let inner_container_cross_size = container_cross_size - padding_cross - border_cross;
 
     // 16. Align all flex lines per align-content.
 
-    let free_space = container_cross_size - total_cross_size;
+    let free_space = inner_container_cross_size - total_cross_size;
     let num_lines = flex_lines.len();
     let mut is_first = true;
 
diff --git a/test_fixtures/justify_content_column_min_height_and_margin_bottom.html b/test_fixtures/justify_content_column_min_height_and_margin_bottom.html
new file mode 100644
index 000000000..4eda0a929
--- /dev/null
+++ b/test_fixtures/justify_content_column_min_height_and_margin_bottom.html
@@ -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="min-height: 50px; justify-content: center; flex-direction: column;">
+  <div style="height: 20px; width: 20px; margin-bottom: 10px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/justify_content_column_min_height_and_margin.html b/test_fixtures/justify_content_column_min_height_and_margin_top.html
similarity index 100%
rename from test_fixtures/justify_content_column_min_height_and_margin.html
rename to test_fixtures/justify_content_column_min_height_and_margin_top.html
diff --git a/test_fixtures/justify_content_colunn_max_height_and_margin.html b/test_fixtures/justify_content_colunn_max_height_and_margin.html
index 8d1a2d4ea..b1fb9ceb4 100644
--- a/test_fixtures/justify_content_colunn_max_height_and_margin.html
+++ b/test_fixtures/justify_content_colunn_max_height_and_margin.html
@@ -9,8 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="height: 100px; max-height: 80px; margin-top: 100px; justify-content: center; flex-direction: column;">
-  <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="height: 100px; max-height: 80px; justify-content: center; flex-direction: column;">
+  <div style="height: 20px; width: 20px; margin-top: 100px;"></div>
 </div>
 
 </body>
diff --git a/test_fixtures/justify_content_overflow_min_max.html b/test_fixtures/justify_content_overflow_min_max.html
index 41f78c570..3300d7082 100644
--- a/test_fixtures/justify_content_overflow_min_max.html
+++ b/test_fixtures/justify_content_overflow_min_max.html
@@ -10,9 +10,9 @@
 <body>
 
 <div id="test-root" style="min-height: 100px; max-height: 110px; justify-content: center; flex-direction: column;">
-  <div style="width: 50px; height: 50px;"></div>
-  <div style="width: 50px; height: 50px;"></div>
-  <div style="width: 50px; height: 50px;"></div>
+  <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
+  <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
+  <div style="width: 50px; height: 50px; flex-shrink: 0;"></div>
 </div>
 
 </body>
diff --git a/test_fixtures/justify_content_row_max_width_and_margin.html b/test_fixtures/justify_content_row_max_width_and_margin.html
index db162a7e1..2dff79893 100644
--- a/test_fixtures/justify_content_row_max_width_and_margin.html
+++ b/test_fixtures/justify_content_row_max_width_and_margin.html
@@ -9,8 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="width: 100px; max-width: 80px; margin-left: 100px; justify-content: center; flex-direction: row;">
-  <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="width: 100px; max-width: 80px; justify-content: center; flex-direction: row;">
+  <div style="height: 20px; width: 20px; margin-left: 100px;"></div>
 </div>
 
 </body>
diff --git a/test_fixtures/justify_content_row_min_width_and_margin.html b/test_fixtures/justify_content_row_min_width_and_margin.html
index 902b528ed..aba377f96 100644
--- a/test_fixtures/justify_content_row_min_width_and_margin.html
+++ b/test_fixtures/justify_content_row_min_width_and_margin.html
@@ -9,8 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="min-width: 50px; margin-left: 100px; justify-content: center; flex-direction: row;">
-  <div style="height: 20px; width: 20px;"></div>
+<div id="test-root" style="min-width: 50px; justify-content: center; flex-direction: row;">
+  <div style="height: 20px; width: 20px; margin-left: 10px;"></div>
 </div>
 
 </body>
diff --git a/tests/generated.rs b/tests/generated.rs
index c6180df4c..60c87641d 100644
--- a/tests/generated.rs
+++ b/tests/generated.rs
@@ -887,6 +887,32 @@ mod generated {
         assert_eq!(layout.children[1].y, 0.0000);
     }
 
+    #[test]
+    fn justify_content_column_min_height_and_margin_top() {
+        let layout = stretch::compute(&stretch::style::Node {
+            flex_direction: stretch::style::FlexDirection::Column,
+            justify_content: stretch::style::JustifyContent::Center,
+            min_height: stretch::style::Dimension::Points(50.0000),
+            children: vec![stretch::style::Node {
+                width: stretch::style::Dimension::Points(20.0000),
+                height: stretch::style::Dimension::Points(20.0000),
+                margin: stretch::style::Edges { top: stretch::style::Dimension::Points(10.0000), ..Default::default() },
+                ..Default::default()
+            }],
+            ..Default::default()
+        });
+
+        assert_eq!(layout.width, 20.0000);
+        assert_eq!(layout.height, 50.0000);
+        assert_eq!(layout.x, 0.0000);
+        assert_eq!(layout.y, 0.0000);
+
+        assert_eq!(layout.children[0].width, 20.0000);
+        assert_eq!(layout.children[0].height, 20.0000);
+        assert_eq!(layout.children[0].x, 0.0000);
+        assert_eq!(layout.children[0].y, 20.0000);
+    }
+
     #[test]
     fn justify_content_overflow_min_max() {
         let layout = stretch::compute(&stretch::style::Node {
@@ -896,16 +922,19 @@ mod generated {
             max_height: stretch::style::Dimension::Points(110.0000),
             children: vec![
                 stretch::style::Node {
+                    flex_shrink: 0.0000,
                     width: stretch::style::Dimension::Points(50.0000),
                     height: stretch::style::Dimension::Points(50.0000),
                     ..Default::default()
                 },
                 stretch::style::Node {
+                    flex_shrink: 0.0000,
                     width: stretch::style::Dimension::Points(50.0000),
                     height: stretch::style::Dimension::Points(50.0000),
                     ..Default::default()
                 },
                 stretch::style::Node {
+                    flex_shrink: 0.0000,
                     width: stretch::style::Dimension::Points(50.0000),
                     height: stretch::style::Dimension::Points(50.0000),
                     ..Default::default()
@@ -920,19 +949,19 @@ mod generated {
         assert_eq!(layout.y, 0.0000);
 
         assert_eq!(layout.children[0].width, 50.0000);
-        assert_eq!(layout.children[0].height, 37.0000);
+        assert_eq!(layout.children[0].height, 50.0000);
         assert_eq!(layout.children[0].x, 0.0000);
-        assert_eq!(layout.children[0].y, 0.0000);
+        assert_eq!(layout.children[0].y, -20.0000);
 
         assert_eq!(layout.children[1].width, 50.0000);
-        assert_eq!(layout.children[1].height, 36.0000);
+        assert_eq!(layout.children[1].height, 50.0000);
         assert_eq!(layout.children[1].x, 0.0000);
-        assert_eq!(layout.children[1].y, 37.0000);
+        assert_eq!(layout.children[1].y, 30.0000);
 
         assert_eq!(layout.children[2].width, 50.0000);
-        assert_eq!(layout.children[2].height, 37.0000);
+        assert_eq!(layout.children[2].height, 50.0000);
         assert_eq!(layout.children[2].x, 0.0000);
-        assert_eq!(layout.children[2].y, 73.0000);
+        assert_eq!(layout.children[2].y, 80.0000);
     }
 
     #[test]
@@ -1917,10 +1946,13 @@ mod generated {
         let layout = stretch::compute(&stretch::style::Node {
             justify_content: stretch::style::JustifyContent::Center,
             min_width: stretch::style::Dimension::Points(50.0000),
-            margin: stretch::style::Edges { start: stretch::style::Dimension::Points(100.0000), ..Default::default() },
             children: vec![stretch::style::Node {
                 width: stretch::style::Dimension::Points(20.0000),
                 height: stretch::style::Dimension::Points(20.0000),
+                margin: stretch::style::Edges {
+                    start: stretch::style::Dimension::Points(10.0000),
+                    ..Default::default()
+                },
                 ..Default::default()
             }],
             ..Default::default()
@@ -1928,12 +1960,12 @@ mod generated {
 
         assert_eq!(layout.width, 50.0000);
         assert_eq!(layout.height, 20.0000);
-        assert_eq!(layout.x, 100.0000);
+        assert_eq!(layout.x, 0.0000);
         assert_eq!(layout.y, 0.0000);
 
         assert_eq!(layout.children[0].width, 20.0000);
         assert_eq!(layout.children[0].height, 20.0000);
-        assert_eq!(layout.children[0].x, 15.0000);
+        assert_eq!(layout.children[0].x, 20.0000);
         assert_eq!(layout.children[0].y, 0.0000);
     }
 
@@ -5736,10 +5768,13 @@ mod generated {
             justify_content: stretch::style::JustifyContent::Center,
             width: stretch::style::Dimension::Points(100.0000),
             max_width: stretch::style::Dimension::Points(80.0000),
-            margin: stretch::style::Edges { start: stretch::style::Dimension::Points(100.0000), ..Default::default() },
             children: vec![stretch::style::Node {
                 width: stretch::style::Dimension::Points(20.0000),
                 height: stretch::style::Dimension::Points(20.0000),
+                margin: stretch::style::Edges {
+                    start: stretch::style::Dimension::Points(100.0000),
+                    ..Default::default()
+                },
                 ..Default::default()
             }],
             ..Default::default()
@@ -5747,12 +5782,12 @@ mod generated {
 
         assert_eq!(layout.width, 80.0000);
         assert_eq!(layout.height, 20.0000);
-        assert_eq!(layout.x, 100.0000);
+        assert_eq!(layout.x, 0.0000);
         assert_eq!(layout.y, 0.0000);
 
-        assert_eq!(layout.children[0].width, 20.0000);
+        assert_eq!(layout.children[0].width, 0.0000);
         assert_eq!(layout.children[0].height, 20.0000);
-        assert_eq!(layout.children[0].x, 30.0000);
+        assert_eq!(layout.children[0].x, 90.0000);
         assert_eq!(layout.children[0].y, 0.0000);
     }
 
@@ -6275,10 +6310,13 @@ mod generated {
             justify_content: stretch::style::JustifyContent::Center,
             height: stretch::style::Dimension::Points(100.0000),
             max_height: stretch::style::Dimension::Points(80.0000),
-            margin: stretch::style::Edges { top: stretch::style::Dimension::Points(100.0000), ..Default::default() },
             children: vec![stretch::style::Node {
                 width: stretch::style::Dimension::Points(20.0000),
                 height: stretch::style::Dimension::Points(20.0000),
+                margin: stretch::style::Edges {
+                    top: stretch::style::Dimension::Points(100.0000),
+                    ..Default::default()
+                },
                 ..Default::default()
             }],
             ..Default::default()
@@ -6287,12 +6325,12 @@ mod generated {
         assert_eq!(layout.width, 20.0000);
         assert_eq!(layout.height, 80.0000);
         assert_eq!(layout.x, 0.0000);
-        assert_eq!(layout.y, 100.0000);
+        assert_eq!(layout.y, 0.0000);
 
         assert_eq!(layout.children[0].width, 20.0000);
-        assert_eq!(layout.children[0].height, 20.0000);
+        assert_eq!(layout.children[0].height, 0.0000);
         assert_eq!(layout.children[0].x, 0.0000);
-        assert_eq!(layout.children[0].y, 30.0000);
+        assert_eq!(layout.children[0].y, 90.0000);
     }
 
     #[test]
@@ -8419,32 +8457,6 @@ mod generated {
         assert_eq!(layout.children[1].y, 75.0000);
     }
 
-    #[test]
-    fn justify_content_column_min_height_and_margin() {
-        let layout = stretch::compute(&stretch::style::Node {
-            flex_direction: stretch::style::FlexDirection::Column,
-            justify_content: stretch::style::JustifyContent::Center,
-            min_height: stretch::style::Dimension::Points(50.0000),
-            children: vec![stretch::style::Node {
-                width: stretch::style::Dimension::Points(20.0000),
-                height: stretch::style::Dimension::Points(20.0000),
-                margin: stretch::style::Edges { top: stretch::style::Dimension::Points(10.0000), ..Default::default() },
-                ..Default::default()
-            }],
-            ..Default::default()
-        });
-
-        assert_eq!(layout.width, 20.0000);
-        assert_eq!(layout.height, 50.0000);
-        assert_eq!(layout.x, 0.0000);
-        assert_eq!(layout.y, 0.0000);
-
-        assert_eq!(layout.children[0].width, 20.0000);
-        assert_eq!(layout.children[0].height, 20.0000);
-        assert_eq!(layout.children[0].x, 0.0000);
-        assert_eq!(layout.children[0].y, 20.0000);
-    }
-
     #[test]
     fn align_flex_start_with_shrinking_children() {
         let layout = stretch::compute(&stretch::style::Node {
@@ -8488,4 +8500,33 @@ mod generated {
         assert_eq!(layout.children[0].children[0].children[0].y, 0.0000);
     }
 
+    #[test]
+    fn justify_content_column_min_height_and_margin_bottom() {
+        let layout = stretch::compute(&stretch::style::Node {
+            flex_direction: stretch::style::FlexDirection::Column,
+            justify_content: stretch::style::JustifyContent::Center,
+            min_height: stretch::style::Dimension::Points(50.0000),
+            children: vec![stretch::style::Node {
+                width: stretch::style::Dimension::Points(20.0000),
+                height: stretch::style::Dimension::Points(20.0000),
+                margin: stretch::style::Edges {
+                    bottom: stretch::style::Dimension::Points(10.0000),
+                    ..Default::default()
+                },
+                ..Default::default()
+            }],
+            ..Default::default()
+        });
+
+        assert_eq!(layout.width, 20.0000);
+        assert_eq!(layout.height, 50.0000);
+        assert_eq!(layout.x, 0.0000);
+        assert_eq!(layout.y, 0.0000);
+
+        assert_eq!(layout.children[0].width, 20.0000);
+        assert_eq!(layout.children[0].height, 20.0000);
+        assert_eq!(layout.children[0].x, 0.0000);
+        assert_eq!(layout.children[0].y, 10.0000);
+    }
+
 }