diff options
-rw-r--r-- | components/layout/block.rs | 94 | ||||
-rw-r--r-- | tests/ref/basic.list | 1 | ||||
-rw-r--r-- | tests/ref/block_formatting_context_complex_a.html | 43 | ||||
-rw-r--r-- | tests/ref/block_formatting_context_complex_ref.html | 43 |
4 files changed, 151 insertions, 30 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index 64056147bf0..ed442ece546 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -510,9 +510,13 @@ pub struct BlockFlow { /// Static y offset of an absolute flow from its CB. pub static_b_offset: Au, - /// The inline-size of the last float prior to this block. This is used to speculatively lay out - /// block formatting contexts. - previous_float_inline_size: Option<Au>, + /// The sum of the inline-sizes of all logically left floats that precede this block. This is + /// used to speculatively lay out block formatting contexts. + inline_size_of_preceding_left_floats: Au, + + /// The sum of the inline-sizes of all logically right floats that precede this block. This is + /// used to speculatively lay out block formatting contexts. + inline_size_of_preceding_right_floats: Au, /// Additional floating flow members. pub float: Option<Box<FloatedBlockInfo>> @@ -525,7 +529,8 @@ impl BlockFlow { fragment: Fragment::new(constructor, node), is_root: false, static_b_offset: Au::new(0), - previous_float_inline_size: None, + inline_size_of_preceding_left_floats: Au(0), + inline_size_of_preceding_right_floats: Au(0), float: None } } @@ -536,7 +541,8 @@ impl BlockFlow { fragment: fragment, is_root: false, static_b_offset: Au::new(0), - previous_float_inline_size: None, + inline_size_of_preceding_left_floats: Au(0), + inline_size_of_preceding_right_floats: Au(0), float: None } } @@ -550,7 +556,8 @@ impl BlockFlow { fragment: Fragment::new(constructor, node), is_root: false, static_b_offset: Au::new(0), - previous_float_inline_size: None, + inline_size_of_preceding_left_floats: Au(0), + inline_size_of_preceding_right_floats: Au(0), float: Some(box FloatedBlockInfo::new(float_kind)), base: base, } @@ -565,7 +572,8 @@ impl BlockFlow { fragment: fragment, is_root: false, static_b_offset: Au::new(0), - previous_float_inline_size: None, + inline_size_of_preceding_left_floats: Au(0), + inline_size_of_preceding_right_floats: Au(0), float: Some(box FloatedBlockInfo::new(float_kind)), base: base, } @@ -1321,11 +1329,17 @@ impl BlockFlow { // This value is used only for table cells. let mut inline_start_margin_edge = inline_start_content_edge; - // The inline-size of the last float, if there was one. This is used for estimating the - // inline-sizes of block formatting contexts. (We estimate that the inline-size of any - // block formatting context that we see will be based on the inline-size of the containing - // block as well as the last float seen before it.) - let mut last_float_inline_size = None; + // Remember the inline-sizes of the last left and right floats, if there were any. These + // are used for estimating the inline-sizes of block formatting contexts. (We estimate that + // the inline-size of any block formatting context that we see will be based on the + // inline-size of the containing block as well as the last float seen before it in each + // direction.) + let mut inline_size_of_preceding_left_floats = Au(0); + let mut inline_size_of_preceding_right_floats = Au(0); + if self.formatting_context_type() == NonformattingContext { + inline_size_of_preceding_left_floats = self.inline_size_of_preceding_left_floats; + inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats; + } // Calculate non-auto block size to pass to children. let content_block_size = self.fragment.style().content_block_size(); @@ -1345,29 +1359,44 @@ impl BlockFlow { let kid_block = kid.as_block(); kid_block.base.absolute_static_i_offset = absolute_static_i_offset; kid_block.base.fixed_static_i_offset = fixed_static_i_offset; + } - if kid_block.is_float() { - last_float_inline_size = Some(kid_block.base.intrinsic_inline_sizes.preferred_inline_size) - } else { - kid_block.previous_float_inline_size = last_float_inline_size + match kid.float_kind() { + float::none => {} + float::left => { + inline_size_of_preceding_left_floats = inline_size_of_preceding_left_floats + + flow::base(kid).intrinsic_inline_sizes.preferred_inline_size; + } + float::right => { + inline_size_of_preceding_right_floats = inline_size_of_preceding_right_floats + + flow::base(kid).intrinsic_inline_sizes.preferred_inline_size; } } - // The inline-start margin edge of the child flow is at our inline-start content edge, and its inline-size - // is our content inline-size. + // The inline-start margin edge of the child flow is at our inline-start content edge, + // and its inline-size is our content inline-size. flow::mut_base(kid).position.start.i = inline_start_content_edge; flow::mut_base(kid).position.size.inline = content_inline_size; // Determine float impaction. match kid.float_clearance() { clear::none => {} - clear::left => inline_start_floats_impact_child = false, - clear::right => inline_end_floats_impact_child = false, + clear::left => { + inline_start_floats_impact_child = false; + inline_size_of_preceding_left_floats = Au(0); + } + clear::right => { + inline_end_floats_impact_child = false; + inline_size_of_preceding_right_floats = Au(0); + } clear::both => { inline_start_floats_impact_child = false; inline_end_floats_impact_child = false; + inline_size_of_preceding_left_floats = Au(0); + inline_size_of_preceding_right_floats = Au(0); } } + { let kid_base = flow::mut_base(kid); inline_start_floats_impact_child = inline_start_floats_impact_child || @@ -1378,6 +1407,14 @@ impl BlockFlow { kid_base.flags.set_impacted_by_right_floats(inline_end_floats_impact_child); } + if kid.is_block_flow() { + let kid_block = kid.as_block(); + kid_block.inline_size_of_preceding_left_floats = + inline_size_of_preceding_left_floats; + kid_block.inline_size_of_preceding_right_floats = + inline_size_of_preceding_right_floats; + } + // Handle tables. match opt_col_inline_sizes { Some(ref col_inline_sizes) => { @@ -1591,16 +1628,13 @@ impl Flow for BlockFlow { self.base.flags.set_impacted_by_left_floats(false); self.base.flags.set_impacted_by_right_floats(false); - // We can't actually compute the inline-size of this block now, because floats might - // affect it. Speculate that its inline-size is equal to the inline-size computed above minus - // the inline-size of the previous float. - match self.previous_float_inline_size { - None => {} - Some(previous_float_inline_size) => { - self.fragment.border_box.size.inline = - self.fragment.border_box.size.inline - previous_float_inline_size - } - } + // We can't actually compute the inline-size of this block now, because floats + // might affect it. Speculate that its inline-size is equal to the inline-size + // computed above minus the inline-size of the previous left and/or right floats. + self.fragment.border_box.size.inline = + self.fragment.border_box.size.inline - + self.inline_size_of_preceding_left_floats - + self.inline_size_of_preceding_right_floats; } OtherFormattingContext => { self.base.flags.set_impacted_by_left_floats(false); diff --git a/tests/ref/basic.list b/tests/ref/basic.list index dce827a76b6..c342c3bec9c 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -146,3 +146,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html == block_formatting_context_translation_a.html block_formatting_context_translation_ref.html == floated_table_with_margin_a.html floated_table_with_margin_ref.html == margins_inside_floats_a.html margins_inside_floats_ref.html +== block_formatting_context_complex_a.html block_formatting_context_complex_ref.html diff --git a/tests/ref/block_formatting_context_complex_a.html b/tests/ref/block_formatting_context_complex_a.html new file mode 100644 index 00000000000..aa79a65a6af --- /dev/null +++ b/tests/ref/block_formatting_context_complex_a.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<style> +.a { + height: 999999px; + color: white; +} +</style> +</head> +<body> +<div class=a style="float: right; width: 200px; background: blue;">Meow</div> +<div class=a style="float: left; width: 50px; background: orange;">Mimi</div> +<div class=a style="float: left; width: 50px; background: green;">the</div> +<div class=a style="float: left; width: 50px; background: violet;">cat</div> +<div style="overflow: hidden;"> +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +</div> +</body> +</html> + diff --git a/tests/ref/block_formatting_context_complex_ref.html b/tests/ref/block_formatting_context_complex_ref.html new file mode 100644 index 00000000000..8a894c3106b --- /dev/null +++ b/tests/ref/block_formatting_context_complex_ref.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<style> +.a { + height: 999999px; + color: white; +} +</style> +</head> +<body> +<div class=a style="float: right; width: 200px; background: blue;">Meow</div> +<div class=a style="float: left; width: 50px; background: orange;">Mimi</div> +<div class=a style="float: left; width: 50px; background: green;">the</div> +<div class=a style="float: left; width: 50px; background: violet;">cat</div> +<div> +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +There once was an engine named Servo +</div> +</body> +</html> + |