mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Merge pull request #3467 from pcwalton/enhance-block-formatting-context-guess
layout: Enhance the heuristic that guesses the inline size of block formatting contexts. Reviewed-by: glennw
This commit is contained in:
commit
20f5fdd000
4 changed files with 151 additions and 30 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
43
tests/ref/block_formatting_context_complex_a.html
Normal file
43
tests/ref/block_formatting_context_complex_a.html
Normal file
|
@ -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>
|
||||
|
43
tests/ref/block_formatting_context_complex_ref.html
Normal file
43
tests/ref/block_formatting_context_complex_ref.html
Normal file
|
@ -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>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue