aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2020-03-13 19:47:00 -0700
committerPatrick Walton <pcwalton@mimiga.net>2020-03-17 11:15:17 -0700
commit9cb824e77ca1cea699358971f7568e869c1c4664 (patch)
tree581f9f329a6de51af60f678e6fd7755a5f89762c /components
parent2ff776b241f847bff9053e08a8004b6c7edc48b0 (diff)
downloadservo-9cb824e77ca1cea699358971f7568e869c1c4664.tar.gz
servo-9cb824e77ca1cea699358971f7568e869c1c4664.zip
Wrap `BlockLevelBox` and `InlineLevelBox` with `AtomicRefCell`
Diffstat (limited to 'components')
-rw-r--r--components/layout_2020/element_data.rs5
-rw-r--r--components/layout_2020/flow/construct.rs144
-rw-r--r--components/layout_2020/flow/inline.rs13
-rw-r--r--components/layout_2020/flow/mod.rs9
-rw-r--r--components/layout_2020/flow/root.rs25
5 files changed, 101 insertions, 95 deletions
diff --git a/components/layout_2020/element_data.rs b/components/layout_2020/element_data.rs
index ccd48ac04e3..e8afab10bc7 100644
--- a/components/layout_2020/element_data.rs
+++ b/components/layout_2020/element_data.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::cell::ArcRefCell;
use crate::flow::inline::InlineLevelBox;
use crate::flow::BlockLevelBox;
use atomic_refcell::AtomicRefCell;
@@ -21,6 +22,6 @@ pub(super) struct PseudoElementBoxes {
pub(super) enum LayoutBox {
DisplayContents,
- BlockLevel(Arc<BlockLevelBox>),
- InlineLevel(Arc<InlineLevelBox>),
+ BlockLevel(ArcRefCell<BlockLevelBox>),
+ InlineLevel(ArcRefCell<InlineLevelBox>),
}
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs
index 6eee3675a8e..89a54d08840 100644
--- a/components/layout_2020/flow/construct.rs
+++ b/components/layout_2020/flow/construct.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::dom_traversal::{BoxSlot, Contents, NodeExt, NonReplacedContents, TraversalHandler};
use crate::element_data::LayoutBox;
@@ -282,54 +283,48 @@ where
// context with the parent style of that builder.
let inlines = self.current_inline_level_boxes();
- fn last_text(inlines: &mut [Arc<InlineLevelBox>]) -> Option<&mut String> {
- let last = inlines.last_mut()?;
- if let InlineLevelBox::TextRun(_) = &**last {
- // We never clone text run boxes, so the refcount is 1 and unwrap succeeds:
- let last = Arc::get_mut(last).unwrap();
- if let InlineLevelBox::TextRun(TextRun { text, .. }) = last {
- Some(text)
- } else {
- unreachable!()
- }
- } else {
- None
- }
- }
-
let mut new_text_run_contents;
let output;
- if let Some(text) = last_text(inlines) {
- // Append to the existing text run
- new_text_run_contents = None;
- output = text;
- } else {
- new_text_run_contents = Some(String::new());
- output = new_text_run_contents.as_mut().unwrap();
- }
- if leading_whitespace {
- output.push(' ')
- }
- loop {
- if let Some(i) = input.bytes().position(|b| b.is_ascii_whitespace()) {
- let (non_whitespace, rest) = input.split_at(i);
- output.push_str(non_whitespace);
- output.push(' ');
- if let Some(i) = rest.bytes().position(|b| !b.is_ascii_whitespace()) {
- input = &rest[i..];
+ {
+ let mut last_box = inlines.last_mut().map(|last| last.borrow_mut());
+ let last_text = last_box.as_mut().and_then(|last| match &mut **last {
+ InlineLevelBox::TextRun(last) => Some(&mut last.text),
+ _ => None,
+ });
+
+ if let Some(text) = last_text {
+ // Append to the existing text run
+ new_text_run_contents = None;
+ output = text;
+ } else {
+ new_text_run_contents = Some(String::new());
+ output = new_text_run_contents.as_mut().unwrap();
+ }
+
+ if leading_whitespace {
+ output.push(' ')
+ }
+ loop {
+ if let Some(i) = input.bytes().position(|b| b.is_ascii_whitespace()) {
+ let (non_whitespace, rest) = input.split_at(i);
+ output.push_str(non_whitespace);
+ output.push(' ');
+ if let Some(i) = rest.bytes().position(|b| !b.is_ascii_whitespace()) {
+ input = &rest[i..];
+ } else {
+ break;
+ }
} else {
+ output.push_str(input);
break;
}
- } else {
- output.push_str(input);
- break;
}
}
if let Some(text) = new_text_run_contents {
let parent_style = parent_style.clone();
- inlines.push(Arc::new(InlineLevelBox::TextRun(TextRun {
+ inlines.push(ArcRefCell::new(InlineLevelBox::TextRun(TextRun {
tag: node.as_opaque(),
parent_style,
text,
@@ -356,23 +351,27 @@ where
let mut inline_level_boxes = self.current_inline_level_boxes().iter().rev();
let mut stack = Vec::new();
let preserved = loop {
- match inline_level_boxes.next().map(|b| &**b) {
- Some(InlineLevelBox::TextRun(r)) => break !r.text.ends_with(' '),
- Some(InlineLevelBox::Atomic { .. }) => break false,
- Some(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(_)) |
- Some(InlineLevelBox::OutOfFlowFloatBox(_)) => {},
- Some(InlineLevelBox::InlineBox(b)) => {
+ let inline_box = match inline_level_boxes.next() {
+ Some(box_) => box_,
+ None => match stack.pop() {
+ Some(iter) => {
+ inline_level_boxes = iter;
+ continue;
+ },
+ None => break false,
+ },
+ };{
+ match &*inline_box.borrow() {
+ InlineLevelBox::TextRun(r) => break !r.text.ends_with(' '),
+ InlineLevelBox::Atomic { .. } => break false,
+ InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(_) |
+ InlineLevelBox::OutOfFlowFloatBox(_) => {},
+ InlineLevelBox::InlineBox(b) => {
stack.push(inline_level_boxes);
inline_level_boxes = b.children.iter().rev()
},
- None => {
- if let Some(iter) = stack.pop() {
- inline_level_boxes = iter
- } else {
- break false; // Paragraph start
- }
- },
- }
+ };}
+ ()
};
let text = text.trim_start_matches(|c: char| c.is_ascii_whitespace());
(preserved, text)
@@ -384,7 +383,7 @@ where
style: &Arc<ComputedValues>,
display_inside: DisplayInside,
contents: Contents,
- ) -> Arc<InlineLevelBox> {
+ ) -> ArcRefCell<InlineLevelBox> {
let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() {
// We found un inline box.
// Whatever happened before, all we need to do before recurring
@@ -410,9 +409,9 @@ where
.pop()
.expect("no ongoing inline level box found");
inline_box.last_fragment = true;
- Arc::new(InlineLevelBox::InlineBox(inline_box))
+ ArcRefCell::new(InlineLevelBox::InlineBox(inline_box))
} else {
- Arc::new(InlineLevelBox::Atomic(
+ ArcRefCell::new(InlineLevelBox::Atomic(
IndependentFormattingContext::construct(
self.context,
node,
@@ -466,13 +465,13 @@ where
for mut fragmented_parent_inline_box in fragmented_inline_boxes {
fragmented_parent_inline_box
.children
- .push(Arc::new(fragmented_inline));
+ .push(ArcRefCell::new(fragmented_inline));
fragmented_inline = InlineLevelBox::InlineBox(fragmented_parent_inline_box);
}
self.ongoing_inline_formatting_context
.inline_level_boxes
- .push(Arc::new(fragmented_inline));
+ .push(ArcRefCell::new(fragmented_inline));
}
// We found a block level element, so the ongoing inline formatting
@@ -525,7 +524,7 @@ where
kind,
});
} else {
- let box_ = Arc::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
+ let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
AbsolutelyPositionedBox::construct(
self.context,
node,
@@ -561,7 +560,7 @@ where
kind,
});
} else {
- let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct(
+ let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct(
self.context,
node,
style,
@@ -610,7 +609,7 @@ where
});
}
- fn current_inline_level_boxes(&mut self) -> &mut Vec<Arc<InlineLevelBox>> {
+ fn current_inline_level_boxes(&mut self) -> &mut Vec<ArcRefCell<InlineLevelBox>> {
match self.ongoing_inline_boxes_stack.last_mut() {
Some(last) => &mut last.children,
None => &mut self.ongoing_inline_formatting_context.inline_level_boxes,
@@ -634,7 +633,7 @@ where
self,
context: &LayoutContext,
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
- ) -> (Arc<BlockLevelBox>, ContainsFloats) {
+ ) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
let node = self.node;
let style = self.style;
let (block_level_box, contains_floats) = match self.kind {
@@ -651,7 +650,7 @@ where
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
to.max_assign(&box_content_sizes.outer_inline(&style))
}
- let block_level_box = Arc::new(BlockLevelBox::SameFormattingContextBlock {
+ let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
tag: node.as_opaque(),
contents,
style,
@@ -678,7 +677,7 @@ where
to.max_assign(&contents.content_sizes.outer_inline(&contents.style))
}
(
- Arc::new(BlockLevelBox::Independent(contents)),
+ ArcRefCell::new(BlockLevelBox::Independent(contents)),
ContainsFloats::No,
)
},
@@ -686,22 +685,23 @@ where
display_inside,
contents,
} => {
- let block_level_box = Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
- Arc::new(AbsolutelyPositionedBox::construct(
- context,
- node,
- style,
- display_inside,
- contents,
- )),
- ));
+ let block_level_box =
+ ArcRefCell::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
+ AbsolutelyPositionedBox::construct(
+ context,
+ node,
+ style,
+ display_inside,
+ contents,
+ ),
+ )));
(block_level_box, ContainsFloats::No)
},
BlockLevelCreator::OutOfFlowFloatBox {
display_inside,
contents,
} => {
- let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox(
+ let block_level_box = ArcRefCell::new(BlockLevelBox::OutOfFlowFloatBox(
FloatBox::construct(context, node, style, display_inside, contents),
));
(block_level_box, ContainsFloats::Yes)
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs
index 8e1587568c0..0d1f2199597 100644
--- a/components/layout_2020/flow/inline.rs
+++ b/components/layout_2020/flow/inline.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::flow::float::FloatBox;
use crate::flow::FlowLayout;
@@ -27,7 +28,7 @@ use webrender_api::FontInstanceKey;
#[derive(Debug, Default, Serialize)]
pub(crate) struct InlineFormattingContext {
- pub(super) inline_level_boxes: Vec<Arc<InlineLevelBox>>,
+ pub(super) inline_level_boxes: Vec<ArcRefCell<InlineLevelBox>>,
}
#[derive(Debug, Serialize)]
@@ -46,7 +47,7 @@ pub(crate) struct InlineBox {
pub style: Arc<ComputedValues>,
pub first_fragment: bool,
pub last_fragment: bool,
- pub children: Vec<Arc<InlineLevelBox>>,
+ pub children: Vec<ArcRefCell<InlineLevelBox>>,
}
/// https://www.w3.org/TR/css-display-3/#css-text-run
@@ -59,7 +60,7 @@ pub(crate) struct TextRun {
}
struct InlineNestingLevelState<'box_tree> {
- remaining_boxes: std::slice::Iter<'box_tree, Arc<InlineLevelBox>>,
+ remaining_boxes: std::slice::Iter<'box_tree, ArcRefCell<InlineLevelBox>>,
fragments_so_far: Vec<Fragment>,
inline_start: Length,
max_block_size_of_fragments_so_far: Length,
@@ -105,10 +106,10 @@ impl InlineFormattingContext {
fn traverse(
&mut self,
layout_context: &LayoutContext,
- inline_level_boxes: &[Arc<InlineLevelBox>],
+ inline_level_boxes: &[ArcRefCell<InlineLevelBox>],
) {
for inline_level_box in inline_level_boxes {
- match &**inline_level_box {
+ match &*inline_level_box.borrow() {
InlineLevelBox::InlineBox(inline_box) => {
let padding = inline_box.style.padding();
let border = inline_box.style.border_width();
@@ -229,7 +230,7 @@ impl InlineFormattingContext {
};
loop {
if let Some(child) = ifc.current_nesting_level.remaining_boxes.next() {
- match &**child {
+ match &*child.borrow() {
InlineLevelBox::InlineBox(inline) => {
let partial = inline.start_layout(&mut ifc);
ifc.partial_inline_boxes_stack.push(partial)
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index 1f6d6db49df..fa0ed0b7c00 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -4,6 +4,7 @@
//! Flow layout, also known as block-and-inline layout.
+use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::flow::float::{FloatBox, FloatContext};
use crate::flow::inline::InlineFormattingContext;
@@ -38,7 +39,7 @@ pub(crate) struct BlockFormattingContext {
#[derive(Debug, Serialize)]
pub(crate) enum BlockContainer {
- BlockLevelBoxes(Vec<Arc<BlockLevelBox>>),
+ BlockLevelBoxes(Vec<ArcRefCell<BlockLevelBox>>),
InlineFormattingContext(InlineFormattingContext),
}
@@ -133,7 +134,7 @@ impl BlockContainer {
fn layout_block_level_children(
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
- child_boxes: &[Arc<BlockLevelBox>],
+ child_boxes: &[ArcRefCell<BlockLevelBox>],
containing_block: &ContainingBlock,
tree_rank: usize,
mut float_context: Option<&mut FloatContext>,
@@ -204,7 +205,7 @@ fn layout_block_level_children(
.iter()
.enumerate()
.map(|(tree_rank, box_)| {
- let mut fragment = box_.layout(
+ let mut fragment = box_.borrow().layout(
layout_context,
positioning_context,
containing_block,
@@ -224,7 +225,7 @@ fn layout_block_level_children(
.mapfold_reduce_into(
positioning_context,
|positioning_context, (tree_rank, box_)| {
- box_.layout(
+ box_.borrow().layout(
layout_context,
positioning_context,
containing_block,
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs
index 63ca58ead1d..6a8be578630 100644
--- a/components/layout_2020/flow/root.rs
+++ b/components/layout_2020/flow/root.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::display_list::stacking_context::{
ContainingBlock, ContainingBlockInfo, StackingContext, StackingContextBuildMode,
@@ -62,7 +63,7 @@ impl BoxTreeRoot {
fn construct_for_root_element<'dom>(
context: &LayoutContext,
root_element: impl NodeExt<'dom>,
-) -> (ContainsFloats, Vec<Arc<BlockLevelBox>>) {
+) -> (ContainsFloats, Vec<ArcRefCell<BlockLevelBox>>) {
let style = root_element.style(context);
let replaced = ReplacedContent::for_element(root_element);
let box_style = style.get_box();
@@ -83,27 +84,29 @@ fn construct_for_root_element<'dom>(
if box_style.position.is_absolutely_positioned() {
(
ContainsFloats::No,
- vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
- Arc::new(AbsolutelyPositionedBox::construct(
- context,
- root_element,
- style,
- display_inside,
- contents,
+ vec![ArcRefCell::new(
+ BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
+ AbsolutelyPositionedBox::construct(
+ context,
+ root_element,
+ style,
+ display_inside,
+ contents,
+ ),
)),
- ))],
+ )],
)
} else if box_style.float.is_floating() {
(
ContainsFloats::Yes,
- vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(
+ vec![ArcRefCell::new(BlockLevelBox::OutOfFlowFloatBox(
FloatBox::construct(context, root_element, style, display_inside, contents),
))],
)
} else {
(
ContainsFloats::No,
- vec![Arc::new(BlockLevelBox::Independent(
+ vec![ArcRefCell::new(BlockLevelBox::Independent(
IndependentFormattingContext::construct(
context,
root_element,