layout: Initial implementation of flex-direction: column and column-reverse (#33031)

This change removes restrictions on using the column layout mode of
flexbox and adds an initial implementation of sizing for that flex
direction. There's a lot of missing pieces still, but in some cases this
does render column flexbox.

In particular, there are now two code paths for preferred widths
(intrinsic size) calcuation: one in the main axis (row) and one in
the cross axis (column) corresponding to the flex direciton with
horizontal writing modes.

In addition, `FlexItemBox::inline_content_sizes` is removed in favor of
making `sizing::outer_inline` /
`IndependentFormattingContext::outer_inline_content_sizes` generic
enough to handle using a different value for auto minimum sizes, which
flexbox needs.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Martin Robinson 2024-08-14 16:25:09 +02:00 committed by GitHub
parent c059bab6f4
commit 7633bdccd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
124 changed files with 541 additions and 605 deletions

View file

@ -91,6 +91,7 @@ pub(crate) fn outer_inline(
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
get_content_size: impl FnOnce() -> ContentSizes,
get_auto_minimum: impl FnOnce() -> Au,
) -> ContentSizes {
let padding = style.padding(containing_block_writing_mode);
let border = style.border_width(containing_block_writing_mode);
@ -100,9 +101,11 @@ pub(crate) fn outer_inline(
// for determining intrinsic size contributions.
// https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution
let zero = Length::zero();
let pb_lengths = border.inline_sum() +
padding.inline_start.percentage_relative_to(zero) +
padding.inline_end.percentage_relative_to(zero);
let pb_lengths = Au::from(
border.inline_sum() +
padding.inline_start.percentage_relative_to(zero) +
padding.inline_end.percentage_relative_to(zero),
);
let mut m_lengths = zero;
if let Some(m) = margin.inline_start.non_auto() {
m_lengths += m.percentage_relative_to(zero)
@ -123,22 +126,21 @@ pub(crate) fn outer_inline(
.inline
// Percentages for 'min-width' are treated as zero
.percentage_relative_to(zero)
// FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero);
.map(Au::from)
.auto_is(get_auto_minimum);
let max_inline_size = style
.max_box_size(containing_block_writing_mode)
.inline
// Percentages for 'max-width' are treated as 'none'
.and_then(|lp| lp.to_length());
let clamp = |l: Au| {
l.clamp_between_extremums(min_inline_size.into(), max_inline_size.map(|t| t.into()))
};
.and_then(|lp| lp.to_length())
.map(Au::from);
let clamp = |l: Au| l.clamp_between_extremums(min_inline_size, max_inline_size);
let border_box_sizes = match inline_size {
Some(non_auto) => {
let clamped = clamp(non_auto.into());
let border_box_size = match box_sizing {
BoxSizing::ContentBox => clamped + pb_lengths.into(),
BoxSizing::ContentBox => clamped + pb_lengths,
BoxSizing::BorderBox => clamped,
};
ContentSizes {
@ -149,8 +151,8 @@ pub(crate) fn outer_inline(
None => get_content_size().map(|content_box_size| {
match box_sizing {
// Clamp to 'min-width' and 'max-width', which are sizing the…
BoxSizing::ContentBox => clamp(content_box_size) + pb_lengths.into(),
BoxSizing::BorderBox => clamp(content_box_size + pb_lengths.into()),
BoxSizing::ContentBox => clamp(content_box_size) + pb_lengths,
BoxSizing::BorderBox => clamp(content_box_size + pb_lengths),
}
}),
};