diff options
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/block.rs | 54 | ||||
-rw-r--r-- | components/layout/data.rs | 2 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 24 | ||||
-rw-r--r-- | components/layout/flex.rs | 4 | ||||
-rw-r--r-- | components/layout/flow.rs | 90 | ||||
-rw-r--r-- | components/layout/fragment.rs | 15 | ||||
-rw-r--r-- | components/layout/incremental.rs | 4 | ||||
-rw-r--r-- | components/layout/inline.rs | 28 | ||||
-rw-r--r-- | components/layout/list_item.rs | 4 | ||||
-rw-r--r-- | components/layout/table.rs | 16 | ||||
-rw-r--r-- | components/layout/table_row.rs | 12 | ||||
-rw-r--r-- | components/layout/table_wrapper.rs | 75 | ||||
-rw-r--r-- | components/layout/traversal.rs | 4 |
13 files changed, 246 insertions, 86 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index d697cad97a9..3926384379a 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); } } @@ -561,7 +561,7 @@ pub struct BlockFlow { bitflags! { flags BlockFlowFlags: u8 { - #[doc="If this is set, then this block flow is the root flow."] + #[doc = "If this is set, then this block flow is the root flow."] const IS_ROOT = 0x01, } } @@ -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<Au> { - 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/data.rs b/components/layout/data.rs index 4b551e2fd9e..097852096fa 100644 --- a/components/layout/data.rs +++ b/components/layout/data.rs @@ -54,7 +54,7 @@ impl PrivateLayoutData { bitflags! { flags LayoutDataFlags: u8 { - #[doc="Whether a flow has been newly constructed."] + #[doc = "Whether a flow has been newly constructed."] const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01 } } 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/flex.rs b/components/layout/flex.rs index 3c34aeaf728..88fe929a9d3 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -312,6 +312,10 @@ impl Flow for FlexFlow { &mut self.block_flow } + fn mark_as_root(&mut self) { + self.block_flow.mark_as_root(); + } + fn bubble_inline_sizes(&mut self) { let _scope = layout_debug_scope!("flex::bubble_inline_sizes {:x}", self.block_flow.base.debug_id()); diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 6d319bdd991..4e2da89f513 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -222,7 +222,11 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { if impacted { mut_base(self).thread_id = parent_thread_id; self.assign_block_size(layout_context); - self.store_overflow(layout_context); + // FIXME(pcwalton): Should use `early_store_overflow()` here but that fails due to a + // compiler bug (`Self` does not have a constant size). + if !self.contains_relatively_positioned_fragments() { + self.store_overflow(layout_context) + } mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } impacted @@ -246,7 +250,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { match self.class() { FlowClass::Block | FlowClass::TableCaption | - FlowClass::TableCell if !base(self).children.is_empty() => { + FlowClass::TableCell => { // FIXME(#2795): Get the real container size. let container_size = Size2D::zero(); for kid in mut_base(self).children.iter_mut() { @@ -310,13 +314,6 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { // different behaviour for different types of Flow, so they can't go into // the Immutable / Mutable Flow Utils traits without additional casts. - /// Return true if store overflow is delayed for this flow. - /// - /// Currently happens only for absolutely positioned flows. - fn is_store_overflow_delayed(&mut self) -> bool { - false - } - fn is_root(&self) -> bool { false } @@ -459,6 +456,11 @@ pub trait ImmutableFlowUtils { /// Returns true if this flow is an inline flow. fn is_inline_flow(self) -> bool; + /// Returns true if this flow can have its overflow area calculated early (during its + /// block-size assignment) or false if it must have its overflow area calculated late (during + /// its parent's block-size assignment). + fn can_calculate_overflow_area_early(self) -> bool; + /// Dumps the flow tree for debugging. fn dump(self); @@ -495,6 +497,12 @@ pub trait MutableFlowUtils { /// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of /// calling them individually, since there is no reason not to perform both operations. fn repair_style_and_bubble_inline_sizes(self, style: &Arc<ComputedValues>); + + /// Calls `store_overflow()` if the overflow can be calculated early. + fn early_store_overflow(self, layout_context: &LayoutContext); + + /// Calls `store_overflow()` if the overflow cannot be calculated early. + fn late_store_overflow(self, layout_context: &LayoutContext); } pub trait MutableOwnedFlowUtils { @@ -780,15 +788,30 @@ impl<'a> Iterator for AbsoluteDescendantIter<'a> { pub type AbsoluteDescendantOffsetIter<'a> = Zip<AbsoluteDescendantIter<'a>, IterMut<'a, Au>>; /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be -/// confused with absolutely-positioned flows). -#[derive(RustcEncodable, Copy, Clone)] -pub struct AbsolutePositionInfo { +/// confused with absolutely-positioned flows) that is computed during block-size assignment. +pub struct EarlyAbsolutePositionInfo { /// The size of the containing block for relatively-positioned descendants. pub relative_containing_block_size: LogicalSize<Au>, /// The writing mode for `relative_containing_block_size`. pub relative_containing_block_mode: WritingMode, +} + +impl EarlyAbsolutePositionInfo { + pub fn new(writing_mode: WritingMode) -> EarlyAbsolutePositionInfo { + // FIXME(pcwalton): The initial relative containing block-size should be equal to the size + // of the root layer. + EarlyAbsolutePositionInfo { + relative_containing_block_size: LogicalSize::zero(writing_mode), + relative_containing_block_mode: writing_mode, + } + } +} +/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be +/// confused with absolutely-positioned flows) that is computed during final position assignment. +#[derive(RustcEncodable, Copy, Clone)] +pub struct LateAbsolutePositionInfo { /// The position of the absolute containing block relative to the nearest ancestor stacking /// context. If the absolute containing block establishes the stacking context for this flow, /// and this flow is not itself absolutely-positioned, then this is (0, 0). @@ -800,13 +823,9 @@ pub struct AbsolutePositionInfo { pub layers_needed_for_positioned_flows: bool, } -impl AbsolutePositionInfo { - pub fn new(writing_mode: WritingMode) -> AbsolutePositionInfo { - // FIXME(pcwalton): The initial relative containing block-size should be equal to the size - // of the root layer. - AbsolutePositionInfo { - relative_containing_block_size: LogicalSize::zero(writing_mode), - relative_containing_block_mode: writing_mode, +impl LateAbsolutePositionInfo { + pub fn new() -> LateAbsolutePositionInfo { + LateAbsolutePositionInfo { stacking_relative_position_of_absolute_containing_block: Point2D::zero(), layers_needed_for_positioned_flows: false, } @@ -875,8 +894,13 @@ pub struct BaseFlow { pub absolute_cb: ContainingBlockLink, /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be - /// confused with absolutely-positioned flows). - pub absolute_position_info: AbsolutePositionInfo, + /// confused with absolutely-positioned flows) that is computed during block-size assignment. + pub early_absolute_position_info: EarlyAbsolutePositionInfo, + + /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be + /// confused with absolutely-positioned flows) that is computed during final position + /// assignment. + pub late_absolute_position_info: LateAbsolutePositionInfo, /// The clipping region for this flow and its descendants, in layer coordinates. pub clip: ClippingRegion, @@ -1038,7 +1062,8 @@ impl BaseFlow { block_container_explicit_block_size: None, absolute_cb: ContainingBlockLink::new(), display_list_building_result: DisplayListBuildingResult::None, - absolute_position_info: AbsolutePositionInfo::new(writing_mode), + early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode), + late_absolute_position_info: LateAbsolutePositionInfo::new(), clip: ClippingRegion::max(), stacking_relative_position_of_display_port: Rect::zero(), flags: flags, @@ -1276,6 +1301,13 @@ impl<'a> ImmutableFlowUtils for &'a Flow { } } + /// Returns true if this flow can have its overflow area calculated early (during its + /// block-size assignment) or false if it must have its overflow area calculated late (during + /// its parent's block-size assignment). + fn can_calculate_overflow_area_early(self) -> bool { + !self.contains_relatively_positioned_fragments() + } + /// Dumps the flow tree for debugging. fn dump(self) { self.dump_with_level(0) @@ -1354,6 +1386,20 @@ impl<'a> MutableFlowUtils for &'a mut Flow { traversal.process(*self) } + + /// Calls `store_overflow()` if the overflow can be calculated early. + fn early_store_overflow(self, layout_context: &LayoutContext) { + if self.can_calculate_overflow_area_early() { + self.store_overflow(layout_context) + } + } + + /// Calls `store_overflow()` if the overflow cannot be calculated early. + fn late_store_overflow(self, layout_context: &LayoutContext) { + if !self.can_calculate_overflow_area_early() { + self.store_overflow(layout_context) + } + } } impl MutableOwnedFlowUtils for FlowRef { diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 02af5569d84..3b9596d27b9 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<Au> { + pub fn compute_overflow(&self, relative_containing_block_size: &LogicalSize<Au>) -> Rect<Au> { // 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. @@ -2300,10 +2299,10 @@ bitflags! { // Various flags we can use when splitting fragments. See // `calculate_split_position_using_breaking_strategy()`. flags SplitOptions: u8 { - #[doc="True if this is the first fragment on the line."] + #[doc = "True if this is the first fragment on the line."] const STARTS_LINE = 0x01, - #[doc="True if we should attempt to split at character boundaries if this split fails. \ - This is used to implement `overflow-wrap: break-word`."] + #[doc = "True if we should attempt to split at character boundaries if this split fails. \ + This is used to implement `overflow-wrap: break-word`."] const RETRY_AT_CHARACTER_BOUNDARIES = 0x02, } } diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs index 623fa4685fe..14205b32cb5 100644 --- a/components/layout/incremental.rs +++ b/components/layout/incremental.rs @@ -42,8 +42,8 @@ bitflags! { bitflags! { flags SpecialRestyleDamage: u8 { - #[doc="If this flag is set, we need to reflow the entire document. This is more or less a \ - temporary hack to deal with cases that we don't handle incrementally yet."] + #[doc = "If this flag is set, we need to reflow the entire document. This is more or less a \ + temporary hack to deal with cases that we don't handle incrementally yet."] const REFLOW_ENTIRE_DOCUMENT = 0x01, } } diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 4b5a6b985c7..17d6af7ccbc 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -183,9 +183,9 @@ int_range_index! { bitflags! { flags InlineReflowFlags: u8 { - #[doc="The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."] + #[doc = "The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."] const NO_WRAP_INLINE_REFLOW_FLAG = 0x01, - #[doc="The `white-space: pre` property from CSS 2.1 § 16.6 is in effect."] + #[doc = "The `white-space: pre` property from CSS 2.1 § 16.6 is in effect."] const WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG = 0x02 } } @@ -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<Au> { 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..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::{ImmutableFlowUtils, OpaqueFlow}; -use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_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; @@ -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/table_wrapper.rs b/components/layout/table_wrapper.rs index c3312bceba9..ebf96020634 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -13,12 +13,12 @@ #![deny(unsafe_code)] -use block::{BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput}; +use block::{BlockFlow, FloatNonReplaced, AbsoluteNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput}; use block::{ISizeConstraintSolution, MarginsMayCollapseFlag}; use context::LayoutContext; use floats::FloatKind; use flow::{FlowClass, Flow, ImmutableFlowUtils}; -use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, OpaqueFlow}; +use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator}; use model::MaybeAuto; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize}; @@ -242,6 +242,26 @@ impl TableWrapperFlow { return } + if !self.block_flow.base.flags.contains(INLINE_POSITION_IS_STATIC) { + let inline_size_computer = AbsoluteTable { + minimum_width_of_all_columns: minimum_width_of_all_columns, + preferred_width_of_all_columns: preferred_width_of_all_columns, + border_collapse: border_collapse, + }; + let input = + inline_size_computer.compute_inline_size_constraint_inputs(&mut self.block_flow, + parent_flow_inline_size, + layout_context); + + let solution = inline_size_computer.solve_inline_size_constraints(&mut self.block_flow, + &input); + inline_size_computer.set_inline_size_constraint_solutions(&mut self.block_flow, + solution); + inline_size_computer.set_inline_position_of_flow_if_necessary(&mut self.block_flow, + solution); + return + } + let inline_size_computer = Table { minimum_width_of_all_columns: minimum_width_of_all_columns, preferred_width_of_all_columns: preferred_width_of_all_columns, @@ -791,3 +811,54 @@ impl ISizeAndMarginsComputer for FloatedTable { FloatNonReplaced.solve_inline_size_constraints(block, input) } } + +struct AbsoluteTable { + minimum_width_of_all_columns: Au, + preferred_width_of_all_columns: Au, + border_collapse: border_collapse::T, +} + +impl ISizeAndMarginsComputer for AbsoluteTable { + fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) { + block.fragment.compute_border_and_padding(containing_block_inline_size, + self.border_collapse) + } + + fn initial_computed_inline_size(&self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + layout_context: &LayoutContext) + -> MaybeAuto { + let containing_block_inline_size = + self.containing_block_inline_size(block, + parent_flow_inline_size, + layout_context); + initial_computed_inline_size(block, + containing_block_inline_size, + self.minimum_width_of_all_columns, + self.preferred_width_of_all_columns) + } + + fn containing_block_inline_size(&self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + layout_context: &LayoutContext) + -> Au { + AbsoluteNonReplaced.containing_block_inline_size(block, parent_flow_inline_size, layout_context) + } + + fn solve_inline_size_constraints(&self, + block: &mut BlockFlow, + input: &ISizeConstraintInput) + -> ISizeConstraintSolution { + AbsoluteNonReplaced.solve_inline_size_constraints(block, input) + } + + fn set_inline_position_of_flow_if_necessary(&self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution) { + AbsoluteNonReplaced.set_inline_position_of_flow_if_necessary(block, solution); + } + +} + diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 7c4687a1b00..ed8ae6ab76a 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -7,7 +7,7 @@ use construct::FlowConstructor; use context::LayoutContext; use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult}; -use flow::{PreorderFlowTraversal, PostorderFlowTraversal}; +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; @@ -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] |