diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2020-03-13 19:47:00 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2020-03-17 11:15:17 -0700 |
commit | 9cb824e77ca1cea699358971f7568e869c1c4664 (patch) | |
tree | 581f9f329a6de51af60f678e6fd7755a5f89762c /components/layout_2020/flow/construct.rs | |
parent | 2ff776b241f847bff9053e08a8004b6c7edc48b0 (diff) | |
download | servo-9cb824e77ca1cea699358971f7568e869c1c4664.tar.gz servo-9cb824e77ca1cea699358971f7568e869c1c4664.zip |
Wrap `BlockLevelBox` and `InlineLevelBox` with `AtomicRefCell`
Diffstat (limited to 'components/layout_2020/flow/construct.rs')
-rw-r--r-- | components/layout_2020/flow/construct.rs | 144 |
1 files changed, 72 insertions, 72 deletions
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) |