Skip to content

Commit

Permalink
Switch the standard slice iterator in inline layout to a custom one i…
Browse files Browse the repository at this point in the history
…n order to

avoid lifetime problems
  • Loading branch information
pcwalton committed Mar 18, 2020
1 parent 1d9f669 commit 4205868
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 10 deletions.
73 changes: 64 additions & 9 deletions components/layout_2020/flow/inline.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand All @@ -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),
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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!(),
},
}
}
}
2 changes: 1 addition & 1 deletion components/layout_2020/flow/mod.rs
Expand Up @@ -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(
Expand Down

0 comments on commit 4205868

Please sign in to comment.