mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
Switch the standard slice iterator in inline layout to a custom one in order to
avoid lifetime problems
This commit is contained in:
parent
1d9f669cf0
commit
42058681a5
2 changed files with 65 additions and 10 deletions
|
@ -60,7 +60,7 @@ pub(crate) struct TextRun {
|
|||
}
|
||||
|
||||
struct InlineNestingLevelState<'box_tree> {
|
||||
remaining_boxes: std::slice::Iter<'box_tree, ArcRefCell<InlineLevelBox>>,
|
||||
remaining_boxes: InlineBoxChildIter<'box_tree>,
|
||||
fragments_so_far: Vec<Fragment>,
|
||||
inline_start: Length,
|
||||
max_block_size_of_fragments_so_far: Length,
|
||||
|
@ -222,7 +222,7 @@ impl InlineFormattingContext {
|
|||
},
|
||||
inline_position: Length::zero(),
|
||||
current_nesting_level: InlineNestingLevelState {
|
||||
remaining_boxes: self.inline_level_boxes.iter(),
|
||||
remaining_boxes: InlineBoxChildIter::from_formatting_context(self),
|
||||
fragments_so_far: Vec::with_capacity(self.inline_level_boxes.len()),
|
||||
inline_start: Length::zero(),
|
||||
max_block_size_of_fragments_so_far: Length::zero(),
|
||||
|
@ -232,7 +232,7 @@ impl InlineFormattingContext {
|
|||
if let Some(child) = ifc.current_nesting_level.remaining_boxes.next() {
|
||||
match &*child.borrow() {
|
||||
InlineLevelBox::InlineBox(inline) => {
|
||||
let partial = inline.start_layout(&mut ifc);
|
||||
let partial = inline.start_layout(child.clone(), &mut ifc);
|
||||
ifc.partial_inline_boxes_stack.push(partial)
|
||||
},
|
||||
InlineLevelBox::TextRun(run) => run.layout(layout_context, &mut ifc),
|
||||
|
@ -257,7 +257,8 @@ impl InlineFormattingContext {
|
|||
panic!("display:none does not generate an abspos box")
|
||||
},
|
||||
};
|
||||
let hoisted_fragment = box_.to_hoisted(initial_start_corner, tree_rank);
|
||||
let hoisted_fragment =
|
||||
box_.clone().to_hoisted(initial_start_corner, tree_rank);
|
||||
let hoisted_fragment_id = hoisted_fragment.fragment_id;
|
||||
ifc.positioning_context.push(hoisted_fragment);
|
||||
ifc.lines
|
||||
|
@ -365,7 +366,8 @@ impl Lines {
|
|||
|
||||
impl InlineBox {
|
||||
fn start_layout<'box_tree>(
|
||||
&'box_tree self,
|
||||
&self,
|
||||
this_inline_level_box: ArcRefCell<InlineLevelBox>,
|
||||
ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>,
|
||||
) -> PartialInlineBoxFragment<'box_tree> {
|
||||
let style = self.style.clone();
|
||||
|
@ -401,7 +403,9 @@ impl InlineBox {
|
|||
parent_nesting_level: std::mem::replace(
|
||||
&mut ifc.current_nesting_level,
|
||||
InlineNestingLevelState {
|
||||
remaining_boxes: self.children.iter(),
|
||||
remaining_boxes: InlineBoxChildIter::from_inline_level_box(
|
||||
this_inline_level_box,
|
||||
),
|
||||
fragments_so_far: Vec::with_capacity(self.children.len()),
|
||||
inline_start: ifc.inline_position,
|
||||
max_block_size_of_fragments_so_far: Length::zero(),
|
||||
|
@ -461,10 +465,10 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> {
|
|||
}
|
||||
}
|
||||
|
||||
fn layout_atomic<'box_tree>(
|
||||
fn layout_atomic(
|
||||
layout_context: &LayoutContext,
|
||||
ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>,
|
||||
atomic: &'box_tree IndependentFormattingContext,
|
||||
ifc: &mut InlineFormattingContextState,
|
||||
atomic: &IndependentFormattingContext,
|
||||
) {
|
||||
let cbis = ifc.containing_block.inline_size;
|
||||
let padding = atomic.style.padding().percentages_relative_to(cbis);
|
||||
|
@ -759,3 +763,54 @@ impl TextRun {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum InlineBoxChildIter<'box_tree> {
|
||||
InlineFormattingContext(std::slice::Iter<'box_tree, ArcRefCell<InlineLevelBox>>),
|
||||
InlineBox {
|
||||
inline_level_box: ArcRefCell<InlineLevelBox>,
|
||||
child_index: usize,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'box_tree> InlineBoxChildIter<'box_tree> {
|
||||
fn from_formatting_context(
|
||||
inline_formatting_context: &'box_tree InlineFormattingContext,
|
||||
) -> InlineBoxChildIter<'box_tree> {
|
||||
InlineBoxChildIter::InlineFormattingContext(
|
||||
inline_formatting_context.inline_level_boxes.iter(),
|
||||
)
|
||||
}
|
||||
|
||||
fn from_inline_level_box(
|
||||
inline_level_box: ArcRefCell<InlineLevelBox>,
|
||||
) -> InlineBoxChildIter<'box_tree> {
|
||||
InlineBoxChildIter::InlineBox {
|
||||
inline_level_box,
|
||||
child_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'box_tree> Iterator for InlineBoxChildIter<'box_tree> {
|
||||
type Item = ArcRefCell<InlineLevelBox>;
|
||||
fn next(&mut self) -> Option<ArcRefCell<InlineLevelBox>> {
|
||||
match *self {
|
||||
InlineBoxChildIter::InlineFormattingContext(ref mut iter) => iter.next().cloned(),
|
||||
InlineBoxChildIter::InlineBox {
|
||||
ref inline_level_box,
|
||||
ref mut child_index,
|
||||
} => match *inline_level_box.borrow() {
|
||||
InlineLevelBox::InlineBox(ref inline_box) => {
|
||||
if *child_index >= inline_box.children.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let kid = inline_box.children[*child_index].clone();
|
||||
*child_index += 1;
|
||||
Some(kid)
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ impl BlockLevelBox {
|
|||
))
|
||||
},
|
||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
|
||||
let hoisted_fragment = box_.to_hoisted(Vec2::zero(), tree_rank);
|
||||
let hoisted_fragment = box_.clone().to_hoisted(Vec2::zero(), tree_rank);
|
||||
let hoisted_fragment_id = hoisted_fragment.fragment_id.clone();
|
||||
positioning_context.push(hoisted_fragment);
|
||||
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue