From 858bc5aca681fae70ce640d70d5fa80f7edd3dc9 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 26 Nov 2019 16:21:11 +0100 Subject: [PATCH] Split FlowChildren in IndependentLayout and FlowLayout The result of doing the layout of an independent formatting context should be unconcerned with margin collapsing. --- components/layout_2020/flow/inline.rs | 8 +-- components/layout_2020/flow/mod.rs | 67 +++++++++++-------- components/layout_2020/flow/root.rs | 11 ++- components/layout_2020/formatting_contexts.rs | 13 +++- components/layout_2020/lib.rs | 2 +- components/layout_2020/positioned.rs | 8 +-- 6 files changed, 61 insertions(+), 48 deletions(-) diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index f6e0d003e03..5a48ac9a2ee 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -4,7 +4,7 @@ use crate::context::LayoutContext; use crate::flow::float::FloatBox; -use crate::flow::FlowChildren; +use crate::flow::FlowLayout; use crate::fragments::{ AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment, TextFragment, }; @@ -88,7 +88,7 @@ impl InlineFormattingContext { containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec>, - ) -> FlowChildren { + ) -> FlowLayout { let mut ifc = InlineFormattingContextState { containing_block, partial_inline_boxes_stack: Vec::new(), @@ -156,9 +156,9 @@ impl InlineFormattingContext { } else { ifc.line_boxes .finish_line(&mut ifc.current_nesting_level, containing_block); - return FlowChildren { + return FlowLayout { fragments: ifc.line_boxes.boxes, - block_size: ifc.line_boxes.next_line_block_position, + content_block_size: ifc.line_boxes.next_line_block_position, collapsible_margins_in_children: CollapsedBlockMargins::zero(), }; } diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index f8ea3e54722..9281c135760 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -7,11 +7,11 @@ use crate::context::LayoutContext; use crate::flow::float::{FloatBox, FloatContext}; use crate::flow::inline::InlineFormattingContext; -use crate::formatting_contexts::IndependentFormattingContext; +use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout}; use crate::fragments::{ AnonymousFragment, BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, }; -use crate::geom::flow_relative::{Rect, Vec2}; +use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{ adjust_static_positions, AbsolutelyPositionedBox, AbsolutelyPositionedFragment, }; @@ -54,9 +54,9 @@ pub(crate) enum BlockLevelBox { Independent(IndependentFormattingContext), } -pub(super) struct FlowChildren { +struct FlowLayout { pub fragments: Vec, - pub block_size: Length, + pub content_block_size: Length, pub collapsible_margins_in_children: CollapsedBlockMargins, } @@ -70,7 +70,7 @@ impl BlockFormattingContext { containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec>, - ) -> FlowChildren { + ) -> IndependentLayout { let mut float_context; let float_context = if self.contains_floats { float_context = FloatContext::new(); @@ -78,7 +78,7 @@ impl BlockFormattingContext { } else { None }; - let mut flow_children = self.contents.layout( + let flow_layout = self.contents.layout( layout_context, containing_block, tree_rank, @@ -86,12 +86,16 @@ impl BlockFormattingContext { float_context, CollapsibleWithParentStartMargin(false), ); - flow_children.block_size += flow_children.collapsible_margins_in_children.end.solve(); - flow_children - .collapsible_margins_in_children - .collapsed_through = false; - flow_children.collapsible_margins_in_children.end = CollapsedMargin::zero(); - flow_children + assert!( + !flow_layout + .collapsible_margins_in_children + .collapsed_through + ); + IndependentLayout { + fragments: flow_layout.fragments, + content_block_size: flow_layout.content_block_size + + flow_layout.collapsible_margins_in_children.end.solve(), + } } } @@ -104,7 +108,7 @@ impl BlockContainer { absolutely_positioned_fragments: &mut Vec>, float_context: Option<&mut FloatContext>, collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, - ) -> FlowChildren { + ) -> FlowLayout { match self { BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children( layout_context, @@ -133,7 +137,7 @@ fn layout_block_level_children<'a>( absolutely_positioned_fragments: &mut Vec>, float_context: Option<&mut FloatContext>, collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, -) -> FlowChildren { +) -> FlowLayout { fn place_block_level_fragment(fragment: &mut Fragment, placement_state: &mut PlacementState) { match fragment { Fragment::Box(fragment) => { @@ -249,9 +253,9 @@ fn layout_block_level_children<'a>( tree_rank, ); - FlowChildren { + FlowLayout { fragments, - block_size: placement_state.current_block_direction_position, + content_block_size: placement_state.current_block_direction_position, collapsible_margins_in_children: CollapsedBlockMargins { collapsed_through: placement_state .next_in_flow_margin_collapses_with_parent_start_margin, @@ -302,12 +306,17 @@ impl BlockLevelBox { &contents.style, BlockLevelKind::EstablishesAnIndependentFormattingContext, |containing_block, nested_abspos, _| { - non_replaced.layout( + let independent_layout = non_replaced.layout( layout_context, containing_block, tree_rank, nested_abspos, - ) + ); + FlowLayout { + fragments: independent_layout.fragments, + content_block_size: independent_layout.content_block_size, + collapsible_margins_in_children: CollapsedBlockMargins::zero(), + } }, )), }, @@ -341,7 +350,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( &ContainingBlock, &mut Vec>, CollapsibleWithParentStartMargin, - ) -> FlowChildren, + ) -> FlowLayout, ) -> BoxFragment { let cbis = containing_block.inline_size; let padding = style.padding().percentages_relative_to(cbis); @@ -400,7 +409,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( LengthOrAuto::Auto, ); let mut nested_abspos = vec![]; - let mut flow_children = layout_contents( + let mut flow_layout = layout_contents( &containing_block_for_children, if style.get_box().position == Position::Relative { &mut nested_abspos @@ -412,15 +421,15 @@ fn layout_in_flow_non_replaced_block_level<'a>( if this_start_margin_can_collapse_with_children.0 { block_margins_collapsed_with_children .start - .adjoin_assign(&flow_children.collapsible_margins_in_children.start); - if flow_children + .adjoin_assign(&flow_layout.collapsible_margins_in_children.start); + if flow_layout .collapsible_margins_in_children .collapsed_through { block_margins_collapsed_with_children .start .adjoin_assign(&std::mem::replace( - &mut flow_children.collapsible_margins_in_children.end, + &mut flow_layout.collapsible_margins_in_children.end, CollapsedMargin::zero(), )); } @@ -428,18 +437,18 @@ fn layout_in_flow_non_replaced_block_level<'a>( if this_end_margin_can_collapse_with_children { block_margins_collapsed_with_children .end - .adjoin_assign(&flow_children.collapsible_margins_in_children.end); + .adjoin_assign(&flow_layout.collapsible_margins_in_children.end); } else { - flow_children.block_size += flow_children.collapsible_margins_in_children.end.solve(); + flow_layout.content_block_size += flow_layout.collapsible_margins_in_children.end.solve(); } block_margins_collapsed_with_children.collapsed_through = this_start_margin_can_collapse_with_children.0 && this_end_margin_can_collapse_with_children && - flow_children + flow_layout .collapsible_margins_in_children .collapsed_through; let relative_adjustement = relative_adjustement(style, inline_size, block_size); - let block_size = block_size.auto_is(|| flow_children.block_size); + let block_size = block_size.auto_is(|| flow_layout.content_block_size); let content_rect = Rect { start_corner: Vec2 { block: pb.block_start + relative_adjustement.block, @@ -454,7 +463,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( AbsolutelyPositionedFragment::in_positioned_containing_block( layout_context, &nested_abspos, - &mut flow_children.fragments, + &mut flow_layout.fragments, &content_rect.size, &padding, containing_block_for_children.mode, @@ -462,7 +471,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( } BoxFragment { style: style.clone(), - children: flow_children.fragments, + children: flow_layout.fragments, content_rect, padding, border, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index a56ca0d30bb..8df332b90d6 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -31,10 +31,7 @@ pub struct BoxTreeRoot(BlockFormattingContext); pub struct FragmentTreeRoot(Vec); impl BoxTreeRoot { - pub fn construct<'dom, Node>( - context: &SharedStyleContext<'_>, - root_element: Node, - ) -> Self + pub fn construct<'dom, Node>(context: &SharedStyleContext<'_>, root_element: Node) -> Self where Node: 'dom + Copy + LayoutNode + Send + Sync, { @@ -124,7 +121,7 @@ impl BoxTreeRoot { }; let dummy_tree_rank = 0; let mut absolutely_positioned_fragments = vec![]; - let mut flow_children = self.0.layout( + let mut independent_layout = self.0.layout( layout_context, &initial_containing_block, dummy_tree_rank, @@ -135,12 +132,12 @@ impl BoxTreeRoot { size: initial_containing_block_size, mode: initial_containing_block.mode, }; - flow_children.fragments.par_extend( + independent_layout.fragments.par_extend( absolutely_positioned_fragments .par_iter() .map(|a| a.layout(layout_context, &initial_containing_block)), ); - FragmentTreeRoot(flow_children.fragments) + FragmentTreeRoot(independent_layout.fragments) } } diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index b4f9552dff0..96294947720 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -4,7 +4,8 @@ use crate::context::LayoutContext; use crate::dom_traversal::{Contents, NodeExt}; -use crate::flow::{BlockFormattingContext, FlowChildren}; +use crate::flow::BlockFormattingContext; +use crate::fragments::Fragment; use crate::geom::flow_relative::Vec2; use crate::positioned::AbsolutelyPositionedFragment; use crate::replaced::ReplacedContent; @@ -14,6 +15,7 @@ use servo_arc::Arc; use std::convert::TryInto; use style::context::SharedStyleContext; use style::properties::ComputedValues; +use style::values::computed::Length; /// https://drafts.csswg.org/css-display/#independent-formatting-context #[derive(Debug)] @@ -22,6 +24,11 @@ pub(crate) struct IndependentFormattingContext { contents: IndependentFormattingContextContents, } +pub(crate) struct IndependentLayout { + pub fragments: Vec, + pub content_block_size: Length, +} + // Private so that code outside of this module cannot match variants. // It should got through methods instead. #[derive(Debug)] @@ -74,7 +81,7 @@ impl IndependentFormattingContext { containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec>, - ) -> FlowChildren { + ) -> IndependentLayout { match self.as_replaced() { Ok(replaced) => match *replaced {}, Err(ifc) => ifc.layout( @@ -94,7 +101,7 @@ impl<'a> NonReplacedIFC<'a> { containing_block: &ContainingBlock, tree_rank: usize, absolutely_positioned_fragments: &mut Vec>, - ) -> FlowChildren { + ) -> IndependentLayout { match &self.0 { NonReplacedIFCKind::Flow(bfc) => bfc.layout( layout_context, diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs index f1b3c308be2..07956417087 100644 --- a/components/layout_2020/lib.rs +++ b/components/layout_2020/lib.rs @@ -33,7 +33,7 @@ pub use flow::{BoxTreeRoot, FragmentTreeRoot}; use crate::context::LayoutContext; use crate::dom_traversal::{Contents, NodeExt}; -use crate::flow::{BlockFormattingContext, FlowChildren}; +use crate::flow::BlockFormattingContext; use crate::geom::flow_relative::Vec2; use crate::positioned::AbsolutelyPositionedFragment; use crate::replaced::ReplacedContent; diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 1f98512a648..92bd4c8a4d5 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -274,7 +274,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { ); let dummy_tree_rank = 0; let mut absolutely_positioned_fragments = vec![]; - let mut flow_children = self.absolutely_positioned_box.contents.layout( + let mut independent_layout = self.absolutely_positioned_box.contents.layout( layout_context, &containing_block_for_children, dummy_tree_rank, @@ -286,7 +286,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { Anchor::End(end) => cbbs - end - pb.inline_end - margin.inline_end - inline_size, }; - let block_size = block_size.auto_is(|| flow_children.block_size); + let block_size = block_size.auto_is(|| independent_layout.content_block_size); let block_start = match block_anchor { Anchor::Start(start) => start + pb.block_start + margin.block_start, Anchor::End(end) => cbbs - end - pb.block_end - margin.block_end - block_size, @@ -306,7 +306,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { AbsolutelyPositionedFragment::in_positioned_containing_block( layout_context, &absolutely_positioned_fragments, - &mut flow_children.fragments, + &mut independent_layout.fragments, &content_rect.size, &padding, containing_block_for_children.mode, @@ -314,7 +314,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { Fragment::Box(BoxFragment { style: style.clone(), - children: flow_children.fragments, + children: independent_layout.fragments, content_rect, padding, border,