Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start using `AtomicRefCell` in layout 2020 as preparation for incremental layout #25957

Merged
merged 8 commits into from Mar 18, 2020

Switch the standard slice iterator in inline layout to a custom one i…

…n order to

avoid lifetime problems
  • Loading branch information
pcwalton committed Mar 18, 2020
commit 42058681a5d04ca4203bac4fc8c60547a8fed2f8
@@ -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(
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.