mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Layout: use Au
in ContentSizes
(#31135)
* use app_units * resolve errors in table layout * fmt * add back current_line.min_content * update expectation * review fix
This commit is contained in:
parent
bd25c07b22
commit
45af1198aa
8 changed files with 60 additions and 50 deletions
|
@ -30,7 +30,7 @@ use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment};
|
|||
use crate::geom::{AuOrAuto, LengthOrAuto, LogicalRect, LogicalSides, LogicalVec2};
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
use crate::sizing::ContentSizes;
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use crate::style_ext::{Clamp, ComputedValuesExt};
|
||||
use crate::ContainingBlock;
|
||||
|
||||
// FIMXE: “Flex items […] `z-index` values other than `auto` create a stacking context
|
||||
|
@ -479,8 +479,8 @@ impl<'a> FlexItem<'a> {
|
|||
.inline_size_over_block_size_intrinsic_ratio(box_.style())
|
||||
{
|
||||
inline_content_size.clamp_between_extremums(
|
||||
min_size.block.auto_is(|| Length::zero()) * ratio,
|
||||
max_size.block.map(|l| l * ratio),
|
||||
(min_size.block.auto_is(|| Length::zero()) * ratio).into(),
|
||||
max_size.block.map(|l| (l * ratio).into()),
|
||||
)
|
||||
} else {
|
||||
inline_content_size
|
||||
|
@ -489,12 +489,12 @@ impl<'a> FlexItem<'a> {
|
|||
};
|
||||
|
||||
let result = match specified_size_suggestion {
|
||||
LengthOrAuto::LengthPercentage(l) => l.min(content_size_suggestion),
|
||||
LengthOrAuto::LengthPercentage(l) => l.min(content_size_suggestion.into()),
|
||||
LengthOrAuto::Auto => {
|
||||
if let Some(l) = transferred_size_suggestion {
|
||||
l.min(content_size_suggestion)
|
||||
l.min(content_size_suggestion.into())
|
||||
} else {
|
||||
content_size_suggestion
|
||||
content_size_suggestion.into()
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -625,6 +625,7 @@ fn flex_base_size(
|
|||
flex_item
|
||||
.inline_content_sizes(flex_context.layout_context)
|
||||
.max_content
|
||||
.into()
|
||||
} else {
|
||||
// FIXME: block-axis content sizing requires another pass
|
||||
// of "full" layout
|
||||
|
|
|
@ -915,7 +915,8 @@ impl FloatBox {
|
|||
containing_block.inline_size - pbm_sums.inline_sum();
|
||||
non_replaced
|
||||
.inline_content_sizes(layout_context)
|
||||
.shrink_to_fit(available_size)
|
||||
.shrink_to_fit(available_size.into())
|
||||
.into()
|
||||
});
|
||||
let inline_size = tentative_inline_size
|
||||
.clamp_between_extremums(min_box_size.inline, max_box_size.inline);
|
||||
|
|
|
@ -1828,7 +1828,8 @@ impl IndependentFormattingContext {
|
|||
let available_size = ifc.containing_block.inline_size - pbm_sums.inline_sum();
|
||||
non_replaced
|
||||
.inline_content_sizes(layout_context)
|
||||
.shrink_to_fit(available_size)
|
||||
.shrink_to_fit(available_size.into())
|
||||
.into()
|
||||
});
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
|
||||
|
@ -2327,8 +2328,8 @@ impl<'a> ContentSizesComputation<'a> {
|
|||
|
||||
if !run.glyph_store.is_whitespace() {
|
||||
self.had_non_whitespace_content_yet = true;
|
||||
self.current_line.min_content += advance;
|
||||
self.current_line.max_content += self.pending_whitespace + advance;
|
||||
self.current_line.min_content += advance.into();
|
||||
self.current_line.max_content += (self.pending_whitespace + advance).into();
|
||||
self.pending_whitespace = Length::zero();
|
||||
} else {
|
||||
// If this run is a forced line break, we *must* break the line
|
||||
|
@ -2358,7 +2359,8 @@ impl<'a> ContentSizesComputation<'a> {
|
|||
self.containing_block_writing_mode,
|
||||
);
|
||||
|
||||
self.current_line.min_content += self.pending_whitespace + outer.min_content;
|
||||
self.current_line.min_content +=
|
||||
(self.pending_whitespace + outer.min_content.into()).into();
|
||||
self.current_line.max_content += outer.max_content;
|
||||
self.pending_whitespace = Length::zero();
|
||||
self.had_non_whitespace_content_yet = true;
|
||||
|
@ -2371,23 +2373,21 @@ impl<'a> ContentSizesComputation<'a> {
|
|||
}
|
||||
|
||||
fn add_length(&mut self, l: Length) {
|
||||
self.current_line.min_content += l;
|
||||
self.current_line.max_content += l;
|
||||
self.current_line.min_content += l.into();
|
||||
self.current_line.max_content += l.into();
|
||||
}
|
||||
|
||||
fn line_break_opportunity(&mut self) {
|
||||
self.paragraph
|
||||
.min_content
|
||||
.max_assign(self.current_line.min_content);
|
||||
self.current_line.min_content = Length::zero();
|
||||
self.paragraph.min_content =
|
||||
std::cmp::max(self.paragraph.min_content, self.current_line.min_content);
|
||||
self.current_line.min_content = Au::zero();
|
||||
}
|
||||
|
||||
fn forced_line_break(&mut self) {
|
||||
self.line_break_opportunity();
|
||||
self.paragraph
|
||||
.max_content
|
||||
.max_assign(self.current_line.max_content);
|
||||
self.current_line.max_content = Length::zero();
|
||||
self.paragraph.max_content =
|
||||
std::cmp::max(self.paragraph.max_content, self.current_line.max_content);
|
||||
self.current_line.max_content = Au::zero();
|
||||
}
|
||||
|
||||
/// Compute the [`ContentSizes`] of the given [`InlineFormattingContext`].
|
||||
|
|
|
@ -563,7 +563,8 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
cbis - anchor - pbm.padding_border_sums.inline - margin_sum;
|
||||
non_replaced
|
||||
.inline_content_sizes(layout_context)
|
||||
.shrink_to_fit(available_size)
|
||||
.shrink_to_fit(available_size.into())
|
||||
.into()
|
||||
});
|
||||
|
||||
// If the tentative used inline size is greater than ‘max-inline-size’,
|
||||
|
|
|
@ -241,8 +241,8 @@ impl ReplacedContent {
|
|||
.inline
|
||||
.unwrap_or(Length::zero());
|
||||
ContentSizes {
|
||||
min_content: inline,
|
||||
max_content: inline,
|
||||
min_content: inline.into(),
|
||||
max_content: inline.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
//! <https://drafts.csswg.org/css-sizing/>
|
||||
|
||||
use app_units::Au;
|
||||
use serde::Serialize;
|
||||
use style::logical_geometry::WritingMode;
|
||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||
|
@ -11,24 +12,24 @@ use style::properties::ComputedValues;
|
|||
use style::values::computed::Length;
|
||||
use style::Zero;
|
||||
|
||||
use crate::style_ext::ComputedValuesExt;
|
||||
use crate::style_ext::{Clamp, ComputedValuesExt};
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub(crate) struct ContentSizes {
|
||||
pub min_content: Length,
|
||||
pub max_content: Length,
|
||||
pub min_content: Au,
|
||||
pub max_content: Au,
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-sizing/#intrinsic-sizes>
|
||||
impl ContentSizes {
|
||||
pub fn zero() -> Self {
|
||||
Self {
|
||||
min_content: Length::zero(),
|
||||
max_content: Length::zero(),
|
||||
min_content: Au::zero(),
|
||||
max_content: Au::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map(&self, f: impl Fn(Length) -> Length) -> Self {
|
||||
pub fn map(&self, f: impl Fn(Au) -> Au) -> Self {
|
||||
Self {
|
||||
min_content: f(self.min_content),
|
||||
max_content: f(self.max_content),
|
||||
|
@ -52,7 +53,7 @@ impl ContentSizes {
|
|||
|
||||
impl ContentSizes {
|
||||
/// <https://drafts.csswg.org/css2/visudet.html#shrink-to-fit-float>
|
||||
pub fn shrink_to_fit(&self, available_size: Length) -> Length {
|
||||
pub fn shrink_to_fit(&self, available_size: Au) -> Au {
|
||||
available_size.max(self.min_content).min(self.max_content)
|
||||
}
|
||||
}
|
||||
|
@ -100,28 +101,30 @@ pub(crate) fn outer_inline(
|
|||
.inline
|
||||
// Percentages for 'max-width' are treated as 'none'
|
||||
.and_then(|lp| lp.to_length());
|
||||
let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size);
|
||||
let clamp = |l: Au| {
|
||||
l.clamp_between_extremums(min_inline_size.into(), max_inline_size.map(|t| t.into()))
|
||||
};
|
||||
|
||||
let border_box_sizes = match inline_size {
|
||||
Some(non_auto) => {
|
||||
let clamped = clamp(non_auto);
|
||||
let clamped = clamp(non_auto.into());
|
||||
let border_box_size = match box_sizing {
|
||||
BoxSizing::ContentBox => clamped + pb_lengths,
|
||||
BoxSizing::ContentBox => clamped + pb_lengths.into(),
|
||||
BoxSizing::BorderBox => clamped,
|
||||
};
|
||||
ContentSizes {
|
||||
min_content: border_box_size,
|
||||
max_content: border_box_size,
|
||||
min_content: border_box_size.into(),
|
||||
max_content: border_box_size.into(),
|
||||
}
|
||||
},
|
||||
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,
|
||||
BoxSizing::BorderBox => clamp(content_box_size + pb_lengths),
|
||||
BoxSizing::ContentBox => clamp(content_box_size.into()) + pb_lengths.into(),
|
||||
BoxSizing::BorderBox => clamp(content_box_size + pb_lengths.into()),
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
border_box_sizes.map(|s| s + m_lengths)
|
||||
border_box_sizes.map(|s| s + m_lengths.into())
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ impl<'a> TableLayout<'a> {
|
|||
|
||||
// https://drafts.csswg.org/css-tables/#used-min-width-of-table
|
||||
// > The used min-width of a table is the greater of the resolved min-width, CAPMIN, and GRIDMIN.
|
||||
let used_min_width_of_table = grid_min_inline_size.max(min_content_sizes.inline);
|
||||
let used_min_width_of_table = grid_min_inline_size.max(min_content_sizes.inline.into());
|
||||
|
||||
// https://drafts.csswg.org/css-tables/#used-width-of-table
|
||||
// > The used width of a table depends on the columns and captions widths as follows:
|
||||
|
@ -105,10 +105,13 @@ impl<'a> TableLayout<'a> {
|
|||
// > * If the table-root has 'width: auto', the used width is the greater of min(GRIDMAX,
|
||||
// > the table’s containing block width), the used min-width of the table.
|
||||
let used_width_of_table = match content_box_size.inline {
|
||||
LengthPercentage(length_percentage) => length_percentage.max(used_min_width_of_table),
|
||||
LengthPercentage(length_percentage) => {
|
||||
length_percentage.max(used_min_width_of_table.into())
|
||||
},
|
||||
Auto => grid_max_inline_size
|
||||
.min(containing_block.inline_size)
|
||||
.max(used_min_width_of_table),
|
||||
.min(containing_block.inline_size.into())
|
||||
.max(used_min_width_of_table)
|
||||
.into(),
|
||||
};
|
||||
|
||||
self.assignable_width = used_width_of_table.into();
|
||||
|
@ -185,8 +188,11 @@ impl<'a> TableLayout<'a> {
|
|||
max_content_sizing_guess,
|
||||
) = match inline_size {
|
||||
LengthPercentage(length_percentage) if length_percentage.has_percentage() => {
|
||||
let percent_guess = min_content_width
|
||||
.max(length_percentage.resolve(self.assignable_width.into()));
|
||||
let percent_guess = min_content_width.max(
|
||||
length_percentage
|
||||
.resolve(self.assignable_width.into())
|
||||
.into(),
|
||||
);
|
||||
(percent_guess, percent_guess, percent_guess)
|
||||
},
|
||||
LengthPercentage(_) => (min_content_width, max_content_width, max_content_width),
|
||||
|
@ -450,7 +456,7 @@ impl Table {
|
|||
};
|
||||
|
||||
let sizes = cell.inline_content_sizes(layout_context, writing_mode);
|
||||
sizes.map(|size| size / cell.colspan as f32)
|
||||
sizes.map(|size| size.scale_by(1.0 / cell.colspan as f32))
|
||||
}
|
||||
|
||||
pub(crate) fn compute_inline_content_sizes(
|
||||
|
@ -520,8 +526,8 @@ impl TableSlotCell {
|
|||
.contents
|
||||
.contents
|
||||
.inline_content_sizes(layout_context, writing_mode);
|
||||
sizes.min_content += border_padding_sum;
|
||||
sizes.max_content += border_padding_sum;
|
||||
sizes.min_content += border_padding_sum.into();
|
||||
sizes.max_content += border_padding_sum.into();
|
||||
sizes
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[floats-141.xht]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue