Skip to content

Commit

Permalink
Split FlowChildren in IndependentLayout and FlowLayout
Browse files Browse the repository at this point in the history
The result of doing the layout of an independent formatting context
should be unconcerned with margin collapsing.
  • Loading branch information
nox authored and SimonSapin committed Nov 26, 2019
1 parent 24b7ead commit 858bc5a
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 48 deletions.
8 changes: 4 additions & 4 deletions components/layout_2020/flow/inline.rs
Expand Up @@ -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,
};
Expand Down Expand Up @@ -88,7 +88,7 @@ impl InlineFormattingContext {
containing_block: &ContainingBlock,
tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> FlowChildren {
) -> FlowLayout {
let mut ifc = InlineFormattingContextState {
containing_block,
partial_inline_boxes_stack: Vec::new(),
Expand Down Expand Up @@ -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(),
};
}
Expand Down
67 changes: 38 additions & 29 deletions components/layout_2020/flow/mod.rs
Expand Up @@ -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,
};
Expand Down Expand Up @@ -54,9 +54,9 @@ pub(crate) enum BlockLevelBox {
Independent(IndependentFormattingContext),
}

pub(super) struct FlowChildren {
struct FlowLayout {
pub fragments: Vec<Fragment>,
pub block_size: Length,
pub content_block_size: Length,
pub collapsible_margins_in_children: CollapsedBlockMargins,
}

Expand All @@ -70,28 +70,32 @@ impl BlockFormattingContext {
containing_block: &ContainingBlock,
tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> FlowChildren {
) -> IndependentLayout {
let mut float_context;
let float_context = if self.contains_floats {
float_context = FloatContext::new();
Some(&mut float_context)
} else {
None
};
let mut flow_children = self.contents.layout(
let flow_layout = self.contents.layout(
layout_context,
containing_block,
tree_rank,
absolutely_positioned_fragments,
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(),
}
}
}

Expand All @@ -104,7 +108,7 @@ impl BlockContainer {
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
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,
Expand Down Expand Up @@ -133,7 +137,7 @@ fn layout_block_level_children<'a>(
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
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) => {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
}
},
)),
},
Expand Down Expand Up @@ -341,7 +350,7 @@ fn layout_in_flow_non_replaced_block_level<'a>(
&ContainingBlock,
&mut Vec<AbsolutelyPositionedFragment<'a>>,
CollapsibleWithParentStartMargin,
) -> FlowChildren,
) -> FlowLayout,
) -> BoxFragment {
let cbis = containing_block.inline_size;
let padding = style.padding().percentages_relative_to(cbis);
Expand Down Expand Up @@ -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
Expand All @@ -412,34 +421,34 @@ 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(),
));
}
}
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,
Expand All @@ -454,15 +463,15 @@ 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,
)
}
BoxFragment {
style: style.clone(),
children: flow_children.fragments,
children: flow_layout.fragments,
content_rect,
padding,
border,
Expand Down
11 changes: 4 additions & 7 deletions components/layout_2020/flow/root.rs
Expand Up @@ -31,10 +31,7 @@ pub struct BoxTreeRoot(BlockFormattingContext);
pub struct FragmentTreeRoot(Vec<Fragment>);

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,
{
Expand Down Expand Up @@ -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,
Expand All @@ -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)
}
}

Expand Down
13 changes: 10 additions & 3 deletions components/layout_2020/formatting_contexts.rs
Expand Up @@ -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;
Expand All @@ -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)]
Expand All @@ -22,6 +24,11 @@ pub(crate) struct IndependentFormattingContext {
contents: IndependentFormattingContextContents,
}

pub(crate) struct IndependentLayout {
pub fragments: Vec<Fragment>,
pub content_block_size: Length,
}

// Private so that code outside of this module cannot match variants.
// It should got through methods instead.
#[derive(Debug)]
Expand Down Expand Up @@ -74,7 +81,7 @@ impl IndependentFormattingContext {
containing_block: &ContainingBlock,
tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> FlowChildren {
) -> IndependentLayout {
match self.as_replaced() {
Ok(replaced) => match *replaced {},
Err(ifc) => ifc.layout(
Expand All @@ -94,7 +101,7 @@ impl<'a> NonReplacedIFC<'a> {
containing_block: &ContainingBlock,
tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> FlowChildren {
) -> IndependentLayout {
match &self.0 {
NonReplacedIFCKind::Flow(bfc) => bfc.layout(
layout_context,
Expand Down
2 changes: 1 addition & 1 deletion components/layout_2020/lib.rs
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions components/layout_2020/positioned.rs
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -306,15 +306,15 @@ 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,
);

Fragment::Box(BoxFragment {
style: style.clone(),
children: flow_children.fragments,
children: independent_layout.fragments,
content_rect,
padding,
border,
Expand Down

0 comments on commit 858bc5a

Please sign in to comment.