aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow/inline
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout_2020/flow/inline')
-rw-r--r--components/layout_2020/flow/inline/inline_box.rs4
-rw-r--r--components/layout_2020/flow/inline/line.rs83
-rw-r--r--components/layout_2020/flow/inline/mod.rs41
3 files changed, 82 insertions, 46 deletions
diff --git a/components/layout_2020/flow/inline/inline_box.rs b/components/layout_2020/flow/inline/inline_box.rs
index c14117b5651..2eceae944f2 100644
--- a/components/layout_2020/flow/inline/inline_box.rs
+++ b/components/layout_2020/flow/inline/inline_box.rs
@@ -73,6 +73,10 @@ impl InlineBoxes {
self.inline_boxes.len()
}
+ pub(super) fn iter(&self) -> impl Iterator<Item = &ArcRefCell<InlineBox>> {
+ self.inline_boxes.iter()
+ }
+
pub(super) fn get(&self, identifier: &InlineBoxIdentifier) -> ArcRefCell<InlineBox> {
self.inline_boxes[identifier.index_in_inline_boxes as usize].clone()
}
diff --git a/components/layout_2020/flow/inline/line.rs b/components/layout_2020/flow/inline/line.rs
index 145627a8f48..c42f32c9242 100644
--- a/components/layout_2020/flow/inline/line.rs
+++ b/components/layout_2020/flow/inline/line.rs
@@ -492,9 +492,11 @@ impl LineItemLayout<'_, '_> {
}
self.current_state.inline_advance += inner_state.inline_advance + pbm_sums.inline_sum();
- self.current_state
- .fragments
- .push((Fragment::Box(ArcRefCell::new(fragment)), content_rect));
+
+ let fragment = Fragment::Box(ArcRefCell::new(fragment));
+ inline_box.base.add_fragment(fragment.clone());
+
+ self.current_state.fragments.push((fragment, content_rect));
}
fn calculate_inline_box_block_start(
@@ -587,32 +589,34 @@ impl LineItemLayout<'_, '_> {
// This needs to be added to the calculated block and inline positions.
// Make the final result relative to the parent box.
let ifc_writing_mode = self.layout.containing_block.style.writing_mode;
- let padding_border_margin_sides = atomic
- .fragment
- .padding_border_margin()
- .to_logical(ifc_writing_mode);
-
- let mut atomic_offset = LogicalVec2 {
- inline: self.current_state.inline_advance + padding_border_margin_sides.inline_start,
- block: atomic.calculate_block_start(&self.line_metrics) -
- self.current_state.parent_offset.block +
- padding_border_margin_sides.block_start,
- };
+ let content_rect = {
+ let block_start = atomic.calculate_block_start(&self.line_metrics);
+ let atomic_fragment = atomic.fragment.borrow_mut();
+ let padding_border_margin_sides = atomic_fragment
+ .padding_border_margin()
+ .to_logical(ifc_writing_mode);
+
+ let mut atomic_offset = LogicalVec2 {
+ inline: self.current_state.inline_advance +
+ padding_border_margin_sides.inline_start,
+ block: block_start - self.current_state.parent_offset.block +
+ padding_border_margin_sides.block_start,
+ };
- if atomic.fragment.style.get_box().position == Position::Relative {
- atomic_offset +=
- relative_adjustement(&atomic.fragment.style, self.layout.containing_block);
- }
+ if atomic_fragment.style.get_box().position == Position::Relative {
+ atomic_offset +=
+ relative_adjustement(&atomic_fragment.style, self.layout.containing_block);
+ }
- // Reconstruct a logical rectangle relative to the inline box container that will be used
- // after the inline box is procesed to find a final physical rectangle.
- let content_rect = LogicalRect {
- start_corner: atomic_offset,
- size: atomic
- .fragment
- .content_rect
- .size
- .to_logical(ifc_writing_mode),
+ // Reconstruct a logical rectangle relative to the inline box container that will be used
+ // after the inline box is procesed to find a final physical rectangle.
+ LogicalRect {
+ start_corner: atomic_offset,
+ size: atomic_fragment
+ .content_rect
+ .size
+ .to_logical(ifc_writing_mode),
+ }
};
if let Some(mut positioning_context) = atomic.positioning_context {
@@ -628,10 +632,10 @@ impl LineItemLayout<'_, '_> {
}
self.current_state.inline_advance += atomic.size.inline;
- self.current_state.fragments.push((
- Fragment::Box(ArcRefCell::new(atomic.fragment)),
- content_rect,
- ));
+
+ self.current_state
+ .fragments
+ .push((Fragment::Box(atomic.fragment), content_rect));
}
fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) {
@@ -691,7 +695,7 @@ impl LineItemLayout<'_, '_> {
));
}
- fn layout_float(&mut self, mut float: FloatLineItem) {
+ fn layout_float(&mut self, float: FloatLineItem) {
self.current_state
.flags
.insert(LineLayoutInlineContainerFlags::HAD_ANY_FLOATS);
@@ -705,13 +709,12 @@ impl LineItemLayout<'_, '_> {
inline: self.current_state.parent_offset.inline,
block: self.line_metrics.block_offset + self.current_state.parent_offset.block,
};
- float.fragment.content_rect.origin -= distance_from_parent_to_ifc
+ float.fragment.borrow_mut().content_rect.origin -= distance_from_parent_to_ifc
.to_physical_size(self.layout.containing_block.style.writing_mode);
- self.current_state.fragments.push((
- Fragment::Float(ArcRefCell::new(float.fragment)),
- LogicalRect::zero(),
- ));
+ self.current_state
+ .fragments
+ .push((Fragment::Float(float.fragment), LogicalRect::zero()));
}
}
@@ -829,7 +832,7 @@ impl TextRunLineItem {
}
pub(super) struct AtomicLineItem {
- pub fragment: BoxFragment,
+ pub fragment: ArcRefCell<BoxFragment>,
pub size: LogicalVec2<Au>,
pub positioning_context: Option<PositioningContext>,
@@ -849,7 +852,7 @@ impl AtomicLineItem {
/// Given the metrics for a line, our vertical alignment, and our block size, find a block start
/// position relative to the top of the line.
fn calculate_block_start(&self, line_metrics: &LineMetrics) -> Au {
- match self.fragment.style.clone_vertical_align() {
+ match self.fragment.borrow().style.clone_vertical_align() {
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Top) => Au::zero(),
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Bottom) => {
line_metrics.block_size - self.size.block
@@ -869,7 +872,7 @@ pub(super) struct AbsolutelyPositionedLineItem {
}
pub(super) struct FloatLineItem {
- pub fragment: BoxFragment,
+ pub fragment: ArcRefCell<BoxFragment>,
/// Whether or not this float Fragment has been placed yet. Fragments that
/// do not fit on a line need to be placed after the hypothetical block start
/// of the next line.
diff --git a/components/layout_2020/flow/inline/mod.rs b/components/layout_2020/flow/inline/mod.rs
index d864807aa45..7564b5004c6 100644
--- a/components/layout_2020/flow/inline/mod.rs
+++ b/components/layout_2020/flow/inline/mod.rs
@@ -221,6 +221,22 @@ impl InlineItem {
},
}
}
+
+ pub(crate) fn fragments(&self) -> Vec<Fragment> {
+ match self {
+ InlineItem::StartInlineBox(inline_box) => inline_box.borrow().base.fragments(),
+ InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
+ unreachable!("Should never have these kind of fragments attached to a DOM node")
+ },
+ InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
+ positioned_box.borrow().context.base.fragments()
+ },
+ InlineItem::OutOfFlowFloatBox(float_box) => float_box.contents.base.fragments(),
+ InlineItem::Atomic(independent_formatting_context, ..) => {
+ independent_formatting_context.base.fragments()
+ },
+ }
+ }
}
/// Information about the current line under construction for a particular
@@ -1081,8 +1097,8 @@ impl InlineFormattingContextLayout<'_> {
float_item: &mut FloatLineItem,
line_inline_size_without_trailing_whitespace: Au,
) {
- let logical_margin_rect_size = float_item
- .fragment
+ let mut float_fragment = float_item.fragment.borrow_mut();
+ let logical_margin_rect_size = float_fragment
.margin_rect()
.size
.to_logical(self.containing_block.style.writing_mode);
@@ -1106,7 +1122,7 @@ impl InlineFormattingContextLayout<'_> {
if needs_placement_later {
self.current_line.has_floats_waiting_to_be_placed = true;
} else {
- self.place_float_fragment(&mut float_item.fragment);
+ self.place_float_fragment(&mut float_fragment);
float_item.needs_placement = false;
}
@@ -1657,6 +1673,11 @@ impl InlineFormattingContext {
Au::zero()
};
+ // Clear any cached inline fragments from previous layouts.
+ for inline_box in self.inline_boxes.iter() {
+ inline_box.borrow().base.clear_fragments();
+ }
+
let style = containing_block.style;
// It's unfortunate that it isn't possible to get this during IFC text processing, but in
@@ -2055,6 +2076,10 @@ impl IndependentFormattingContext {
size.inline,
SegmentContentFlags::empty(),
);
+
+ let fragment = ArcRefCell::new(fragment);
+ self.base.set_fragment(Fragment::Box(fragment.clone()));
+
layout.push_line_item_to_unbreakable_segment(LineItem::Atomic(
layout.current_inline_box_identifier(),
AtomicLineItem {
@@ -2131,11 +2156,15 @@ impl IndependentFormattingContext {
impl FloatBox {
fn layout_into_line_items(&self, layout: &mut InlineFormattingContextLayout) {
- let fragment = self.layout(
+ let fragment = ArcRefCell::new(self.layout(
layout.layout_context,
layout.positioning_context,
layout.containing_block,
- );
+ ));
+
+ self.contents
+ .base
+ .set_fragment(Fragment::Box(fragment.clone()));
layout.push_line_item_to_unbreakable_segment(LineItem::Float(
layout.current_inline_box_identifier(),
FloatLineItem {
@@ -2150,7 +2179,7 @@ fn place_pending_floats(ifc: &mut InlineFormattingContextLayout, line_items: &mu
for item in line_items.iter_mut() {
if let LineItem::Float(_, float_line_item) = item {
if float_line_item.needs_placement {
- ifc.place_float_fragment(&mut float_line_item.fragment);
+ ifc.place_float_fragment(&mut float_line_item.fragment.borrow_mut());
}
}
}