aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/flow.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r--components/layout/flow.rs90
1 files changed, 68 insertions, 22 deletions
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 6d319bdd991..4e2da89f513 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -222,7 +222,11 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
if impacted {
mut_base(self).thread_id = parent_thread_id;
self.assign_block_size(layout_context);
- self.store_overflow(layout_context);
+ // FIXME(pcwalton): Should use `early_store_overflow()` here but that fails due to a
+ // compiler bug (`Self` does not have a constant size).
+ if !self.contains_relatively_positioned_fragments() {
+ self.store_overflow(layout_context)
+ }
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
}
impacted
@@ -246,7 +250,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
match self.class() {
FlowClass::Block |
FlowClass::TableCaption |
- FlowClass::TableCell if !base(self).children.is_empty() => {
+ FlowClass::TableCell => {
// FIXME(#2795): Get the real container size.
let container_size = Size2D::zero();
for kid in mut_base(self).children.iter_mut() {
@@ -310,13 +314,6 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
// different behaviour for different types of Flow, so they can't go into
// the Immutable / Mutable Flow Utils traits without additional casts.
- /// Return true if store overflow is delayed for this flow.
- ///
- /// Currently happens only for absolutely positioned flows.
- fn is_store_overflow_delayed(&mut self) -> bool {
- false
- }
-
fn is_root(&self) -> bool {
false
}
@@ -459,6 +456,11 @@ pub trait ImmutableFlowUtils {
/// Returns true if this flow is an inline flow.
fn is_inline_flow(self) -> bool;
+ /// Returns true if this flow can have its overflow area calculated early (during its
+ /// block-size assignment) or false if it must have its overflow area calculated late (during
+ /// its parent's block-size assignment).
+ fn can_calculate_overflow_area_early(self) -> bool;
+
/// Dumps the flow tree for debugging.
fn dump(self);
@@ -495,6 +497,12 @@ pub trait MutableFlowUtils {
/// 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>);
+
+ /// Calls `store_overflow()` if the overflow can be calculated early.
+ fn early_store_overflow(self, layout_context: &LayoutContext);
+
+ /// Calls `store_overflow()` if the overflow cannot be calculated early.
+ fn late_store_overflow(self, layout_context: &LayoutContext);
}
pub trait MutableOwnedFlowUtils {
@@ -780,15 +788,30 @@ impl<'a> Iterator for AbsoluteDescendantIter<'a> {
pub type AbsoluteDescendantOffsetIter<'a> = Zip<AbsoluteDescendantIter<'a>, IterMut<'a, Au>>;
/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
-/// confused with absolutely-positioned flows).
-#[derive(RustcEncodable, Copy, Clone)]
-pub struct AbsolutePositionInfo {
+/// confused with absolutely-positioned flows) that is computed during block-size assignment.
+pub struct EarlyAbsolutePositionInfo {
/// The size of the containing block for relatively-positioned descendants.
pub relative_containing_block_size: LogicalSize<Au>,
/// The writing mode for `relative_containing_block_size`.
pub relative_containing_block_mode: WritingMode,
+}
+
+impl EarlyAbsolutePositionInfo {
+ pub fn new(writing_mode: WritingMode) -> EarlyAbsolutePositionInfo {
+ // FIXME(pcwalton): The initial relative containing block-size should be equal to the size
+ // of the root layer.
+ EarlyAbsolutePositionInfo {
+ relative_containing_block_size: LogicalSize::zero(writing_mode),
+ relative_containing_block_mode: writing_mode,
+ }
+ }
+}
+/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
+/// confused with absolutely-positioned flows) that is computed during final position assignment.
+#[derive(RustcEncodable, Copy, Clone)]
+pub struct LateAbsolutePositionInfo {
/// The position of the absolute containing block relative to the nearest ancestor stacking
/// context. If the absolute containing block establishes the stacking context for this flow,
/// and this flow is not itself absolutely-positioned, then this is (0, 0).
@@ -800,13 +823,9 @@ pub struct AbsolutePositionInfo {
pub layers_needed_for_positioned_flows: bool,
}
-impl AbsolutePositionInfo {
- pub fn new(writing_mode: WritingMode) -> AbsolutePositionInfo {
- // FIXME(pcwalton): The initial relative containing block-size should be equal to the size
- // of the root layer.
- AbsolutePositionInfo {
- relative_containing_block_size: LogicalSize::zero(writing_mode),
- relative_containing_block_mode: writing_mode,
+impl LateAbsolutePositionInfo {
+ pub fn new() -> LateAbsolutePositionInfo {
+ LateAbsolutePositionInfo {
stacking_relative_position_of_absolute_containing_block: Point2D::zero(),
layers_needed_for_positioned_flows: false,
}
@@ -875,8 +894,13 @@ pub struct BaseFlow {
pub absolute_cb: ContainingBlockLink,
/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
- /// confused with absolutely-positioned flows).
- pub absolute_position_info: AbsolutePositionInfo,
+ /// confused with absolutely-positioned flows) that is computed during block-size assignment.
+ pub early_absolute_position_info: EarlyAbsolutePositionInfo,
+
+ /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
+ /// confused with absolutely-positioned flows) that is computed during final position
+ /// assignment.
+ pub late_absolute_position_info: LateAbsolutePositionInfo,
/// The clipping region for this flow and its descendants, in layer coordinates.
pub clip: ClippingRegion,
@@ -1038,7 +1062,8 @@ impl BaseFlow {
block_container_explicit_block_size: None,
absolute_cb: ContainingBlockLink::new(),
display_list_building_result: DisplayListBuildingResult::None,
- absolute_position_info: AbsolutePositionInfo::new(writing_mode),
+ early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
+ late_absolute_position_info: LateAbsolutePositionInfo::new(),
clip: ClippingRegion::max(),
stacking_relative_position_of_display_port: Rect::zero(),
flags: flags,
@@ -1276,6 +1301,13 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
}
}
+ /// Returns true if this flow can have its overflow area calculated early (during its
+ /// block-size assignment) or false if it must have its overflow area calculated late (during
+ /// its parent's block-size assignment).
+ fn can_calculate_overflow_area_early(self) -> bool {
+ !self.contains_relatively_positioned_fragments()
+ }
+
/// Dumps the flow tree for debugging.
fn dump(self) {
self.dump_with_level(0)
@@ -1354,6 +1386,20 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
traversal.process(*self)
}
+
+ /// Calls `store_overflow()` if the overflow can be calculated early.
+ fn early_store_overflow(self, layout_context: &LayoutContext) {
+ if self.can_calculate_overflow_area_early() {
+ self.store_overflow(layout_context)
+ }
+ }
+
+ /// Calls `store_overflow()` if the overflow cannot be calculated early.
+ fn late_store_overflow(self, layout_context: &LayoutContext) {
+ if !self.can_calculate_overflow_area_early() {
+ self.store_overflow(layout_context)
+ }
+ }
}
impl MutableOwnedFlowUtils for FlowRef {