diff options
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/block.rs | 42 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 194 | ||||
-rw-r--r-- | components/layout/flex.rs | 7 | ||||
-rw-r--r-- | components/layout/flow.rs | 42 | ||||
-rw-r--r-- | components/layout/inline.rs | 9 | ||||
-rw-r--r-- | components/layout/layout_thread.rs | 13 | ||||
-rw-r--r-- | components/layout/list_item.rs | 6 | ||||
-rw-r--r-- | components/layout/multicol.rs | 4 | ||||
-rw-r--r-- | components/layout/sequential.rs | 13 | ||||
-rw-r--r-- | components/layout/table.rs | 2 | ||||
-rw-r--r-- | components/layout/table_caption.rs | 2 | ||||
-rw-r--r-- | components/layout/table_cell.rs | 2 | ||||
-rw-r--r-- | components/layout/table_colgroup.rs | 2 | ||||
-rw-r--r-- | components/layout/table_row.rs | 2 | ||||
-rw-r--r-- | components/layout/table_rowgroup.rs | 2 | ||||
-rw-r--r-- | components/layout/table_wrapper.rs | 2 | ||||
-rw-r--r-- | components/layout/traversal.rs | 26 |
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 } } |