aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/block.rs42
-rw-r--r--components/layout/display_list_builder.rs194
-rw-r--r--components/layout/flex.rs7
-rw-r--r--components/layout/flow.rs42
-rw-r--r--components/layout/inline.rs9
-rw-r--r--components/layout/layout_thread.rs13
-rw-r--r--components/layout/list_item.rs6
-rw-r--r--components/layout/multicol.rs4
-rw-r--r--components/layout/sequential.rs13
-rw-r--r--components/layout/table.rs2
-rw-r--r--components/layout/table_caption.rs2
-rw-r--r--components/layout/table_cell.rs2
-rw-r--r--components/layout/table_colgroup.rs2
-rw-r--r--components/layout/table_row.rs2
-rw-r--r--components/layout/table_rowgroup.rs2
-rw-r--r--components/layout/table_wrapper.rs2
-rw-r--r--components/layout/traversal.rs26
17 files changed, 160 insertions, 210 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index a538a768efd..19bb6e71ce2 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -64,7 +64,6 @@ use style::properties::ComputedValues;
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use util::geometry::MAX_RECT;
-use util::opts;
use util::print_tree::PrintTree;
/// Information specific to floated blocks.
@@ -1622,14 +1621,18 @@ impl BlockFlow {
}
}
- pub fn establishes_pseudo_stacking_context(&self) -> bool {
+ pub fn block_stacking_context_type(&self) -> BlockStackingContextType {
if self.fragment.establishes_stacking_context() {
- return false;
+ return BlockStackingContextType::StackingContext
}
- self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
- self.fragment.style.get_box().position != position::T::static_ ||
- self.base.flags.is_float()
+ if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
+ self.fragment.style.get_box().position != position::T::static_ ||
+ self.base.flags.is_float() {
+ BlockStackingContextType::PseudoStackingContext
+ } else {
+ BlockStackingContextType::NonstackingContext
+ }
}
pub fn has_scrolling_overflow(&self) -> bool {
@@ -1954,8 +1957,10 @@ impl Flow for BlockFlow {
self.base.position.size.to_physical(self.base.writing_mode);
// Compute the origin and clipping rectangle for children.
+ //
+ // `clip` is in the child coordinate system.
+ let mut clip;
let origin_for_children;
- let clip_in_child_coordinate_system;
let is_stacking_context = self.fragment.establishes_stacking_context();
if is_stacking_context {
// We establish a stacking context, so the position of our children is vertically
@@ -1966,12 +1971,11 @@ impl Flow for BlockFlow {
// FIXME(pcwalton): Is this vertical-writing-direction-safe?
let margin = self.fragment.margin.to_physical(self.base.writing_mode);
origin_for_children = Point2D::new(-margin.left, Au(0));
- clip_in_child_coordinate_system =
- self.base.clip.translate(&-self.base.stacking_relative_position);
+ clip = self.base.clip.translate(&-self.base.stacking_relative_position);
} else {
let relative_offset = relative_offset.to_physical(self.base.writing_mode);
origin_for_children = self.base.stacking_relative_position + relative_offset;
- clip_in_child_coordinate_system = self.base.clip.clone();
+ clip = self.base.clip.clone();
}
let stacking_relative_position_of_display_port_for_children =
@@ -2003,8 +2007,8 @@ impl Flow for BlockFlow {
.early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Own);
- let clip = self.fragment.clipping_region_for_children(
- &clip_in_child_coordinate_system,
+ self.fragment.adjust_clipping_region_for_children(
+ &mut clip,
&stacking_relative_border_box,
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
@@ -2109,7 +2113,7 @@ impl Flow for BlockFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.collect_stacking_contexts_for_block(parent_id, contexts)
}
@@ -2117,9 +2121,6 @@ impl Flow for BlockFlow {
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
self.build_display_list_for_block(state, BorderPaintingMode::Separate);
self.fragment.restyle_damage.remove(REPAINT);
- if opts::get().validate_display_list_geometry {
- self.base.validate_display_list_geometry();
- }
}
fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
@@ -3036,3 +3037,12 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced {
MaybeAuto::Specified(fragment.content_inline_size())
}
}
+
+/// A stacking context, a pseudo-stacking context, or a non-stacking context.
+#[derive(Copy, Clone, PartialEq)]
+pub enum BlockStackingContextType {
+ NonstackingContext,
+ PseudoStackingContext,
+ StackingContext,
+}
+
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 04beaca2064..b93c3c56c15 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -12,13 +12,13 @@
use app_units::{Au, AU_PER_PX};
use azure::azure_hl::Color;
-use block::BlockFlow;
+use block::{BlockFlow, BlockStackingContextType};
use canvas_traits::{CanvasMsg, CanvasPixelData, CanvasData, FromLayoutMsg};
use context::LayoutContext;
use euclid::num::Zero;
use euclid::{Matrix4, Point2D, Point3D, Rect, SideOffsets2D, Size2D};
use flex::FlexFlow;
-use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
+use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow_ref;
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
use fragment::{SpecificFragmentInfo};
@@ -67,8 +67,7 @@ pub struct DisplayListBuildState<'a> {
}
impl<'a> DisplayListBuildState<'a> {
- pub fn new(layout_context: &'a LayoutContext,
- stacking_context_id: StackingContextId)
+ pub fn new(layout_context: &'a LayoutContext, stacking_context_id: StackingContextId)
-> DisplayListBuildState<'a> {
DisplayListBuildState {
layout_context: layout_context,
@@ -87,21 +86,15 @@ impl<'a> DisplayListBuildState<'a> {
});
}
- fn append_from(&mut self, other_list: &mut Option<Vec<DisplayListEntry>>) {
- if let Some(mut other) = other_list.take() {
- self.items.append(&mut other);
- }
- }
-
fn stacking_context_id(&self) -> StackingContextId {
self.stacking_context_id_stack.last().unwrap().clone()
}
- fn push_stacking_context_id(&mut self, stacking_context_id: StackingContextId) {
+ pub fn push_stacking_context_id(&mut self, stacking_context_id: StackingContextId) {
self.stacking_context_id_stack.push(stacking_context_id);
}
- fn pop_stacking_context_id(&mut self) {
+ pub fn pop_stacking_context_id(&mut self) {
self.stacking_context_id_stack.pop();
assert!(!self.stacking_context_id_stack.is_empty());
}
@@ -232,19 +225,17 @@ pub trait FragmentDisplayListBuilding {
clip: &ClippingRegion,
stacking_relative_display_port: &Rect<Au>);
- /// Returns the appropriate clipping region for descendants of this fragment.
- fn clipping_region_for_children(&self,
- current_clip: &ClippingRegion,
- stacking_relative_border_box: &Rect<Au>,
- is_absolutely_positioned: bool)
- -> ClippingRegion;
+ /// Adjusts the clipping region for descendants of this fragment as appropriate.
+ fn adjust_clipping_region_for_children(&self,
+ current_clip: &mut ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>,
+ is_absolutely_positioned: bool);
- /// Calculates the clipping rectangle for a fragment, taking the `clip` property into account
+ /// Adjusts the clipping rectangle for a fragment to take the `clip` property into account
/// per CSS 2.1 § 11.1.2.
- fn calculate_style_specified_clip(&self,
- parent_clip: &ClippingRegion,
- stacking_relative_border_box: &Rect<Au>)
- -> ClippingRegion;
+ fn adjust_clip_for_style(&self,
+ parent_clip: &mut ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>);
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
/// if any.
@@ -287,7 +278,7 @@ pub trait FragmentDisplayListBuilding {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode)
- -> StackingContext;
+ -> Box<StackingContext>;
}
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
@@ -482,7 +473,8 @@ impl FragmentDisplayListBuilding for Fragment {
// Clip.
//
// TODO: Check the bounds to see if a clip item is actually required.
- let clip = clip.clone().intersect_rect(&bounds);
+ let mut clip = clip.clone();
+ clip.intersect_rect(&bounds);
// Background image should be positioned on the padding box basis.
let border = style.logical_border_width().to_physical(style.writing_mode);
@@ -581,7 +573,8 @@ impl FragmentDisplayListBuilding for Fragment {
clip: &ClippingRegion,
gradient: &LinearGradient,
style: &ComputedValues) {
- let clip = clip.clone().intersect_rect(absolute_bounds);
+ let mut clip = clip.clone();
+ clip.intersect_rect(absolute_bounds);
// This is the distance between the center and the ending point; i.e. half of the distance
// between the starting point and the ending point.
@@ -894,15 +887,14 @@ impl FragmentDisplayListBuilding for Fragment {
}), DisplayListSection::Content);
}
- fn calculate_style_specified_clip(&self,
- parent_clip: &ClippingRegion,
- stacking_relative_border_box: &Rect<Au>)
- -> ClippingRegion {
+ fn adjust_clip_for_style(&self,
+ parent_clip: &mut ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>) {
// Account for `clip` per CSS 2.1 § 11.1.2.
let style_clip_rect = match (self.style().get_box().position,
self.style().get_effects().clip.0) {
(position::T::absolute, Some(style_clip_rect)) => style_clip_rect,
- _ => return (*parent_clip).clone(),
+ _ => return,
};
// FIXME(pcwalton, #2795): Get the real container size.
@@ -911,7 +903,7 @@ impl FragmentDisplayListBuilding for Fragment {
let right = style_clip_rect.right.unwrap_or(stacking_relative_border_box.size.width);
let bottom = style_clip_rect.bottom.unwrap_or(stacking_relative_border_box.size.height);
let clip_size = Size2D::new(right - clip_origin.x, bottom - clip_origin.y);
- (*parent_clip).clone().intersect_rect(&Rect::new(clip_origin, clip_size))
+ parent_clip.intersect_rect(&Rect::new(clip_origin, clip_size))
}
fn build_display_items_for_selection_if_necessary(&self,
@@ -996,7 +988,8 @@ impl FragmentDisplayListBuilding for Fragment {
// Calculate the clip rect. If there's nothing to render at all, don't even construct
// display list items.
- let clip = self.calculate_style_specified_clip(clip, &stacking_relative_border_box);
+ let mut clip = (*clip).clone();
+ self.adjust_clip_for_style(&mut clip, &stacking_relative_border_box);
if !clip.might_intersect_rect(&stacking_relative_border_box) {
return;
}
@@ -1277,7 +1270,7 @@ impl FragmentDisplayListBuilding for Fragment {
base_flow: &BaseFlow,
scroll_policy: ScrollPolicy,
mode: StackingContextCreationMode)
- -> StackingContext {
+ -> Box<StackingContext> {
let border_box = match mode {
StackingContextCreationMode::InnerScrollWrapper => {
Rect::new(Point2D::zero(), base_flow.overflow.scroll.size)
@@ -1411,33 +1404,31 @@ impl FragmentDisplayListBuilding for Fragment {
_ => StackingContextType::Real,
};
- StackingContext::new(id,
- context_type,
- &border_box,
- &overflow,
- self.effective_z_index(),
- filters,
- self.style().get_effects().mix_blend_mode,
- transform,
- perspective,
- establishes_3d_context,
- scrolls_overflow_area,
- layer_info)
+ Box::new(StackingContext::new(id,
+ context_type,
+ &border_box,
+ &overflow,
+ self.effective_z_index(),
+ filters,
+ self.style().get_effects().mix_blend_mode,
+ transform,
+ perspective,
+ establishes_3d_context,
+ scrolls_overflow_area,
+ layer_info))
}
- fn clipping_region_for_children(&self,
- current_clip: &ClippingRegion,
- stacking_relative_border_box: &Rect<Au>,
- is_absolutely_positioned: bool)
- -> ClippingRegion {
+ fn adjust_clipping_region_for_children(&self,
+ current_clip: &mut ClippingRegion,
+ stacking_relative_border_box: &Rect<Au>,
+ is_absolutely_positioned: bool) {
// Don't clip if we're text.
if self.is_scanned_text_fragment() {
- return (*current_clip).clone()
+ return
}
// Account for style-specified `clip`.
- let mut current_clip = self.calculate_style_specified_clip(current_clip,
- stacking_relative_border_box);
+ self.adjust_clip_for_style(current_clip, stacking_relative_border_box);
// Clip according to the values of `overflow-x` and `overflow-y`.
//
@@ -1453,7 +1444,7 @@ impl FragmentDisplayListBuilding for Fragment {
let max_x = cmp::min(bounds.max_x(), stacking_relative_border_box.max_x());
bounds.origin.x = cmp::max(bounds.origin.x, stacking_relative_border_box.origin.x);
bounds.size.width = max_x - bounds.origin.x;
- current_clip = current_clip.intersect_rect(&bounds)
+ current_clip.intersect_rect(&bounds)
}
_ => {}
}
@@ -1465,12 +1456,10 @@ impl FragmentDisplayListBuilding for Fragment {
let max_y = cmp::min(bounds.max_y(), stacking_relative_border_box.max_y());
bounds.origin.y = cmp::max(bounds.origin.y, stacking_relative_border_box.origin.y);
bounds.size.height = max_y - bounds.origin.y;
- current_clip = current_clip.intersect_rect(&bounds)
+ current_clip.intersect_rect(&bounds)
}
_ => {}
}
-
- current_clip
}
fn build_display_list_for_text_fragment(&self,
@@ -1600,7 +1589,7 @@ impl FragmentDisplayListBuilding for Fragment {
pub trait BlockFlowDisplayListBuilding {
fn collect_stacking_contexts_for_block(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId;
fn build_display_list_for_block(&mut self,
state: &mut DisplayListBuildState,
@@ -1610,10 +1599,10 @@ pub trait BlockFlowDisplayListBuilding {
impl BlockFlowDisplayListBuilding for BlockFlow {
fn collect_stacking_contexts_for_block(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
- if !self.fragment.establishes_stacking_context() &&
- !self.establishes_pseudo_stacking_context() {
+ let block_stacking_context_type = self.block_stacking_context_type();
+ if block_stacking_context_type == BlockStackingContextType::NonstackingContext {
self.base.stacking_context_id = parent_id;
self.base.collect_stacking_contexts_for_children(parent_id, contexts);
return parent_id;
@@ -1625,8 +1614,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.base.stacking_context_id = stacking_context_id;
let inner_stacking_context_id = if self.has_scrolling_overflow() {
- StackingContextId::new_of_type(self.base.flow_id(),
- self.fragment.fragment_type())
+ StackingContextId::new_of_type(self.base.flow_id(), self.fragment.fragment_type())
} else {
stacking_context_id
};
@@ -1635,7 +1623,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.base.collect_stacking_contexts_for_children(inner_stacking_context_id,
&mut child_contexts);
- if self.establishes_pseudo_stacking_context() {
+ if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext {
let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
self.fragment.style.get_box().position != position::T::static_ {
StackingContextCreationMode::PseudoPositioned
@@ -1644,18 +1632,24 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
StackingContextCreationMode::PseudoFloat
};
- let mut stacking_context =
- self.fragment.create_stacking_context(stacking_context_id,
- &self.base,
- ScrollPolicy::Scrollable,
- creation_mode);
- let (mut floating, mut positioned) = child_contexts.into_iter().partition(|context| {
- context.context_type == StackingContextType::PseudoFloat
- });
+ let stacking_context_index = contexts.len();
+ contexts.push(self.fragment.create_stacking_context(stacking_context_id,
+ &self.base,
+ ScrollPolicy::Scrollable,
+ creation_mode));
+
+ let mut floating = vec![];
+ for child_context in child_contexts.into_iter() {
+ if child_context.context_type == StackingContextType::PseudoFloat {
+ // Floating.
+ floating.push(child_context)
+ } else {
+ // Positioned.
+ contexts.push(child_context)
+ }
+ }
- stacking_context.children.append(&mut floating);
- contexts.push(stacking_context);
- contexts.append(&mut positioned);
+ contexts[stacking_context_index].children = floating;
return stacking_context_id;
}
@@ -1671,7 +1665,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&self.base,
scroll_policy,
StackingContextCreationMode::InnerScrollWrapper);
- inner_stacking_context.children.append(&mut child_contexts);
+ inner_stacking_context.children = child_contexts;
let mut outer_stacking_context = self.fragment.create_stacking_context(
stacking_context_id,
@@ -1686,7 +1680,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&self.base,
scroll_policy,
StackingContextCreationMode::Normal);
- stacking_context.children.append(&mut child_contexts);
+ stacking_context.children = child_contexts;
stacking_context
};
@@ -1697,10 +1691,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
fn build_display_list_for_block(&mut self,
state: &mut DisplayListBuildState,
border_painting_mode: BorderPaintingMode) {
+ let establishes_stacking_context = self.fragment.establishes_stacking_context();
let background_border_section = if self.base.flags.is_float() {
DisplayListSection::BackgroundAndBorders
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
- if self.fragment.establishes_stacking_context() {
+ if establishes_stacking_context {
DisplayListSection::BackgroundAndBorders
} else {
DisplayListSection::BlockBackgroundsAndBorders
@@ -1710,10 +1705,14 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
};
// Add the box that starts the block context.
- let clip = if self.fragment.establishes_stacking_context() {
- self.base.clip.translate(&-self.base.stacking_relative_position)
+ let translated_clip = if establishes_stacking_context {
+ Some(self.base.clip.translate(&-self.base.stacking_relative_position))
} else {
- self.base.clip.clone()
+ None
+ };
+ let clip = match translated_clip {
+ Some(ref translated_clip) => translated_clip,
+ None => &self.base.clip,
};
self.fragment
@@ -1727,14 +1726,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
.relative_containing_block_mode,
border_painting_mode,
background_border_section,
- &clip,
+ clip,
&self.base.stacking_relative_position_of_display_port);
- // Add children.
- for kid in self.base.children.iter_mut() {
- state.append_from(&mut flow::mut_base(kid).display_list_building_result);
- }
-
self.base.build_display_items_for_debugging_tint(state, self.fragment.node);
}
}
@@ -1742,7 +1736,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
pub trait InlineFlowDisplayListBuilding {
fn collect_stacking_contexts_for_inline(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId;
fn build_display_list_for_inline_fragment_at_index(&mut self,
state: &mut DisplayListBuildState,
@@ -1753,7 +1747,7 @@ pub trait InlineFlowDisplayListBuilding {
impl InlineFlowDisplayListBuilding for InlineFlow {
fn collect_stacking_contexts_for_inline(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.base.stacking_context_id = parent_id;
@@ -1799,22 +1793,6 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
DisplayListSection::Content,
&self.base.clip,
&self.base.stacking_relative_position_of_display_port);
-
- match fragment.specific {
- SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
- let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
- state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
- }
- SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
- let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
- state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
- }
- SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => {
- let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref);
- state.append_from(&mut flow::mut_base(block_flow).display_list_building_result)
- }
- _ => {}
- }
}
fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState) {
@@ -1847,10 +1825,6 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
self.base.build_display_items_for_debugging_tint(state,
self.fragments.fragments[0].node);
}
-
- if opts::get().validate_display_list_geometry {
- self.base.validate_display_list_geometry();
- }
}
}
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index c4e08ed6ffa..b53bb697c49 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -31,7 +31,6 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::properties::style_structs;
use style::values::computed::LengthOrPercentageOrAuto;
-use util::opts;
// A mode describes which logical axis a flex axis is parallel with.
// The logical axises are inline and block, the flex axises are main and cross.
@@ -422,15 +421,11 @@ impl Flow for FlexFlow {
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
self.build_display_list_for_flex(state);
-
- if opts::get().validate_display_list_geometry {
- self.block_flow.base.validate_display_list_geometry();
- }
}
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index cf8b1be451d..1dd4b386ad8 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -34,7 +34,7 @@ use floats::Floats;
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::{self, FlowRef, WeakFlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
-use gfx::display_list::{ClippingRegion, DisplayListEntry, StackingContext, StackingContextId};
+use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
use gfx_traits::{LayerId, LayerType};
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
use inline::InlineFlow;
@@ -224,7 +224,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
fn collect_stacking_contexts(&mut self,
_parent_id: StackingContextId,
- _: &mut Vec<StackingContext>)
+ _: &mut Vec<Box<StackingContext>>)
-> StackingContextId;
/// If this is a float, places it. The default implementation does nothing.
@@ -957,9 +957,6 @@ pub struct BaseFlow {
/// per-stacking-context.
pub stacking_relative_position_of_display_port: Rect<Au>,
- /// The results of display list building for this flow.
- pub display_list_building_result: Option<Vec<DisplayListEntry>>,
-
/// The writing mode for this flow.
pub writing_mode: WritingMode,
@@ -1129,7 +1126,6 @@ impl BaseFlow {
block_container_writing_mode: writing_mode,
block_container_explicit_block_size: None,
absolute_cb: ContainingBlockLink::new(),
- display_list_building_result: None,
early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
late_absolute_position_info: LateAbsolutePositionInfo::new(),
clip: ClippingRegion::max(),
@@ -1147,8 +1143,6 @@ impl BaseFlow {
children: children,
restyle_damage: self.restyle_damage | REPAINT | REFLOW_OUT_OF_FLOW | REFLOW,
parallel: FlowParallelInfo::new(),
- display_list_building_result: None,
-
floats: self.floats.clone(),
abs_descendants: self.abs_descendants.clone(),
absolute_cb: self.absolute_cb.clone(),
@@ -1167,43 +1161,13 @@ impl BaseFlow {
p as usize
}
- /// Ensures that all display list items generated by this flow are within the flow's overflow
- /// rect. This should only be used for debugging.
- pub fn validate_display_list_geometry(&self) {
- // FIXME(pcwalton, #2795): Get the real container size.
- let container_size = Size2D::zero();
- let position_with_overflow = self.position
- .to_physical(self.writing_mode, container_size)
- .union(&self.overflow.paint);
- let bounds = Rect::new(self.stacking_relative_position, position_with_overflow.size);
-
- let items = match self.display_list_building_result {
- Some(ref items) => items,
- None => return,
- };
-
- for item in items.iter() {
- let base_item = item.item.base();
- let paint_bounds = base_item.clip.clone().intersect_rect(&base_item.bounds);
- if !paint_bounds.might_be_nonempty() {
- continue;
- }
-
- if bounds.union(&paint_bounds.bounding_rect()) != bounds {
- error!("DisplayList item {:?} outside of Flow overflow ({:?})",
- item.item,
- paint_bounds);
- }
- }
- }
-
pub fn flow_id(&self) -> usize {
return self as *const BaseFlow as usize;
}
pub fn collect_stacking_contexts_for_children(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>) {
+ contexts: &mut Vec<Box<StackingContext>>) {
for kid in self.children.iter_mut() {
kid.collect_stacking_contexts(parent_id, contexts);
}
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index ed07f339720..1212f8a3cfc 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -1680,9 +1680,10 @@ impl Flow for InlineFlow {
CoordinateSystem::Parent);
let stacking_relative_content_box =
fragment.stacking_relative_content_box(&stacking_relative_border_box);
- let clip = fragment.clipping_region_for_children(&self.base.clip,
- &stacking_relative_border_box,
- false);
+ let mut clip = self.base.clip.clone();
+ fragment.adjust_clipping_region_for_children(&mut clip,
+ &stacking_relative_border_box,
+ false);
let is_positioned = fragment.is_positioned();
match fragment.specific {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
@@ -1750,7 +1751,7 @@ impl Flow for InlineFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.collect_stacking_contexts_for_inline(parent_id, contexts)
}
diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs
index bf4a6ac9745..a361e42fb15 100644
--- a/components/layout/layout_thread.rs
+++ b/components/layout/layout_thread.rs
@@ -875,9 +875,10 @@ impl LayoutThread {
false,
None);
- sequential::build_display_list_for_subtree(layout_root,
- &mut root_stacking_context,
- shared_layout_context);
+ let display_list_entries =
+ sequential::build_display_list_for_subtree(layout_root,
+ &mut root_stacking_context,
+ shared_layout_context);
if data.goal == ReflowGoal::ForDisplay {
debug!("Done building display list.");
@@ -900,11 +901,9 @@ impl LayoutThread {
ScrollPolicy::Scrollable,
None,
root_background_color));
- let display_list = DisplayList::new(
- root_stacking_context,
- &mut flow::mut_base(flow_ref::deref_mut(layout_root))
- .display_list_building_result);
+ let display_list = DisplayList::new(root_stacking_context,
+ &mut Some(display_list_entries));
if opts::get().dump_display_list {
display_list.print();
}
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 701ac4ecdf9..6c8817ec1da 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -25,7 +25,6 @@ use style::computed_values::{list_style_type, position};
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use text;
-use util::opts;
/// A block with the CSS `display` property equal to `list-item`.
#[derive(Debug)]
@@ -144,14 +143,11 @@ impl Flow for ListItemFlow {
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
self.build_display_list_for_list_item(state);
- if opts::get().validate_display_list_geometry {
- self.block_flow.base.validate_display_list_geometry();
- }
}
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index 36815c82533..4b7ac7d8814 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -186,7 +186,7 @@ impl Flow for MulticolFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
@@ -271,7 +271,7 @@ impl Flow for MulticolColumnFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs
index e0207ee7ca0..a54d46848ca 100644
--- a/components/layout/sequential.rs
+++ b/components/layout/sequential.rs
@@ -6,13 +6,14 @@
use app_units::Au;
use context::{LayoutContext, SharedLayoutContext};
+use display_list_builder::DisplayListBuildState;
use euclid::point::Point2D;
use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
use flow_ref::{self, FlowRef};
use fragment::FragmentBorderBoxIterator;
use generated_content::ResolveGeneratedContent;
-use gfx::display_list::StackingContext;
+use gfx::display_list::{DisplayListEntry, StackingContext};
use style::dom::TNode;
use style::traversal::DomTraversalContext;
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes};
@@ -77,13 +78,19 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
pub fn build_display_list_for_subtree(root: &mut FlowRef,
root_stacking_context: &mut StackingContext,
- shared_layout_context: &SharedLayoutContext) {
+ shared_layout_context: &SharedLayoutContext)
+ -> Vec<DisplayListEntry> {
let flow_root = flow_ref::deref_mut(root);
let layout_context = LayoutContext::new(shared_layout_context);
flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: &layout_context });
flow_root.collect_stacking_contexts(root_stacking_context.id,
&mut root_stacking_context.children);
- flow_root.traverse_postorder(&BuildDisplayList { layout_context: &layout_context });
+ let mut build_display_list = BuildDisplayList {
+ state: DisplayListBuildState::new(&layout_context,
+ flow::base(&**root).stacking_context_id),
+ };
+ build_display_list.traverse(&mut *flow_root);
+ build_display_list.state.items
}
pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
diff --git a/components/layout/table.rs b/components/layout/table.rs
index eb0c57f615a..0c8d8865a8d 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -467,7 +467,7 @@ impl Flow for TableFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index 4bb783154d2..e1706fc53cd 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -83,7 +83,7 @@ impl Flow for TableCaptionFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 0faebcb3cf2..523ea86a5f5 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -193,7 +193,7 @@ impl Flow for TableCellFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 9f1a03e7e0b..32d2c693131 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -96,7 +96,7 @@ impl Flow for TableColGroupFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- _: &mut Vec<StackingContext>)
+ _: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
parent_id
}
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 7fc8381f76f..45e8bca12ec 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -435,7 +435,7 @@ impl Flow for TableRowFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 6971df77787..44da4878119 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -212,7 +212,7 @@ impl Flow for TableRowGroupFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index d3224126929..a8e16812efd 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -451,7 +451,7 @@ impl Flow for TableWrapperFlow {
fn collect_stacking_contexts(&mut self,
parent_id: StackingContextId,
- contexts: &mut Vec<StackingContext>)
+ contexts: &mut Vec<Box<StackingContext>>)
-> StackingContextId {
self.block_flow.collect_stacking_contexts(parent_id, contexts)
}
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index 696c43b210b..7e0a9e3a499 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -215,23 +215,27 @@ impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> {
}
}
-#[derive(Copy, Clone)]
pub struct BuildDisplayList<'a> {
- pub layout_context: &'a LayoutContext<'a>,
+ pub state: DisplayListBuildState<'a>,
}
-impl<'a> PostorderFlowTraversal for BuildDisplayList<'a> {
+impl<'a> BuildDisplayList<'a> {
#[inline]
- fn process(&self, flow: &mut Flow) {
- let mut state = DisplayListBuildState::new(
- self.layout_context, flow::base(flow).stacking_context_id);
- flow.build_display_list(&mut state);
- flow::mut_base(flow).display_list_building_result = Some(state.items);
- flow::mut_base(flow).restyle_damage.remove(REPAINT);
+ pub fn traverse(&mut self, flow: &mut Flow) {
+ if self.should_process() {
+ self.state.push_stacking_context_id(flow::base(flow).stacking_context_id);
+ flow.build_display_list(&mut self.state);
+ flow::mut_base(flow).restyle_damage.remove(REPAINT);
+ self.state.pop_stacking_context_id();
+ }
+
+ for kid in flow::child_iter(flow) {
+ self.traverse(kid);
+ }
}
#[inline]
- fn should_process(&self, _: &mut Flow) -> bool {
- self.layout_context.shared_context().goal == ReflowGoal::ForDisplay
+ fn should_process(&self) -> bool {
+ self.state.layout_context.shared_context().goal == ReflowGoal::ForDisplay
}
}