Introduce PositioningContext

This commit is contained in:
Simon Sapin 2019-12-12 15:37:01 +01:00
parent 06e3d13795
commit b43a3de51d
5 changed files with 90 additions and 69 deletions

View file

@ -9,7 +9,7 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::CollapsedBlockMargins; use crate::fragments::CollapsedBlockMargins;
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment}; use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::sizing::ContentSizes; use crate::sizing::ContentSizes;
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside}; use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
use crate::{relative_adjustement, ContainingBlock}; use crate::{relative_adjustement, ContainingBlock};
@ -68,9 +68,9 @@ struct PartialInlineBoxFragment<'box_tree> {
parent_nesting_level: InlineNestingLevelState<'box_tree>, parent_nesting_level: InlineNestingLevelState<'box_tree>,
} }
struct InlineFormattingContextState<'box_tree, 'a> { struct InlineFormattingContextState<'box_tree, 'a, 'b> {
absolutely_positioned_fragments: &'a mut Vec<AbsolutelyPositionedFragment<'box_tree>>, positioning_context: &'a mut PositioningContext<'box_tree>,
containing_block: &'a ContainingBlock<'a>, containing_block: &'b ContainingBlock<'b>,
lines: Lines, lines: Lines,
inline_position: Length, inline_position: Length,
partial_inline_boxes_stack: Vec<PartialInlineBoxFragment<'box_tree>>, partial_inline_boxes_stack: Vec<PartialInlineBoxFragment<'box_tree>>,
@ -195,12 +195,12 @@ impl InlineFormattingContext {
pub(super) fn layout<'a>( pub(super) fn layout<'a>(
&'a self, &'a self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> FlowLayout { ) -> FlowLayout {
let mut ifc = InlineFormattingContextState { let mut ifc = InlineFormattingContextState {
absolutely_positioned_fragments, positioning_context,
containing_block, containing_block,
partial_inline_boxes_stack: Vec::new(), partial_inline_boxes_stack: Vec::new(),
lines: Lines { lines: Lines {
@ -244,7 +244,8 @@ impl InlineFormattingContext {
panic!("display:none does not generate an abspos box") panic!("display:none does not generate an abspos box")
}, },
}; };
ifc.absolutely_positioned_fragments ifc.positioning_context
.abspos
.push(box_.layout(initial_start_corner, tree_rank)); .push(box_.layout(initial_start_corner, tree_rank));
}, },
InlineLevelBox::OutOfFlowFloatBox(_box_) => { InlineLevelBox::OutOfFlowFloatBox(_box_) => {
@ -346,7 +347,7 @@ impl Lines {
impl InlineBox { impl InlineBox {
fn start_layout<'box_tree>( fn start_layout<'box_tree>(
&'box_tree self, &'box_tree self,
ifc: &mut InlineFormattingContextState<'box_tree, '_>, ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>,
) -> PartialInlineBoxFragment<'box_tree> { ) -> PartialInlineBoxFragment<'box_tree> {
let style = self.style.clone(); let style = self.style.clone();
let cbis = ifc.containing_block.inline_size; let cbis = ifc.containing_block.inline_size;
@ -440,7 +441,7 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> {
fn layout_atomic<'box_tree>( fn layout_atomic<'box_tree>(
layout_context: &LayoutContext, layout_context: &LayoutContext,
ifc: &mut InlineFormattingContextState<'box_tree, '_>, ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>,
atomic: &'box_tree IndependentFormattingContext, atomic: &'box_tree IndependentFormattingContext,
) { ) {
let cbis = ifc.containing_block.inline_size; let cbis = ifc.containing_block.inline_size;
@ -521,9 +522,9 @@ fn layout_atomic<'box_tree>(
// FIXME: Do we need to call `adjust_static_positions` somewhere near here? // FIXME: Do we need to call `adjust_static_positions` somewhere near here?
let independent_layout = non_replaced.layout( let independent_layout = non_replaced.layout(
layout_context, layout_context,
ifc.positioning_context,
&containing_block_for_children, &containing_block_for_children,
dummy_tree_rank, dummy_tree_rank,
ifc.absolutely_positioned_fragments,
); );
// https://drafts.csswg.org/css2/visudet.html#block-root-margin // https://drafts.csswg.org/css2/visudet.html#block-root-margin

View file

@ -12,7 +12,7 @@ use crate::fragments::{AnonymousFragment, BoxFragment, Fragment};
use crate::fragments::{CollapsedBlockMargins, CollapsedMargin}; use crate::fragments::{CollapsedBlockMargins, CollapsedMargin};
use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::adjust_static_positions; use crate::positioned::adjust_static_positions;
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;
use crate::style_ext::ComputedValuesExt; use crate::style_ext::ComputedValuesExt;
use crate::{relative_adjustement, ContainingBlock}; use crate::{relative_adjustement, ContainingBlock};
@ -67,9 +67,9 @@ impl BlockFormattingContext {
pub(super) fn layout<'a>( pub(super) fn layout<'a>(
&'a self, &'a self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> IndependentLayout { ) -> IndependentLayout {
let mut float_context; let mut float_context;
let float_context = if self.contains_floats { let float_context = if self.contains_floats {
@ -80,9 +80,9 @@ impl BlockFormattingContext {
}; };
let flow_layout = self.contents.layout( let flow_layout = self.contents.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments,
float_context, float_context,
CollapsibleWithParentStartMargin(false), CollapsibleWithParentStartMargin(false),
); );
@ -103,27 +103,27 @@ impl BlockContainer {
fn layout<'a>( fn layout<'a>(
&'a self, &'a self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
float_context: Option<&mut FloatContext>, float_context: Option<&mut FloatContext>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
) -> FlowLayout { ) -> FlowLayout {
match self { match self {
BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children( BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children(
layout_context, layout_context,
positioning_context,
child_boxes, child_boxes,
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments,
float_context, float_context,
collapsible_with_parent_start_margin, collapsible_with_parent_start_margin,
), ),
BlockContainer::InlineFormattingContext(ifc) => ifc.layout( BlockContainer::InlineFormattingContext(ifc) => ifc.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments,
), ),
} }
} }
@ -131,10 +131,10 @@ impl BlockContainer {
fn layout_block_level_children<'a>( fn layout_block_level_children<'a>(
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
child_boxes: &'a [Arc<BlockLevelBox>], child_boxes: &'a [Arc<BlockLevelBox>],
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
mut float_context: Option<&mut FloatContext>, mut float_context: Option<&mut FloatContext>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
) -> FlowLayout { ) -> FlowLayout {
@ -194,7 +194,7 @@ fn layout_block_level_children<'a>(
current_block_direction_position: Length, current_block_direction_position: Length,
} }
let abspos_so_far = absolutely_positioned_fragments.len(); let abspos_so_far = positioning_context.abspos.len();
let mut placement_state = PlacementState { let mut placement_state = PlacementState {
next_in_flow_margin_collapses_with_parent_start_margin: next_in_flow_margin_collapses_with_parent_start_margin:
collapsible_with_parent_start_margin.0, collapsible_with_parent_start_margin.0,
@ -213,9 +213,9 @@ fn layout_block_level_children<'a>(
.map(|(tree_rank, box_)| { .map(|(tree_rank, box_)| {
let mut fragment = box_.layout( let mut fragment = box_.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments,
float_context.as_mut().map(|c| &mut **c), float_context.as_mut().map(|c| &mut **c),
); );
place_block_level_fragment(&mut fragment, &mut placement_state); place_block_level_fragment(&mut fragment, &mut placement_state);
@ -227,19 +227,17 @@ fn layout_block_level_children<'a>(
.par_iter() .par_iter()
.enumerate() .enumerate()
.mapfold_reduce_into( .mapfold_reduce_into(
absolutely_positioned_fragments, positioning_context,
|abspos_fragments, (tree_rank, box_)| { |positioning_context, (tree_rank, box_)| {
box_.layout( box_.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
abspos_fragments,
/* float_context = */ None, /* float_context = */ None,
) )
}, },
|left_abspos_fragments, mut right_abspos_fragments| { |left, right| left.append(right),
left_abspos_fragments.append(&mut right_abspos_fragments);
},
) )
.collect(); .collect();
for fragment in &mut fragments { for fragment in &mut fragments {
@ -248,7 +246,7 @@ fn layout_block_level_children<'a>(
} }
adjust_static_positions( adjust_static_positions(
&mut absolutely_positioned_fragments[abspos_so_far..], &mut positioning_context.abspos[abspos_so_far..],
&mut fragments, &mut fragments,
tree_rank, tree_rank,
); );
@ -269,25 +267,27 @@ impl BlockLevelBox {
fn layout<'a>( fn layout<'a>(
&'a self, &'a self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
float_context: Option<&mut FloatContext>, float_context: Option<&mut FloatContext>,
) -> Fragment { ) -> Fragment {
match self { match self {
BlockLevelBox::SameFormattingContextBlock { style, contents } => { BlockLevelBox::SameFormattingContextBlock { style, contents } => {
Fragment::Box(layout_in_flow_non_replaced_block_level( Fragment::Box(layout_in_flow_non_replaced_block_level(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
absolutely_positioned_fragments,
style, style,
BlockLevelKind::SameFormattingContextBlock, BlockLevelKind::SameFormattingContextBlock,
|containing_block, nested_abspos, collapsible_with_parent_start_margin| { |positioning_context,
containing_block,
collapsible_with_parent_start_margin| {
contents.layout( contents.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
nested_abspos,
float_context, float_context,
collapsible_with_parent_start_margin, collapsible_with_parent_start_margin,
) )
@ -302,16 +302,16 @@ impl BlockLevelBox {
)), )),
Err(non_replaced) => Fragment::Box(layout_in_flow_non_replaced_block_level( Err(non_replaced) => Fragment::Box(layout_in_flow_non_replaced_block_level(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
absolutely_positioned_fragments,
&contents.style, &contents.style,
BlockLevelKind::EstablishesAnIndependentFormattingContext, BlockLevelKind::EstablishesAnIndependentFormattingContext,
|containing_block, nested_abspos, _| { |positioning_context, containing_block, _| {
let independent_layout = non_replaced.layout( let independent_layout = non_replaced.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
nested_abspos,
); );
FlowLayout { FlowLayout {
fragments: independent_layout.fragments, fragments: independent_layout.fragments,
@ -322,7 +322,9 @@ impl BlockLevelBox {
)), )),
}, },
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
absolutely_positioned_fragments.push(box_.layout(Vec2::zero(), tree_rank)); positioning_context
.abspos
.push(box_.layout(Vec2::zero(), tree_rank));
Fragment::Anonymous(AnonymousFragment::no_op( Fragment::Anonymous(AnonymousFragment::no_op(
containing_block.style.writing_mode, containing_block.style.writing_mode,
)) ))
@ -347,13 +349,13 @@ enum BlockLevelKind {
/// https://drafts.csswg.org/css2/visudet.html#normal-block /// https://drafts.csswg.org/css2/visudet.html#normal-block
fn layout_in_flow_non_replaced_block_level<'a>( fn layout_in_flow_non_replaced_block_level<'a>(
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
block_level_kind: BlockLevelKind, block_level_kind: BlockLevelKind,
layout_contents: impl FnOnce( layout_contents: impl FnOnce(
&mut PositioningContext<'a>,
&ContainingBlock, &ContainingBlock,
&mut Vec<AbsolutelyPositionedFragment<'a>>,
CollapsibleWithParentStartMargin, CollapsibleWithParentStartMargin,
) -> FlowLayout, ) -> FlowLayout,
) -> BoxFragment { ) -> BoxFragment {
@ -436,14 +438,14 @@ fn layout_in_flow_non_replaced_block_level<'a>(
min_box_size.block == Length::zero() && min_box_size.block == Length::zero() &&
pb.block_end == Length::zero() && pb.block_end == Length::zero() &&
block_level_kind == BlockLevelKind::SameFormattingContextBlock; block_level_kind == BlockLevelKind::SameFormattingContextBlock;
let mut nested_abspos = vec![]; let mut nested_positioning_context = PositioningContext { abspos: Vec::new() };
let mut flow_layout = layout_contents( let mut flow_layout = layout_contents(
&containing_block_for_children,
if style.get_box().position == Position::Relative { if style.get_box().position == Position::Relative {
&mut nested_abspos &mut nested_positioning_context
} else { } else {
absolutely_positioned_fragments positioning_context
}, },
&containing_block_for_children,
this_start_margin_can_collapse_with_children, this_start_margin_can_collapse_with_children,
); );
let mut block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin); let mut block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin);
@ -493,9 +495,8 @@ fn layout_in_flow_non_replaced_block_level<'a>(
}, },
}; };
if style.get_box().position == Position::Relative { if style.get_box().position == Position::Relative {
AbsolutelyPositionedFragment::in_positioned_containing_block( nested_positioning_context.layout_abspos(
layout_context, layout_context,
&nested_abspos,
&mut flow_layout.fragments, &mut flow_layout.fragments,
&content_rect.size, &content_rect.size,
&padding, &padding,

View file

@ -12,7 +12,8 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Fragment; use crate::fragments::Fragment;
use crate::geom; use crate::geom;
use crate::geom::flow_relative::Vec2; use crate::geom::flow_relative::Vec2;
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment}; use crate::positioned::PositioningContext;
use crate::positioned::{AbsolutelyPositionedBox, CollectedAbsolutelyPositionedBox};
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;
use crate::sizing::ContentSizesRequest; use crate::sizing::ContentSizesRequest;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside}; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
@ -110,24 +111,25 @@ impl BoxTreeRoot {
}; };
let dummy_tree_rank = 0; let dummy_tree_rank = 0;
let mut absolutely_positioned_fragments = vec![]; let mut positioning_context = PositioningContext { abspos: Vec::new() };
let mut independent_layout = self.0.layout( let mut independent_layout = self.0.layout(
layout_context, layout_context,
&mut positioning_context,
&(&initial_containing_block).into(), &(&initial_containing_block).into(),
dummy_tree_rank, dummy_tree_rank,
&mut absolutely_positioned_fragments,
); );
let map = let map = |a: &CollectedAbsolutelyPositionedBox| {
|a: &AbsolutelyPositionedFragment| a.layout(layout_context, &initial_containing_block); a.layout(layout_context, &initial_containing_block)
};
if layout_context.use_rayon { if layout_context.use_rayon {
independent_layout independent_layout
.fragments .fragments
.par_extend(absolutely_positioned_fragments.par_iter().map(map)) .par_extend(positioning_context.abspos.par_iter().map(map))
} else { } else {
independent_layout independent_layout
.fragments .fragments
.extend(absolutely_positioned_fragments.iter().map(map)) .extend(positioning_context.abspos.iter().map(map))
} }
FragmentTreeRoot(independent_layout.fragments) FragmentTreeRoot(independent_layout.fragments)

View file

@ -6,7 +6,7 @@ use crate::context::LayoutContext;
use crate::dom_traversal::{Contents, NodeExt}; use crate::dom_traversal::{Contents, NodeExt};
use crate::flow::BlockFormattingContext; use crate::flow::BlockFormattingContext;
use crate::fragments::Fragment; use crate::fragments::Fragment;
use crate::positioned::AbsolutelyPositionedFragment; use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;
use crate::sizing::{BoxContentSizes, ContentSizesRequest}; use crate::sizing::{BoxContentSizes, ContentSizesRequest};
use crate::style_ext::DisplayInside; use crate::style_ext::DisplayInside;
@ -101,16 +101,16 @@ impl<'a> NonReplacedIFC<'a> {
pub fn layout( pub fn layout(
&self, &self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
) -> IndependentLayout { ) -> IndependentLayout {
match &self.0 { match &self.0 {
NonReplacedIFCKind::Flow(bfc) => bfc.layout( NonReplacedIFCKind::Flow(bfc) => bfc.layout(
layout_context, layout_context,
positioning_context,
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments,
), ),
} }
} }

View file

@ -21,9 +21,15 @@ pub(crate) struct AbsolutelyPositionedBox {
pub contents: IndependentFormattingContext, pub contents: IndependentFormattingContext,
} }
#[derive(Default)]
pub(crate) struct PositioningContext<'box_tree> {
/// With `position: absolute`
pub abspos: Vec<CollectedAbsolutelyPositionedBox<'box_tree>>,
}
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct AbsolutelyPositionedFragment<'box_> { pub(crate) struct CollectedAbsolutelyPositionedBox<'box_tree> {
absolutely_positioned_box: &'box_ AbsolutelyPositionedBox, absolutely_positioned_box: &'box_tree AbsolutelyPositionedBox,
/// The rank of the child from which this absolutely positioned fragment /// The rank of the child from which this absolutely positioned fragment
/// came from, when doing the layout of a block container. Used to compute /// came from, when doing the layout of a block container. Used to compute
@ -81,7 +87,7 @@ impl AbsolutelyPositionedBox {
&'a self, &'a self,
initial_start_corner: Vec2<Length>, initial_start_corner: Vec2<Length>,
tree_rank: usize, tree_rank: usize,
) -> AbsolutelyPositionedFragment { ) -> CollectedAbsolutelyPositionedBox {
fn absolute_box_offsets( fn absolute_box_offsets(
initial_static_start: Length, initial_static_start: Length,
start: LengthPercentageOrAuto, start: LengthPercentageOrAuto,
@ -98,7 +104,7 @@ impl AbsolutelyPositionedBox {
} }
let box_offsets = self.contents.style.box_offsets(); let box_offsets = self.contents.style.box_offsets();
AbsolutelyPositionedFragment { CollectedAbsolutelyPositionedBox {
absolutely_positioned_box: self, absolutely_positioned_box: self,
tree_rank, tree_rank,
box_offsets: Vec2 { box_offsets: Vec2 {
@ -117,16 +123,25 @@ impl AbsolutelyPositionedBox {
} }
} }
impl<'a> AbsolutelyPositionedFragment<'a> { impl PositioningContext<'_> {
pub(crate) fn in_positioned_containing_block( /// Unlike `Vec::append`, this takes ownership of the other value.
pub(crate) fn append(&mut self, mut other: Self) {
if self.abspos.is_empty() {
self.abspos = other.abspos
} else {
self.abspos.append(&mut other.abspos)
}
}
pub(crate) fn layout_abspos(
self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
absolute: &[Self],
fragments: &mut Vec<Fragment>, fragments: &mut Vec<Fragment>,
content_rect_size: &Vec2<Length>, content_rect_size: &Vec2<Length>,
padding: &Sides<Length>, padding: &Sides<Length>,
style: &ComputedValues, style: &ComputedValues,
) { ) {
if absolute.is_empty() { if self.abspos.is_empty() {
return; return;
} }
let padding_rect = Rect { let padding_rect = Rect {
@ -139,11 +154,12 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
size: padding_rect.size.clone(), size: padding_rect.size.clone(),
style, style,
}; };
let map = |a: &AbsolutelyPositionedFragment| a.layout(layout_context, &containing_block); let map =
|a: &CollectedAbsolutelyPositionedBox| a.layout(layout_context, &containing_block);
let children = if layout_context.use_rayon { let children = if layout_context.use_rayon {
absolute.par_iter().map(map).collect() self.abspos.par_iter().map(map).collect()
} else { } else {
absolute.iter().map(map).collect() self.abspos.iter().map(map).collect()
}; };
fragments.push(Fragment::Anonymous(AnonymousFragment { fragments.push(Fragment::Anonymous(AnonymousFragment {
children, children,
@ -151,7 +167,9 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
mode: style.writing_mode, mode: style.writing_mode,
})) }))
} }
}
impl CollectedAbsolutelyPositionedBox<'_> {
pub(crate) fn layout( pub(crate) fn layout(
&self, &self,
layout_context: &LayoutContext, layout_context: &LayoutContext,
@ -216,7 +234,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
block_end: block_axis.margin_end, block_end: block_axis.margin_end,
}; };
let mut absolutely_positioned_fragments = Vec::new(); let mut positioning_context = PositioningContext { abspos: Vec::new() };
let (size, mut fragments) = match self.absolutely_positioned_box.contents.as_replaced() { let (size, mut fragments) = match self.absolutely_positioned_box.contents.as_replaced() {
Ok(replaced) => { Ok(replaced) => {
// https://drafts.csswg.org/css2/visudet.html#abs-replaced-width // https://drafts.csswg.org/css2/visudet.html#abs-replaced-width
@ -256,9 +274,9 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
let dummy_tree_rank = 0; let dummy_tree_rank = 0;
let independent_layout = non_replaced.layout( let independent_layout = non_replaced.layout(
layout_context, layout_context,
&mut positioning_context,
&containing_block_for_children, &containing_block_for_children,
dummy_tree_rank, dummy_tree_rank,
&mut absolutely_positioned_fragments,
); );
let size = Vec2 { let size = Vec2 {
@ -288,9 +306,8 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
size, size,
}; };
AbsolutelyPositionedFragment::in_positioned_containing_block( positioning_context.layout_abspos(
layout_context, layout_context,
&absolutely_positioned_fragments,
&mut fragments, &mut fragments,
&content_rect.size, &content_rect.size,
&padding, &padding,
@ -414,8 +431,8 @@ fn solve_axis(
} }
pub(crate) fn adjust_static_positions( pub(crate) fn adjust_static_positions(
absolutely_positioned_fragments: &mut [AbsolutelyPositionedFragment], absolutely_positioned_fragments: &mut [CollectedAbsolutelyPositionedBox],
child_fragments: &mut [Fragment], child_fragments: &[Fragment],
tree_rank_in_parent: usize, tree_rank_in_parent: usize,
) { ) {
for abspos_fragment in absolutely_positioned_fragments { for abspos_fragment in absolutely_positioned_fragments {