From d2ccf419c3c717cfd1cc3cc8921cfa6fbfb0b26f Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Wed, 9 Jul 2025 17:04:57 +0200 Subject: [PATCH] layout: Move `BoxFragment`'s block-level info into a dedicated struct (#37938) `BoxFragment` had 2 fields that are only relevant for block-level boxes: `clearance` and a boxed `block_margins_collapsed_with_children`. This moves both pieces of data into a new `BlockLevelLayoutInfo` struct, which is boxed. As a result, the size of `BoxFragment` is reduced from 272 to 264 bytes. Testing: Unneeded (no behavior change) Signed-off-by: Oriol Brufau --- components/layout/flow/mod.rs | 21 +++++--- .../layout/fragment_tree/box_fragment.rs | 53 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index fee8970eb3f..5775f20fb98 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -32,7 +32,8 @@ use crate::formatting_contexts::{ Baselines, IndependentFormattingContext, IndependentFormattingContextContents, }; use crate::fragment_tree::{ - BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags, + BaseFragmentInfo, BlockLevelLayoutInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin, + Fragment, FragmentFlags, }; use crate::geom::{ AuOrAuto, LazySize, LogicalRect, LogicalSides, LogicalSides1D, LogicalVec2, PhysicalPoint, @@ -1175,8 +1176,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context( flow_layout.specific_layout_info, ) .with_baselines(flow_layout.baselines) - .with_block_margins_collapsed_with_children(block_margins_collapsed_with_children) - .with_clearance(clearance) + .with_block_level_layout_info(block_margins_collapsed_with_children, clearance) } impl IndependentFormattingContext { @@ -1288,7 +1288,7 @@ impl IndependentFormattingContext { layout.specific_layout_info, ) .with_baselines(layout.baselines) - .with_block_margins_collapsed_with_children(block_margins_collapsed_with_children) + .with_block_level_layout_info(block_margins_collapsed_with_children, None) } /// Lay out a normal in flow non-replaced block that establishes an independent @@ -1605,8 +1605,7 @@ impl IndependentFormattingContext { layout.specific_layout_info, ) .with_baselines(layout.baselines) - .with_block_margins_collapsed_with_children(CollapsedBlockMargins::from_margin(&margin)) - .with_clearance(clearance) + .with_block_level_layout_info(CollapsedBlockMargins::from_margin(&margin), clearance) } } @@ -2076,7 +2075,13 @@ impl<'container> PlacementState<'container> { return; } - let fragment_block_margins = fragment.block_margins_collapsed_with_children(); + let BlockLevelLayoutInfo { + clearance, + block_margins_collapsed_with_children: fragment_block_margins, + } = &**fragment + .block_level_layout_info + .as_ref() + .expect("A block-level fragment should have a BlockLevelLayoutInfo."); let mut fragment_block_size = fragment .border_rect() .size @@ -2088,7 +2093,7 @@ impl<'container> PlacementState<'container> { // > If the top and bottom margins of an element with clearance are adjoining, // > its margins collapse with the adjoining margins of following siblings but that // > resulting margin does not collapse with the bottom margin of the parent block. - if let Some(clearance) = fragment.clearance { + if let Some(clearance) = *clearance { fragment_block_size += clearance; // Margins can't be adjoining if they are separated by clearance. // Setting `next_in_flow_margin_collapses_with_parent_start_margin` to false diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index 730c19b3bc2..0e032b5b9f8 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -54,6 +54,19 @@ pub(crate) enum SpecificLayoutInfo { TableWrapper, } +#[derive(MallocSizeOf)] +pub(crate) struct BlockLevelLayoutInfo { + /// When the `clear` property is not set to `none`, it may introduce clearance. + /// Clearance is some extra spacing that is added above the top margin, + /// so that the element doesn't overlap earlier floats in the same BFC. + /// The presence of clearance prevents the top margin from collapsing with + /// earlier margins or with the bottom margin of the parent block. + /// + pub clearance: Option, + + pub block_margins_collapsed_with_children: CollapsedBlockMargins, +} + #[derive(MallocSizeOf)] pub(crate) struct BoxFragment { pub base: BaseFragment, @@ -73,21 +86,11 @@ pub(crate) struct BoxFragment { pub border: PhysicalSides, pub margin: PhysicalSides, - /// When the `clear` property is not set to `none`, it may introduce clearance. - /// Clearance is some extra spacing that is added above the top margin, - /// so that the element doesn't overlap earlier floats in the same BFC. - /// The presence of clearance prevents the top margin from collapsing with - /// earlier margins or with the bottom margin of the parent block. - /// - pub clearance: Option, - /// When this [`BoxFragment`] is for content that has a baseline, this tracks /// the first and last baselines of that content. This is used to propagate baselines /// to things such as tables and inline formatting contexts. baselines: Baselines, - block_margins_collapsed_with_children: Option>, - /// The scrollable overflow of this box fragment in the same coordiante system as /// [`Self::content_rect`] ie a rectangle within the parent fragment's content /// rectangle. This does not take into account any transforms this fragment applies. @@ -103,6 +106,9 @@ pub(crate) struct BoxFragment { /// Additional information of from layout that could be used by Javascripts and devtools. pub specific_layout_info: Option, + + /// Additional information for block-level boxes. + pub block_level_layout_info: Option>, } impl BoxFragment { @@ -126,13 +132,12 @@ impl BoxFragment { padding, border, margin, - clearance: None, baselines: Baselines::default(), - block_margins_collapsed_with_children: None, scrollable_overflow: None, resolved_sticky_insets: AtomicRefCell::default(), background_mode: BackgroundMode::Normal, specific_layout_info, + block_level_layout_info: None, } } @@ -185,16 +190,15 @@ impl BoxFragment { self.background_mode = BackgroundMode::None; } - pub fn with_block_margins_collapsed_with_children( + pub fn with_block_level_layout_info( mut self, - collapsed_margins: CollapsedBlockMargins, + block_margins_collapsed_with_children: CollapsedBlockMargins, + clearance: Option, ) -> Self { - self.block_margins_collapsed_with_children = Some(collapsed_margins.into()); - self - } - - pub fn with_clearance(mut self, clearance: Option) -> Self { - self.clearance = clearance; + self.block_level_layout_info = Some(Box::new(BlockLevelLayoutInfo { + block_margins_collapsed_with_children, + clearance, + })); self } @@ -300,7 +304,6 @@ impl BoxFragment { \npadding rect={:?}\ \nborder rect={:?}\ \nmargin={:?}\ - \nclearance={:?}\ \nscrollable_overflow={:?}\ \nbaselines={:?}\ \noverflow={:?}", @@ -309,7 +312,6 @@ impl BoxFragment { self.padding_rect(), self.border_rect(), self.margin, - self.clearance, self.scrollable_overflow(), self.baselines, self.style.effective_overflow(self.base.flags), @@ -513,11 +515,4 @@ impl BoxFragment { _ => false, } } - - pub(crate) fn block_margins_collapsed_with_children(&self) -> CollapsedBlockMargins { - match self.block_margins_collapsed_with_children.as_ref() { - Some(collapsed_block_margins) => *(collapsed_block_margins).clone(), - _ => CollapsedBlockMargins::zero(), - } - } }