diff options
Diffstat (limited to 'components/layout_2020/flow/inline')
-rw-r--r-- | components/layout_2020/flow/inline/inline_box.rs | 4 | ||||
-rw-r--r-- | components/layout_2020/flow/inline/line.rs | 83 | ||||
-rw-r--r-- | components/layout_2020/flow/inline/mod.rs | 41 |
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()); } } } |