mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
layout: Add an indefinite containing block for intrinsic sizing (#33204)
When computing the min-content or max-content size of an element we need to ignore `inline-size`, `min-inline-size` and `max-inline-size`. However, we should take the block-axis sizing properties into account. That's because the contents could have percentages depending on them, which can then affect their inline size via an aspect ratio. Therefore, this patch adds `IndefiniteContainingBlock`, which is similar to `ContainingBlock`, but it allows an indefinite inline-size. This struct is then passed arround during intrinsic sizing. More refinement will be needed in follow-up patches in order to fully address the problem. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
46dbe4ce32
commit
93abdf7cb5
29 changed files with 600 additions and 332 deletions
|
@ -30,7 +30,7 @@ use crate::geom::{
|
|||
AuOrAuto, LengthOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides,
|
||||
PhysicalSize,
|
||||
};
|
||||
use crate::ContainingBlock;
|
||||
use crate::{ContainingBlock, IndefiniteContainingBlock};
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum Display {
|
||||
|
@ -233,11 +233,25 @@ pub(crate) trait ComputedValuesExt {
|
|||
box_size: LogicalVec2<Option<Length>>,
|
||||
pbm: &PaddingBorderMargin,
|
||||
) -> LogicalVec2<Option<Length>>;
|
||||
fn content_box_sizes_and_padding_border_margin(
|
||||
&self,
|
||||
containing_block: &IndefiniteContainingBlock,
|
||||
) -> (
|
||||
LogicalVec2<AuOrAuto>,
|
||||
LogicalVec2<AuOrAuto>,
|
||||
LogicalVec2<Option<Au>>,
|
||||
PaddingBorderMargin,
|
||||
);
|
||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
|
||||
fn padding_border_margin_for_intrinsic_size(
|
||||
&self,
|
||||
writing_mode: WritingMode,
|
||||
) -> PaddingBorderMargin;
|
||||
fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
||||
&self,
|
||||
writing_mode: WritingMode,
|
||||
containing_block_inline_size: Au,
|
||||
) -> PaddingBorderMargin;
|
||||
fn padding(
|
||||
&self,
|
||||
containing_block_writing_mode: WritingMode,
|
||||
|
@ -263,7 +277,8 @@ pub(crate) trait ComputedValuesExt {
|
|||
fn preferred_aspect_ratio(
|
||||
&self,
|
||||
natural_aspect_ratio: Option<CSSFloat>,
|
||||
containing_block: &ContainingBlock,
|
||||
containing_block: Option<&ContainingBlock>,
|
||||
containing_block_writing_mode: WritingMode,
|
||||
) -> Option<AspectRatio>;
|
||||
fn background_is_transparent(&self) -> bool;
|
||||
fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags;
|
||||
|
@ -431,6 +446,49 @@ impl ComputedValuesExt for ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
fn content_box_sizes_and_padding_border_margin(
|
||||
&self,
|
||||
containing_block: &IndefiniteContainingBlock,
|
||||
) -> (
|
||||
LogicalVec2<AuOrAuto>,
|
||||
LogicalVec2<AuOrAuto>,
|
||||
LogicalVec2<Option<Au>>,
|
||||
PaddingBorderMargin,
|
||||
) {
|
||||
// <https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution>
|
||||
// If max size properties or preferred size properties are set to a value containing
|
||||
// indefinite percentages, we treat the entire value as the initial value of the property.
|
||||
// However, for min size properties, as well as for margins and paddings,
|
||||
// we instead resolve indefinite percentages against zero.
|
||||
let containing_block_size = containing_block.size.map(|v| v.non_auto().map(Into::into));
|
||||
let containing_block_size_auto_is_zero =
|
||||
containing_block_size.map(|v| v.unwrap_or_else(Length::zero));
|
||||
let writing_mode = self.writing_mode;
|
||||
let pbm = self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
||||
writing_mode,
|
||||
containing_block.size.inline.auto_is(Au::zero),
|
||||
);
|
||||
let box_size = self
|
||||
.box_size(writing_mode)
|
||||
.maybe_percentages_relative_to_basis(&containing_block_size);
|
||||
let content_box_size = self
|
||||
.content_box_size_for_box_size(box_size, &pbm)
|
||||
.map(|v| v.map(Au::from));
|
||||
let min_size = self
|
||||
.min_box_size(writing_mode)
|
||||
.percentages_relative_to_basis(&containing_block_size_auto_is_zero);
|
||||
let content_min_size = self
|
||||
.content_min_box_size_for_min_size(min_size, &pbm)
|
||||
.map(|v| v.map(Au::from));
|
||||
let max_size = self
|
||||
.max_box_size(writing_mode)
|
||||
.maybe_percentages_relative_to_basis(&containing_block_size);
|
||||
let content_max_size = self
|
||||
.content_max_box_size_for_max_size(max_size, &pbm)
|
||||
.map(|v| v.map(Au::from));
|
||||
(content_box_size, content_min_size, content_max_size, pbm)
|
||||
}
|
||||
|
||||
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
|
||||
let cbis = containing_block.inline_size;
|
||||
let padding = self
|
||||
|
@ -473,6 +531,30 @@ impl ComputedValuesExt for ComputedValues {
|
|||
}
|
||||
}
|
||||
|
||||
fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
||||
&self,
|
||||
writing_mode: WritingMode,
|
||||
containing_block_inline_size: Au,
|
||||
) -> PaddingBorderMargin {
|
||||
let containing_block_inline_size = containing_block_inline_size.into();
|
||||
let padding = self
|
||||
.padding(writing_mode)
|
||||
.percentages_relative_to(containing_block_inline_size);
|
||||
let border = self.border_width(writing_mode);
|
||||
let margin = self
|
||||
.margin(writing_mode)
|
||||
.percentages_relative_to(containing_block_inline_size);
|
||||
PaddingBorderMargin {
|
||||
padding_border_sums: LogicalVec2 {
|
||||
inline: (padding.inline_sum() + border.inline_sum()).into(),
|
||||
block: (padding.block_sum() + border.block_sum()).into(),
|
||||
},
|
||||
padding: padding.into(),
|
||||
border: border.into(),
|
||||
margin: margin.map(|margin_side| margin_side.map(Into::into)),
|
||||
}
|
||||
}
|
||||
|
||||
fn padding(
|
||||
&self,
|
||||
containing_block_writing_mode: WritingMode,
|
||||
|
@ -677,7 +759,8 @@ impl ComputedValuesExt for ComputedValues {
|
|||
fn preferred_aspect_ratio(
|
||||
&self,
|
||||
natural_aspect_ratio: Option<CSSFloat>,
|
||||
containing_block: &ContainingBlock,
|
||||
containing_block: Option<&ContainingBlock>,
|
||||
containing_block_writing_mode: WritingMode,
|
||||
) -> Option<AspectRatio> {
|
||||
let GenericAspectRatio {
|
||||
auto,
|
||||
|
@ -728,8 +811,13 @@ impl ComputedValuesExt for ComputedValues {
|
|||
let box_sizing_adjustment = match self.clone_box_sizing() {
|
||||
BoxSizing::ContentBox => LogicalVec2::zero(),
|
||||
BoxSizing::BorderBox => {
|
||||
self.padding_border_margin(containing_block)
|
||||
.padding_border_sums
|
||||
match containing_block {
|
||||
Some(containing_block) => self.padding_border_margin(containing_block),
|
||||
None => self.padding_border_margin_for_intrinsic_size(
|
||||
containing_block_writing_mode,
|
||||
),
|
||||
}
|
||||
.padding_border_sums
|
||||
},
|
||||
};
|
||||
Some(AspectRatio {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue