mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Clean up inline layout data types a bit (#34563)
- Remove the `LayoutBox::InlineBox` variant that was only used for inline level boxes. Now they are stored in `LayoutBox::InlineLevel` along with other kinds of out-of-flow and atomic inline items. - Reduce the size of `InlineItem` by 260 bytes per item by using atomic indirection / pointers. This adds a bit of overhead to access items in exchange for a lot of memory saved. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
f1b8d49e77
commit
9d11d584f6
6 changed files with 35 additions and 35 deletions
|
@ -22,7 +22,6 @@ use crate::cell::ArcRefCell;
|
|||
use crate::context::LayoutContext;
|
||||
use crate::dom_traversal::WhichPseudoElement;
|
||||
use crate::flexbox::FlexLevelBox;
|
||||
use crate::flow::inline::inline_box::InlineBox;
|
||||
use crate::flow::inline::InlineItem;
|
||||
use crate::flow::BlockLevelBox;
|
||||
use crate::geom::PhysicalSize;
|
||||
|
@ -41,8 +40,6 @@ pub struct InnerDOMLayoutData {
|
|||
pub(super) enum LayoutBox {
|
||||
DisplayContents,
|
||||
BlockLevel(ArcRefCell<BlockLevelBox>),
|
||||
#[allow(dead_code)]
|
||||
InlineBox(ArcRefCell<InlineBox>),
|
||||
InlineLevel(ArcRefCell<InlineItem>),
|
||||
FlexLevel(ArcRefCell<FlexLevelBox>),
|
||||
TaffyItemBox(ArcRefCell<TaffyItemBox>),
|
||||
|
|
|
@ -448,7 +448,8 @@ where
|
|||
|
||||
// Otherwise, this is just a normal inline box. Whatever happened before, all we need to do
|
||||
// before recurring is to remember this ongoing inline level box.
|
||||
self.inline_formatting_context_builder
|
||||
let inline_item = self
|
||||
.inline_formatting_context_builder
|
||||
.start_inline_box(InlineBox::new(info));
|
||||
|
||||
if is_list_item {
|
||||
|
@ -467,9 +468,8 @@ where
|
|||
|
||||
self.finish_anonymous_table_if_needed();
|
||||
|
||||
box_slot.set(LayoutBox::InlineBox(
|
||||
self.inline_formatting_context_builder.end_inline_box(),
|
||||
));
|
||||
self.inline_formatting_context_builder.end_inline_box();
|
||||
box_slot.set(LayoutBox::InlineLevel(inline_item));
|
||||
}
|
||||
|
||||
fn handle_block_level_element(
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::borrow::Cow;
|
|||
use std::char::{ToLowercase, ToUppercase};
|
||||
|
||||
use icu_segmenter::WordSegmenter;
|
||||
use servo_arc::Arc;
|
||||
use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse;
|
||||
use style::values::computed::TextDecorationLine;
|
||||
use style::values::specified::text::TextTransformCase;
|
||||
|
@ -124,7 +125,7 @@ impl InlineFormattingContextBuilder {
|
|||
independent_formatting_context: IndependentFormattingContext,
|
||||
) -> ArcRefCell<InlineItem> {
|
||||
let inline_level_box = ArcRefCell::new(InlineItem::Atomic(
|
||||
independent_formatting_context,
|
||||
Arc::new(independent_formatting_context),
|
||||
self.current_text_offset,
|
||||
Level::ltr(), /* This will be assigned later if necessary. */
|
||||
));
|
||||
|
@ -155,19 +156,20 @@ impl InlineFormattingContextBuilder {
|
|||
}
|
||||
|
||||
pub(crate) fn push_float_box(&mut self, float_box: FloatBox) -> ArcRefCell<InlineItem> {
|
||||
let inline_level_box = ArcRefCell::new(InlineItem::OutOfFlowFloatBox(float_box));
|
||||
let inline_level_box = ArcRefCell::new(InlineItem::OutOfFlowFloatBox(Arc::new(float_box)));
|
||||
self.inline_items.push(inline_level_box.clone());
|
||||
self.contains_floats = true;
|
||||
inline_level_box
|
||||
}
|
||||
|
||||
pub(crate) fn start_inline_box(&mut self, inline_box: InlineBox) {
|
||||
pub(crate) fn start_inline_box(&mut self, inline_box: InlineBox) -> ArcRefCell<InlineItem> {
|
||||
self.push_control_character_string(inline_box.style.bidi_control_chars().0);
|
||||
|
||||
let identifier = self.inline_boxes.start_inline_box(inline_box);
|
||||
self.inline_items
|
||||
.push(ArcRefCell::new(InlineItem::StartInlineBox(identifier)));
|
||||
let (identifier, inline_box) = self.inline_boxes.start_inline_box(inline_box);
|
||||
let inline_level_box = ArcRefCell::new(InlineItem::StartInlineBox(inline_box));
|
||||
self.inline_items.push(inline_level_box.clone());
|
||||
self.inline_box_stack.push(identifier);
|
||||
inline_level_box
|
||||
}
|
||||
|
||||
pub(crate) fn end_inline_box(&mut self) -> ArcRefCell<InlineBox> {
|
||||
|
@ -256,16 +258,14 @@ impl InlineFormattingContextBuilder {
|
|||
|
||||
if let Some(inline_item) = self.inline_items.last() {
|
||||
if let InlineItem::TextRun(text_run) = &mut *inline_item.borrow_mut() {
|
||||
text_run.text_range.end = new_range.end;
|
||||
text_run.borrow_mut().text_range.end = new_range.end;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.inline_items
|
||||
.push(ArcRefCell::new(InlineItem::TextRun(TextRun::new(
|
||||
info.into(),
|
||||
info.style.clone(),
|
||||
new_range,
|
||||
.push(ArcRefCell::new(InlineItem::TextRun(ArcRefCell::new(
|
||||
TextRun::new(info.into(), info.style.clone(), new_range),
|
||||
))));
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,10 @@ impl InlineBoxes {
|
|||
.push(InlineBoxTreePathToken::End(identifier));
|
||||
}
|
||||
|
||||
pub(super) fn start_inline_box(&mut self, mut inline_box: InlineBox) -> InlineBoxIdentifier {
|
||||
pub(super) fn start_inline_box(
|
||||
&mut self,
|
||||
mut inline_box: InlineBox,
|
||||
) -> (InlineBoxIdentifier, ArcRefCell<InlineBox>) {
|
||||
assert!(self.inline_boxes.len() <= u32::MAX as usize);
|
||||
assert!(self.inline_box_tree.len() <= u32::MAX as usize);
|
||||
|
||||
|
@ -94,11 +97,13 @@ impl InlineBoxes {
|
|||
index_in_inline_boxes,
|
||||
};
|
||||
inline_box.identifier = identifier;
|
||||
let inline_box = ArcRefCell::new(inline_box);
|
||||
|
||||
self.inline_boxes.push(ArcRefCell::new(inline_box));
|
||||
self.inline_boxes.push(inline_box.clone());
|
||||
self.inline_box_tree
|
||||
.push(InlineBoxTreePathToken::Start(identifier));
|
||||
identifier
|
||||
|
||||
(identifier, inline_box)
|
||||
}
|
||||
|
||||
pub(super) fn get_path(
|
||||
|
|
|
@ -180,16 +180,16 @@ pub(crate) struct FontKeyAndMetrics {
|
|||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub(crate) enum InlineItem {
|
||||
StartInlineBox(InlineBoxIdentifier),
|
||||
StartInlineBox(ArcRefCell<InlineBox>),
|
||||
EndInlineBox,
|
||||
TextRun(TextRun),
|
||||
TextRun(ArcRefCell<TextRun>),
|
||||
OutOfFlowAbsolutelyPositionedBox(
|
||||
ArcRefCell<AbsolutelyPositionedBox>,
|
||||
usize, /* offset_in_text */
|
||||
),
|
||||
OutOfFlowFloatBox(FloatBox),
|
||||
OutOfFlowFloatBox(Arc<FloatBox>),
|
||||
Atomic(
|
||||
IndependentFormattingContext,
|
||||
Arc<IndependentFormattingContext>,
|
||||
usize, /* offset_in_text */
|
||||
Level, /* bidi_level */
|
||||
),
|
||||
|
@ -1536,7 +1536,7 @@ impl InlineFormattingContext {
|
|||
for item in builder.inline_items.iter() {
|
||||
match &mut *item.borrow_mut() {
|
||||
InlineItem::TextRun(ref mut text_run) => {
|
||||
text_run.segment_and_shape(
|
||||
text_run.borrow_mut().segment_and_shape(
|
||||
&text_content,
|
||||
&layout_context.font_context,
|
||||
&mut new_linebreaker,
|
||||
|
@ -1544,8 +1544,7 @@ impl InlineFormattingContext {
|
|||
&bidi_info,
|
||||
);
|
||||
},
|
||||
InlineItem::StartInlineBox(identifier) => {
|
||||
let inline_box = builder.inline_boxes.get(identifier);
|
||||
InlineItem::StartInlineBox(inline_box) => {
|
||||
let inline_box = &mut *inline_box.borrow_mut();
|
||||
if let Some(font) = get_font_for_first_font_for_style(
|
||||
&inline_box.style,
|
||||
|
@ -1676,11 +1675,11 @@ impl InlineFormattingContext {
|
|||
}
|
||||
|
||||
match item {
|
||||
InlineItem::StartInlineBox(identifier) => {
|
||||
layout.start_inline_box(&self.inline_boxes.get(identifier).borrow());
|
||||
InlineItem::StartInlineBox(inline_box) => {
|
||||
layout.start_inline_box(&inline_box.borrow());
|
||||
},
|
||||
InlineItem::EndInlineBox => layout.finish_inline_box(),
|
||||
InlineItem::TextRun(run) => run.layout_into_line_items(&mut layout),
|
||||
InlineItem::TextRun(run) => run.borrow().layout_into_line_items(&mut layout),
|
||||
InlineItem::Atomic(atomic_formatting_context, offset_in_text, bidi_level) => {
|
||||
atomic_formatting_context.layout_into_line_items(
|
||||
&mut layout,
|
||||
|
@ -2237,12 +2236,11 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
inline_formatting_context: &InlineFormattingContext,
|
||||
) {
|
||||
match inline_item {
|
||||
InlineItem::StartInlineBox(identifier) => {
|
||||
InlineItem::StartInlineBox(inline_box) => {
|
||||
// For margins and paddings, a cyclic percentage is resolved against zero
|
||||
// for determining intrinsic size contributions.
|
||||
// https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution
|
||||
let inline_box = inline_formatting_context.inline_boxes.get(identifier);
|
||||
let inline_box = (*inline_box).borrow();
|
||||
let inline_box = inline_box.borrow();
|
||||
let zero = Au::zero();
|
||||
let writing_mode = self.constraint_space.writing_mode;
|
||||
let padding = inline_box
|
||||
|
@ -2271,6 +2269,7 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
|||
self.add_inline_size(length);
|
||||
},
|
||||
InlineItem::TextRun(text_run) => {
|
||||
let text_run = &*text_run.borrow();
|
||||
for segment in text_run.shaped_text.iter() {
|
||||
let style_text = text_run.parent_style.get_inherited_text();
|
||||
let can_wrap = style_text.text_wrap_mode == TextWrapMode::Wrap;
|
||||
|
|
|
@ -185,7 +185,6 @@ impl BoxTree {
|
|||
},
|
||||
_ => return None,
|
||||
},
|
||||
LayoutBox::InlineBox(_) => return None,
|
||||
LayoutBox::InlineLevel(inline_level_box) => match &*inline_level_box.borrow() {
|
||||
InlineItem::OutOfFlowAbsolutelyPositionedBox(_, text_offset_index)
|
||||
if box_style.position.is_absolutely_positioned() =>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue