servo: Merge #12754 - Fix unexpected freeze of flex item (from stshine:no-divide-by-zero); r=pcwalton
authorPu Xingyu <pu.stshine@gmail.com>
Mon, 08 Aug 2016 00:39:05 -0500
changeset 339452 aac1e5c61fc01e735bd1365e601b8086a28a0b37
parent 339451 fbff82db52716111ef49973d0185f1c63e647941
child 339453 f1ac3e8ac9e8ff25ed07f6ab7c39b145a106f520
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
servo: Merge #12754 - Fix unexpected freeze of flex item (from stshine:no-divide-by-zero); r=pcwalton <!-- Please describe your changes on the following line: --> Fix the currently logic that a item will freeze if it should grow(shrink) and its basesize is less(more) than its min(max) size. This also fix the divide by zero error when an item should shrink but it has zero length and zero min size. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] There are tests for these changes <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: a83fed2144bc3c6ba5125d9b26d102b4e1e73b5a
servo/components/layout/flex.rs
--- a/servo/components/layout/flex.rs
+++ b/servo/components/layout/flex.rs
@@ -271,19 +271,18 @@ impl FlexLine {
         let mut total_shrink = 0.0;
         let mut total_scaled = 0.0;
         let mut active_count = 0;
         // Iterate through items, collect total factors and freeze those that have already met
         // their constraints or won't grow/shrink in corresponding scenario.
         // https://drafts.csswg.org/css-flexbox/#resolve-flexible-lengths
         for item in items.iter_mut().filter(|i| !(i.is_strut && collapse)) {
             item.main_size = max(item.min_size, min(item.base_size, item.max_size));
-            if item.main_size != item.base_size
-                || (self.free_space > Au(0) && item.flex_grow == 0.0)
-                || (self.free_space < Au(0) && item.flex_shrink == 0.0) {
+            if (self.free_space > Au(0) && (item.flex_grow == 0.0 || item.base_size >= item.max_size)) ||
+                (self.free_space < Au(0) && (item.flex_shrink == 0.0 || item.base_size <= item.min_size)) {
                     item.is_frozen = true;
                 } else {
                     item.is_frozen = false;
                     total_grow += item.flex_grow;
                     total_shrink += item.flex_shrink;
                     // The scaled factor is used to calculate flex shrink
                     total_scaled += item.flex_shrink * item.base_size.0 as f32;
                     active_count += 1;
@@ -306,17 +305,17 @@ impl FlexLine {
             for item in items.iter_mut().filter(|i| !i.is_frozen).filter(|i| !(i.is_strut && collapse)) {
                 // Use this and the 'abs()' below to make the code work in both grow and shrink scenarios.
                 let (factor, end_size) = if self.free_space > Au(0) {
                     (item.flex_grow / total_grow, item.max_size)
                 } else {
                     (item.flex_shrink * item.base_size.0 as f32 / total_scaled, item.min_size)
                 };
                 let variation = self.free_space.scale_by(factor);
-                if variation.0.abs() > (end_size - item.main_size).0.abs() {
+                if variation.0.abs() >= (end_size - item.main_size).0.abs() {
                     // Use constraint as the target main size, and freeze item.
                     total_variation += end_size - item.main_size;
                     item.main_size = end_size;
                     item.is_frozen = true;
                     active_count -= 1;
                     total_shrink -= item.flex_shrink;
                     total_grow -= item.flex_grow;
                     total_scaled -= item.flex_shrink * item.base_size.0 as f32;