mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Add a LayoutBoxBase
to inline boxes (#36513)
`LayoutBoxBase` will soon contain laid out `Fragment`s of a box tree node in order to facilitate incremental layout and also layout queries. This is currently missing for inline boxes, so this change adds a `LayoutBoxBase` to them. Testing: This should not change any observable behavior, so existing WPT suites should suffice for testing. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
440739090f
commit
d46a17a487
6 changed files with 29 additions and 24 deletions
|
@ -163,7 +163,7 @@ impl InlineFormattingContextBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn start_inline_box(&mut self, inline_box: InlineBox) -> ArcRefCell<InlineItem> {
|
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);
|
self.push_control_character_string(inline_box.base.style.bidi_control_chars().0);
|
||||||
|
|
||||||
let (identifier, inline_box) = self.inline_boxes.start_inline_box(inline_box);
|
let (identifier, inline_box) = self.inline_boxes.start_inline_box(inline_box);
|
||||||
let inline_level_box = ArcRefCell::new(InlineItem::StartInlineBox(inline_box));
|
let inline_level_box = ArcRefCell::new(InlineItem::StartInlineBox(inline_box));
|
||||||
|
@ -177,7 +177,9 @@ impl InlineFormattingContextBuilder {
|
||||||
let inline_level_box = self.inline_boxes.get(&identifier);
|
let inline_level_box = self.inline_boxes.get(&identifier);
|
||||||
inline_level_box.borrow_mut().is_last_fragment = true;
|
inline_level_box.borrow_mut().is_last_fragment = true;
|
||||||
|
|
||||||
self.push_control_character_string(inline_level_box.borrow().style.bidi_control_chars().1);
|
self.push_control_character_string(
|
||||||
|
inline_level_box.borrow().base.style.bidi_control_chars().1,
|
||||||
|
);
|
||||||
|
|
||||||
inline_level_box
|
inline_level_box
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ use std::vec::IntoIter;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use fonts::FontMetrics;
|
use fonts::FontMetrics;
|
||||||
use servo_arc::Arc;
|
|
||||||
use style::properties::ComputedValues;
|
|
||||||
|
|
||||||
use super::{InlineContainerState, InlineContainerStateFlags, inline_container_needs_strut};
|
use super::{InlineContainerState, InlineContainerStateFlags, inline_container_needs_strut};
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
|
@ -16,12 +14,12 @@ use crate::context::LayoutContext;
|
||||||
use crate::dom::NodeExt;
|
use crate::dom::NodeExt;
|
||||||
use crate::dom_traversal::NodeAndStyleInfo;
|
use crate::dom_traversal::NodeAndStyleInfo;
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::style_ext::{LayoutStyle, PaddingBorderMargin};
|
use crate::style_ext::{LayoutStyle, PaddingBorderMargin};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct InlineBox {
|
pub(crate) struct InlineBox {
|
||||||
pub base_fragment_info: BaseFragmentInfo,
|
pub base: LayoutBoxBase,
|
||||||
pub style: Arc<ComputedValues>,
|
|
||||||
/// The identifier of this inline box in the containing [`super::InlineFormattingContext`].
|
/// The identifier of this inline box in the containing [`super::InlineFormattingContext`].
|
||||||
pub(super) identifier: InlineBoxIdentifier,
|
pub(super) identifier: InlineBoxIdentifier,
|
||||||
pub is_first_fragment: bool,
|
pub is_first_fragment: bool,
|
||||||
|
@ -34,8 +32,7 @@ pub(crate) struct InlineBox {
|
||||||
impl InlineBox {
|
impl InlineBox {
|
||||||
pub(crate) fn new<'dom, Node: NodeExt<'dom>>(info: &NodeAndStyleInfo<Node>) -> Self {
|
pub(crate) fn new<'dom, Node: NodeExt<'dom>>(info: &NodeAndStyleInfo<Node>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base_fragment_info: info.into(),
|
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||||
style: info.style.clone(),
|
|
||||||
// This will be assigned later, when the box is actually added to the IFC.
|
// This will be assigned later, when the box is actually added to the IFC.
|
||||||
identifier: InlineBoxIdentifier::default(),
|
identifier: InlineBoxIdentifier::default(),
|
||||||
is_first_fragment: true,
|
is_first_fragment: true,
|
||||||
|
@ -46,7 +43,7 @@ impl InlineBox {
|
||||||
|
|
||||||
pub(crate) fn split_around_block(&self) -> Self {
|
pub(crate) fn split_around_block(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
style: self.style.clone(),
|
base: LayoutBoxBase::new(self.base.base_fragment_info, self.base.style.clone()),
|
||||||
is_first_fragment: false,
|
is_first_fragment: false,
|
||||||
is_last_fragment: false,
|
is_last_fragment: false,
|
||||||
..*self
|
..*self
|
||||||
|
@ -55,7 +52,7 @@ impl InlineBox {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
||||||
LayoutStyle::Default(&self.style)
|
LayoutStyle::Default(&self.base.style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +215,7 @@ impl InlineBoxContainerState {
|
||||||
is_last_fragment: bool,
|
is_last_fragment: bool,
|
||||||
font_metrics: Option<&FontMetrics>,
|
font_metrics: Option<&FontMetrics>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let style = inline_box.style.clone();
|
let style = inline_box.base.style.clone();
|
||||||
let pbm = inline_box
|
let pbm = inline_box
|
||||||
.layout_style()
|
.layout_style()
|
||||||
.padding_border_margin(containing_block);
|
.padding_border_margin(containing_block);
|
||||||
|
@ -237,7 +234,7 @@ impl InlineBoxContainerState {
|
||||||
font_metrics,
|
font_metrics,
|
||||||
),
|
),
|
||||||
identifier: inline_box.identifier,
|
identifier: inline_box.identifier,
|
||||||
base_fragment_info: inline_box.base_fragment_info,
|
base_fragment_info: inline_box.base.base_fragment_info,
|
||||||
pbm,
|
pbm,
|
||||||
is_last_fragment,
|
is_last_fragment,
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,7 +326,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
let inline_box = self.layout.ifc.inline_boxes.get(identifier);
|
let inline_box = self.layout.ifc.inline_boxes.get(identifier);
|
||||||
let inline_box = &*(inline_box.borrow());
|
let inline_box = &*(inline_box.borrow());
|
||||||
|
|
||||||
let style = &inline_box.style;
|
let style = &inline_box.base.style;
|
||||||
let space_above_baseline = inline_box_state.calculate_space_above_baseline();
|
let space_above_baseline = inline_box_state.calculate_space_above_baseline();
|
||||||
let block_start_offset =
|
let block_start_offset =
|
||||||
self.calculate_inline_box_block_start(inline_box_state, space_above_baseline);
|
self.calculate_inline_box_block_start(inline_box_state, space_above_baseline);
|
||||||
|
@ -378,7 +378,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
|
|
||||||
let containing_block_writing_mode = self.layout.containing_block.style.writing_mode;
|
let containing_block_writing_mode = self.layout.containing_block.style.writing_mode;
|
||||||
if containing_block_writing_mode.is_bidi_ltr() !=
|
if containing_block_writing_mode.is_bidi_ltr() !=
|
||||||
inline_box.style.writing_mode.is_bidi_ltr()
|
inline_box.base.style.writing_mode.is_bidi_ltr()
|
||||||
{
|
{
|
||||||
std::mem::swap(&mut had_start, &mut had_end)
|
std::mem::swap(&mut had_start, &mut had_end)
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
|
|
||||||
// Relative adjustment should not affect the rest of line layout, so we can
|
// Relative adjustment should not affect the rest of line layout, so we can
|
||||||
// do it right before creating the Fragment.
|
// do it right before creating the Fragment.
|
||||||
let style = &inline_box.style;
|
let style = &inline_box.base.style;
|
||||||
if style.get_box().position == Position::Relative {
|
if style.get_box().position == Position::Relative {
|
||||||
content_rect.start_corner += relative_adjustement(style, self.layout.containing_block);
|
content_rect.start_corner += relative_adjustement(style, self.layout.containing_block);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
// but they need to be made relative to this fragment.
|
// but they need to be made relative to this fragment.
|
||||||
let physical_content_rect = content_rect.as_physical(Some(self.layout.containing_block));
|
let physical_content_rect = content_rect.as_physical(Some(self.layout.containing_block));
|
||||||
let mut fragment = BoxFragment::new(
|
let mut fragment = BoxFragment::new(
|
||||||
inline_box.base_fragment_info,
|
inline_box.base.base_fragment_info,
|
||||||
style.clone(),
|
style.clone(),
|
||||||
fragments,
|
fragments,
|
||||||
physical_content_rect,
|
physical_content_rect,
|
||||||
|
|
|
@ -200,8 +200,10 @@ pub(crate) enum InlineItem {
|
||||||
impl InlineItem {
|
impl InlineItem {
|
||||||
pub(crate) fn invalidate_cached_fragment(&self) {
|
pub(crate) fn invalidate_cached_fragment(&self) {
|
||||||
match self {
|
match self {
|
||||||
InlineItem::StartInlineBox(..) | InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
|
InlineItem::StartInlineBox(inline_box) => {
|
||||||
|
inline_box.borrow().base.invalidate_cached_fragment()
|
||||||
},
|
},
|
||||||
|
InlineItem::EndInlineBox | InlineItem::TextRun(..) => {},
|
||||||
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
||||||
positioned_box
|
positioned_box
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -732,6 +734,7 @@ impl InlineFormattingContextLayout<'_> {
|
||||||
);
|
);
|
||||||
|
|
||||||
self.depends_on_block_constraints |= inline_box
|
self.depends_on_block_constraints |= inline_box
|
||||||
|
.base
|
||||||
.style
|
.style
|
||||||
.depends_on_block_constraints_due_to_relative_positioning(
|
.depends_on_block_constraints_due_to_relative_positioning(
|
||||||
self.containing_block.style.writing_mode,
|
self.containing_block.style.writing_mode,
|
||||||
|
@ -1603,7 +1606,7 @@ impl InlineFormattingContext {
|
||||||
InlineItem::StartInlineBox(inline_box) => {
|
InlineItem::StartInlineBox(inline_box) => {
|
||||||
let inline_box = &mut *inline_box.borrow_mut();
|
let inline_box = &mut *inline_box.borrow_mut();
|
||||||
if let Some(font) = get_font_for_first_font_for_style(
|
if let Some(font) = get_font_for_first_font_for_style(
|
||||||
&inline_box.style,
|
&inline_box.base.style,
|
||||||
&layout_context.font_context,
|
&layout_context.font_context,
|
||||||
) {
|
) {
|
||||||
inline_box.default_font_index = Some(add_or_get_font(
|
inline_box.default_font_index = Some(add_or_get_font(
|
||||||
|
@ -2309,6 +2312,7 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
|
||||||
.percentages_relative_to(zero);
|
.percentages_relative_to(zero);
|
||||||
let border = layout_style.border_width(writing_mode);
|
let border = layout_style.border_width(writing_mode);
|
||||||
let margin = inline_box
|
let margin = inline_box
|
||||||
|
.base
|
||||||
.style
|
.style
|
||||||
.margin(writing_mode)
|
.margin(writing_mode)
|
||||||
.percentages_relative_to(zero)
|
.percentages_relative_to(zero)
|
||||||
|
|
|
@ -275,6 +275,7 @@ impl IndependentNonReplacedContents {
|
||||||
depends_on_block_constraints: bool,
|
depends_on_block_constraints: bool,
|
||||||
) -> CacheableLayoutResult {
|
) -> CacheableLayoutResult {
|
||||||
if let Some(cache) = base.cached_layout_result.borrow().as_ref() {
|
if let Some(cache) = base.cached_layout_result.borrow().as_ref() {
|
||||||
|
let cache = &**cache;
|
||||||
if cache.containing_block_for_children_size.inline ==
|
if cache.containing_block_for_children_size.inline ==
|
||||||
containing_block_for_children.size.inline &&
|
containing_block_for_children.size.inline &&
|
||||||
(cache.containing_block_for_children_size.block ==
|
(cache.containing_block_for_children_size.block ==
|
||||||
|
@ -305,11 +306,11 @@ impl IndependentNonReplacedContents {
|
||||||
depends_on_block_constraints,
|
depends_on_block_constraints,
|
||||||
);
|
);
|
||||||
|
|
||||||
*base.cached_layout_result.borrow_mut() = Some(CacheableLayoutResultAndInputs {
|
*base.cached_layout_result.borrow_mut() = Some(Box::new(CacheableLayoutResultAndInputs {
|
||||||
result: result.clone(),
|
result: result.clone(),
|
||||||
positioning_context: child_positioning_context.clone(),
|
positioning_context: child_positioning_context.clone(),
|
||||||
containing_block_for_children_size: containing_block_for_children.size.clone(),
|
containing_block_for_children_size: containing_block_for_children.size.clone(),
|
||||||
});
|
}));
|
||||||
positioning_context.append(child_positioning_context);
|
positioning_context.append(child_positioning_context);
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
|
@ -27,8 +27,8 @@ pub(crate) struct LayoutBoxBase {
|
||||||
pub base_fragment_info: BaseFragmentInfo,
|
pub base_fragment_info: BaseFragmentInfo,
|
||||||
pub style: Arc<ComputedValues>,
|
pub style: Arc<ComputedValues>,
|
||||||
pub cached_inline_content_size:
|
pub cached_inline_content_size:
|
||||||
AtomicRefCell<Option<(SizeConstraint, InlineContentSizesResult)>>,
|
AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>,
|
||||||
pub cached_layout_result: AtomicRefCell<Option<CacheableLayoutResultAndInputs>>,
|
pub cached_layout_result: AtomicRefCell<Option<Box<CacheableLayoutResultAndInputs>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutBoxBase {
|
impl LayoutBoxBase {
|
||||||
|
@ -50,7 +50,8 @@ impl LayoutBoxBase {
|
||||||
layout_box: &impl ComputeInlineContentSizes,
|
layout_box: &impl ComputeInlineContentSizes,
|
||||||
) -> InlineContentSizesResult {
|
) -> InlineContentSizesResult {
|
||||||
let mut cache = self.cached_inline_content_size.borrow_mut();
|
let mut cache = self.cached_inline_content_size.borrow_mut();
|
||||||
if let Some((previous_cb_block_size, result)) = *cache {
|
if let Some(cached_inline_content_size) = cache.as_ref() {
|
||||||
|
let (previous_cb_block_size, result) = **cached_inline_content_size;
|
||||||
if !result.depends_on_block_constraints ||
|
if !result.depends_on_block_constraints ||
|
||||||
previous_cb_block_size == constraint_space.block_size
|
previous_cb_block_size == constraint_space.block_size
|
||||||
{
|
{
|
||||||
|
@ -60,7 +61,7 @@ impl LayoutBoxBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = layout_box.compute_inline_content_sizes(layout_context, constraint_space);
|
let result = layout_box.compute_inline_content_sizes(layout_context, constraint_space);
|
||||||
*cache = Some((constraint_space.block_size, result));
|
*cache = Some(Box::new((constraint_space.block_size, result)));
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue