Store abspos boxes in a RefCell too

We want to mutate them when lazily computing their content sizes, but they
are behind an Arc for the hoisting infra, so it also needs its own layer
of inner mutability.
This commit is contained in:
Anthony Ramine 2020-06-09 13:44:43 +02:00
parent e044d8582c
commit e975d24c4b
7 changed files with 65 additions and 53 deletions

View file

@ -571,9 +571,14 @@ where
kind,
});
} else {
let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
AbsolutelyPositionedBox::construct(self.context, info, display_inside, contents),
)));
let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(
ArcRefCell::new(AbsolutelyPositionedBox::construct(
self.context,
info,
display_inside,
contents,
)),
));
self.current_inline_level_boxes().push(box_.clone());
box_slot.set(LayoutBox::InlineLevel(box_))
}
@ -722,10 +727,11 @@ where
display_inside,
contents,
} => {
let block_level_box =
ArcRefCell::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
let block_level_box = ArcRefCell::new(
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
AbsolutelyPositionedBox::construct(context, info, display_inside, contents),
)));
)),
);
(block_level_box, ContainsFloats::No)
},
BlockLevelCreator::OutOfFlowFloatBox {

View file

@ -20,6 +20,7 @@ use crate::sizing::ContentSizes;
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
use crate::ContainingBlock;
use app_units::Au;
use atomic_refcell::AtomicRef;
use gfx::text::text_run::GlyphRun;
use servo_arc::Arc;
use style::properties::ComputedValues;
@ -39,7 +40,7 @@ pub(crate) struct InlineFormattingContext {
pub(crate) enum InlineLevelBox {
InlineBox(InlineBox),
TextRun(TextRun),
OutOfFlowAbsolutelyPositionedBox(Arc<AbsolutelyPositionedBox>),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
OutOfFlowFloatBox(FloatBox),
Atomic(IndependentFormattingContext),
}
@ -283,8 +284,9 @@ impl InlineFormattingContext {
InlineLevelBox::TextRun(run) => run.layout(layout_context, &mut ifc),
InlineLevelBox::Atomic(a) => layout_atomic(layout_context, &mut ifc, a),
InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
let style = AtomicRef::map(box_.borrow(), |box_| &box_.contents.style);
let initial_start_corner =
match Display::from(box_.contents.style.get_box().original_display) {
match Display::from(style.get_box().original_display) {
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside {
outside,
inside: _,
@ -313,7 +315,7 @@ impl InlineFormattingContext {
Fragment::AbsoluteOrFixedPositioned(
AbsoluteOrFixedPositionedFragment {
hoisted_fragment,
position: box_.contents.style.clone_position(),
position: style.clone_position(),
},
),
);

View file

@ -52,7 +52,7 @@ pub(crate) enum BlockLevelBox {
style: Arc<ComputedValues>,
contents: BlockContainer,
},
OutOfFlowAbsolutelyPositionedBox(Arc<AbsolutelyPositionedBox>),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
OutOfFlowFloatBox(FloatBox),
Independent(IndependentFormattingContext),
}
@ -322,7 +322,7 @@ impl BlockLevelBox {
positioning_context.push(hoisted_box);
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment {
hoisted_fragment,
position: box_.contents.style.clone_position(),
position: box_.borrow().contents.style.clone_position(),
})
},
BlockLevelBox::OutOfFlowFloatBox(_box_) => {

View file

@ -207,7 +207,7 @@ impl BoxTree {
let contents = ReplacedContent::for_element(dirty_node)
.map_or(Contents::OfElement, Contents::Replaced);
let info = NodeAndStyleInfo::new(dirty_node, Arc::clone(&primary_style));
let out_of_flow_absolutely_positioned_box = Arc::new(
let out_of_flow_absolutely_positioned_box = ArcRefCell::new(
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
);
match update_point {
@ -267,7 +267,7 @@ fn construct_for_root_element<'dom>(
let (contains_floats, root_box) = if box_style.position.is_absolutely_positioned() {
(
ContainsFloats::No,
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
)),
)