diff options
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r-- | components/layout/flow.rs | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/components/layout/flow.rs b/components/layout/flow.rs index a36fca0df0a..f20d5a0c128 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -32,7 +32,7 @@ use display_list_builder::DisplayListBuildingResult; use floats::Floats; use flow_list::{FlowList, FlowListIterator, MutFlowListIterator}; use flow_ref::FlowRef; -use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo}; +use fragment::{Fragment, FragmentOverflowIterator, SpecificFragmentInfo}; use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage}; use inline::InlineFlow; use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo}; @@ -50,7 +50,7 @@ use geom::{Point2D, Rect, Size2D}; use gfx::display_list::ClippingRegion; use serialize::{Encoder, Encodable}; use servo_msg::compositor_msg::LayerId; -use servo_util::geometry::Au; +use servo_util::geometry::{Au, ZERO_RECT}; use servo_util::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use std::mem; use std::fmt; @@ -220,8 +220,11 @@ pub trait Flow: fmt::Show + ToString + Sync { /// Phase 5 of reflow: builds display lists. fn build_display_list(&mut self, layout_context: &LayoutContext); - /// Perform an iteration of fragment bounds on this flow. - fn iterate_through_fragment_bounds(&self, iterator: &mut FragmentBoundsIterator); + /// Returns the union of all overflow rects of all of this flow's fragments. + fn compute_overflow(&self) -> Rect<Au>; + + /// Iterates through overflow rects of all of this flow's fragments. + fn iterate_through_fragment_overflow(&self, iterator: &mut FragmentOverflowIterator); fn compute_collapsible_block_start_margin(&mut self, _layout_context: &mut LayoutContext, @@ -718,7 +721,7 @@ pub struct BaseFlow { /// The amount of overflow of this flow, relative to the containing block. Must include all the /// pixels of all the display list items for correct invalidation. - pub overflow: LogicalRect<Au>, + pub overflow: Rect<Au>, /// Data used during parallel traversals. /// @@ -894,7 +897,7 @@ impl BaseFlow { children: FlowList::new(), intrinsic_inline_sizes: IntrinsicISizes::new(), position: LogicalRect::zero(writing_mode), - overflow: LogicalRect::zero(writing_mode), + overflow: ZERO_RECT, parallel: FlowParallelInfo::new(), floats: Floats::new(writing_mode), collapsible_margins: CollapsibleMargins::new(), @@ -929,10 +932,12 @@ impl BaseFlow { /// 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) { - let position_with_overflow = self.position.union(&self.overflow); - let bounds = Rect(self.stacking_relative_position, - Size2D(position_with_overflow.size.inline, - position_with_overflow.size.block)); + // 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); + let bounds = Rect(self.stacking_relative_position, position_with_overflow.size); let all_items = match self.display_list_building_result { DisplayListBuildingResult::None => Vec::new(), @@ -1175,40 +1180,29 @@ impl<'a> MutableFlowUtils for &'a mut Flow + 'a { /// already been set. /// Assumption: Absolute descendants have had their overflow calculated. fn store_overflow(self, _: &LayoutContext) { - let my_position = mut_base(self).position; - - // FIXME(pcwalton): We should calculate overflow on a per-fragment basis, because their - // styles can affect overflow regions. Consider `box-shadow`, `outline`, etc.--anything - // that can draw outside the border box. For now we assume overflow is the border box, but - // that is wrong. - let mut overflow = my_position; - + // Calculate overflow on a per-fragment basis. + let mut overflow = self.compute_overflow(); if self.is_block_container() { - let writing_mode = base(self).writing_mode; - // FIXME(#2795): Get the real container size + // FIXME(#2795): Get the real container size. let container_size = Size2D::zero(); for kid in child_iter(self) { - if kid.is_store_overflow_delayed() { - // Absolute flows will be handled by their CB. If we are - // their CB, they will show up in `abs_descendants`. - continue; + if base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { + continue } - let kid_base = base(kid); - let mut kid_overflow = kid_base.overflow.convert( - kid_base.writing_mode, writing_mode, container_size); - kid_overflow = kid_overflow.translate(&my_position.start); - overflow = overflow.union(&kid_overflow) + 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)) } - // FIXME(#2004, pcwalton): This is wrong for `position: fixed`. - for descendant_link in mut_base(self).abs_descendants.iter() { - let kid_base = base(descendant_link); - let mut kid_overflow = kid_base.overflow.convert( - kid_base.writing_mode, writing_mode, container_size); - kid_overflow = kid_overflow.translate(&my_position.start); - overflow = overflow.union(&kid_overflow) + 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; } |