mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Refactor box size computation (#34671)
in each layout logic, in order to correctly resolve sizing keywords. This patch adds a new `Sizes` struct which holds the preferred, min and max sizing values for one axis, and unifies the logic to resolve the final size into there. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
28e330c9b6
commit
e2a0ac07ff
8 changed files with 311 additions and 343 deletions
|
@ -34,7 +34,7 @@ use crate::formatting_contexts::{
|
|||
Baselines, IndependentFormattingContextContents, IndependentLayout,
|
||||
};
|
||||
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags};
|
||||
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, Size};
|
||||
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, Size, Sizes};
|
||||
use crate::positioned::{
|
||||
relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength,
|
||||
};
|
||||
|
@ -1957,20 +1957,22 @@ impl FlexItem<'_> {
|
|||
let item_style = independent_formatting_context.style();
|
||||
match &independent_formatting_context.contents {
|
||||
IndependentFormattingContextContents::Replaced(replaced) => {
|
||||
let min_size = flex_axis.vec2_to_flow_relative(self.content_min_size);
|
||||
let max_size = flex_axis.vec2_to_flow_relative(self.content_max_size);
|
||||
let size = replaced.used_size_as_if_inline_element_from_content_box_sizes(
|
||||
containing_block,
|
||||
item_style,
|
||||
self.preferred_aspect_ratio,
|
||||
LogicalVec2 {
|
||||
inline: Size::Numeric(inline_size),
|
||||
block: block_size.non_auto().map_or(Size::Initial, Size::Numeric),
|
||||
},
|
||||
flex_axis
|
||||
.vec2_to_flow_relative(self.content_min_size)
|
||||
.map(|size| Size::Numeric(*size)),
|
||||
flex_axis
|
||||
.vec2_to_flow_relative(self.content_max_size)
|
||||
.map(|size| size.map_or(Size::Initial, Size::Numeric)),
|
||||
&Sizes::new(
|
||||
block_size.non_auto().map_or(Size::Initial, Size::Numeric),
|
||||
Size::Numeric(min_size.block),
|
||||
max_size.block.map_or(Size::Initial, Size::Numeric),
|
||||
),
|
||||
&Sizes::new(
|
||||
Size::Numeric(inline_size),
|
||||
Size::Numeric(min_size.inline),
|
||||
max_size.inline.map_or(Size::Initial, Size::Numeric),
|
||||
),
|
||||
flex_axis.vec2_to_flow_relative(self.pbm_auto_is_zero),
|
||||
);
|
||||
let hypothetical_cross_size = flex_axis.vec2_to_flex_relative(size).cross;
|
||||
|
@ -2777,10 +2779,22 @@ impl FlexItemBox {
|
|||
flex_context.containing_block,
|
||||
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)),
|
||||
max_size.map(|size| size.map_or(Size::Initial, Size::Numeric)),
|
||||
&Sizes::new(
|
||||
content_box_size
|
||||
.block
|
||||
.non_auto()
|
||||
.map_or(Size::Initial, Size::Numeric),
|
||||
Size::Numeric(min_size.block),
|
||||
max_size.block.map_or(Size::Initial, Size::Numeric),
|
||||
),
|
||||
&Sizes::new(
|
||||
content_box_size
|
||||
.inline
|
||||
.non_auto()
|
||||
.map_or(Size::Initial, Size::Numeric),
|
||||
Size::Numeric(min_size.inline),
|
||||
max_size.inline.map_or(Size::Initial, Size::Numeric),
|
||||
),
|
||||
padding_border_margin.padding_border_sums +
|
||||
padding_border_margin.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
//! Flow layout, also known as block-and-inline layout.
|
||||
|
||||
use std::cell::LazyCell;
|
||||
|
||||
use app_units::Au;
|
||||
use inline::InlineFormattingContext;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
|
@ -35,7 +33,7 @@ use crate::fragment_tree::{
|
|||
};
|
||||
use crate::geom::{
|
||||
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
|
||||
Size, ToLogical, ToLogicalWithContainingBlock,
|
||||
Size, Sizes, ToLogical, ToLogicalWithContainingBlock,
|
||||
};
|
||||
use crate::layout_box_base::LayoutBoxBase;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
|
@ -796,9 +794,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
|
|||
let ContainingBlockPaddingAndBorder {
|
||||
containing_block: containing_block_for_children,
|
||||
pbm,
|
||||
preferred_block_size,
|
||||
min_block_size,
|
||||
max_block_size,
|
||||
block_sizes,
|
||||
depends_on_block_constraints,
|
||||
available_block_size,
|
||||
} = solve_containing_block_padding_and_border_for_in_flow_box(
|
||||
|
@ -939,16 +935,12 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
|
|||
content_block_size += collapsible_margins_in_children.end.solve();
|
||||
}
|
||||
|
||||
let available_block_size = available_block_size.unwrap_or(content_block_size);
|
||||
let block_content_sizes = LazyCell::new(|| content_block_size.into());
|
||||
let preferred_block_size =
|
||||
preferred_block_size.resolve(Size::FitContent, available_block_size, &block_content_sizes);
|
||||
let min_block_size = min_block_size
|
||||
.resolve_non_initial(available_block_size, &block_content_sizes)
|
||||
.unwrap_or_default();
|
||||
let max_block_size =
|
||||
max_block_size.resolve_non_initial(available_block_size, &block_content_sizes);
|
||||
let block_size = preferred_block_size.clamp_between_extremums(min_block_size, max_block_size);
|
||||
let block_size = block_sizes.resolve(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
available_block_size.unwrap_or(content_block_size),
|
||||
|| content_block_size.into(),
|
||||
);
|
||||
|
||||
if let Some(ref mut sequential_layout_state) = sequential_layout_state {
|
||||
// Now that we're done laying out our children, we can restore the
|
||||
|
@ -1042,9 +1034,7 @@ impl IndependentNonReplacedContents {
|
|||
let ContainingBlockPaddingAndBorder {
|
||||
containing_block: containing_block_for_children,
|
||||
pbm,
|
||||
preferred_block_size,
|
||||
min_block_size,
|
||||
max_block_size,
|
||||
block_sizes,
|
||||
depends_on_block_constraints,
|
||||
available_block_size,
|
||||
} = solve_containing_block_padding_and_border_for_in_flow_box(
|
||||
|
@ -1063,21 +1053,12 @@ impl IndependentNonReplacedContents {
|
|||
let (block_size, inline_size) = match layout.content_inline_size_for_table {
|
||||
Some(inline_size) => (layout.content_block_size, inline_size),
|
||||
None => {
|
||||
let available_block_size =
|
||||
available_block_size.unwrap_or(layout.content_block_size);
|
||||
let block_content_sizes = LazyCell::new(|| layout.content_block_size.into());
|
||||
let preferred_block_size = preferred_block_size.resolve(
|
||||
let block_size = block_sizes.resolve(
|
||||
Size::FitContent,
|
||||
available_block_size,
|
||||
&block_content_sizes,
|
||||
Au::zero(),
|
||||
available_block_size.unwrap_or(layout.content_block_size),
|
||||
|| layout.content_block_size.into(),
|
||||
);
|
||||
let min_block_size = min_block_size
|
||||
.resolve_non_initial(available_block_size, &block_content_sizes)
|
||||
.unwrap_or_default();
|
||||
let max_block_size =
|
||||
max_block_size.resolve_non_initial(available_block_size, &block_content_sizes);
|
||||
let block_size =
|
||||
preferred_block_size.clamp_between_extremums(min_block_size, max_block_size);
|
||||
(block_size, containing_block_for_children.size.inline)
|
||||
},
|
||||
};
|
||||
|
@ -1137,9 +1118,7 @@ impl IndependentNonReplacedContents {
|
|||
let style = &base.style;
|
||||
let containing_block_writing_mode = containing_block.style.writing_mode;
|
||||
let ContentBoxSizesAndPBM {
|
||||
content_box_size,
|
||||
content_min_box_size,
|
||||
content_max_box_size,
|
||||
content_box_sizes,
|
||||
pbm,
|
||||
depends_on_block_constraints,
|
||||
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
|
@ -1181,21 +1160,14 @@ impl IndependentNonReplacedContents {
|
|||
.block
|
||||
.non_auto()
|
||||
.map(|block_size| Au::zero().max(block_size - pbm_sums.block_sum()));
|
||||
let preferred_block_size = content_box_size
|
||||
let (preferred_block_size, min_block_size, max_block_size) = content_box_sizes
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
let min_block_size = content_min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size)
|
||||
.unwrap_or_default();
|
||||
let max_block_size = content_max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
.resolve_each_extrinsic(Size::FitContent, Au::zero(), available_block_size);
|
||||
let tentative_block_size =
|
||||
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size);
|
||||
|
||||
// With the tentative block size we can compute the inline min/max-content sizes.
|
||||
let inline_content_sizes = LazyCell::new(|| {
|
||||
let get_inline_content_sizes = || {
|
||||
let constraint_space = ConstraintSpace::new(
|
||||
tentative_block_size,
|
||||
style.writing_mode,
|
||||
|
@ -1203,55 +1175,29 @@ impl IndependentNonReplacedContents {
|
|||
);
|
||||
base.inline_content_sizes(layout_context, &constraint_space, self)
|
||||
.sizes
|
||||
});
|
||||
};
|
||||
|
||||
// The final inline size can depend on the available space, which depends on where
|
||||
// we are placing the box, since floats reduce the available space.
|
||||
// TODO: this logic could be refined further, since even if some of the 3 sizes
|
||||
// depends on the available space, the resulting size might not. For example,
|
||||
// `min-width: 200px; width: 100px; max-width: stretch`.
|
||||
let inline_size_depends_on_available_space = matches!(
|
||||
content_box_size.inline,
|
||||
Size::Initial | Size::Stretch | Size::FitContent
|
||||
) || matches!(
|
||||
content_min_box_size.inline,
|
||||
Size::Stretch | Size::FitContent
|
||||
) || matches!(
|
||||
content_max_box_size.inline,
|
||||
Size::Stretch | Size::FitContent
|
||||
);
|
||||
let compute_inline_size = |stretch_size| {
|
||||
let preferred_inline_size =
|
||||
content_box_size
|
||||
.inline
|
||||
.resolve(Size::Stretch, stretch_size, &inline_content_sizes);
|
||||
let min_inline_size = content_min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(stretch_size, &inline_content_sizes)
|
||||
.unwrap_or_default();
|
||||
let max_inline_size = content_max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(stretch_size, &inline_content_sizes);
|
||||
preferred_inline_size.clamp_between_extremums(min_inline_size, max_inline_size)
|
||||
content_box_sizes.inline.resolve(
|
||||
Size::Stretch,
|
||||
Au::zero(),
|
||||
stretch_size,
|
||||
get_inline_content_sizes,
|
||||
)
|
||||
};
|
||||
|
||||
let compute_block_size = |layout: &IndependentLayout| {
|
||||
let stretch_size = available_block_size.unwrap_or(layout.content_block_size);
|
||||
let block_contents_size = LazyCell::new(|| layout.content_block_size.into());
|
||||
let min_block_size = content_min_box_size
|
||||
.block
|
||||
.resolve_non_initial(stretch_size, &block_contents_size)
|
||||
.unwrap_or_default();
|
||||
let max_block_size = content_max_box_size
|
||||
.block
|
||||
.resolve_non_initial(stretch_size, &block_contents_size);
|
||||
tentative_block_size
|
||||
.to_definite()
|
||||
.unwrap_or(layout.content_block_size)
|
||||
.clamp_between_extremums(min_block_size, max_block_size)
|
||||
content_box_sizes.block.resolve(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
available_block_size.unwrap_or(layout.content_block_size),
|
||||
|| layout.content_block_size.into(),
|
||||
)
|
||||
};
|
||||
|
||||
if !inline_size_depends_on_available_space {
|
||||
// The final inline size can depend on the available space, which depends on where
|
||||
// we are placing the box, since floats reduce the available space.
|
||||
if !content_box_sizes.inline.depends_on_available_space() {
|
||||
// If the inline size doesn't depend on the available inline space, we can just
|
||||
// compute it with an available inline space of zero. Then, after layout we can
|
||||
// compute the block size, and finally place among floats.
|
||||
|
@ -1591,9 +1537,7 @@ impl ReplacedContents {
|
|||
struct ContainingBlockPaddingAndBorder<'a> {
|
||||
containing_block: ContainingBlock<'a>,
|
||||
pbm: PaddingBorderMargin,
|
||||
preferred_block_size: Size<Au>,
|
||||
min_block_size: Size<Au>,
|
||||
max_block_size: Size<Au>,
|
||||
block_sizes: Sizes,
|
||||
depends_on_block_constraints: bool,
|
||||
available_block_size: Option<Au>,
|
||||
}
|
||||
|
@ -1637,9 +1581,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
|
|||
return ContainingBlockPaddingAndBorder {
|
||||
containing_block: containing_block_for_children,
|
||||
pbm: PaddingBorderMargin::zero(),
|
||||
preferred_block_size: Size::default(),
|
||||
min_block_size: Size::default(),
|
||||
max_block_size: Size::default(),
|
||||
block_sizes: Sizes::default(),
|
||||
depends_on_block_constraints: false,
|
||||
// The available block size may actually be definite, but it should be irrelevant
|
||||
// since the sizing properties are set to their initial value.
|
||||
|
@ -1648,9 +1590,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
|
|||
}
|
||||
|
||||
let ContentBoxSizesAndPBM {
|
||||
content_box_size,
|
||||
content_min_box_size,
|
||||
content_max_box_size,
|
||||
content_box_sizes,
|
||||
pbm,
|
||||
depends_on_block_constraints,
|
||||
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
|
@ -1668,42 +1608,27 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
|
|||
|
||||
// https://drafts.csswg.org/css2/#the-height-property
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-heights
|
||||
let preferred_block_size = content_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
let min_block_size = content_min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size)
|
||||
.unwrap_or_default();
|
||||
let max_block_size = content_max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
let tentative_block_size =
|
||||
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size);
|
||||
let tentative_block_size = content_box_sizes.block.resolve_extrinsic(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
available_block_size,
|
||||
);
|
||||
|
||||
// https://drafts.csswg.org/css2/#the-width-property
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||
let inline_content_sizes = LazyCell::new(|| {
|
||||
let get_inline_content_sizes = || {
|
||||
get_inline_content_sizes(&ConstraintSpace::new(
|
||||
tentative_block_size,
|
||||
writing_mode,
|
||||
None, /* TODO: support preferred aspect ratios on non-replaced boxes */
|
||||
))
|
||||
});
|
||||
let preferred_inline_size = content_box_size.inline.resolve(
|
||||
};
|
||||
let inline_size = content_box_sizes.inline.resolve(
|
||||
Size::Stretch,
|
||||
Au::zero(),
|
||||
available_inline_size,
|
||||
&inline_content_sizes,
|
||||
get_inline_content_sizes,
|
||||
);
|
||||
let min_inline_size = content_min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(available_inline_size, &inline_content_sizes)
|
||||
.unwrap_or_default();
|
||||
let max_inline_size = content_max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(available_inline_size, &inline_content_sizes);
|
||||
let inline_size =
|
||||
preferred_inline_size.clamp_between_extremums(min_inline_size, max_inline_size);
|
||||
|
||||
let containing_block_for_children = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
|
@ -1724,9 +1649,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
|
|||
ContainingBlockPaddingAndBorder {
|
||||
containing_block: containing_block_for_children,
|
||||
pbm,
|
||||
preferred_block_size: content_box_size.block,
|
||||
min_block_size: content_min_box_size.block,
|
||||
max_block_size: content_max_box_size.block,
|
||||
block_sizes: content_box_sizes.block,
|
||||
depends_on_block_constraints,
|
||||
available_block_size,
|
||||
}
|
||||
|
@ -2182,23 +2105,12 @@ impl IndependentFormattingContext {
|
|||
.block
|
||||
.non_auto()
|
||||
.map(|block_size| (block_size - pbm_sums.block_sum()).max(Au::zero()));
|
||||
let preferred_block_size = content_box_sizes_and_pbm
|
||||
.content_box_size
|
||||
let tentative_block_size = content_box_sizes_and_pbm
|
||||
.content_box_sizes
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
let min_block_size = content_box_sizes_and_pbm
|
||||
.content_min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size)
|
||||
.unwrap_or_default();
|
||||
let max_block_size = content_box_sizes_and_pbm
|
||||
.content_max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
let tentative_block_size =
|
||||
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size);
|
||||
.resolve_extrinsic(Size::FitContent, Au::zero(), available_block_size);
|
||||
|
||||
let content_size = LazyCell::new(|| {
|
||||
let get_content_size = || {
|
||||
let constraint_space = ConstraintSpace::new(
|
||||
tentative_block_size,
|
||||
writing_mode,
|
||||
|
@ -2206,29 +2118,14 @@ impl IndependentFormattingContext {
|
|||
);
|
||||
self.inline_content_sizes(layout_context, &constraint_space)
|
||||
.sizes
|
||||
});
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#float-width
|
||||
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
|
||||
let tentative_inline_size = content_box_sizes_and_pbm
|
||||
.content_box_size
|
||||
.inline
|
||||
.resolve(Size::FitContent, available_inline_size, &content_size);
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||
// In this case “applying the rules above again” with a non-auto inline-size
|
||||
// always results in that size.
|
||||
let min_inline_size = content_box_sizes_and_pbm
|
||||
.content_min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(available_inline_size, &content_size)
|
||||
.unwrap_or_default();
|
||||
let max_inline_size = content_box_sizes_and_pbm
|
||||
.content_max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(available_inline_size, &content_size);
|
||||
let inline_size =
|
||||
tentative_inline_size.clamp_between_extremums(min_inline_size, max_inline_size);
|
||||
let inline_size = content_box_sizes_and_pbm.content_box_sizes.inline.resolve(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
available_inline_size,
|
||||
get_content_size,
|
||||
);
|
||||
|
||||
let containing_block_for_children = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
|
@ -2249,31 +2146,21 @@ impl IndependentFormattingContext {
|
|||
&containing_block_for_children,
|
||||
containing_block,
|
||||
);
|
||||
let (inline_size, block_size) =
|
||||
match independent_layout.content_inline_size_for_table {
|
||||
Some(inline) => (inline, independent_layout.content_block_size),
|
||||
None => {
|
||||
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
||||
let stretch_size = available_block_size
|
||||
.unwrap_or(independent_layout.content_block_size);
|
||||
let content_size =
|
||||
LazyCell::new(|| independent_layout.content_block_size.into());
|
||||
let min_block_size = content_box_sizes_and_pbm
|
||||
.content_min_box_size
|
||||
.block
|
||||
.resolve_non_initial(stretch_size, &content_size)
|
||||
.unwrap_or_default();
|
||||
let max_block_size = content_box_sizes_and_pbm
|
||||
.content_max_box_size
|
||||
.block
|
||||
.resolve_non_initial(stretch_size, &content_size);
|
||||
let block_size = tentative_block_size
|
||||
.to_definite()
|
||||
.unwrap_or(independent_layout.content_block_size)
|
||||
.clamp_between_extremums(min_block_size, max_block_size);
|
||||
(inline_size, block_size)
|
||||
},
|
||||
};
|
||||
let (inline_size, block_size) = match independent_layout
|
||||
.content_inline_size_for_table
|
||||
{
|
||||
Some(inline) => (inline, independent_layout.content_block_size),
|
||||
None => {
|
||||
// https://drafts.csswg.org/css2/visudet.html#block-root-margin
|
||||
let block_size = content_box_sizes_and_pbm.content_box_sizes.block.resolve(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
available_block_size.unwrap_or(independent_layout.content_block_size),
|
||||
|| independent_layout.content_block_size.into(),
|
||||
);
|
||||
(inline_size, block_size)
|
||||
},
|
||||
};
|
||||
|
||||
let content_size = LogicalVec2 {
|
||||
block: block_size,
|
||||
|
|
|
@ -870,3 +870,122 @@ impl SizeConstraint {
|
|||
.map_or(AutoOr::Auto, AutoOr::LengthPercentage)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct Sizes {
|
||||
/// <https://drafts.csswg.org/css-sizing-3/#preferred-size-properties>
|
||||
pub preferred: Size<Au>,
|
||||
/// <https://drafts.csswg.org/css-sizing-3/#min-size-properties>
|
||||
pub min: Size<Au>,
|
||||
/// <https://drafts.csswg.org/css-sizing-3/#max-size-properties>
|
||||
pub max: Size<Au>,
|
||||
}
|
||||
|
||||
impl Sizes {
|
||||
#[inline]
|
||||
pub(crate) fn new(preferred: Size<Au>, min: Size<Au>, max: Size<Au>) -> Self {
|
||||
Self {
|
||||
preferred,
|
||||
min,
|
||||
max,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn depends_on_available_space(&self) -> bool {
|
||||
// TODO: this logic could be refined further, since even if some of the 3 sizes
|
||||
// depends on the available space, the resulting size might not. For example,
|
||||
// `min-width: 200px; width: 100px; max-width: stretch`.
|
||||
matches!(
|
||||
self.preferred,
|
||||
Size::Initial | Size::Stretch | Size::FitContent
|
||||
) || matches!(self.min, Size::Stretch | Size::FitContent) ||
|
||||
matches!(self.max, Size::Stretch | Size::FitContent)
|
||||
}
|
||||
|
||||
/// Resolves the three sizes into a single numerical value.
|
||||
#[inline]
|
||||
pub(crate) fn resolve(
|
||||
&self,
|
||||
automatic_size: Size<Au>,
|
||||
automatic_minimum_size: Au,
|
||||
stretch_size: Au,
|
||||
get_content_size: impl FnOnce() -> ContentSizes,
|
||||
) -> Au {
|
||||
let (preferred, min, max) = self.resolve_each(
|
||||
automatic_size,
|
||||
automatic_minimum_size,
|
||||
stretch_size,
|
||||
get_content_size,
|
||||
);
|
||||
preferred.clamp_between_extremums(min, max)
|
||||
}
|
||||
|
||||
/// Resolves each of the three sizes into a numerical value, separately.
|
||||
#[inline]
|
||||
pub(crate) fn resolve_each(
|
||||
&self,
|
||||
automatic_size: Size<Au>,
|
||||
automatic_minimum_size: Au,
|
||||
stretch_size: Au,
|
||||
get_content_size: impl FnOnce() -> ContentSizes,
|
||||
) -> (Au, Au, Option<Au>) {
|
||||
// The provided `get_content_size` is a FnOnce but we may need its result multiple times.
|
||||
// A LazyCell will only invoke it once if needed, and then reuse the result.
|
||||
let content_size = LazyCell::new(get_content_size);
|
||||
(
|
||||
self.preferred
|
||||
.resolve(automatic_size, stretch_size, &content_size),
|
||||
self.min
|
||||
.resolve_non_initial(stretch_size, &content_size)
|
||||
.unwrap_or(automatic_minimum_size),
|
||||
self.max.resolve_non_initial(stretch_size, &content_size),
|
||||
)
|
||||
}
|
||||
|
||||
/// Tries to extrinsically resolve the three sizes into a single [`SizeConstraint`].
|
||||
/// Values that are intrinsic or need `stretch_size` when it's `None` are handled as such:
|
||||
/// - On the preferred size, they make the returned value be an indefinite [`SizeConstraint::MinMax`].
|
||||
/// - On the min size, they are treated as `auto`, enforcing the automatic minimum size.
|
||||
/// - On the max size, they are treated as `none`, enforcing no maximum.
|
||||
#[inline]
|
||||
pub(crate) fn resolve_extrinsic(
|
||||
&self,
|
||||
automatic_size: Size<Au>,
|
||||
automatic_minimum_size: Au,
|
||||
stretch_size: Option<Au>,
|
||||
) -> SizeConstraint {
|
||||
let (preferred, min, max) =
|
||||
self.resolve_each_extrinsic(automatic_size, automatic_minimum_size, stretch_size);
|
||||
SizeConstraint::new(preferred, min, max)
|
||||
}
|
||||
|
||||
/// Tries to extrinsically resolve each of the three sizes into a numerical value, separately.
|
||||
/// This can't resolve values that are intrinsic or need `stretch_size` but it's `None`.
|
||||
/// - The 1st returned value is the resolved preferred size. If it can't be resolved then
|
||||
/// the returned value is `None`. Note that this is different than treating it as `auto`.
|
||||
/// TODO: This needs to be discussed in <https://github.com/w3c/csswg-drafts/issues/11387>.
|
||||
/// - The 2nd returned value is the resolved minimum size. If it can't be resolved then we
|
||||
/// treat it as the initial `auto`, returning the automatic minimum size.
|
||||
/// - The 3rd returned value is the resolved maximum size. If it can't be resolved then we
|
||||
/// treat it as the initial `none`, returning `None`.
|
||||
#[inline]
|
||||
pub(crate) fn resolve_each_extrinsic(
|
||||
&self,
|
||||
automatic_size: Size<Au>,
|
||||
automatic_minimum_size: Au,
|
||||
stretch_size: Option<Au>,
|
||||
) -> (Option<Au>, Au, Option<Au>) {
|
||||
(
|
||||
if self.preferred.is_initial() {
|
||||
automatic_size.maybe_resolve_extrinsic(stretch_size)
|
||||
} else {
|
||||
self.preferred.maybe_resolve_extrinsic(stretch_size)
|
||||
},
|
||||
self.min
|
||||
.maybe_resolve_extrinsic(stretch_size)
|
||||
.unwrap_or(automatic_minimum_size),
|
||||
self.max.maybe_resolve_extrinsic(stretch_size),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::LazyCell;
|
||||
use std::mem;
|
||||
|
||||
use app_units::Au;
|
||||
|
@ -28,10 +27,10 @@ use crate::fragment_tree::{
|
|||
};
|
||||
use crate::geom::{
|
||||
AuOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint,
|
||||
PhysicalRect, PhysicalVec, Size, ToLogical, ToLogicalWithContainingBlock,
|
||||
PhysicalRect, PhysicalVec, Size, Sizes, ToLogical, ToLogicalWithContainingBlock,
|
||||
};
|
||||
use crate::sizing::ContentSizes;
|
||||
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
||||
use crate::style_ext::{ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside};
|
||||
use crate::{
|
||||
ConstraintSpace, ContainingBlock, ContainingBlockSize, DefiniteContainingBlock, SizeConstraint,
|
||||
};
|
||||
|
@ -460,11 +459,12 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
let absolutely_positioned_box = self.absolutely_positioned_box.borrow();
|
||||
let context = &absolutely_positioned_box.context;
|
||||
let style = context.style().clone();
|
||||
let ContentBoxSizesAndPBM {
|
||||
content_box_sizes,
|
||||
pbm,
|
||||
..
|
||||
} = style.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
let containing_block = &containing_block.into();
|
||||
let pbm = style.padding_border_margin(containing_block);
|
||||
let computed_size = style.content_box_size(containing_block, &pbm);
|
||||
let computed_min_size = style.content_min_box_size(containing_block, &pbm);
|
||||
let computed_max_size = style.content_max_box_size(containing_block, &pbm);
|
||||
|
||||
let shared_fragment = self.fragment.borrow();
|
||||
let static_position_rect = shared_fragment
|
||||
|
@ -489,9 +489,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
padding_border_sum: pbm.padding_border_sums.inline,
|
||||
computed_margin_start: pbm.margin.inline_start,
|
||||
computed_margin_end: pbm.margin.inline_end,
|
||||
computed_size: computed_size.inline,
|
||||
computed_min_size: computed_min_size.inline,
|
||||
computed_max_size: computed_max_size.inline,
|
||||
computed_sizes: content_box_sizes.inline,
|
||||
avoid_negative_margin_start: true,
|
||||
box_offsets: inline_box_offsets,
|
||||
static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Inline),
|
||||
|
@ -515,9 +513,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
padding_border_sum: pbm.padding_border_sums.block,
|
||||
computed_margin_start: pbm.margin.block_start,
|
||||
computed_margin_end: pbm.margin.block_end,
|
||||
computed_size: computed_size.block,
|
||||
computed_min_size: computed_min_size.block,
|
||||
computed_max_size: computed_max_size.block,
|
||||
computed_sizes: content_box_sizes.block,
|
||||
avoid_negative_margin_start: false,
|
||||
box_offsets: block_box_offsets,
|
||||
static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Block),
|
||||
|
@ -536,9 +532,8 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
containing_block,
|
||||
&style,
|
||||
context.preferred_aspect_ratio(&pbm.padding_border_sums),
|
||||
computed_size,
|
||||
computed_min_size,
|
||||
computed_max_size,
|
||||
&block_axis_solver.computed_sizes,
|
||||
&inline_axis_solver.computed_sizes,
|
||||
pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum() + inset_sums,
|
||||
);
|
||||
inline_axis_solver.override_size(used_size.inline);
|
||||
|
@ -746,9 +741,7 @@ struct AbsoluteAxisSolver<'a> {
|
|||
padding_border_sum: Au,
|
||||
computed_margin_start: AuOrAuto,
|
||||
computed_margin_end: AuOrAuto,
|
||||
computed_size: Size<Au>,
|
||||
computed_min_size: Size<Au>,
|
||||
computed_max_size: Size<Au>,
|
||||
computed_sizes: Sizes,
|
||||
avoid_negative_margin_start: bool,
|
||||
box_offsets: AbsoluteBoxOffsets<'a>,
|
||||
static_position_rect_axis: RectAxis,
|
||||
|
@ -795,40 +788,21 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
///
|
||||
/// In the replaced case, `size` is never `Auto`.
|
||||
fn solve(&self, get_content_size: Option<impl FnOnce() -> ContentSizes>) -> AxisResult {
|
||||
// The provided `get_content_size` is a FnOnce but we may need its result multiple times.
|
||||
// A LazyCell will only invoke it once if needed, and then reuse the result.
|
||||
let content_size = get_content_size.map(LazyCell::new);
|
||||
let solve_size = |initial_behavior, stretch_size: Au| -> SizeConstraint {
|
||||
let stretch_size = stretch_size.max(Au::zero());
|
||||
if let Some(ref content_size) = content_size {
|
||||
let preferred_size = Some(self.computed_size.resolve(
|
||||
if let Some(get_content_size) = get_content_size {
|
||||
SizeConstraint::Definite(self.computed_sizes.resolve(
|
||||
initial_behavior,
|
||||
Au::zero(),
|
||||
stretch_size,
|
||||
content_size,
|
||||
));
|
||||
let min_size = self
|
||||
.computed_min_size
|
||||
.resolve_non_initial(stretch_size, content_size)
|
||||
.unwrap_or_default();
|
||||
let max_size = self
|
||||
.computed_max_size
|
||||
.resolve_non_initial(stretch_size, content_size);
|
||||
SizeConstraint::new(preferred_size, min_size, max_size)
|
||||
get_content_size,
|
||||
))
|
||||
} else {
|
||||
let preferred_size = if self.computed_size.is_initial() {
|
||||
initial_behavior
|
||||
} else {
|
||||
self.computed_size
|
||||
}
|
||||
.maybe_resolve_extrinsic(Some(stretch_size));
|
||||
let min_size = self
|
||||
.computed_min_size
|
||||
.maybe_resolve_extrinsic(Some(stretch_size))
|
||||
.unwrap_or_default();
|
||||
let max_size = self
|
||||
.computed_max_size
|
||||
.maybe_resolve_extrinsic(Some(stretch_size));
|
||||
SizeConstraint::new(preferred_size, min_size, max_size)
|
||||
self.computed_sizes.resolve_extrinsic(
|
||||
initial_behavior,
|
||||
Au::zero(),
|
||||
Some(stretch_size),
|
||||
)
|
||||
}
|
||||
};
|
||||
if self.box_offsets.either_auto() {
|
||||
|
@ -891,9 +865,9 @@ impl<'a> AbsoluteAxisSolver<'a> {
|
|||
}
|
||||
|
||||
fn override_size(&mut self, size: Au) {
|
||||
self.computed_size = Size::Numeric(size);
|
||||
self.computed_min_size = Size::default();
|
||||
self.computed_max_size = Size::default();
|
||||
self.computed_sizes.preferred = Size::Numeric(size);
|
||||
self.computed_sizes.min = Size::default();
|
||||
self.computed_sizes.max = Size::default();
|
||||
}
|
||||
|
||||
fn origin_for_margin_box(
|
||||
|
|
|
@ -30,7 +30,7 @@ use webrender_api::ImageKey;
|
|||
use crate::context::LayoutContext;
|
||||
use crate::dom::NodeExt;
|
||||
use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment};
|
||||
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size};
|
||||
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
|
||||
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
|
||||
|
@ -439,9 +439,8 @@ impl ReplacedContents {
|
|||
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,
|
||||
&content_box_sizes_and_pbm.content_box_sizes.block,
|
||||
&content_box_sizes_and_pbm.content_box_sizes.inline,
|
||||
pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
}
|
||||
|
@ -481,15 +480,13 @@ impl ReplacedContents {
|
|||
///
|
||||
/// <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>>,
|
||||
block_sizes: &Sizes,
|
||||
inline_sizes: &Sizes,
|
||||
pbm_sums: LogicalVec2<Au>,
|
||||
) -> LogicalVec2<Au> {
|
||||
// <https://drafts.csswg.org/css-images-3/#natural-dimensions>
|
||||
|
@ -520,19 +517,9 @@ impl ReplacedContents {
|
|||
// First, compute the inline size. Intrinsic values depend on the block sizing properties
|
||||
// through the aspect ratio, but these can also be intrinsic and depend on the inline size.
|
||||
// Therefore, we tentatively treat intrinsic block sizing properties as their initial value.
|
||||
let inline_content_size = LazyCell::new(|| {
|
||||
let get_block_size = || {
|
||||
SizeConstraint::new(
|
||||
box_size.block.maybe_resolve_extrinsic(block_stretch_size),
|
||||
min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(block_stretch_size)
|
||||
.unwrap_or_default(),
|
||||
max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(block_stretch_size),
|
||||
)
|
||||
};
|
||||
let get_inline_content_size = || {
|
||||
let get_block_size =
|
||||
|| block_sizes.resolve_extrinsic(Size::FitContent, Au::zero(), block_stretch_size);
|
||||
self.content_size(
|
||||
Direction::Inline,
|
||||
preferred_aspect_ratio,
|
||||
|
@ -540,24 +527,19 @@ impl ReplacedContents {
|
|||
&get_inline_fallback_size,
|
||||
)
|
||||
.into()
|
||||
});
|
||||
let preferred_inline =
|
||||
box_size
|
||||
.inline
|
||||
.resolve(Size::FitContent, inline_stretch_size, &inline_content_size);
|
||||
let min_inline = min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &inline_content_size)
|
||||
.unwrap_or_default();
|
||||
let max_inline = max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &inline_content_size);
|
||||
};
|
||||
let (preferred_inline, min_inline, max_inline) = inline_sizes.resolve_each(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
inline_stretch_size,
|
||||
get_inline_content_size,
|
||||
);
|
||||
let inline_size = preferred_inline.clamp_between_extremums(min_inline, max_inline);
|
||||
|
||||
// Now we can compute the block size, using the inline size from above.
|
||||
let block_content_size = LazyCell::new(|| -> ContentSizes {
|
||||
let get_inline_size = || {
|
||||
if box_size.inline.is_initial() {
|
||||
if inline_sizes.preferred.is_initial() {
|
||||
// TODO: do we really need to special-case `auto`?
|
||||
// https://github.com/w3c/csswg-drafts/issues/11236
|
||||
SizeConstraint::MinMax(min_inline, max_inline)
|
||||
|
@ -573,20 +555,12 @@ impl ReplacedContents {
|
|||
)
|
||||
.into()
|
||||
});
|
||||
let block_stretch_size =
|
||||
block_stretch_size.unwrap_or_else(|| block_content_size.max_content);
|
||||
let preferred_block =
|
||||
box_size
|
||||
.block
|
||||
.resolve(Size::FitContent, block_stretch_size, &block_content_size);
|
||||
let min_block = min_box_size
|
||||
.block
|
||||
.resolve_non_initial(block_stretch_size, &block_content_size)
|
||||
.unwrap_or_default();
|
||||
let max_block = max_box_size
|
||||
.block
|
||||
.resolve_non_initial(block_stretch_size, &block_content_size);
|
||||
let block_size = preferred_block.clamp_between_extremums(min_block, max_block);
|
||||
let block_size = block_sizes.resolve(
|
||||
Size::FitContent,
|
||||
Au::zero(),
|
||||
block_stretch_size.unwrap_or_else(|| block_content_size.max_content),
|
||||
|| *block_content_size,
|
||||
);
|
||||
|
||||
LogicalVec2 {
|
||||
inline: inline_size,
|
||||
|
|
|
@ -15,7 +15,7 @@ use style::Zero;
|
|||
use crate::context::LayoutContext;
|
||||
use crate::geom::Size;
|
||||
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
|
||||
use crate::{ConstraintSpace, IndefiniteContainingBlock, LogicalVec2, SizeConstraint};
|
||||
use crate::{ConstraintSpace, IndefiniteContainingBlock, LogicalVec2};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub(crate) enum IntrinsicSizingMode {
|
||||
|
@ -118,9 +118,7 @@ pub(crate) fn outer_inline(
|
|||
get_content_size: impl FnOnce(&ConstraintSpace) -> InlineContentSizesResult,
|
||||
) -> InlineContentSizesResult {
|
||||
let ContentBoxSizesAndPBM {
|
||||
content_box_size,
|
||||
content_min_box_size,
|
||||
content_max_box_size,
|
||||
content_box_sizes,
|
||||
pbm,
|
||||
mut depends_on_block_constraints,
|
||||
} = style.content_box_sizes_and_padding_border_margin(containing_block);
|
||||
|
@ -135,25 +133,20 @@ pub(crate) fn outer_inline(
|
|||
.block
|
||||
.non_auto()
|
||||
.map(|v| Au::zero().max(v - pbm_sums.block));
|
||||
let preferred_block_size = if content_box_size.block.is_initial() &&
|
||||
let automatic_size = if content_box_sizes.block.preferred.is_initial() &&
|
||||
auto_block_size_stretches_to_containing_block
|
||||
{
|
||||
depends_on_block_constraints = true;
|
||||
available_block_size
|
||||
Size::Stretch
|
||||
} else {
|
||||
content_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size)
|
||||
Size::FitContent
|
||||
};
|
||||
let min_block_size = content_min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size)
|
||||
.unwrap_or(auto_minimum.block);
|
||||
let max_block_size = content_max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(available_block_size);
|
||||
get_content_size(&ConstraintSpace::new(
|
||||
SizeConstraint::new(preferred_block_size, min_block_size, max_block_size),
|
||||
content_box_sizes.block.resolve_extrinsic(
|
||||
automatic_size,
|
||||
auto_minimum.block,
|
||||
available_block_size,
|
||||
),
|
||||
style.writing_mode,
|
||||
get_preferred_aspect_ratio(&pbm.padding_border_sums),
|
||||
))
|
||||
|
@ -180,14 +173,14 @@ pub(crate) fn outer_inline(
|
|||
})
|
||||
};
|
||||
let (preferred_min_content, preferred_max_content, preferred_depends_on_block_constraints) =
|
||||
resolve_non_initial(content_box_size.inline)
|
||||
resolve_non_initial(content_box_sizes.inline.preferred)
|
||||
.unwrap_or_else(|| resolve_non_initial(Size::FitContent).unwrap());
|
||||
let (min_min_content, min_max_content, min_depends_on_block_constraints) = resolve_non_initial(
|
||||
content_min_box_size.inline,
|
||||
content_box_sizes.inline.min,
|
||||
)
|
||||
.unwrap_or((auto_minimum.inline, auto_minimum.inline, false));
|
||||
let (max_min_content, max_max_content, max_depends_on_block_constraints) =
|
||||
resolve_non_initial(content_max_box_size.inline)
|
||||
resolve_non_initial(content_box_sizes.inline.max)
|
||||
.map(|(min_content, max_content, depends_on_block_constraints)| {
|
||||
(
|
||||
Some(min_content),
|
||||
|
|
|
@ -29,7 +29,7 @@ use crate::dom_traversal::Contents;
|
|||
use crate::fragment_tree::FragmentFlags;
|
||||
use crate::geom::{
|
||||
AuOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize,
|
||||
PhysicalVec, Size,
|
||||
PhysicalVec, Size, Sizes,
|
||||
};
|
||||
use crate::{ContainingBlock, IndefiniteContainingBlock};
|
||||
|
||||
|
@ -189,9 +189,7 @@ impl AspectRatio {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ContentBoxSizesAndPBM {
|
||||
pub content_box_size: LogicalVec2<Size<Au>>,
|
||||
pub content_min_box_size: LogicalVec2<Size<Au>>,
|
||||
pub content_max_box_size: LogicalVec2<Size<Au>>,
|
||||
pub content_box_sizes: LogicalVec2<Sizes>,
|
||||
pub pbm: PaddingBorderMargin,
|
||||
pub depends_on_block_constraints: bool,
|
||||
}
|
||||
|
@ -199,9 +197,11 @@ pub(crate) struct ContentBoxSizesAndPBM {
|
|||
impl From<ContentBoxSizesAndPBM> for ContentBoxSizesAndPBMDeprecated {
|
||||
fn from(sizes: ContentBoxSizesAndPBM) -> Self {
|
||||
Self {
|
||||
content_box_size: sizes.content_box_size.map(Size::to_auto_or),
|
||||
content_min_box_size: sizes.content_min_box_size.map(Size::to_auto_or),
|
||||
content_max_box_size: sizes.content_max_box_size.map(Size::to_numeric),
|
||||
content_box_size: sizes
|
||||
.content_box_sizes
|
||||
.map(|size| size.preferred.to_auto_or()),
|
||||
content_min_box_size: sizes.content_box_sizes.map(|size| size.min.to_auto_or()),
|
||||
content_max_box_size: sizes.content_box_sizes.map(|size| size.max.to_numeric()),
|
||||
pbm: sizes.pbm.clone(),
|
||||
depends_on_block_constraints: sizes.depends_on_block_constraints,
|
||||
}
|
||||
|
@ -560,9 +560,18 @@ impl ComputedValuesExt for ComputedValues {
|
|||
.content_max_box_size_for_max_size(max_size, &pbm)
|
||||
.map(|v| v.map(Au::from));
|
||||
ContentBoxSizesAndPBM {
|
||||
content_box_size,
|
||||
content_min_box_size,
|
||||
content_max_box_size,
|
||||
content_box_sizes: LogicalVec2 {
|
||||
block: Sizes::new(
|
||||
content_box_size.block,
|
||||
content_min_box_size.block,
|
||||
content_max_box_size.block,
|
||||
),
|
||||
inline: Sizes::new(
|
||||
content_box_size.inline,
|
||||
content_min_box_size.inline,
|
||||
content_max_box_size.inline,
|
||||
),
|
||||
},
|
||||
pbm,
|
||||
depends_on_block_constraints,
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::formatting_contexts::{
|
|||
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment};
|
||||
use crate::geom::{
|
||||
LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
|
||||
SizeConstraint,
|
||||
SizeConstraint, Sizes,
|
||||
};
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
|
@ -155,18 +155,16 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
style,
|
||||
independent_context
|
||||
.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),
|
||||
},
|
||||
LogicalVec2 {
|
||||
inline: Size::Numeric(Au::zero()),
|
||||
block: Size::Numeric(Au::zero()),
|
||||
},
|
||||
LogicalVec2 {
|
||||
inline: Size::Initial,
|
||||
block: Size::Initial,
|
||||
},
|
||||
&Sizes::new(
|
||||
option_f32_to_size(content_box_known_dimensions.height),
|
||||
Size::Initial,
|
||||
Size::Initial,
|
||||
),
|
||||
&Sizes::new(
|
||||
option_f32_to_size(content_box_known_dimensions.width),
|
||||
Size::Initial,
|
||||
Size::Initial,
|
||||
),
|
||||
pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
.to_physical_size(self.style.writing_mode);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue