Refactor computation of preferred aspect ratios (#34416)

* Refactor computation of preferred aspect ratios

Computing min/max-content sizes required a ContainingBlock in order to
resolve the padding and border when determining the preferred aspect
ratio. However, all callers already knew the padding and border, so they
can compute the ratio themselves, and pass it directly instead of
the ContainingBlock.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

* Put preferred aspect ratio into ConstraintSpace

Signed-off-by: Oriol Brufau <obrufau@igalia.com>

---------

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-11-29 12:40:52 +01:00 committed by GitHub
parent 16da1c2721
commit 19a7e95a6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 133 additions and 113 deletions

View file

@ -38,7 +38,7 @@ use crate::positioned::{
};
use crate::sizing::{ContentSizes, InlineContentSizesResult, IntrinsicSizingMode};
use crate::style_ext::{
Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated, PaddingBorderMargin,
AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated, PaddingBorderMargin,
};
use crate::{ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, SizeConstraint};
@ -84,6 +84,9 @@ struct FlexItem<'a> {
/// Whether or not the size of this [`FlexItem`] depends on its block constraints.
depends_on_block_constraints: bool,
/// <https://drafts.csswg.org/css-sizing-4/#preferred-aspect-ratio>
preferred_aspect_ratio: Option<AspectRatio>,
}
/// Child of a FlexContainer. Can either be absolutely positioned, or not. If not,
@ -1105,6 +1108,7 @@ fn allocate_free_cross_space_for_flex_line(
impl<'a> FlexItem<'a> {
fn new(flex_context: &FlexContext, box_: &'a FlexItemBox) -> Self {
let config = &flex_context.config;
let containing_block = flex_context.containing_block;
let parent_writing_mode = containing_block.style.writing_mode;
let item_writing_mode = box_.style().writing_mode;
@ -1114,7 +1118,7 @@ impl<'a> FlexItem<'a> {
let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis(
container_is_horizontal,
item_is_horizontal,
flex_context.config.flex_axis,
config.flex_axis,
);
let ContentBoxSizesAndPBMDeprecated {
@ -1128,6 +1132,9 @@ impl<'a> FlexItem<'a> {
.content_box_sizes_and_padding_border_margin(&containing_block.into())
.into();
let preferred_aspect_ratio = box_
.independent_formatting_context
.preferred_aspect_ratio(&pbm.padding_border_sums);
let margin_auto_is_zero = flex_context.sides_to_flex_relative(pbm.margin.auto_is(Au::zero));
let padding = flex_context.sides_to_flex_relative(pbm.padding);
let border = flex_context.sides_to_flex_relative(pbm.border);
@ -1138,9 +1145,8 @@ impl<'a> FlexItem<'a> {
cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis();
let item_with_auto_cross_size_stretches_to_container_size = flex_context
.config
.item_with_auto_cross_size_stretches_to_container_size(box_.style(), &margin);
let item_with_auto_cross_size_stretches_to_container_size =
config.item_with_auto_cross_size_stretches_to_container_size(box_.style(), &margin);
let flex_relative_content_box_size = flex_context.vec2_to_flex_relative(content_box_size);
let flex_relative_content_max_size =
@ -1156,6 +1162,7 @@ impl<'a> FlexItem<'a> {
flex_relative_content_box_size,
flex_relative_content_min_size,
flex_relative_content_max_size,
preferred_aspect_ratio,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| {
@ -1167,6 +1174,7 @@ impl<'a> FlexItem<'a> {
content_box_size,
min_size_auto_is_zero,
content_max_box_size,
preferred_aspect_ratio,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size,
)
@ -1175,25 +1183,20 @@ impl<'a> FlexItem<'a> {
}),
cross: flex_relative_content_min_size.cross.auto_is(Au::zero),
};
let align_self = AlignItems(
flex_context
.config
.resolve_align_self_for_child(box_.style()),
);
let align_self = AlignItems(config.resolve_align_self_for_child(box_.style()));
let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size(
flex_context.layout_context,
&containing_block.into(),
flex_context.container_definite_inner_size,
cross_axis_is_item_block_axis,
flex_relative_content_box_size,
flex_relative_content_min_size,
flex_relative_content_max_size,
preferred_aspect_ratio,
padding_border,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| {
let min_size = flex_context
.config
let min_size = config
.flex_axis
.vec2_to_flow_relative(flex_relative_content_min_size);
item.layout_for_block_content_size(
@ -1202,6 +1205,7 @@ impl<'a> FlexItem<'a> {
content_box_size,
min_size,
content_max_box_size,
preferred_aspect_ratio,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size,
)
@ -1228,6 +1232,7 @@ impl<'a> FlexItem<'a> {
hypothetical_main_size,
align_self,
depends_on_block_constraints,
preferred_aspect_ratio,
}
}
@ -1892,11 +1897,8 @@ impl FlexItem<'_> {
}),
};
let item_writing_mode = self
.box_
.independent_formatting_context
.style()
.writing_mode;
let context = &self.box_.independent_formatting_context;
let item_writing_mode = context.style().writing_mode;
let item_is_horizontal = item_writing_mode.is_horizontal();
let flex_axis = flex_context.config.flex_axis;
let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis(
@ -1922,14 +1924,10 @@ impl FlexItem<'_> {
let constraint_space = ConstraintSpace::new(
SizeConstraint::Definite(used_main_size),
item_writing_mode,
self.preferred_aspect_ratio,
);
self.box_
.independent_formatting_context
.inline_content_sizes(
flex_context.layout_context,
&constraint_space,
&containing_block.into(),
)
context
.inline_content_sizes(flex_context.layout_context, &constraint_space)
.sizes
.shrink_to_fit(stretch_size)
.clamp_between_extremums(
@ -1951,13 +1949,14 @@ impl FlexItem<'_> {
};
let container_writing_mode = containing_block.style.writing_mode;
match &self.box_.independent_formatting_context {
match context {
IndependentFormattingContext::Replaced(replaced) => {
let size = replaced
.contents
.used_size_as_if_inline_element_from_content_box_sizes(
containing_block,
&replaced.style,
self.preferred_aspect_ratio,
LogicalVec2 {
inline: Size::Numeric(inline_size),
block: block_size.non_auto().map_or(Size::Initial, Size::Numeric),
@ -2263,6 +2262,9 @@ impl FlexItemBox {
} = style
.content_box_sizes_and_padding_border_margin(containing_block)
.into();
let preferred_aspect_ratio = self
.independent_formatting_context
.preferred_aspect_ratio(&pbm.padding_border_sums);
let padding = main_start_cross_start.sides_to_flex_relative(pbm.padding);
let border = main_start_cross_start.sides_to_flex_relative(pbm.border);
let margin = main_start_cross_start.sides_to_flex_relative(pbm.margin);
@ -2283,6 +2285,7 @@ impl FlexItemBox {
flex_axis.vec2_to_flex_relative(content_box_size),
flex_axis.vec2_to_flex_relative(content_min_box_size),
flex_axis.vec2_to_flex_relative(content_max_box_size),
preferred_aspect_ratio,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| {
@ -2292,6 +2295,7 @@ impl FlexItemBox {
content_box_size,
content_min_box_size.map(|v| v.auto_is(Au::zero)),
content_max_box_size,
preferred_aspect_ratio,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size,
)
@ -2315,6 +2319,7 @@ impl FlexItemBox {
content_box_size,
content_min_size_no_auto,
content_max_box_size,
preferred_aspect_ratio,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size,
)
@ -2344,6 +2349,7 @@ impl FlexItemBox {
content_box_size,
content_min_size_no_auto,
content_max_box_size,
preferred_aspect_ratio,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Contribution,
);
@ -2359,7 +2365,6 @@ impl FlexItemBox {
// we compute the base sizes of the items twice. We should consider caching.
let (flex_base_size, _) = self.flex_base_size(
layout_context,
containing_block,
config
.flex_axis
.vec2_to_flex_relative(containing_block.size.map(|v| v.non_auto())),
@ -2367,6 +2372,7 @@ impl FlexItemBox {
content_box_size,
content_min_size_no_auto,
content_max_size,
preferred_aspect_ratio,
padding_border,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
@ -2475,6 +2481,7 @@ impl FlexItemBox {
content_box_size: FlexRelativeVec2<AuOrAuto>,
min_size: FlexRelativeVec2<GenericLengthPercentageOrAuto<Au>>,
max_size: FlexRelativeVec2<Option<Au>>,
preferred_aspect_ratio: Option<AspectRatio>,
pbm_auto_is_zero: &FlexRelativeVec2<Au>,
auto_cross_size_stretches_to_container_size: bool,
block_content_size_callback: impl FnOnce(&FlexItemBox) -> Au,
@ -2490,12 +2497,7 @@ impl FlexItemBox {
// > size suggestion is that size. It is otherwise undefined.
let specified_size_suggestion = content_box_size.main.non_auto();
let (is_replaced, ratio) = match self.independent_formatting_context {
IndependentFormattingContext::NonReplaced(_) => (false, None),
IndependentFormattingContext::Replaced(ref replaced) => {
(true, replaced.preferred_aspect_ratio(containing_block))
},
};
let is_replaced = self.independent_formatting_context.is_replaced();
let main_axis = if cross_axis_is_item_block_axis {
Direction::Inline
} else {
@ -2522,7 +2524,7 @@ impl FlexItemBox {
// > If the item has a preferred aspect ratio and its preferred cross size is definite, then the
// > transferred size suggestion is that size (clamped by its minimum and maximum cross sizes if they
// > are definite), converted through the aspect ratio. It is otherwise undefined.
let transferred_size_suggestion = match (ratio, cross_size) {
let transferred_size_suggestion = match (preferred_aspect_ratio, cross_size) {
(Some(ratio), SizeConstraint::Definite(cross_size)) => {
Some(ratio.compute_dependent_size(main_axis, cross_size))
},
@ -2535,15 +2537,16 @@ impl FlexItemBox {
// > aspect ratio.
let main_content_size = if cross_axis_is_item_block_axis {
let writing_mode = style.writing_mode;
let constraint_space = ConstraintSpace::new(cross_size, writing_mode);
let constraint_space =
ConstraintSpace::new(cross_size, writing_mode, preferred_aspect_ratio);
self.independent_formatting_context
.inline_content_sizes(layout_context, &constraint_space, containing_block)
.inline_content_sizes(layout_context, &constraint_space)
.sizes
.min_content
} else {
block_content_size_callback(self)
};
let content_size_suggestion = ratio
let content_size_suggestion = preferred_aspect_ratio
.map(|ratio| {
main_content_size.clamp_between_extremums(
ratio.compute_dependent_size(main_axis, min_size.cross.auto_is(Au::zero)),
@ -2573,12 +2576,12 @@ impl FlexItemBox {
fn flex_base_size(
&self,
layout_context: &LayoutContext,
containing_block: &IndefiniteContainingBlock,
container_definite_inner_size: FlexRelativeVec2<Option<Au>>,
cross_axis_is_item_block_axis: bool,
content_box_size: FlexRelativeVec2<AuOrAuto>,
content_min_box_size: FlexRelativeVec2<Au>,
content_max_box_size: FlexRelativeVec2<Option<Au>>,
preferred_aspect_ratio: Option<AspectRatio>,
padding_border_sums: FlexRelativeVec2<Au>,
pbm_auto_is_zero: &FlexRelativeVec2<Au>,
item_with_auto_cross_size_stretches_to_container_size: bool,
@ -2649,7 +2652,6 @@ impl FlexItemBox {
// > - a used flex basis of content, and
// > - a definite cross size,
// > then the flex base size is calculated from its used cross size and the flex items aspect ratio.
let ratio = flex_item.preferred_aspect_ratio(containing_block);
let main_axis = if cross_axis_is_item_block_axis {
Direction::Inline
} else {
@ -2667,7 +2669,7 @@ impl FlexItemBox {
} else {
content_box_size.cross.non_auto()
};
if let (Some(ratio), Some(cross_size)) = (ratio, cross_size) {
if let (Some(ratio), Some(cross_size)) = (preferred_aspect_ratio, cross_size) {
let cross_size = cross_size.clamp_between_extremums(
content_min_box_size.cross,
content_max_box_size.cross,
@ -2694,12 +2696,13 @@ impl FlexItemBox {
content_max_box_size.cross,
),
writing_mode,
preferred_aspect_ratio,
);
let max_content = flex_item
.inline_content_sizes(layout_context, &constraint_space, containing_block)
.inline_content_sizes(layout_context, &constraint_space)
.sizes
.max_content;
if let Some(ratio) = ratio {
if let Some(ratio) = preferred_aspect_ratio {
max_content.clamp_between_extremums(
ratio.compute_dependent_size(main_axis, content_min_box_size.cross),
content_max_box_size
@ -2734,6 +2737,7 @@ impl FlexItemBox {
mut content_box_size: LogicalVec2<AuOrAuto>,
mut min_size: LogicalVec2<Au>,
mut max_size: LogicalVec2<Option<Au>>,
preferred_aspect_ratio: Option<AspectRatio>,
item_with_auto_cross_size_stretches_to_container_size: bool,
intrinsic_sizing_mode: IntrinsicSizingMode,
) -> Au {
@ -2756,6 +2760,7 @@ impl FlexItemBox {
.used_size_as_if_inline_element_from_content_box_sizes(
flex_context.containing_block,
&replaced.style,
preferred_aspect_ratio,
content_box_size
.map(|size| size.non_auto().map_or(Size::Initial, Size::Numeric)),
min_size.map(|size| Size::Numeric(*size)),
@ -2780,12 +2785,15 @@ impl FlexItemBox {
if item_with_auto_cross_size_stretches_to_container_size {
containing_block_inline_size_minus_pbm
} else {
let containing_block_for_children =
ConstraintSpace::new_for_style(&non_replaced.style);
let constraint_space = ConstraintSpace::new(
SizeConstraint::default(),
non_replaced.style.writing_mode,
non_replaced.preferred_aspect_ratio(),
);
non_replaced
.inline_content_sizes(
flex_context.layout_context,
&containing_block_for_children,
&constraint_space,
)
.sizes
.shrink_to_fit(containing_block_inline_size_minus_pbm)

View file

@ -1965,7 +1965,7 @@ impl IndependentFormattingContext {
// Lay out absolutely positioned children if this new atomic establishes a containing block
// for absolutes.
let positioning_context = if matches!(self, IndependentFormattingContext::Replaced(_)) {
let positioning_context = if self.is_replaced() {
None
} else {
if fragment

View file

@ -235,10 +235,13 @@ impl OutsideMarker {
sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
) -> Fragment {
let content_sizes = self.block_container.inline_content_sizes(
layout_context,
&ConstraintSpace::new_for_style(&self.marker_style),
let constraint_space = ConstraintSpace::new_for_style_and_ratio(
&self.marker_style,
None, /* TODO: support preferred aspect ratios on non-replaced boxes */
);
let content_sizes = self
.block_container
.inline_content_sizes(layout_context, &constraint_space);
let containing_block_for_children = ContainingBlock {
inline_size: content_sizes.sizes.max_content,
block_size: AuOrAuto::auto(),
@ -394,7 +397,8 @@ fn calculate_inline_content_size_for_block_level_boxes(
style,
containing_block,
&LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
false, /* auto_block_size_stretches_to_containing_block */
|_| None, /* TODO: support preferred aspect ratios on non-replaced boxes */
|constraint_space| {
contents.inline_content_sizes(layout_context, constraint_space)
},
@ -2054,7 +2058,11 @@ impl IndependentFormattingContext {
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size);
let content_size = LazyCell::new(|| {
let constraint_space = ConstraintSpace::new(tentative_block_size, writing_mode);
let constraint_space = ConstraintSpace::new(
tentative_block_size,
writing_mode,
non_replaced.preferred_aspect_ratio(),
);
non_replaced
.inline_content_sizes(layout_context, &constraint_space)
.sizes

View file

@ -185,6 +185,10 @@ impl IndependentFormattingContext {
}
}
pub fn is_replaced(&self) -> bool {
matches!(self, Self::Replaced(_))
}
pub fn style(&self) -> &Arc<ComputedValues> {
match self {
Self::NonReplaced(inner) => &inner.style,
@ -203,17 +207,14 @@ impl IndependentFormattingContext {
&self,
layout_context: &LayoutContext,
constraint_space: &ConstraintSpace,
containing_block: &IndefiniteContainingBlock,
) -> InlineContentSizesResult {
match self {
Self::NonReplaced(inner) => {
inner.inline_content_sizes(layout_context, constraint_space)
},
Self::Replaced(inner) => inner.contents.inline_content_sizes(
layout_context,
constraint_space,
inner.preferred_aspect_ratio(containing_block),
),
Self::Replaced(inner) => inner
.contents
.inline_content_sizes(layout_context, constraint_space),
}
}
@ -236,12 +237,11 @@ impl IndependentFormattingContext {
containing_block,
auto_minimum,
auto_block_size_stretches_to_containing_block,
|padding_border_sums| replaced.preferred_aspect_ratio(padding_border_sums),
|constraint_space| {
replaced.contents.inline_content_sizes(
layout_context,
constraint_space,
replaced.preferred_aspect_ratio(containing_block),
)
replaced
.contents
.inline_content_sizes(layout_context, constraint_space)
},
),
}
@ -249,11 +249,11 @@ impl IndependentFormattingContext {
pub(crate) fn preferred_aspect_ratio(
&self,
containing_block: &IndefiniteContainingBlock,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
match self {
Self::NonReplaced(_) => None,
Self::Replaced(replaced) => replaced.preferred_aspect_ratio(containing_block),
Self::NonReplaced(non_replaced) => non_replaced.preferred_aspect_ratio(),
Self::Replaced(replaced) => replaced.preferred_aspect_ratio(padding_border_sums),
}
}
}
@ -293,6 +293,12 @@ impl NonReplacedFormattingContext {
}
}
#[inline]
pub(crate) fn preferred_aspect_ratio(&self) -> Option<AspectRatio> {
// TODO: support preferred aspect ratios on non-replaced boxes.
None
}
pub(crate) fn inline_content_sizes(
&self,
layout_context: &LayoutContext,
@ -327,6 +333,7 @@ impl NonReplacedFormattingContext {
containing_block,
auto_minimum,
auto_block_size_stretches_to_containing_block,
|_| self.preferred_aspect_ratio(),
|constraint_space| self.inline_content_sizes(layout_context, constraint_space),
)
}
@ -352,9 +359,9 @@ impl NonReplacedFormattingContextContents {
impl ReplacedFormattingContext {
pub(crate) fn preferred_aspect_ratio(
&self,
containing_block: &IndefiniteContainingBlock,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
self.contents
.preferred_aspect_ratio(containing_block, &self.style)
.preferred_aspect_ratio(&self.style, padding_border_sums)
}
}

View file

@ -35,24 +35,38 @@ use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use crate::geom::{LogicalVec2, SizeConstraint};
use crate::style_ext::AspectRatio;
/// Represents the set of constraints that we use when computing the min-content
/// and max-content inline sizes of an element.
pub(crate) struct ConstraintSpace {
pub block_size: SizeConstraint,
pub writing_mode: WritingMode,
pub preferred_aspect_ratio: Option<AspectRatio>,
}
impl ConstraintSpace {
fn new(block_size: SizeConstraint, writing_mode: WritingMode) -> Self {
fn new(
block_size: SizeConstraint,
writing_mode: WritingMode,
preferred_aspect_ratio: Option<AspectRatio>,
) -> Self {
Self {
block_size,
writing_mode,
preferred_aspect_ratio,
}
}
fn new_for_style(style: &ComputedValues) -> Self {
Self::new(SizeConstraint::default(), style.writing_mode)
fn new_for_style_and_ratio(
style: &ComputedValues,
preferred_aspect_ratio: Option<AspectRatio>,
) -> Self {
Self::new(
SizeConstraint::default(),
style.writing_mode,
preferred_aspect_ratio,
)
}
}

View file

@ -550,9 +550,10 @@ impl HoistedAbsolutelyPositionedBox {
// The inline axis can be fully resolved, computing intrinsic sizes using the
// tentative block size.
let mut inline_axis = inline_axis_solver.solve(Some(|| {
let constraint_space = ConstraintSpace::new(block_axis.size, style.writing_mode);
let ratio = context.preferred_aspect_ratio(&pbm.padding_border_sums);
let constraint_space = ConstraintSpace::new(block_axis.size, style.writing_mode, ratio);
context
.inline_content_sizes(layout_context, &constraint_space, &containing_block.into())
.inline_content_sizes(layout_context, &constraint_space)
.sizes
}));

View file

@ -31,7 +31,7 @@ use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFrag
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size};
use crate::sizing::{ContentSizes, InlineContentSizesResult};
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
use crate::{ConstraintSpace, ContainingBlock, IndefiniteContainingBlock, SizeConstraint};
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
#[derive(Debug, Serialize)]
pub(crate) struct ReplacedContent {
@ -282,7 +282,6 @@ impl ReplacedContent {
&self,
_: &LayoutContext,
constraint_space: &ConstraintSpace,
preferred_aspect_ratio: Option<AspectRatio>,
) -> InlineContentSizesResult {
let get_inline_fallback_size = || {
let writing_mode = constraint_space.writing_mode;
@ -292,13 +291,13 @@ impl ReplacedContent {
};
let inline_content_size = self.content_size(
Direction::Inline,
preferred_aspect_ratio,
constraint_space.preferred_aspect_ratio,
&|| constraint_space.block_size,
&get_inline_fallback_size,
);
InlineContentSizesResult {
sizes: inline_content_size.into(),
depends_on_block_constraints: preferred_aspect_ratio.is_some(),
depends_on_block_constraints: constraint_space.preferred_aspect_ratio.is_some(),
}
}
@ -417,13 +416,13 @@ impl ReplacedContent {
pub(crate) fn preferred_aspect_ratio(
&self,
containing_block: &IndefiniteContainingBlock,
style: &ComputedValues,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
style
.preferred_aspect_ratio(
self.inline_size_over_block_size_intrinsic_ratio(style),
containing_block,
padding_border_sums,
)
.or_else(|| {
matches!(self.kind, ReplacedContentKind::Video(_)).then(|| {
@ -450,6 +449,7 @@ impl ReplacedContent {
self.used_size_as_if_inline_element_from_content_box_sizes(
containing_block,
style,
self.preferred_aspect_ratio(style, &pbm.padding_border_sums),
content_box_sizes_and_pbm.content_box_size,
content_box_sizes_and_pbm.content_min_box_size,
content_box_sizes_and_pbm.content_max_box_size,
@ -492,18 +492,17 @@ impl ReplacedContent {
///
/// <https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers>
/// <https://github.com/w3c/csswg-drafts/issues/6071#issuecomment-2243986313>
#[allow(clippy::too_many_arguments)]
pub(crate) fn used_size_as_if_inline_element_from_content_box_sizes(
&self,
containing_block: &ContainingBlock,
style: &ComputedValues,
preferred_aspect_ratio: Option<AspectRatio>,
box_size: LogicalVec2<Size<Au>>,
min_box_size: LogicalVec2<Size<Au>>,
max_box_size: LogicalVec2<Size<Au>>,
pbm_sums: LogicalVec2<Au>,
) -> LogicalVec2<Au> {
// <https://drafts.csswg.org/css-sizing-4/#preferred-aspect-ratio>
let ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
// <https://drafts.csswg.org/css-images-3/#natural-dimensions>
// <https://drafts.csswg.org/css-images-3/#default-object-size>
let writing_mode = style.writing_mode;
@ -549,7 +548,7 @@ impl ReplacedContent {
};
self.content_size(
Direction::Inline,
ratio,
preferred_aspect_ratio,
&get_block_size,
&get_inline_fallback_size,
)
@ -581,7 +580,7 @@ impl ReplacedContent {
};
self.content_size(
Direction::Block,
ratio,
preferred_aspect_ratio,
&get_inline_size,
&get_block_fallback_size,
)

View file

@ -13,7 +13,7 @@ use style::properties::ComputedValues;
use style::Zero;
use crate::geom::Size;
use crate::style_ext::{Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
use crate::{ConstraintSpace, IndefiniteContainingBlock, LogicalVec2, SizeConstraint};
#[derive(PartialEq)]
@ -113,6 +113,7 @@ pub(crate) fn outer_inline(
containing_block: &IndefiniteContainingBlock,
auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool,
get_preferred_aspect_ratio: impl FnOnce(&LogicalVec2<Au>) -> Option<AspectRatio>,
get_content_size: impl FnOnce(&ConstraintSpace) -> InlineContentSizesResult,
) -> InlineContentSizesResult {
let ContentBoxSizesAndPBM {
@ -153,6 +154,7 @@ pub(crate) fn outer_inline(
get_content_size(&ConstraintSpace::new(
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size),
style.writing_mode,
get_preferred_aspect_ratio(&pbm.padding_border_sums),
))
});
let resolve_non_initial = |inline_size| {

View file

@ -281,10 +281,6 @@ pub(crate) trait ComputedValuesExt {
containing_block: &IndefiniteContainingBlock,
) -> ContentBoxSizesAndPBM;
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,
@ -319,7 +315,7 @@ pub(crate) trait ComputedValuesExt {
fn preferred_aspect_ratio(
&self,
natural_aspect_ratio: Option<CSSFloat>,
containing_block: &IndefiniteContainingBlock,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio>;
fn background_is_transparent(&self) -> bool;
fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags;
@ -579,16 +575,6 @@ impl ComputedValuesExt for ComputedValues {
)
}
fn padding_border_margin_for_intrinsic_size(
&self,
writing_mode: WritingMode,
) -> PaddingBorderMargin {
self.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
writing_mode,
Au::zero(),
)
}
fn padding_border_margin_with_writing_mode_and_containing_block_inline_size(
&self,
writing_mode: WritingMode,
@ -878,7 +864,7 @@ impl ComputedValuesExt for ComputedValues {
fn preferred_aspect_ratio(
&self,
natural_aspect_ratio: Option<CSSFloat>,
containing_block: &IndefiniteContainingBlock,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
let GenericAspectRatio {
auto,
@ -921,15 +907,7 @@ impl ComputedValuesExt for ComputedValues {
// border when calculating the aspect ratio.
let box_sizing_adjustment = match self.clone_box_sizing() {
BoxSizing::ContentBox => LogicalVec2::zero(),
BoxSizing::BorderBox => containing_block.size.inline.non_auto().map_or_else(
|| self.padding_border_margin_for_intrinsic_size(containing_block.writing_mode),
|containing_block_inline_size| self
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
containing_block.writing_mode,
containing_block_inline_size,
)
)
.padding_border_sums,
BoxSizing::BorderBox => *padding_border_sums,
};
Some(AspectRatio {
i_over_b: (preferred_ratio.0).0 / (preferred_ratio.1).0,

View file

@ -296,12 +296,13 @@ impl<'a> TableLayout<'a> {
let mut inline_content_sizes = if is_in_fixed_mode {
ContentSizes::zero()
} else {
let constraint_space = ConstraintSpace::new_for_style_and_ratio(
&cell.style,
None, /* TODO: support preferred aspect ratios on non-replaced boxes */
);
cell.contents
.contents
.inline_content_sizes(
layout_context,
&ConstraintSpace::new_for_style(&cell.style),
)
.inline_content_sizes(layout_context, &constraint_space)
.sizes
};
inline_content_sizes.min_content += padding_border_sums.inline;

View file

@ -156,6 +156,7 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
.used_size_as_if_inline_element_from_content_box_sizes(
containing_block,
&replaced.style,
replaced.preferred_aspect_ratio(&pbm.padding_border_sums),
LogicalVec2 {
inline: option_f32_to_size(content_box_known_dimensions.width),
block: option_f32_to_size(content_box_known_dimensions.height),
@ -226,6 +227,7 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
None,
),
writing_mode: self.style.writing_mode,
preferred_aspect_ratio: non_replaced.preferred_aspect_ratio(),
};
let result = non_replaced