Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some more boring stuff to change how we compute content sizes #26852

Merged
merged 5 commits into from Jun 15, 2020

Make outer_inline and outer_inline_and_percentages free functions

They now take a closure that will compute the content sizes on demand.
  • Loading branch information
nox committed Jun 15, 2020
commit 07d8c28d4aa8c2834bba0759321ae1363ba43d54
@@ -14,7 +14,7 @@ use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Tag;
use crate::positioned::AbsolutelyPositionedBox;
use crate::sizing::{BoxContentSizes, ContentSizes, ContentSizesRequest};
use crate::sizing::{self, BoxContentSizes, ContentSizes, ContentSizesRequest};
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
@@ -701,10 +701,11 @@ where
),
);
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
to.max_assign(
&box_content_sizes
.outer_inline(&info.style, not_actually_containing_block_writing_mode),
)
to.max_assign(&sizing::outer_inline(
&info.style,
not_actually_containing_block_writing_mode,
|| box_content_sizes.expect_inline().clone(),
))
}
let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
tag: Tag::from_node_and_style_info(info),
@@ -731,12 +732,11 @@ where
propagated_text_decoration_line,
);
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
to.max_assign(
&contents.content_sizes.outer_inline(
&contents.style,
not_actually_containing_block_writing_mode,
),
)
to.max_assign(&sizing::outer_inline(
&contents.style,
not_actually_containing_block_writing_mode,
|| contents.content_sizes.expect_inline().clone(),
))
}
(
ArcRefCell::new(BlockLevelBox::Independent(contents)),
@@ -16,7 +16,7 @@ use crate::positioned::{
relative_adjustement, AbsolutelyPositionedBox, HoistedAbsolutelyPositionedBox,
PositioningContext,
};
use crate::sizing::ContentSizes;
use crate::sizing::{self, ContentSizes};
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
use crate::ContainingBlock;
use app_units::Au;
@@ -200,9 +200,10 @@ impl InlineFormattingContext {
}
},
InlineLevelBox::Atomic(atomic) => {
let (outer, pc) = atomic.content_sizes.outer_inline_and_percentages(
let (outer, pc) = sizing::outer_inline_and_percentages(
&atomic.style,
self.containing_block_writing_mode,
|| atomic.content_sizes.expect_inline().clone(),
);
self.current_line.min_content += outer.min_content;
self.current_line.max_content += outer.max_content;
@@ -64,7 +64,7 @@ impl ContentSizes {
}
}

fn map(&self, f: impl Fn(Length) -> Length) -> Self {
pub fn map(&self, f: impl Fn(Length) -> Length) -> Self {
Self {
min_content: f(self.min_content),
max_content: f(self.max_content),
@@ -98,95 +98,13 @@ pub(crate) enum BoxContentSizes {
}

impl BoxContentSizes {
fn expect_inline(&self) -> &ContentSizes {
pub fn expect_inline(&self) -> &ContentSizes {
match self {
Self::NoneWereRequested => panic!("Accessing content size that was not requested"),
Self::Inline(s) => s,
}
}

/// https://dbaron.org/css/intrinsic/#outer-intrinsic
pub fn outer_inline(
&self,
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
) -> ContentSizes {
let (mut outer, percentages) =
self.outer_inline_and_percentages(style, containing_block_writing_mode);
outer.adjust_for_pbm_percentages(percentages);
outer
}

pub(crate) fn outer_inline_and_percentages(
&self,
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
) -> (ContentSizes, Percentage) {
let padding = style.padding(containing_block_writing_mode);
let border = style.border_width(containing_block_writing_mode);
let margin = style.margin(containing_block_writing_mode);

let mut pbm_percentages = Percentage::zero();
let mut decompose = |x: &LengthPercentage| {
pbm_percentages += x.to_percentage().unwrap_or_else(Zero::zero);
x.to_length().unwrap_or_else(Zero::zero)
};
let pb_lengths =
border.inline_sum() + decompose(padding.inline_start) + decompose(padding.inline_end);
let mut m_lengths = Length::zero();
if let Some(m) = margin.inline_start.non_auto() {
m_lengths += decompose(m)
}
if let Some(m) = margin.inline_end.non_auto() {
m_lengths += decompose(m)
}

let box_sizing = style.get_position().box_sizing;
let inline_size = style
.box_size(containing_block_writing_mode)
.inline
.non_auto()
// Percentages for 'width' are treated as 'auto'
.and_then(|lp| lp.to_length());
let min_inline_size = style
.min_box_size(containing_block_writing_mode)
.inline
// Percentages for 'min-width' are treated as zero
.percentage_relative_to(Length::zero())
// FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero);
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: Length| 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);
let border_box_size = match box_sizing {
BoxSizing::ContentBox => clamped + pb_lengths,
BoxSizing::BorderBox => clamped,
};
ContentSizes {
min_content: border_box_size,
max_content: border_box_size,
}
},
None => self.expect_inline().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),
}
}),
};

let outer = border_box_sizes.map(|s| s + m_lengths);
(outer, pbm_percentages)
}

/// https://drafts.csswg.org/css2/visudet.html#shrink-to-fit-float
pub(crate) fn shrink_to_fit(&self, available_size: Length) -> Length {
let inline = self.expect_inline();
@@ -195,3 +113,84 @@ impl BoxContentSizes {
.min(inline.max_content)
}
}

pub(crate) fn outer_inline(
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
get_content_size: impl FnOnce() -> ContentSizes,
) -> ContentSizes {
let (mut outer, percentages) =
outer_inline_and_percentages(style, containing_block_writing_mode, get_content_size);
outer.adjust_for_pbm_percentages(percentages);
outer
}

pub(crate) fn outer_inline_and_percentages(
style: &ComputedValues,
containing_block_writing_mode: WritingMode,
get_content_size: impl FnOnce() -> ContentSizes,
) -> (ContentSizes, Percentage) {
let padding = style.padding(containing_block_writing_mode);
let border = style.border_width(containing_block_writing_mode);
let margin = style.margin(containing_block_writing_mode);

let mut pbm_percentages = Percentage::zero();
let mut decompose = |x: &LengthPercentage| {
pbm_percentages += x.to_percentage().unwrap_or_else(Zero::zero);
x.to_length().unwrap_or_else(Zero::zero)
};
let pb_lengths =
border.inline_sum() + decompose(padding.inline_start) + decompose(padding.inline_end);
let mut m_lengths = Length::zero();
if let Some(m) = margin.inline_start.non_auto() {
m_lengths += decompose(m)
}
if let Some(m) = margin.inline_end.non_auto() {
m_lengths += decompose(m)
}

let box_sizing = style.get_position().box_sizing;
let inline_size = style
.box_size(containing_block_writing_mode)
.inline
.non_auto()
// Percentages for 'width' are treated as 'auto'
.and_then(|lp| lp.to_length());
let min_inline_size = style
.min_box_size(containing_block_writing_mode)
.inline
// Percentages for 'min-width' are treated as zero
.percentage_relative_to(Length::zero())
// FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero);
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: Length| 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);
let border_box_size = match box_sizing {
BoxSizing::ContentBox => clamped + pb_lengths,
BoxSizing::BorderBox => clamped,
};
ContentSizes {
min_content: border_box_size,
max_content: border_box_size,
}
},
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),
}
}),
};

let outer = border_box_sizes.map(|s| s + m_lengths);
(outer, pbm_percentages)
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.