Skip to content

Commit

Permalink
layout: Properly parent table-row and table-row-group
Browse files Browse the repository at this point in the history
Put table cell content fragments into a hieararchy of fragments that
include their table row and table row group fragments. This ensures that
things like relative positioning and transforms set on rows and row
groups properly affect cells and cell content.

Co-authored-by: Oriol Brufau <obrufau@igalia.com>
  • Loading branch information
mrobinson and Loirooriol committed Mar 12, 2024
1 parent 1b128bf commit d827e36
Show file tree
Hide file tree
Showing 18 changed files with 424 additions and 153 deletions.
40 changes: 26 additions & 14 deletions components/layout_2020/display_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ use wr::{BoxShadowClipMode, ScrollSensitivity};
use crate::context::LayoutContext;
use crate::display_list::conversions::ToWebRender;
use crate::display_list::stacking_context::StackingContextSection;
use crate::fragment_tree::{BoxFragment, Fragment, FragmentTree, Tag, TextFragment};
use crate::fragment_tree::{
BackgroundMode, BoxFragment, Fragment, FragmentTree, Tag, TextFragment,
};
use crate::geom::{LogicalRect, PhysicalPoint, PhysicalRect};
use crate::replaced::IntrinsicSizes;
use crate::style_ext::ComputedValuesExt;
Expand Down Expand Up @@ -611,19 +613,29 @@ impl<'a> BuilderForBoxFragment<'a> {
return;
}

for extra_background in self.fragment.extra_backgrounds.iter() {
let positioning_area: LogicalRect<Length> = extra_background.rect.clone().into();
let painter = BackgroundPainter {
style: &extra_background.style,
painting_area_override: None,
positioning_area_override: Some(
positioning_area
.to_physical(self.fragment.style.writing_mode, self.containing_block)
.translate(self.containing_block.origin.to_vector())
.to_webrender(),
),
};
self.build_background_for_painter(builder, &painter);
// If this BoxFragment does not paint a background, do nothing.
if let BackgroundMode::None = self.fragment.background_mode {
return;
}

// Paint all extra backgrounds for this BoxFragment. These are painted first, as that's
// the order that they are expected to be painted for table cells (where this feature
// is used).
if let BackgroundMode::Extra(ref extra_backgrounds) = self.fragment.background_mode {
for extra_background in extra_backgrounds {
let positioning_area: LogicalRect<Length> = extra_background.rect.clone().into();
let painter = BackgroundPainter {
style: &extra_background.style,
painting_area_override: None,
positioning_area_override: Some(
positioning_area
.to_physical(self.fragment.style.writing_mode, self.containing_block)
.translate(self.containing_block.origin.to_vector())
.to_webrender(),
),
};
self.build_background_for_painter(builder, &painter);
}
}

let painter = BackgroundPainter {
Expand Down
26 changes: 23 additions & 3 deletions components/layout_2020/fragment_tree/box_fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ use crate::geom::{
};
use crate::style_ext::ComputedValuesExt;

/// Describes how a [`BoxFragment`] paints its background.
pub(crate) enum BackgroundMode {
/// Draw the normal [`BoxFragment`] background as well as the extra backgrounds
/// based on the style and positioning rectangles in this data structure.
Extra(Vec<ExtraBackground>),
/// Do not draw a background for this Fragment. This is used for elements like
/// table tracks and table track groups, which rely on cells to paint their
/// backgrounds.
None,
/// Draw the background normally, getting information from the Fragment style.
Normal,
}

pub(crate) struct ExtraBackground {
pub style: ServoArc<ComputedValues>,
pub rect: LogicalRect<Au>,
Expand Down Expand Up @@ -70,7 +83,7 @@ pub(crate) struct BoxFragment {
pub(crate) resolved_sticky_insets: Option<PhysicalSides<LengthOrAuto>>,

#[serde(skip_serializing)]
pub extra_backgrounds: Vec<ExtraBackground>,
pub background_mode: BackgroundMode,
}

impl BoxFragment {
Expand Down Expand Up @@ -160,7 +173,7 @@ impl BoxFragment {
scrollable_overflow_from_children,
overconstrained,
resolved_sticky_insets: None,
extra_backgrounds: Vec::new(),
background_mode: BackgroundMode::Normal,
}
}

Expand All @@ -178,7 +191,14 @@ impl BoxFragment {
}

pub fn add_extra_background(&mut self, extra_background: ExtraBackground) {
self.extra_backgrounds.push(extra_background);
match self.background_mode {
BackgroundMode::Extra(ref mut backgrounds) => backgrounds.push(extra_background),
_ => self.background_mode = BackgroundMode::Extra(vec![extra_background]),
}
}

pub fn set_does_not_paint_background(&mut self) {
self.background_mode = BackgroundMode::None;
}

pub fn scrollable_overflow(
Expand Down
32 changes: 30 additions & 2 deletions components/layout_2020/geom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::convert::From;
use std::fmt;
use std::ops::{Add, AddAssign, Sub};
use std::ops::{Add, AddAssign, Sub, SubAssign};

use app_units::Au;
use serde::Serialize;
Expand All @@ -26,7 +26,7 @@ pub type LengthOrAuto = AutoOr<Length>;
pub type AuOrAuto = AutoOr<Au>;
pub type LengthPercentageOrAuto<'a> = AutoOr<&'a LengthPercentage>;

#[derive(Clone, Serialize)]
#[derive(Clone, Copy, Serialize)]
pub struct LogicalVec2<T> {
pub inline: T,
pub block: T,
Expand Down Expand Up @@ -117,6 +117,34 @@ where
}
}

impl<T> AddAssign<LogicalVec2<T>> for LogicalVec2<T>
where
T: AddAssign<T> + Copy,
{
fn add_assign(&mut self, other: LogicalVec2<T>) {
self.add_assign(&other);
}
}

impl<T> SubAssign<&'_ LogicalVec2<T>> for LogicalVec2<T>
where
T: SubAssign<T> + Copy,
{
fn sub_assign(&mut self, other: &'_ LogicalVec2<T>) {
self.inline -= other.inline;
self.block -= other.block;
}
}

impl<T> SubAssign<LogicalVec2<T>> for LogicalVec2<T>
where
T: SubAssign<T> + Copy,
{
fn sub_assign(&mut self, other: LogicalVec2<T>) {
self.sub_assign(&other);
}
}

impl<T: Zero> LogicalVec2<T> {
pub fn zero() -> Self {
Self {
Expand Down
34 changes: 23 additions & 11 deletions components/layout_2020/table/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,10 +639,10 @@ where
.stylist
.style_for_anonymous::<Node::ConcreteElement>(
&context.shared_context().guards,
&PseudoElement::ServoAnonymousTableCell,
&PseudoElement::ServoAnonymousTableRow,
&self.info.style,
);
let anonymous_info = self.info.new_anonymous(anonymous_style);
let anonymous_info = self.info.new_anonymous(anonymous_style.clone());
let mut row_builder =
TableRowBuilder::new(self, &anonymous_info, self.current_text_decoration_line);

Expand All @@ -663,6 +663,25 @@ where
}

row_builder.finish();

self.push_table_row(TableTrack {
base_fragment_info: (&anonymous_info).into(),
style: anonymous_style,
group_index: self.current_row_group_index,
is_anonymous: true,
});
}

fn push_table_row(&mut self, table_track: TableTrack) {
self.builder.table.rows.push(table_track);

let last_row = self.builder.table.rows.len();
let row_group = self
.current_row_group_index
.map(|index| &mut self.builder.table.row_groups[index]);
if let Some(row_group) = row_group {
row_group.track_range.end = last_row;
}
}
}

Expand Down Expand Up @@ -714,6 +733,7 @@ where
info,
self,
);
self.finish_anonymous_row_if_needed();

self.current_row_group_index = None;
self.current_text_decoration_line = previous_text_decoration_line;
Expand All @@ -736,21 +756,13 @@ where
);
row_builder.finish();

self.builder.table.rows.push(TableTrack {
self.push_table_row(TableTrack {
base_fragment_info: info.into(),
style: info.style.clone(),
group_index: self.current_row_group_index,
is_anonymous: false,
});

let last_row = self.builder.table.rows.len();
let row_group = self
.current_row_group_index
.map(|index| &mut self.builder.table.row_groups[index]);
if let Some(row_group) = row_group {
row_group.track_range.end = last_row;
}

// We are doing this until we have actually set a Box for this `BoxSlot`.
::std::mem::forget(box_slot)
},
Expand Down

0 comments on commit d827e36

Please sign in to comment.