From 4cb9f32427acfed274d7d709ebc2d46f46326e59 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Fri, 5 Sep 2014 16:32:21 +1000 Subject: [PATCH] Fix inline size bubbling with fixed width block. Improve intrinsic inline size calculation for text fragments. These two fixes are related to the wikipedia metabug #2554. They don't make the wikipedia page look better (they cause a slight regression in the top caption table), but they are prerequisites for fixing some of the other layout issues that remain. Added reftests for each of the three cases I have come across that this patch solves. --- src/components/layout/block.rs | 23 +++++++++---- src/components/layout/fragment.rs | 8 ++--- src/test/ref/basic.list | 3 ++ ...dth_overrides_child_intrinsic_width_a.html | 33 +++++++++++++++++++ ...h_overrides_child_intrinsic_width_ref.html | 23 +++++++++++++ src/test/ref/float_intrinsic_width_a.html | 26 +++++++++++++++ src/test/ref/float_intrinsic_width_ref.html | 25 ++++++++++++++ .../ref/float_right_intrinsic_width_a.html | 25 ++++++++++++++ .../ref/float_right_intrinsic_width_ref.html | 25 ++++++++++++++ 9 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 src/test/ref/fixed_width_overrides_child_intrinsic_width_a.html create mode 100644 src/test/ref/fixed_width_overrides_child_intrinsic_width_ref.html create mode 100644 src/test/ref/float_intrinsic_width_a.html create mode 100644 src/test/ref/float_intrinsic_width_ref.html create mode 100644 src/test/ref/float_right_intrinsic_width_a.html create mode 100644 src/test/ref/float_right_intrinsic_width_ref.html diff --git a/src/components/layout/block.rs b/src/components/layout/block.rs index 5b433e44636..d5da5029dc6 100644 --- a/src/components/layout/block.rs +++ b/src/components/layout/block.rs @@ -1450,6 +1450,14 @@ impl Flow for BlockFlow { flags.set_has_left_floated_descendants(false); flags.set_has_right_floated_descendants(false); + // If this block has a fixed width, just use that for the minimum + // and preferred width, rather than bubbling up children inline + // width. + let fixed_width = match self.fragment.style().get_box().width { + LPA_Length(_) => true, + _ => false, + }; + // Find the maximum inline-size from children. let mut intrinsic_inline_sizes = IntrinsicISizes::new(); for child_ctx in self.base.child_iter() { @@ -1458,12 +1466,15 @@ impl Flow for BlockFlow { child_ctx.is_table_kind()); let child_base = flow::mut_base(child_ctx); - intrinsic_inline_sizes.minimum_inline_size = - geometry::max(intrinsic_inline_sizes.minimum_inline_size, - child_base.intrinsic_inline_sizes.total_minimum_inline_size()); - intrinsic_inline_sizes.preferred_inline_size = - geometry::max(intrinsic_inline_sizes.preferred_inline_size, - child_base.intrinsic_inline_sizes.total_preferred_inline_size()); + + if !fixed_width { + intrinsic_inline_sizes.minimum_inline_size = + geometry::max(intrinsic_inline_sizes.minimum_inline_size, + child_base.intrinsic_inline_sizes.total_minimum_inline_size()); + intrinsic_inline_sizes.preferred_inline_size = + geometry::max(intrinsic_inline_sizes.preferred_inline_size, + child_base.intrinsic_inline_sizes.total_preferred_inline_size()); + } flags.union_floated_descendants_flags(child_base.flags); } diff --git a/src/components/layout/fragment.rs b/src/components/layout/fragment.rs index 876ca785107..09c76d05985 100644 --- a/src/components/layout/fragment.rs +++ b/src/components/layout/fragment.rs @@ -1105,11 +1105,9 @@ impl Fragment { let range = &text_fragment_info.range; let min_line_inline_size = text_fragment_info.run.min_width_for_range(range); - let mut max_line_inline_size = Au::new(0); - for line_range in text_fragment_info.run.iter_natural_lines_for_range(range) { - let line_metrics = text_fragment_info.run.metrics_for_range(&line_range); - max_line_inline_size = Au::max(max_line_inline_size, line_metrics.advance_width); - } + // See http://dev.w3.org/csswg/css-sizing/#max-content-inline-size. + // TODO: Account for soft wrap opportunities. + let max_line_inline_size = text_fragment_info.run.metrics_for_range(range).advance_width; result.minimum_inline_size = geometry::max(result.minimum_inline_size, min_line_inline_size); result.preferred_inline_size = geometry::max(result.preferred_inline_size, max_line_inline_size); diff --git a/src/test/ref/basic.list b/src/test/ref/basic.list index 5cfa5619254..0ffafba5dca 100644 --- a/src/test/ref/basic.list +++ b/src/test/ref/basic.list @@ -107,3 +107,6 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html != inline_background_a.html inline_background_ref.html == inline_element_border_a.html inline_element_border_ref.html +== float_intrinsic_width_a.html float_intrinsic_width_ref.html +== float_right_intrinsic_width_a.html float_right_intrinsic_width_ref.html +== fixed_width_overrides_child_intrinsic_width_a.html fixed_width_overrides_child_intrinsic_width_ref.html diff --git a/src/test/ref/fixed_width_overrides_child_intrinsic_width_a.html b/src/test/ref/fixed_width_overrides_child_intrinsic_width_a.html new file mode 100644 index 00000000000..9d7a94cbbf8 --- /dev/null +++ b/src/test/ref/fixed_width_overrides_child_intrinsic_width_a.html @@ -0,0 +1,33 @@ + + + + + + +
+
+ X X +
+
+ + diff --git a/src/test/ref/fixed_width_overrides_child_intrinsic_width_ref.html b/src/test/ref/fixed_width_overrides_child_intrinsic_width_ref.html new file mode 100644 index 00000000000..439e8a049fc --- /dev/null +++ b/src/test/ref/fixed_width_overrides_child_intrinsic_width_ref.html @@ -0,0 +1,23 @@ + + + + + + +
+ + diff --git a/src/test/ref/float_intrinsic_width_a.html b/src/test/ref/float_intrinsic_width_a.html new file mode 100644 index 00000000000..cd1f4da319e --- /dev/null +++ b/src/test/ref/float_intrinsic_width_a.html @@ -0,0 +1,26 @@ + + + + + + +
X X
+ + diff --git a/src/test/ref/float_intrinsic_width_ref.html b/src/test/ref/float_intrinsic_width_ref.html new file mode 100644 index 00000000000..3e3865ab362 --- /dev/null +++ b/src/test/ref/float_intrinsic_width_ref.html @@ -0,0 +1,25 @@ + + + + + + +
+
+
+ + diff --git a/src/test/ref/float_right_intrinsic_width_a.html b/src/test/ref/float_right_intrinsic_width_a.html new file mode 100644 index 00000000000..5e503e34227 --- /dev/null +++ b/src/test/ref/float_right_intrinsic_width_a.html @@ -0,0 +1,25 @@ + + + + + + +
X X
+ + diff --git a/src/test/ref/float_right_intrinsic_width_ref.html b/src/test/ref/float_right_intrinsic_width_ref.html new file mode 100644 index 00000000000..841fd0ca477 --- /dev/null +++ b/src/test/ref/float_right_intrinsic_width_ref.html @@ -0,0 +1,25 @@ + + + + + + +
+
+
+ +