From b66f17a44549c30d7a4c0440b88425a84ce2c5c4 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 21 Aug 2015 13:49:40 -0700 Subject: [PATCH 1/4] layout: Make overflow calculation take relative percentages into account. This necessitated changing overflow to be calculated by the parent flow if relatively positioned children are present. That is because the overflow regions cannot be calculated without knowing relative offsets, which themselves cannot be calculated without knowing the parent size (because of percentages). To accomplish this without sacrificing parallelism in the non-relative case, this patch splits overflow into "early" and "late" computation. Late overflow computation cannot be parallelized across children, while early overflow computation can. Makes the "Apple Music" text show up over the full-bleed promotional background on apple.com. --- components/layout/block.rs | 52 +++++++---- components/layout/display_list_builder.rs | 24 ++--- components/layout/flow.rs | 90 ++++++++++++++----- components/layout/fragment.rs | 9 +- components/layout/inline.rs | 24 ++--- components/layout/list_item.rs | 4 +- components/layout/table.rs | 16 +++- components/layout/table_row.rs | 12 ++- components/layout/traversal.rs | 4 +- tests/ref/basic.list | 1 + ...lative_vertical_percentage_overflow_a.html | 25 ++++++ ...tive_vertical_percentage_overflow_ref.html | 17 ++++ 12 files changed, 203 insertions(+), 75 deletions(-) create mode 100644 tests/ref/position_relative_vertical_percentage_overflow_a.html create mode 100644 tests/ref/position_relative_vertical_percentage_overflow_ref.html diff --git a/components/layout/block.rs b/components/layout/block.rs index d697cad97a9..1802caa0b47 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -36,10 +36,10 @@ use flow::{CLEARS_LEFT, CLEARS_RIGHT}; use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS}; use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC}; use flow::{IS_ABSOLUTELY_POSITIONED}; -use flow::{ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow, PreorderFlowTraversal}; +use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow}; use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER}; -use flow::{PostorderFlowTraversal, mut_base}; -use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; +use flow::{PostorderFlowTraversal, PreorderFlowTraversal, mut_base}; +use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, ForceNonfloatedFlag, FlowClass, Flow}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER}; use fragment::{SpecificFragmentInfo}; use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; @@ -485,7 +485,7 @@ impl<'a> PostorderFlowTraversal for AbsoluteStoreOverflowTraversal<'a> { } } - flow.store_overflow(self.layout_context); + flow.early_store_overflow(self.layout_context); } } @@ -959,6 +959,19 @@ impl BlockFlow { // // FIXME(pcwalton): This looks not idempotent. Is it? self.fragment.border_box.size.block = block_size; + } + + // Write in the size of the relative containing block for children. (This information + // is also needed to handle RTL.) + for kid in self.base.child_iter() { + flow::mut_base(kid).early_absolute_position_info = EarlyAbsolutePositionInfo { + relative_containing_block_size: self.fragment.content_box().size, + relative_containing_block_mode: self.fragment.style().writing_mode, + }; + kid.late_store_overflow(layout_context) + } + + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { return } @@ -1730,7 +1743,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); + (self as &mut Flow).early_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). } @@ -1775,7 +1788,7 @@ impl Flow for BlockFlow { fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { if (self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && - self.base.absolute_position_info.layers_needed_for_positioned_flows) || + self.base.late_absolute_position_info.layers_needed_for_positioned_flows) || self.base.flags.contains(NEEDS_LAYER) { self.fragment.flags.insert(HAS_LAYER) } @@ -1816,7 +1829,7 @@ impl Flow for BlockFlow { // Absolute position of the containing block + position of absolute // flow w.r.t. the containing block. self.base - .absolute_position_info + .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block + position_start }; @@ -1842,13 +1855,13 @@ impl Flow for BlockFlow { // other hand, is only established if we are positioned. let relative_offset = self.fragment.relative_position(&self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size); if self.contains_positioned_fragments() { let border_box_origin = (self.fragment.border_box - self.fragment.style.logical_border_width()).start; self.base - .absolute_position_info + .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block = self.base.stacking_relative_position + (border_box_origin + relative_offset).to_physical(self.base.writing_mode, @@ -1875,14 +1888,12 @@ impl Flow for BlockFlow { } } else { self.base - .absolute_position_info + .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block }; - let absolute_position_info_for_children = AbsolutePositionInfo { + let late_absolute_position_info_for_children = LateAbsolutePositionInfo { stacking_relative_position_of_absolute_containing_block: stacking_relative_position_of_absolute_containing_block_for_children, - relative_containing_block_size: self.fragment.content_box().size, - relative_containing_block_mode: self.base.writing_mode, layers_needed_for_positioned_flows: self.base .flags .contains(LAYERS_NEEDED_FOR_DESCENDANTS), @@ -1934,10 +1945,10 @@ impl Flow for BlockFlow { self.fragment .stacking_relative_border_box(&self.base.stacking_relative_position, &self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, CoordinateSystem::Own); let clip = self.fragment.clipping_region_for_children( @@ -1985,7 +1996,8 @@ impl Flow for BlockFlow { } } - flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children; + flow::mut_base(kid).late_absolute_position_info = + late_absolute_position_info_for_children; flow::mut_base(kid).clip = clip.clone(); flow::mut_base(kid).stacking_relative_position_of_display_port = stacking_relative_position_of_display_port_for_children; @@ -2056,7 +2068,9 @@ impl Flow for BlockFlow { } fn compute_overflow(&self) -> Rect { - self.fragment.compute_overflow() + self.fragment.compute_overflow(&self.base + .early_absolute_position_info + .relative_containing_block_size) } fn iterate_through_fragment_border_boxes(&self, @@ -2072,10 +2086,10 @@ impl Flow for BlockFlow { &self.fragment .stacking_relative_border_box(&self.base.stacking_relative_position, &self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, CoordinateSystem::Own) .translate(stacking_context_position)); diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 0485d549c4a..19c466ee528 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -1152,9 +1152,9 @@ impl FragmentDisplayListBuilding for Fragment { StackingContextCreationMode::Normal | StackingContextCreationMode::OuterScrollWrapper => { self.stacking_relative_border_box(&base_flow.stacking_relative_position, - &base_flow.absolute_position_info + &base_flow.early_absolute_position_info .relative_containing_block_size, - base_flow.absolute_position_info + base_flow.early_absolute_position_info .relative_containing_block_mode, CoordinateSystem::Parent) } @@ -1533,8 +1533,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow { .build_display_list(display_list, layout_context, &self.base.stacking_relative_position, - &self.base.absolute_position_info.relative_containing_block_size, - self.base.absolute_position_info.relative_containing_block_mode, + &self.base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, border_painting_mode, background_border_level, &clip, @@ -1616,8 +1620,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { &mut outer_display_list_for_overflow_scroll, layout_context, &self.base.stacking_relative_position, - &self.base.absolute_position_info.relative_containing_block_size, - self.base.absolute_position_info.relative_containing_block_mode, + &self.base.early_absolute_position_info.relative_containing_block_size, + self.base.early_absolute_position_info.relative_containing_block_mode, border_painting_mode, BackgroundAndBorderLevel::RootOfStackingContext, &clip, @@ -1775,10 +1779,10 @@ impl InlineFlowDisplayListBuilding for InlineFlow { layout_context, &self.base.stacking_relative_position, &self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, @@ -1857,11 +1861,11 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { &self.block_flow.base.stacking_relative_position, &self.block_flow .base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.block_flow .base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, 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); + + /// 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, 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, /// 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 { diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 02af5569d84..f4a9cad9c5b 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2049,7 +2049,7 @@ impl Fragment { } /// Computes the overflow rect of this fragment relative to the start of the flow. - pub fn compute_overflow(&self) -> Rect { + pub fn compute_overflow(&self, relative_containing_block_size: &LogicalSize) -> Rect { // FIXME(pcwalton, #2795): Get the real container size. let container_size = Size2D::zero(); let mut border_box = self.border_box.to_physical(self.style.writing_mode, container_size); @@ -2058,10 +2058,9 @@ impl Fragment { // // FIXME(pcwalton): I'm not a fan of the way this makes us crawl though so many styles all // the time. Can't we handle relative positioning by just adjusting `border_box`? - let relative_position = - self.relative_position(&LogicalSize::zero(self.style.writing_mode)); - border_box = border_box.translate_by_size(&relative_position.to_physical( - self.style.writing_mode)); + let relative_position = self.relative_position(relative_containing_block_size); + border_box = + border_box.translate_by_size(&relative_position.to_physical(self.style.writing_mode)); let mut overflow = border_box; // Box shadows cause us to draw outside our border box. diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 4b5a6b985c7..e858335a7f8 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1645,10 +1645,10 @@ impl Flow for InlineFlow { let stacking_relative_border_box = fragment.stacking_relative_border_box(&self.base.stacking_relative_position, &self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, CoordinateSystem::Parent); let clip = fragment.clipping_region_for_children(&self.base.clip, @@ -1661,13 +1661,14 @@ impl Flow for InlineFlow { flow::mut_base(flow).clip = clip; let block_flow = flow.as_mut_block(); - block_flow.base.absolute_position_info = self.base.absolute_position_info; + block_flow.base.late_absolute_position_info = + self.base.late_absolute_position_info; let stacking_relative_position = self.base.stacking_relative_position; if is_positioned { let padding_box_origin = containing_block_positions.next().unwrap(); block_flow.base - .absolute_position_info + .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block = stacking_relative_position + *padding_box_origin; } @@ -1681,7 +1682,8 @@ impl Flow for InlineFlow { let flow = flow_ref::deref_mut(&mut info.flow_ref); flow::mut_base(flow).clip = clip; let block_flow = flow.as_mut_block(); - block_flow.base.absolute_position_info = self.base.absolute_position_info; + block_flow.base.late_absolute_position_info = + self.base.late_absolute_position_info; block_flow.base.stacking_relative_position = stacking_relative_border_box.origin; @@ -1693,12 +1695,13 @@ impl Flow for InlineFlow { flow::mut_base(flow).clip = clip; let block_flow = flow.as_mut_block(); - block_flow.base.absolute_position_info = self.base.absolute_position_info; + block_flow.base.late_absolute_position_info = + self.base.late_absolute_position_info; let stacking_relative_position = self.base.stacking_relative_position; let padding_box_origin = containing_block_positions.next().unwrap(); block_flow.base - .absolute_position_info + .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block = stacking_relative_position + *padding_box_origin; @@ -1725,7 +1728,8 @@ impl Flow for InlineFlow { fn compute_overflow(&self) -> Rect { let mut overflow = ZERO_RECT; for fragment in &self.fragments.fragments { - overflow = overflow.union(&fragment.compute_overflow()) + overflow = overflow.union(&fragment.compute_overflow( + &self.base.early_absolute_position_info.relative_containing_block_size)) } overflow } @@ -1742,9 +1746,9 @@ impl Flow for InlineFlow { let stacking_relative_position = &self.base.stacking_relative_position; let relative_containing_block_size = - &self.base.absolute_position_info.relative_containing_block_size; + &self.base.early_absolute_position_info.relative_containing_block_size; let relative_containing_block_mode = - self.base.absolute_position_info.relative_containing_block_mode; + self.base.early_absolute_position_info.relative_containing_block_mode; iterator.process(fragment, level, &fragment.stacking_relative_border_box(stacking_relative_position, diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index b0c3702f2c2..7ba0786f906 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -184,11 +184,11 @@ impl Flow for ListItemFlow { .stacking_relative_position, &self.block_flow .base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_size, self.block_flow .base - .absolute_position_info + .early_absolute_position_info .relative_containing_block_mode, CoordinateSystem::Own) .translate(stacking_context_position)); diff --git a/components/layout/table.rs b/components/layout/table.rs index f5ef95f1989..f0dd4c94ba7 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -10,8 +10,8 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution}; use block::{self, BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; -use flow::{ImmutableFlowUtils, OpaqueFlow}; -use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS}; +use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS}; +use flow::{IMPACTED_BY_RIGHT_FLOATS, ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; @@ -761,7 +761,7 @@ pub trait TableLikeFlow { impl TableLikeFlow for BlockFlow { fn assign_block_size_for_table_like_flow<'a>(&mut self, - _: &'a LayoutContext<'a>, + layout_context: &'a LayoutContext<'a>, block_direction_spacing: Au) { debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == border_collapse::T::separate || block_direction_spacing == Au(0)); @@ -838,6 +838,16 @@ impl TableLikeFlow for BlockFlow { self.fragment.border_box.size.block = current_block_offset; self.fragment.border_box.start.b = Au(0); self.base.position.size.block = current_block_offset; + + // Write in the size of the relative containing block for children. (This information + // is also needed to handle RTL.) + for kid in self.base.child_iter() { + flow::mut_base(kid).early_absolute_position_info = EarlyAbsolutePositionInfo { + relative_containing_block_size: self.fragment.content_box().size, + relative_containing_block_mode: self.fragment.style().writing_mode, + }; + kid.late_store_overflow(layout_context) + } } self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index e2b155bca78..4043363a23a 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -9,7 +9,7 @@ use block::{BlockFlow, ISizeAndMarginsComputer}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; -use flow::{self, FlowClass, Flow, ImmutableFlowUtils, OpaqueFlow}; +use flow::{self, EarlyAbsolutePositionInfo, FlowClass, Flow, ImmutableFlowUtils, OpaqueFlow}; use flow_list::MutFlowListIterator; use fragment::{Fragment, FragmentBorderBoxIterator}; use layout_debug; @@ -162,7 +162,15 @@ impl TableRowFlow { } // Assign the child's block size. - child_table_cell.block_flow.base.position.size.block = block_size + child_table_cell.block_flow.base.position.size.block = block_size; + + // Write in the size of the relative containing block for children. (This information + // is also needed to handle RTL.) + child_table_cell.block_flow.base.early_absolute_position_info = + EarlyAbsolutePositionInfo { + relative_containing_block_size: self.block_flow.fragment.content_box().size, + relative_containing_block_mode: self.block_flow.fragment.style().writing_mode, + }; } } diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 7c4687a1b00..ff654e68364 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -7,8 +7,8 @@ use construct::FlowConstructor; use context::LayoutContext; use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult}; -use flow::{PreorderFlowTraversal, PostorderFlowTraversal}; use flow::{self, Flow}; +use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal}; use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage}; use script::layout_interface::ReflowGoal; use wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode}; @@ -368,7 +368,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> { } flow.assign_block_size(self.layout_context); - flow.store_overflow(self.layout_context); + flow.early_store_overflow(self.layout_context); } #[inline] diff --git a/tests/ref/basic.list b/tests/ref/basic.list index ed4e0d91a4b..3191836d12e 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -294,6 +294,7 @@ flaky_cpu == linebreak_simple_a.html linebreak_simple_b.html == position_relative_painting_order_a.html position_relative_painting_order_ref.html == position_relative_stacking_context_a.html position_relative_stacking_context_ref.html == position_relative_top_percentage_a.html position_relative_top_percentage_b.html +== position_relative_vertical_percentage_overflow_a.html position_relative_vertical_percentage_overflow_ref.html == pre_ignorable_whitespace_a.html pre_ignorable_whitespace_ref.html == pre_with_tab.html pre_with_tab_ref.html == pseudo_element_a.html pseudo_element_b.html diff --git a/tests/ref/position_relative_vertical_percentage_overflow_a.html b/tests/ref/position_relative_vertical_percentage_overflow_a.html new file mode 100644 index 00000000000..ca9aae49050 --- /dev/null +++ b/tests/ref/position_relative_vertical_percentage_overflow_a.html @@ -0,0 +1,25 @@ + + +
+ diff --git a/tests/ref/position_relative_vertical_percentage_overflow_ref.html b/tests/ref/position_relative_vertical_percentage_overflow_ref.html new file mode 100644 index 00000000000..32bdcb8ab59 --- /dev/null +++ b/tests/ref/position_relative_vertical_percentage_overflow_ref.html @@ -0,0 +1,17 @@ + + +
+ From e835fb651409164b41f075aaf159e018d9663eb0 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 21 Aug 2015 14:07:41 -0700 Subject: [PATCH 2/4] gfx: Make some minor formatting cleanups. --- components/gfx/paint_context.rs | 35 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/components/gfx/paint_context.rs b/components/gfx/paint_context.rs index a96d413cafc..17ed31cd54c 100644 --- a/components/gfx/paint_context.rs +++ b/components/gfx/paint_context.rs @@ -960,14 +960,13 @@ impl<'a> PaintContext<'a> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let font = self.font_context.get_paint_font_from_template( &text.text_run.font_template, text.text_run.actual_pt_size); - font - .borrow() - .draw_text(&temporary_draw_target.draw_target, - &*text.text_run, - &text.range, - baseline_origin, - text.text_color, - opts::get().enable_text_antialiasing); + font.borrow() + .draw_text(&temporary_draw_target.draw_target, + &*text.text_run, + &text.range, + baseline_origin, + text.text_color, + opts::get().enable_text_antialiasing); } // Blur, if necessary. @@ -1029,8 +1028,9 @@ impl<'a> PaintContext<'a> { // Calculate the transform matrix. let old_transform = self.draw_target.get_transform(); - let inflated_size = Rect::new(Point2D::new(0.0, 0.0), Size2D::new(size.width as AzFloat, - size.height as AzFloat)); + let inflated_size = Rect::new(Point2D::new(0.0, 0.0), + Size2D::new(size.width as AzFloat, + size.height as AzFloat)); let temporary_draw_target_bounds = old_transform.transform_rect(&inflated_size); matrix = Matrix2D::identity().translate( -temporary_draw_target_bounds.origin.x as AzFloat, @@ -1060,7 +1060,8 @@ impl<'a> PaintContext<'a> { self.draw_target.set_transform(&Matrix2D::identity()); let rect = Rect::new(Point2D::new(0.0, 0.0), self.draw_target.get_size().to_azure_size()); - let rect_temporary = Rect::new(Point2D::new(0.0, 0.0), temporary_draw_target.get_size().to_azure_size()); + let rect_temporary = Rect::new(Point2D::new(0.0, 0.0), + temporary_draw_target.get_size().to_azure_size()); // Create the Azure filter pipeline. let mut accum_blur = Au(0); @@ -1081,7 +1082,10 @@ impl<'a> PaintContext<'a> { self.pop_clip_if_applicable(); debug!("######### use expanded Rect."); - self.draw_target.draw_filter(&filter_node, &rect_temporary, &rect_temporary.origin, draw_options); + self.draw_target.draw_filter(&filter_node, + &rect_temporary, + &rect_temporary.origin, + draw_options); self.push_clip_if_applicable(); } else { debug!("######### use regular Rect."); @@ -1132,9 +1136,10 @@ impl<'a> PaintContext<'a> { } // Draw the shadow, and blur if we need to. - temporary_draw_target.draw_target.fill(&path, - Pattern::Color(ColorPattern::new(color)).to_pattern_ref(), - &DrawOptions::new(1.0, CompositionOp::Over, AntialiasMode::None)); + temporary_draw_target.draw_target.fill( + &path, + Pattern::Color(ColorPattern::new(color)).to_pattern_ref(), + &DrawOptions::new(1.0, CompositionOp::Over, AntialiasMode::None)); self.blur_if_necessary(temporary_draw_target, blur_radius); // Undo the draw target's clip if we need to, and push back the stacking context clip. From 475d358b213dfb8d35fa13c6636dcf4cce6175da Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 1 Sep 2015 08:37:41 -0700 Subject: [PATCH 3/4] layout: Fix tidy failures. --- components/layout/table.rs | 2 +- components/layout/traversal.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index f0dd4c94ba7..54e3f090b59 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -10,8 +10,8 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution}; use block::{self, BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; -use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS}; use flow::{IMPACTED_BY_RIGHT_FLOATS, ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow}; +use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS}; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index ff654e68364..ed8ae6ab76a 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -7,8 +7,8 @@ use construct::FlowConstructor; use context::LayoutContext; use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult}; -use flow::{self, Flow}; use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal}; +use flow::{self, Flow}; use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage}; use script::layout_interface::ReflowGoal; use wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode}; From ce327b823133c9947b424542645fe9c427606070 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 1 Sep 2015 11:30:15 -0700 Subject: [PATCH 4/4] tests: Mark some WPT tests as passing now. --- .../css21_dev/html4/abs-pos-non-replaced-vlr-069.htm.ini | 3 --- .../css21_dev/html4/abs-pos-non-replaced-vlr-177.htm.ini | 3 --- .../css21_dev/html4/abs-pos-non-replaced-vlr-193.htm.ini | 3 --- .../css21_dev/html4/abs-pos-non-replaced-vrl-176.htm.ini | 3 --- .../css21_dev/html4/abs-pos-non-replaced-vrl-192.htm.ini | 3 --- .../css21_dev/html4/absolute-replaced-width-015.htm.ini | 3 --- 6 files changed, 18 deletions(-) delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-069.htm.ini delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-177.htm.ini delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-193.htm.ini delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-176.htm.ini delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-192.htm.ini delete mode 100644 tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-width-015.htm.ini diff --git a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-069.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-069.htm.ini deleted file mode 100644 index 3393052ea38..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-069.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abs-pos-non-replaced-vlr-069.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-177.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-177.htm.ini deleted file mode 100644 index e1c3b4f4d05..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-177.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abs-pos-non-replaced-vlr-177.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-193.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-193.htm.ini deleted file mode 100644 index 5e854311604..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vlr-193.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abs-pos-non-replaced-vlr-193.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-176.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-176.htm.ini deleted file mode 100644 index eefff3cffd7..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-176.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abs-pos-non-replaced-vrl-176.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-192.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-192.htm.ini deleted file mode 100644 index ae93a9937bd..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abs-pos-non-replaced-vrl-192.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abs-pos-non-replaced-vrl-192.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-width-015.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-width-015.htm.ini deleted file mode 100644 index d17e0d4951e..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/absolute-replaced-width-015.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[absolute-replaced-width-015.htm] - type: reftest - expected: FAIL