mirror of
https://github.com/servo/servo.git
synced 2025-06-10 01:23:13 +00:00
layout: Store overflow for flows impacted by floats.
Makes qz.com visible. In order to work around a compiler bug involving Sized, this patch moves `store_overflow` to be a virtual method.
This commit is contained in:
parent
263b69cf7f
commit
b026a8ecf6
6 changed files with 74 additions and 41 deletions
|
@ -33,7 +33,7 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
|
|||
use display_list_builder::{FragmentDisplayListBuilding};
|
||||
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
|
||||
use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
|
||||
use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
|
||||
use flow::{ImmutableFlowUtils, PreorderFlowTraversal};
|
||||
use flow::{PostorderFlowTraversal, mut_base};
|
||||
use flow::{BLOCK_POSITION_IS_STATIC, HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
|
||||
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC};
|
||||
|
@ -1631,6 +1631,7 @@ impl Flow for BlockFlow {
|
|||
self.base.thread_id = parent_thread_id;
|
||||
if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
|
||||
self.assign_block_size(layout_context);
|
||||
self.store_overflow(layout_context);
|
||||
// Don't remove the restyle damage; `assign_block_size` decides whether that is
|
||||
// appropriate (which in the case of e.g. absolutely-positioned flows, it is not).
|
||||
}
|
||||
|
|
|
@ -221,11 +221,55 @@ pub trait Flow: fmt::Debug + Sync {
|
|||
if impacted {
|
||||
mut_base(self).thread_id = parent_thread_id;
|
||||
self.assign_block_size(layout_context);
|
||||
self.store_overflow(layout_context);
|
||||
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||
}
|
||||
impacted
|
||||
}
|
||||
|
||||
/// Calculate and set overflow for current flow.
|
||||
///
|
||||
/// CSS Section 11.1
|
||||
/// This is the union of rectangles of the flows for which we define the
|
||||
/// Containing Block.
|
||||
///
|
||||
/// FIXME(pcwalton): This should not be a virtual method, but currently is due to a compiler
|
||||
/// bug ("the trait `Sized` is not implemented for `self`").
|
||||
///
|
||||
/// Assumption: This is called in a bottom-up traversal, so kids' overflows have
|
||||
/// already been set.
|
||||
/// Assumption: Absolute descendants have had their overflow calculated.
|
||||
fn store_overflow(&mut self, _: &LayoutContext) {
|
||||
// Calculate overflow on a per-fragment basis.
|
||||
let mut overflow = self.compute_overflow();
|
||||
match self.class() {
|
||||
FlowClass::Block |
|
||||
FlowClass::TableCaption |
|
||||
FlowClass::TableCell if base(self).children.len() != 0 => {
|
||||
// FIXME(#2795): Get the real container size.
|
||||
let container_size = Size2D::zero();
|
||||
for kid in mut_base(self).children.iter_mut() {
|
||||
if base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
continue
|
||||
}
|
||||
let kid_overflow = base(kid).overflow;
|
||||
let kid_position = base(kid).position.to_physical(base(kid).writing_mode,
|
||||
container_size);
|
||||
overflow = overflow.union(&kid_overflow.translate(&kid_position.origin))
|
||||
}
|
||||
|
||||
for kid in mut_base(self).abs_descendants.iter() {
|
||||
let kid_overflow = base(kid).overflow;
|
||||
let kid_position = base(kid).position.to_physical(base(kid).writing_mode,
|
||||
container_size);
|
||||
overflow = overflow.union(&kid_overflow.translate(&kid_position.origin))
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
mut_base(self).overflow = overflow;
|
||||
}
|
||||
|
||||
/// Phase 4 of reflow: computes absolute positions.
|
||||
fn compute_absolute_position(&mut self) {
|
||||
// The default implementation is a no-op.
|
||||
|
@ -429,9 +473,6 @@ pub trait MutableFlowUtils {
|
|||
|
||||
// Mutators
|
||||
|
||||
/// Computes the overflow region for this flow.
|
||||
fn store_overflow(self, _: &LayoutContext);
|
||||
|
||||
/// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of
|
||||
/// calling them individually, since there is no reason not to perform both operations.
|
||||
fn repair_style_and_bubble_inline_sizes(self, style: &Arc<ComputedValues>);
|
||||
|
@ -1228,41 +1269,6 @@ impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Calculate and set overflow for current flow.
|
||||
///
|
||||
/// CSS Section 11.1
|
||||
/// This is the union of rectangles of the flows for which we define the
|
||||
/// Containing Block.
|
||||
///
|
||||
/// Assumption: This is called in a bottom-up traversal, so kids' overflows have
|
||||
/// already been set.
|
||||
/// Assumption: Absolute descendants have had their overflow calculated.
|
||||
fn store_overflow(self, _: &LayoutContext) {
|
||||
// Calculate overflow on a per-fragment basis.
|
||||
let mut overflow = self.compute_overflow();
|
||||
if self.is_block_container() {
|
||||
// FIXME(#2795): Get the real container size.
|
||||
let container_size = Size2D::zero();
|
||||
for kid in child_iter(self) {
|
||||
if base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
continue
|
||||
}
|
||||
let kid_overflow = base(kid).overflow;
|
||||
let kid_position = base(kid).position.to_physical(base(kid).writing_mode,
|
||||
container_size);
|
||||
overflow = overflow.union(&kid_overflow.translate(&kid_position.origin))
|
||||
}
|
||||
|
||||
for kid in mut_base(self).abs_descendants.iter() {
|
||||
let kid_overflow = base(kid).overflow;
|
||||
let kid_position = base(kid).position.to_physical(base(kid).writing_mode,
|
||||
container_size);
|
||||
overflow = overflow.union(&kid_overflow.translate(&kid_position.origin))
|
||||
}
|
||||
}
|
||||
|
||||
mut_base(self).overflow = overflow;
|
||||
}
|
||||
|
||||
/// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of
|
||||
/// calling them individually, since there is no reason not to perform both operations.
|
||||
|
|
|
@ -10,9 +10,8 @@ use css::node_style::StyledNode;
|
|||
use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult};
|
||||
use construct::FlowConstructor;
|
||||
use context::LayoutContext;
|
||||
use flow::{Flow, MutableFlowUtils};
|
||||
use flow::{self, Flow};
|
||||
use flow::{PreorderFlowTraversal, PostorderFlowTraversal};
|
||||
use flow;
|
||||
use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
|
||||
use script::layout_interface::ReflowGoal;
|
||||
use wrapper::{layout_node_to_unsafe_layout_node, LayoutNode};
|
||||
|
|
|
@ -92,6 +92,7 @@ flaky_cpu == append_style_a.html append_style_b.html
|
|||
== float_clearance_intrinsic_width_a.html float_clearance_intrinsic_width_ref.html
|
||||
== float_intrinsic_height.html float_intrinsic_height_ref.html
|
||||
== float_intrinsic_width_a.html float_intrinsic_width_ref.html
|
||||
== float_overflow_area_a.html float_overflow_area_ref.html
|
||||
== float_right_intrinsic_width_a.html float_right_intrinsic_width_ref.html
|
||||
== float_table_a.html float_table_ref.html
|
||||
== float_under_top_margin_a.html float_under_top_margin_ref.html
|
||||
|
|
13
tests/ref/float_overflow_area_a.html
Normal file
13
tests/ref/float_overflow_area_a.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="transformX(0)"><div style="float: left">Y</div></div>
|
||||
</body>
|
||||
</html>
|
13
tests/ref/float_overflow_area_ref.html
Normal file
13
tests/ref/float_overflow_area_ref.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body, html {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div><div style="float: left">Y</div></div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue