Skip to content

Commit

Permalink
layout: Generalize ContainingBlock's block size to a `SizeConstrain…
Browse files Browse the repository at this point in the history
…t` (servo#34946)

It used to be an `AuOrAuto`, turning it into a `SizeConstraint` allows
passing the information about the min and max constraints when the
containing block doesn't have a definite block size.

This will be useful for table layout.

Note that in most cases we were already constructing the containing
block from a `SizeConstraint`, but we were calling `to_auto_or()` to
turn it into an `AuOrAuto`.

Signed-off-by: Oriol Brufau <[email protected]>
  • Loading branch information
Loirooriol authored Jan 13, 2025
1 parent de780dc commit f66cd17
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 69 deletions.
39 changes: 21 additions & 18 deletions components/layout_2020/flexbox/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ struct FlexItemLayoutResult {
containing_block_inline_size: Au,

// The containing block block size used to generate this layout.
containing_block_block_size: AuOrAuto,
containing_block_block_size: SizeConstraint,

// Whether or not this layout depended on block constraints.
depends_on_block_constraints: bool,
Expand Down Expand Up @@ -662,7 +662,7 @@ impl FlexContainer {
container_definite_inner_size: self.config.flex_axis.vec2_to_flex_relative(
LogicalVec2 {
inline: Some(containing_block.size.inline),
block: containing_block.size.block.non_auto(),
block: containing_block.size.block.to_definite(),
},
),
};
Expand All @@ -671,12 +671,14 @@ impl FlexContainer {
// https://drafts.csswg.org/css-flexbox/#algo-main-container
let container_main_size = match self.config.flex_axis {
FlexAxis::Row => containing_block.size.inline,
FlexAxis::Column => containing_block.size.block.auto_is(|| {
self.main_content_sizes(layout_context, &containing_block.into(), || &flex_context)
FlexAxis::Column => match containing_block.size.block {
SizeConstraint::Definite(size) => size,
_ => self
.main_content_sizes(layout_context, &containing_block.into(), || &flex_context)
.sizes
.max_content
.clamp_between_extremums(container_min_size.main, container_max_size.main)
}),
.clamp_between_extremums(container_min_size.main, container_max_size.main),
},
};

// Actual length may be less, but we guess that usually not by a lot
Expand Down Expand Up @@ -1894,13 +1896,12 @@ impl FlexItem<'_> {
});

let cross_size = match used_cross_size_override {
Some(s) => AuOrAuto::LengthPercentage(s),
None => self.content_box_size.cross.map(|cross_size| {
cross_size.clamp_between_extremums(
self.content_min_size.cross,
self.content_max_size.cross,
)
}),
Some(s) => SizeConstraint::Definite(s),
None => SizeConstraint::new(
self.content_box_size.cross.non_auto(),
self.content_min_size.cross,
self.content_max_size.cross,
),
};

let independent_formatting_context = &self.box_.independent_formatting_context;
Expand All @@ -1917,7 +1918,7 @@ impl FlexItem<'_> {
(used_main_size, cross_size)
} else {
(
cross_size.auto_is(|| {
cross_size.to_definite().unwrap_or_else(|| {
let style = self.box_.style();
let stretch_size =
Au::zero().max(containing_block.size.inline - self.pbm_auto_is_zero.cross);
Expand Down Expand Up @@ -1947,9 +1948,9 @@ impl FlexItem<'_> {
if self.flex_base_size_is_definite ||
flex_context.container_definite_inner_size.main.is_some()
{
AuOrAuto::LengthPercentage(used_main_size)
SizeConstraint::Definite(used_main_size)
} else {
AuOrAuto::Auto
SizeConstraint::default()
},
)
};
Expand All @@ -1965,7 +1966,9 @@ impl FlexItem<'_> {
item_style,
self.preferred_aspect_ratio,
&Sizes::new(
block_size.non_auto().map_or(Size::Initial, Size::Numeric),
block_size
.to_definite()
.map_or(Size::Initial, Size::Numeric),
Size::Numeric(min_size.block),
max_size.block.map_or(Size::Initial, Size::Numeric),
),
Expand Down Expand Up @@ -2834,7 +2837,7 @@ impl FlexItemBox {
let item_as_containing_block = ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: AuOrAuto::Auto,
block: SizeConstraint::default(),
},
style,
};
Expand Down
2 changes: 1 addition & 1 deletion components/layout_2020/flexbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,6 @@ impl CachedBlockSizeContribution {
item_as_containing_block: &ContainingBlock,
) -> bool {
item_as_containing_block.size.inline == self.containing_block_inline_size &&
item_as_containing_block.size.block.is_auto()
!item_as_containing_block.size.block.is_definite()
}
}
4 changes: 2 additions & 2 deletions components/layout_2020/flow/inline/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::cell::ArcRefCell;
use crate::fragment_tree::{
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, Fragment, TextFragment,
};
use crate::geom::{AuOrAuto, LogicalRect, LogicalVec2, PhysicalRect, ToLogical};
use crate::geom::{LogicalRect, LogicalVec2, PhysicalRect, ToLogical};
use crate::positioned::{
relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength,
};
Expand Down Expand Up @@ -427,7 +427,7 @@ impl LineItemLayout<'_, '_> {
let inline_box_containing_block = ContainingBlock {
size: ContainingBlockSize {
inline: content_rect.size.inline,
block: AuOrAuto::Auto,
block: Default::default(),
},
style: self.layout.containing_block.style,
};
Expand Down
22 changes: 11 additions & 11 deletions components/layout_2020/flow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl BlockLevelBox {

let available_inline_size =
containing_block.size.inline - pbm.padding_border_sums.inline - margin.inline_sum();
let available_block_size = containing_block.size.block.non_auto().map(|block_size| {
let available_block_size = containing_block.size.block.to_definite().map(|block_size| {
Au::zero().max(block_size - pbm.padding_border_sums.block - margin.block_sum())
});

Expand Down Expand Up @@ -174,7 +174,7 @@ impl BlockLevelBox {
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: tentative_block_size.to_auto_or(),
block: tentative_block_size,
},
style,
};
Expand Down Expand Up @@ -269,7 +269,7 @@ impl OutsideMarker {
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: content_sizes.sizes.max_content,
block: AuOrAuto::auto(),
block: SizeConstraint::default(),
},
style: &self.marker_style,
};
Expand Down Expand Up @@ -1202,7 +1202,7 @@ impl IndependentNonReplacedContents {
let available_block_size = containing_block
.size
.block
.non_auto()
.to_definite()
.map(|block_size| Au::zero().max(block_size - pbm_sums.block_sum()));
let (preferred_block_size, min_block_size, max_block_size) = content_box_sizes
.block
Expand Down Expand Up @@ -1265,7 +1265,7 @@ impl IndependentNonReplacedContents {
&ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: tentative_block_size.to_auto_or(),
block: tentative_block_size,
},
style,
},
Expand Down Expand Up @@ -1335,7 +1335,7 @@ impl IndependentNonReplacedContents {
&ContainingBlock {
size: ContainingBlockSize {
inline: proposed_inline_size,
block: tentative_block_size.to_auto_or(),
block: tentative_block_size,
},
style,
},
Expand Down Expand Up @@ -1662,7 +1662,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
let available_block_size = containing_block
.size
.block
.non_auto()
.to_definite()
.map(|block_size| Au::zero().max(block_size - pbm_sums.block_sum()));

// https://drafts.csswg.org/css2/#the-height-property
Expand Down Expand Up @@ -1698,7 +1698,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: tentative_block_size.to_auto_or(),
block: tentative_block_size,
},
style,
};
Expand Down Expand Up @@ -2102,7 +2102,7 @@ fn block_size_is_zero_or_intrinsic(size: &StyleSize, containing_block: &Containi
StyleSize::LengthPercentage(ref lp) => {
// TODO: Should this resolve definite percentages? Blink does it, Gecko and WebKit don't.
lp.is_definitely_zero() ||
(lp.0.has_percentage() && containing_block.size.block.is_auto())
(lp.0.has_percentage() && !containing_block.size.block.is_definite())
},
StyleSize::AnchorSizeFunction(_) => unreachable!("anchor-size() should be disabled"),
}
Expand Down Expand Up @@ -2171,7 +2171,7 @@ impl IndependentFormattingContext {
let available_block_size = containing_block
.size
.block
.non_auto()
.to_definite()
.map(|block_size| (block_size - pbm_sums.block_sum()).max(Au::zero()));
let tentative_block_size = content_box_sizes_and_pbm
.content_box_sizes
Expand All @@ -2198,7 +2198,7 @@ impl IndependentFormattingContext {
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: tentative_block_size.to_auto_or(),
block: tentative_block_size,
},
style: self.style(),
};
Expand Down
9 changes: 8 additions & 1 deletion components/layout_2020/geom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,9 @@ impl LogicalVec2<Size<LengthPercentage>> {
|inline_size| inline_size.map(|lp| lp.to_used_value(containing_block.size.inline)),
|block_size| {
block_size
.maybe_map(|lp| lp.maybe_to_used_value(containing_block.size.block.non_auto()))
.maybe_map(|lp| {
lp.maybe_to_used_value(containing_block.size.block.to_definite())
})
.unwrap_or_default()
},
)
Expand Down Expand Up @@ -856,6 +858,11 @@ impl SizeConstraint {
)
}

#[inline]
pub(crate) fn is_definite(self) -> bool {
matches!(self, Self::Definite(_))
}

#[inline]
pub(crate) fn to_definite(self) -> Option<Au> {
match self {
Expand Down
6 changes: 3 additions & 3 deletions components/layout_2020/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'a> From<&'_ ContainingBlock<'a>> for IndefiniteContainingBlock {
Self {
size: LogicalVec2 {
inline: AuOrAuto::LengthPercentage(containing_block.size.inline),
block: containing_block.size.block,
block: containing_block.size.block.to_auto_or(),
},
writing_mode: containing_block.style.writing_mode,
}
Expand All @@ -118,7 +118,7 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for IndefiniteContainingBlock {
#[derive(Debug, Serialize)]
pub(crate) struct ContainingBlockSize {
inline: Au,
block: AuOrAuto,
block: SizeConstraint,
}

pub(crate) struct ContainingBlock<'a> {
Expand All @@ -136,7 +136,7 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
ContainingBlock {
size: ContainingBlockSize {
inline: definite.size.inline,
block: AuOrAuto::LengthPercentage(definite.size.block),
block: SizeConstraint::Definite(definite.size.block),
},
style: definite.style,
}
Expand Down
8 changes: 4 additions & 4 deletions components/layout_2020/positioned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ impl HoistedAbsolutelyPositionedBox {
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: inline_size,
block: block_axis.size.to_auto_or(),
block: block_axis.size,
},
style: &style,
};
Expand Down Expand Up @@ -1008,9 +1008,9 @@ pub(crate) fn relative_adjustement(
.box_offsets(containing_block.style.writing_mode)
.map_inline_and_block_axes(
|value| value.map(|value| value.to_used_value(cbis)),
|value| match cbbs.non_auto() {
Some(cbbs) => value.map(|value| value.to_used_value(cbbs)),
None => match value.non_auto().and_then(|value| value.to_length()) {
|value| match cbbs {
SizeConstraint::Definite(cbbs) => value.map(|value| value.to_used_value(cbbs)),
_ => match value.non_auto().and_then(|value| value.to_length()) {
Some(value) => AuOrAuto::LengthPercentage(value.into()),
None => AuOrAuto::Auto,
},
Expand Down
2 changes: 1 addition & 1 deletion components/layout_2020/replaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ impl ReplacedContents {
let block_stretch_size = containing_block
.size
.block
.non_auto()
.to_definite()
.map(|block_size| Au::zero().max(block_size - pbm_sums.block));

// First, compute the inline size. Intrinsic values depend on the block sizing properties
Expand Down
5 changes: 4 additions & 1 deletion components/layout_2020/style_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,10 @@ impl ComputedValuesExt for ComputedValues {
.min_box_size(containing_block.style.writing_mode)
.map_inline_and_block_sizes(
|lp| lp.to_used_value(containing_block.size.inline),
|lp| lp.to_used_value(containing_block.size.block.auto_is(Au::zero)),
|lp| {
let cbbs = containing_block.size.block.to_definite();
lp.to_used_value(cbbs.unwrap_or_else(Au::zero))
},
);
self.content_min_box_size_for_min_size(min_size, pbm)
}
Expand Down
12 changes: 6 additions & 6 deletions components/layout_2020/table/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::fragment_tree::{
};
use crate::geom::{
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
Size, ToLogical, ToLogicalWithContainingBlock,
Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
};
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
Expand Down Expand Up @@ -1228,7 +1228,7 @@ impl<'a> TableLayout<'a> {
let containing_block_for_children = ContainingBlock {
size: ContainingBlockSize {
inline: total_cell_width,
block: AuOrAuto::Auto,
block: SizeConstraint::default(),
},
style: &cell.base.style,
};
Expand Down Expand Up @@ -1561,7 +1561,7 @@ impl<'a> TableLayout<'a> {
.content_box_size_deprecated(containing_block_for_table, &self.pbm)
.block
{
LengthPercentage(_) => containing_block_for_children.size.block,
LengthPercentage(_) => containing_block_for_children.size.block.to_auto_or(),
Auto => style
.content_min_box_size_deprecated(containing_block_for_table, &self.pbm)
.block
Expand Down Expand Up @@ -1605,7 +1605,7 @@ impl<'a> TableLayout<'a> {
let containing_block = &ContainingBlock {
size: ContainingBlockSize {
inline: self.table_width + self.pbm.padding_border_sums.inline,
block: AuOrAuto::Auto,
block: SizeConstraint::default(),
},
style: &self.table.style,
};
Expand Down Expand Up @@ -2330,7 +2330,7 @@ impl<'a> RowFragmentLayout<'a> {
let containing_block = ContainingBlock {
size: ContainingBlockSize {
inline: rect.size.inline,
block: AuOrAuto::LengthPercentage(rect.size.block),
block: SizeConstraint::Definite(rect.size.block),
},
style: table_style,
};
Expand Down Expand Up @@ -2360,7 +2360,7 @@ impl<'a> RowFragmentLayout<'a> {
self.rect.start_corner -= row_group_layout.rect.start_corner;
(
row_group_layout.rect.size.inline,
AuOrAuto::LengthPercentage(row_group_layout.rect.size.block),
SizeConstraint::Definite(row_group_layout.rect.size.block),
)
} else {
(
Expand Down
Loading

0 comments on commit f66cd17

Please sign in to comment.