aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout_2020/flow/mod.rs')
-rw-r--r--components/layout_2020/flow/mod.rs259
1 files changed, 73 insertions, 186 deletions
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index d66ab0332a5..e94301391e2 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -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
- .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
+ let (preferred_block_size, min_block_size, max_block_size) = content_box_sizes
.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
- .block
- .maybe_resolve_extrinsic(available_block_size);
- let min_block_size = content_box_sizes_and_pbm
- .content_min_box_size
+ let tentative_block_size = content_box_sizes_and_pbm
+ .content_box_sizes
.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,