mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Generalize ContainingBlock
's block size to a SizeConstraint
(#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 <obrufau@igalia.com>
This commit is contained in:
parent
de780dcde4
commit
f66cd172d6
11 changed files with 71 additions and 69 deletions
|
@ -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,
|
||||
|
@ -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(),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
},
|
||||
)
|
||||
};
|
||||
|
@ -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),
|
||||
),
|
||||
|
@ -2834,7 +2837,7 @@ impl FlexItemBox {
|
|||
let item_as_containing_block = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: inline_size,
|
||||
block: AuOrAuto::Auto,
|
||||
block: SizeConstraint::default(),
|
||||
},
|
||||
style,
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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())
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -1265,7 +1265,7 @@ impl IndependentNonReplacedContents {
|
|||
&ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: inline_size,
|
||||
block: tentative_block_size.to_auto_or(),
|
||||
block: tentative_block_size,
|
||||
},
|
||||
style,
|
||||
},
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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"),
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
},
|
||||
)
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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 {
|
||||
(
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
use app_units::Au;
|
||||
use atomic_refcell::{AtomicRef, AtomicRefCell};
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrAuto};
|
||||
use style::values::specified::align::AlignFlags;
|
||||
use style::values::specified::box_::DisplayInside;
|
||||
use style::Zero;
|
||||
|
@ -122,13 +121,6 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
let mut child = (*self.source_child_nodes[usize::from(node_id)]).borrow_mut();
|
||||
let child = &mut *child;
|
||||
|
||||
fn option_f32_to_lpa(input: Option<f32>) -> LengthPercentageOrAuto<Au> {
|
||||
match input {
|
||||
None => LengthPercentageOrAuto::Auto,
|
||||
Some(length) => LengthPercentageOrAuto::LengthPercentage(Au::from_f32_px(length)),
|
||||
}
|
||||
}
|
||||
|
||||
fn option_f32_to_size(input: Option<f32>) -> Size<Au> {
|
||||
match input {
|
||||
None => Size::Initial,
|
||||
|
@ -241,12 +233,13 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
});
|
||||
}
|
||||
|
||||
let maybe_block_size =
|
||||
option_f32_to_lpa(content_box_known_dimensions.height);
|
||||
let content_box_size_override = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: Au::from_f32_px(inline_size),
|
||||
block: maybe_block_size,
|
||||
block: content_box_known_dimensions
|
||||
.height
|
||||
.map(Au::from_f32_px)
|
||||
.map_or_else(SizeConstraint::default, SizeConstraint::Definite),
|
||||
},
|
||||
style,
|
||||
};
|
||||
|
@ -361,7 +354,7 @@ impl ComputeInlineContentSizes for TaffyContainer {
|
|||
let containing_block = &ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: Au::zero(),
|
||||
block: GenericLengthPercentageOrAuto::Auto,
|
||||
block: SizeConstraint::default(),
|
||||
},
|
||||
style,
|
||||
};
|
||||
|
@ -432,13 +425,6 @@ impl TaffyContainer {
|
|||
child_detailed_layout_infos: vec![None; self.children.len()],
|
||||
};
|
||||
|
||||
fn auto_or_to_option<T>(input: GenericLengthPercentageOrAuto<T>) -> Option<T> {
|
||||
match input {
|
||||
LengthPercentageOrAuto::LengthPercentage(val) => Some(val),
|
||||
LengthPercentageOrAuto::Auto => None,
|
||||
}
|
||||
}
|
||||
|
||||
let container_style = &content_box_size_override.style;
|
||||
let align_items = container_style.clone_align_items();
|
||||
let justify_items = container_style.clone_justify_items();
|
||||
|
@ -449,14 +435,17 @@ impl TaffyContainer {
|
|||
(content_box_size_override.size.inline + pbm.padding_border_sums.inline)
|
||||
.to_f32_px(),
|
||||
),
|
||||
height: auto_or_to_option(content_box_size_override.size.block)
|
||||
height: content_box_size_override
|
||||
.size
|
||||
.block
|
||||
.to_definite()
|
||||
.map(Au::to_f32_px)
|
||||
.maybe_add(pbm.padding_border_sums.block.to_f32_px()),
|
||||
};
|
||||
|
||||
let taffy_containing_block = taffy::Size {
|
||||
width: Some(containing_block.size.inline.to_f32_px()),
|
||||
height: auto_or_to_option(containing_block.size.block).map(Au::to_f32_px),
|
||||
height: containing_block.size.block.to_definite().map(Au::to_f32_px),
|
||||
};
|
||||
|
||||
let layout_input = taffy::LayoutInput {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue