aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Ramine <nox@nox.paris>2020-06-18 14:11:02 +0200
committerAnthony Ramine <nox@nox.paris>2020-06-18 14:11:02 +0200
commit235df94f2eb9227fb35a51a5bc486aa9d29b5036 (patch)
treef1d87a305d07d5e484ca0fbd2cbc269a5f6f4ca9
parentba5568a0a60cbd4bbedd3b766b7182824d75b131 (diff)
downloadservo-235df94f2eb9227fb35a51a5bc486aa9d29b5036.tar.gz
servo-235df94f2eb9227fb35a51a5bc486aa9d29b5036.zip
Compute content sizes lazily in layout 2020
-rw-r--r--components/layout_2020/flexbox/construct.rs13
-rw-r--r--components/layout_2020/flexbox/mod.rs7
-rw-r--r--components/layout_2020/flow/construct.rs123
-rw-r--r--components/layout_2020/flow/float.rs5
-rw-r--r--components/layout_2020/flow/inline.rs11
-rw-r--r--components/layout_2020/flow/mod.rs47
-rw-r--r--components/layout_2020/flow/root.rs2
-rw-r--r--components/layout_2020/formatting_contexts.rs137
-rw-r--r--components/layout_2020/positioned.rs15
-rw-r--r--components/layout_2020/sizing.rs61
-rw-r--r--components/style/values/generics/length.rs2
11 files changed, 176 insertions, 247 deletions
diff --git a/components/layout_2020/flexbox/construct.rs b/components/layout_2020/flexbox/construct.rs
index 385b45985e1..6c7c90635f2 100644
--- a/components/layout_2020/flexbox/construct.rs
+++ b/components/layout_2020/flexbox/construct.rs
@@ -12,7 +12,6 @@ use crate::element_data::LayoutBox;
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Tag;
use crate::positioned::AbsolutelyPositionedBox;
-use crate::sizing::{BoxContentSizes, ContentSizes, ContentSizesRequest};
use crate::style_ext::DisplayGeneratingBox;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::borrow::Cow;
@@ -23,9 +22,8 @@ impl FlexContainer {
context: &LayoutContext,
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
contents: NonReplacedContents,
- content_sizes: ContentSizesRequest,
propagated_text_decoration_line: TextDecorationLine,
- ) -> (Self, BoxContentSizes) {
+ ) -> Self {
let text_decoration_line =
propagated_text_decoration_line | info.style.clone_text_decoration_line();
let mut builder = FlexContainerBuilder {
@@ -37,11 +35,7 @@ impl FlexContainer {
has_text_runs: false,
};
contents.traverse(context, info, &mut builder);
- let content_sizes = content_sizes.compute(|| {
- // FIXME
- ContentSizes::zero()
- });
- (builder.finish(), content_sizes)
+ builder.finish()
}
}
@@ -152,7 +146,6 @@ where
.map(|job| match job {
FlexLevelJob::TextRuns(runs) => ArcRefCell::new(FlexLevelBox::FlexItem(
IndependentFormattingContext::construct_for_text_runs(
- self.context,
&self
.info
.new_replacing_style(anonymous_style.clone().unwrap()),
@@ -161,7 +154,6 @@ where
text: run.text.into(),
parent_style: run.info.style,
}),
- ContentSizesRequest::None, // FIXME: request sizes when we start using them
self.text_decoration_line,
),
)),
@@ -191,7 +183,6 @@ where
&info,
display_inside,
contents,
- ContentSizesRequest::None, // FIXME: request sizes when we start using them
self.text_decoration_line,
),
))
diff --git a/components/layout_2020/flexbox/mod.rs b/components/layout_2020/flexbox/mod.rs
index c7aed0bd0e9..5dd0c476727 100644
--- a/components/layout_2020/flexbox/mod.rs
+++ b/components/layout_2020/flexbox/mod.rs
@@ -5,6 +5,7 @@
use crate::cell::ArcRefCell;
use crate::formatting_contexts::IndependentFormattingContext;
use crate::positioned::AbsolutelyPositionedBox;
+use crate::sizing::ContentSizes;
mod construct;
mod layout;
@@ -19,3 +20,9 @@ pub(crate) enum FlexLevelBox {
FlexItem(IndependentFormattingContext),
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
}
+
+impl FlexContainer {
+ pub fn inline_content_sizes(&self) -> ContentSizes {
+ unimplemented!()
+ }
+}
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs
index 7d72209c6e8..0f49fb85422 100644
--- a/components/layout_2020/flow/construct.rs
+++ b/components/layout_2020/flow/construct.rs
@@ -14,14 +14,12 @@ use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Tag;
use crate::positioned::AbsolutelyPositionedBox;
-use crate::sizing::{self, BoxContentSizes, ContentSizes, ContentSizesRequest};
-use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
+use crate::style_ext::{DisplayGeneratingBox, DisplayInside, DisplayOutside};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
use std::borrow::Cow;
use std::convert::{TryFrom, TryInto};
-use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
use style::values::specified::text::TextDecorationLine;
@@ -31,34 +29,24 @@ impl BlockFormattingContext {
context: &LayoutContext,
info: &NodeAndStyleInfo<Node>,
contents: NonReplacedContents,
- content_sizes: ContentSizesRequest,
propagated_text_decoration_line: TextDecorationLine,
- ) -> (Self, BoxContentSizes)
+ ) -> Self
where
Node: NodeExt<'dom>,
{
- let (contents, contains_floats, inline_content_sizes) = BlockContainer::construct(
- context,
- info,
- contents,
- content_sizes,
- propagated_text_decoration_line,
- );
- // FIXME: add contribution to `inline_content_sizes` of floats in this formatting context
- // https://dbaron.org/css/intrinsic/#intrinsic
+ let (contents, contains_floats) =
+ BlockContainer::construct(context, info, contents, propagated_text_decoration_line);
let bfc = Self {
contents,
contains_floats: contains_floats == ContainsFloats::Yes,
};
- (bfc, inline_content_sizes)
+ bfc
}
pub fn construct_for_text_runs<'dom>(
- context: &LayoutContext,
runs: impl Iterator<Item = TextRun>,
- content_sizes: ContentSizesRequest,
text_decoration_line: TextDecorationLine,
- ) -> (Self, BoxContentSizes) {
+ ) -> Self {
// FIXME: do white space collapsing
let inline_level_boxes = runs
.map(|run| ArcRefCell::new(InlineLevelBox::TextRun(run)))
@@ -68,18 +56,12 @@ impl BlockFormattingContext {
inline_level_boxes,
text_decoration_line,
};
- // FIXME: this is the wrong writing mode
- // but we plan to remove eager content size computation.
- let not_actually_containing_block_writing_mode = WritingMode::empty();
- let content_sizes = content_sizes.compute(|| {
- ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode)
- });
let contents = BlockContainer::InlineFormattingContext(ifc);
let bfc = Self {
contents,
contains_floats: false,
};
- (bfc, content_sizes)
+ bfc
}
}
@@ -181,9 +163,8 @@ impl BlockContainer {
context: &LayoutContext,
info: &NodeAndStyleInfo<Node>,
contents: NonReplacedContents,
- content_sizes: ContentSizesRequest,
propagated_text_decoration_line: TextDecorationLine,
- ) -> (BlockContainer, ContainsFloats, BoxContentSizes)
+ ) -> (BlockContainer, ContainsFloats)
where
Node: NodeExt<'dom>,
{
@@ -209,35 +190,22 @@ impl BlockContainer {
.is_empty()
{
if builder.block_level_boxes.is_empty() {
- // FIXME: this is the wrong writing mode
- // but we plan to remove eager content size computation.
- let not_actually_containing_block_writing_mode = info.style.writing_mode;
- let content_sizes = content_sizes.compute(|| {
- builder
- .ongoing_inline_formatting_context
- .inline_content_sizes(context, not_actually_containing_block_writing_mode)
- });
let container = BlockContainer::InlineFormattingContext(
builder.ongoing_inline_formatting_context,
);
- return (container, builder.contains_floats, content_sizes);
+ return (container, builder.contains_floats);
}
builder.end_ongoing_inline_formatting_context();
}
struct Accumulator {
contains_floats: ContainsFloats,
- outer_content_sizes_of_children: ContentSizes,
}
let mut acc = Accumulator {
contains_floats: builder.contains_floats,
- outer_content_sizes_of_children: ContentSizes::zero(),
};
let mapfold = |acc: &mut Accumulator, creator: BlockLevelJob<'dom, _>| {
- let (block_level_box, box_contains_floats) = creator.finish(
- context,
- content_sizes.if_requests_inline(|| &mut acc.outer_content_sizes_of_children),
- );
+ let (block_level_box, box_contains_floats) = creator.finish(context);
acc.contains_floats |= box_contains_floats;
block_level_box
};
@@ -250,14 +218,9 @@ impl BlockContainer {
mapfold,
|| Accumulator {
contains_floats: ContainsFloats::No,
- outer_content_sizes_of_children: ContentSizes::zero(),
},
|left, right| {
left.contains_floats |= right.contains_floats;
- if content_sizes.requests_inline() {
- left.outer_content_sizes_of_children
- .max_assign(&right.outer_content_sizes_of_children)
- }
},
)
.collect()
@@ -270,12 +233,8 @@ impl BlockContainer {
};
let container = BlockContainer::BlockLevelBoxes(block_level_boxes);
- let Accumulator {
- contains_floats,
- outer_content_sizes_of_children,
- } = acc;
- let content_sizes = content_sizes.compute(|| outer_content_sizes_of_children);
- (container, contains_floats, content_sizes)
+ let Accumulator { contains_floats } = acc;
+ (container, contains_floats)
}
}
@@ -439,7 +398,6 @@ where
display_inside: DisplayInside,
contents: Contents,
) -> ArcRefCell<InlineLevelBox> {
- let style = &info.style;
let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() {
// We found un inline box.
// Whatever happened before, all we need to do before recurring
@@ -464,14 +422,12 @@ where
inline_box.last_fragment = true;
ArcRefCell::new(InlineLevelBox::InlineBox(inline_box))
} else {
- let content_sizes = ContentSizesRequest::inline_if(!style.inline_size_is_length());
ArcRefCell::new(InlineLevelBox::Atomic(
IndependentFormattingContext::construct(
self.context,
info,
display_inside,
contents,
- content_sizes,
// Text decorations are not propagated to atomic inline-level descendants.
TextDecorationLine::NONE,
),
@@ -681,32 +637,11 @@ impl<'dom, Node> BlockLevelJob<'dom, Node>
where
Node: NodeExt<'dom>,
{
- fn finish(
- self,
- context: &LayoutContext,
- max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
- ) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
+ fn finish(self, context: &LayoutContext) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
let info = &self.info;
- // FIXME: this is the wrong writing mode
- // but we plan to remove eager content size computation.
- let not_actually_containing_block_writing_mode = info.style.writing_mode;
let (block_level_box, contains_floats) = match self.kind {
BlockLevelCreator::SameFormattingContextBlock(contents) => {
- let (contents, contains_floats, box_content_sizes) = contents.finish(
- context,
- info,
- ContentSizesRequest::inline_if(
- max_assign_in_flow_outer_content_sizes_to.is_some() &&
- !info.style.inline_size_is_length(),
- ),
- );
- if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
- to.max_assign(&sizing::outer_inline(
- &info.style,
- not_actually_containing_block_writing_mode,
- || box_content_sizes.expect_inline().clone(),
- ))
- }
+ let (contents, contains_floats) = contents.finish(context, info);
let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
tag: Tag::from_node_and_style_info(info),
contents,
@@ -719,25 +654,13 @@ where
contents,
propagated_text_decoration_line,
} => {
- let content_sizes = ContentSizesRequest::inline_if(
- max_assign_in_flow_outer_content_sizes_to.is_some() &&
- !info.style.inline_size_is_length(),
- );
let context = IndependentFormattingContext::construct(
context,
info,
display_inside,
contents,
- content_sizes,
propagated_text_decoration_line,
);
- if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
- to.max_assign(&sizing::outer_inline(
- &context.style(),
- not_actually_containing_block_writing_mode,
- || context.content_sizes(),
- ))
- }
(
ArcRefCell::new(BlockLevelBox::Independent(context)),
ContainsFloats::No,
@@ -775,35 +698,21 @@ impl IntermediateBlockContainer {
self,
context: &LayoutContext,
info: &NodeAndStyleInfo<Node>,
- content_sizes: ContentSizesRequest,
- ) -> (BlockContainer, ContainsFloats, BoxContentSizes)
+ ) -> (BlockContainer, ContainsFloats)
where
Node: NodeExt<'dom>,
{
match self {
IntermediateBlockContainer::Deferred(contents, propagated_text_decoration_line) => {
- BlockContainer::construct(
- context,
- info,
- contents,
- content_sizes,
- propagated_text_decoration_line,
- )
+ BlockContainer::construct(context, info, contents, propagated_text_decoration_line)
},
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
- // FIXME: this is the wrong writing mode
- // but we plan to remove eager content size computation.
- let not_actually_containing_block_writing_mode = info.style.writing_mode;
- let content_sizes = content_sizes.compute(|| {
- ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode)
- });
// If that inline formatting context contained any float, those
// were already taken into account during the first phase of
// box construction.
(
BlockContainer::InlineFormattingContext(ifc),
ContainsFloats::No,
- content_sizes,
)
},
}
diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs
index da70838499f..22b0b1bb66e 100644
--- a/components/layout_2020/flow/float.rs
+++ b/components/layout_2020/flow/float.rs
@@ -5,8 +5,7 @@
use crate::context::LayoutContext;
use crate::dom_traversal::{Contents, NodeAndStyleInfo, NodeExt};
use crate::formatting_contexts::IndependentFormattingContext;
-use crate::sizing::ContentSizesRequest;
-use crate::style_ext::{ComputedValuesExt, DisplayInside};
+use crate::style_ext::DisplayInside;
use style::values::specified::text::TextDecorationLine;
#[derive(Debug, Serialize)]
@@ -32,14 +31,12 @@ impl FloatBox {
display_inside: DisplayInside,
contents: Contents,
) -> Self {
- let content_sizes = ContentSizesRequest::inline_if(!info.style.inline_size_is_length());
Self {
contents: IndependentFormattingContext::construct(
context,
info,
display_inside,
contents,
- content_sizes,
// Text decorations are not propagated to any out-of-flow descendants
TextDecorationLine::NONE,
),
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs
index f6895258dab..910f9e20cea 100644
--- a/components/layout_2020/flow/inline.rs
+++ b/components/layout_2020/flow/inline.rs
@@ -16,7 +16,7 @@ use crate::positioned::{
relative_adjustement, AbsolutelyPositionedBox, HoistedAbsolutelyPositionedBox,
PositioningContext,
};
-use crate::sizing::{self, ContentSizes};
+use crate::sizing::ContentSizes;
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
use crate::ContainingBlock;
use app_units::Au;
@@ -200,10 +200,9 @@ impl InlineFormattingContext {
}
},
InlineLevelBox::Atomic(atomic) => {
- let (outer, pc) = sizing::outer_inline_and_percentages(
- &atomic.style(),
+ let (outer, pc) = atomic.outer_inline_and_percentages(
+ self.layout_context,
self.containing_block_writing_mode,
- || atomic.content_sizes(),
);
self.current_line.min_content += outer.min_content;
self.current_line.max_content += outer.max_content;
@@ -595,7 +594,9 @@ fn layout_atomic(
// https://drafts.csswg.org/css2/visudet.html#inlineblock-width
let tentative_inline_size = box_size.inline.auto_is(|| {
let available_size = ifc.containing_block.inline_size - pbm_sums.inline_sum();
- non_replaced.content_sizes.shrink_to_fit(available_size)
+ non_replaced
+ .inline_content_sizes(layout_context)
+ .shrink_to_fit(available_size)
});
// https://drafts.csswg.org/css2/visudet.html#min-max-widths
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index b8c0d7e500d..c256c6c9a23 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -18,11 +18,13 @@ use crate::fragments::{
use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::replaced::ReplacedContent;
+use crate::sizing::{self, ContentSizes};
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
use crate::ContainingBlock;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
+use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto};
use style::Zero;
@@ -132,6 +134,29 @@ impl BlockContainer {
),
}
}
+
+ pub(super) fn inline_content_sizes(
+ &self,
+ layout_context: &LayoutContext,
+ containing_block_writing_mode: WritingMode,
+ ) -> ContentSizes {
+ match &self {
+ Self::BlockLevelBoxes(boxes) => {
+ let mut content_sizes = ContentSizes::zero();
+ for box_ in boxes {
+ content_sizes.max_assign(
+ &box_
+ .borrow_mut()
+ .inline_content_sizes(layout_context, containing_block_writing_mode),
+ );
+ }
+ content_sizes
+ },
+ Self::InlineFormattingContext(context) => {
+ context.inline_content_sizes(layout_context, containing_block_writing_mode)
+ },
+ }
+ }
}
fn layout_block_level_children(
@@ -350,6 +375,28 @@ impl BlockLevelBox {
},
}
}
+
+ fn inline_content_sizes(
+ &mut self,
+ layout_context: &LayoutContext,
+ containing_block_writing_mode: WritingMode,
+ ) -> ContentSizes {
+ match self {
+ Self::SameFormattingContextBlock {
+ style, contents, ..
+ } => sizing::outer_inline(style, containing_block_writing_mode, || {
+ contents.inline_content_sizes(layout_context, style.writing_mode)
+ }),
+ Self::Independent(independent) => {
+ independent.outer_inline(layout_context, containing_block_writing_mode)
+ },
+ BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(_) => ContentSizes::zero(),
+ BlockLevelBox::OutOfFlowFloatBox(_box_) => {
+ // TODO: Actually implement that.
+ ContentSizes::zero()
+ },
+ }
+ }
}
enum NonReplacedContents<'a> {
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs
index 55c325a3cd0..247d6bde904 100644
--- a/components/layout_2020/flow/root.rs
+++ b/components/layout_2020/flow/root.rs
@@ -22,7 +22,6 @@ use crate::geom::{PhysicalPoint, PhysicalRect, PhysicalSize};
use crate::positioned::AbsolutelyPositionedBox;
use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContent;
-use crate::sizing::ContentSizesRequest;
use crate::style_ext::ComputedValuesExt;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
use crate::wrapper::GetStyleAndLayoutData;
@@ -291,7 +290,6 @@ fn construct_for_root_element<'dom>(
&info,
display_inside,
contents,
- ContentSizesRequest::None,
propagated_text_decoration_line,
)),
)
diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs
index 5f9549238af..9b493f5e168 100644
--- a/components/layout_2020/formatting_contexts.rs
+++ b/components/layout_2020/formatting_contexts.rs
@@ -9,13 +9,14 @@ use crate::flow::BlockFormattingContext;
use crate::fragments::{Fragment, Tag};
use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContent;
-use crate::sizing::{BoxContentSizes, ContentSizes, ContentSizesRequest};
+use crate::sizing::{self, ContentSizes};
use crate::style_ext::DisplayInside;
use crate::ContainingBlock;
use servo_arc::Arc;
use std::convert::TryInto;
+use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
-use style::values::computed::Length;
+use style::values::computed::{Length, Percentage};
use style::values::specified::text::TextDecorationLine;
/// https://drafts.csswg.org/css-display/#independent-formatting-context
@@ -31,7 +32,7 @@ pub(crate) struct NonReplacedFormattingContext {
#[serde(skip_serializing)]
pub style: Arc<ComputedValues>,
/// If it was requested during construction
- pub content_sizes: BoxContentSizes,
+ pub content_sizes: Option<ContentSizes>,
pub contents: NonReplacedFormattingContextContents,
}
@@ -65,41 +66,36 @@ impl IndependentFormattingContext {
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
display_inside: DisplayInside,
contents: Contents,
- content_sizes: ContentSizesRequest,
propagated_text_decoration_line: TextDecorationLine,
) -> Self {
match contents.try_into() {
- Ok(non_replaced) => match display_inside {
- DisplayInside::Flow | DisplayInside::FlowRoot => {
- let (bfc, content_sizes) = BlockFormattingContext::construct(
- context,
- info,
- non_replaced,
- content_sizes,
- propagated_text_decoration_line,
- );
- Self::NonReplaced(NonReplacedFormattingContext {
- tag: Tag::from_node_and_style_info(info),
- style: Arc::clone(&info.style),
- content_sizes,
- contents: NonReplacedFormattingContextContents::Flow(bfc),
- })
- },
- DisplayInside::Flex => {
- let (fc, content_sizes) = FlexContainer::construct(
- context,
- info,
- non_replaced,
- content_sizes,
- propagated_text_decoration_line,
- );
- Self::NonReplaced(NonReplacedFormattingContext {
- tag: Tag::from_node_and_style_info(info),
- style: Arc::clone(&info.style),
- content_sizes,
- contents: NonReplacedFormattingContextContents::Flex(fc),
- })
- },
+ Ok(non_replaced) => {
+ let contents = match display_inside {
+ DisplayInside::Flow | DisplayInside::FlowRoot => {
+ NonReplacedFormattingContextContents::Flow(
+ BlockFormattingContext::construct(
+ context,
+ info,
+ non_replaced,
+ propagated_text_decoration_line,
+ ),
+ )
+ },
+ DisplayInside::Flex => {
+ NonReplacedFormattingContextContents::Flex(FlexContainer::construct(
+ context,
+ info,
+ non_replaced,
+ propagated_text_decoration_line,
+ ))
+ },
+ };
+ Self::NonReplaced(NonReplacedFormattingContext {
+ tag: Tag::from_node_and_style_info(info),
+ style: Arc::clone(&info.style),
+ content_sizes: None,
+ contents,
+ })
},
Err(contents) => Self::Replaced(ReplacedFormattingContext {
tag: Tag::from_node_and_style_info(info),
@@ -110,22 +106,16 @@ impl IndependentFormattingContext {
}
pub fn construct_for_text_runs<'dom>(
- context: &LayoutContext,
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
runs: impl Iterator<Item = crate::flow::inline::TextRun>,
- content_sizes: ContentSizesRequest,
propagated_text_decoration_line: TextDecorationLine,
) -> Self {
- let (bfc, content_sizes) = BlockFormattingContext::construct_for_text_runs(
- context,
- runs,
- content_sizes,
- propagated_text_decoration_line,
- );
+ let bfc =
+ BlockFormattingContext::construct_for_text_runs(runs, propagated_text_decoration_line);
Self::NonReplaced(NonReplacedFormattingContext {
tag: Tag::from_node_and_style_info(info),
style: Arc::clone(&info.style),
- content_sizes,
+ content_sizes: None,
contents: NonReplacedFormattingContextContents::Flow(bfc),
})
}
@@ -144,10 +134,40 @@ impl IndependentFormattingContext {
}
}
- pub fn content_sizes(&self) -> ContentSizes {
+ pub fn outer_inline(
+ &mut self,
+ layout_context: &LayoutContext,
+ containing_block_writing_mode: WritingMode,
+ ) -> ContentSizes {
+ let (mut outer, percentages) =
+ self.outer_inline_and_percentages(layout_context, containing_block_writing_mode);
+ outer.adjust_for_pbm_percentages(percentages);
+ outer
+ }
+
+ pub fn outer_inline_and_percentages(
+ &mut self,
+ layout_context: &LayoutContext,
+ containing_block_writing_mode: WritingMode,
+ ) -> (ContentSizes, Percentage) {
match self {
- Self::NonReplaced(inner) => inner.content_sizes.expect_inline().clone(),
- Self::Replaced(inner) => inner.contents.inline_content_sizes(&inner.style),
+ Self::NonReplaced(non_replaced) => {
+ let style = &non_replaced.style;
+ let content_sizes = &mut non_replaced.content_sizes;
+ let contents = &non_replaced.contents;
+ sizing::outer_inline_and_percentages(&style, containing_block_writing_mode, || {
+ content_sizes
+ .get_or_insert_with(|| {
+ contents.inline_content_sizes(layout_context, style.writing_mode)
+ })
+ .clone()
+ })
+ },
+ Self::Replaced(replaced) => sizing::outer_inline_and_percentages(
+ &replaced.style,
+ containing_block_writing_mode,
+ || replaced.contents.inline_content_sizes(&replaced.style),
+ ),
}
}
}
@@ -175,4 +195,27 @@ impl NonReplacedFormattingContext {
),
}
}
+
+ pub fn inline_content_sizes(&mut self, layout_context: &LayoutContext) -> ContentSizes {
+ let writing_mode = self.style.writing_mode;
+ let contents = &self.contents;
+ self.content_sizes
+ .get_or_insert_with(|| contents.inline_content_sizes(layout_context, writing_mode))
+ .clone()
+ }
+}
+
+impl NonReplacedFormattingContextContents {
+ pub fn inline_content_sizes(
+ &self,
+ layout_context: &LayoutContext,
+ containing_block_writing_mode: WritingMode,
+ ) -> ContentSizes {
+ match self {
+ Self::Flow(inner) => inner
+ .contents
+ .inline_content_sizes(layout_context, containing_block_writing_mode),
+ Self::Flex(inner) => inner.inline_content_sizes(),
+ }
+ }
}
diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs
index dcb1388b36c..853b22347e9 100644
--- a/components/layout_2020/positioned.rs
+++ b/components/layout_2020/positioned.rs
@@ -9,7 +9,6 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::{BoxFragment, CollapsedBlockMargins, Fragment};
use crate::geom::flow_relative::{Rect, Sides, Vec2};
use crate::geom::{LengthOrAuto, LengthPercentageOrAuto};
-use crate::sizing::ContentSizesRequest;
use crate::style_ext::{ComputedValuesExt, DisplayInside};
use crate::{ContainingBlock, DefiniteContainingBlock};
use rayon::iter::{IntoParallelRefMutIterator, ParallelExtend};
@@ -74,22 +73,12 @@ impl AbsolutelyPositionedBox {
display_inside: DisplayInside,
contents: Contents,
) -> Self {
- // "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
- let content_sizes = ContentSizesRequest::inline_if(
- // If inline-size is non-auto, that value is used without shrink-to-fit
- !node_info.style.inline_size_is_length() &&
- // If it is, then the only case where shrink-to-fit is *not* used is
- // if both offsets are non-auto, leaving inline-size as the only variable
- // in the constraint equation.
- !node_info.style.inline_box_offsets_are_both_non_auto(),
- );
Self {
context: IndependentFormattingContext::construct(
context,
node_info,
display_inside,
contents,
- content_sizes,
// Text decorations are not propagated to any out-of-flow descendants.
TextDecorationLine::NONE,
),
@@ -472,7 +461,9 @@ impl HoistedAbsolutelyPositionedBox {
};
let available_size =
cbis - anchor - pbm.padding_border_sums.inline - margin.inline_sum();
- non_replaced.content_sizes.shrink_to_fit(available_size)
+ non_replaced
+ .inline_content_sizes(layout_context)
+ .shrink_to_fit(available_size)
});
let containing_block_for_children = ContainingBlock {
diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs
index dd9574d4f85..ec07861c374 100644
--- a/components/layout_2020/sizing.rs
+++ b/components/layout_2020/sizing.rs
@@ -11,44 +11,6 @@ use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage};
use style::Zero;
-/// Which min/max-content values should be computed during box construction
-#[derive(Clone, Copy, Debug)]
-pub(crate) enum ContentSizesRequest {
- Inline,
- None,
-}
-
-impl ContentSizesRequest {
- pub fn inline_if(condition: bool) -> Self {
- if condition {
- Self::Inline
- } else {
- Self::None
- }
- }
-
- pub fn requests_inline(self) -> bool {
- match self {
- Self::Inline => true,
- Self::None => false,
- }
- }
-
- pub fn if_requests_inline<T>(self, f: impl FnOnce() -> T) -> Option<T> {
- match self {
- Self::Inline => Some(f()),
- Self::None => None,
- }
- }
-
- pub fn compute(self, compute_inline: impl FnOnce() -> ContentSizes) -> BoxContentSizes {
- match self {
- Self::Inline => BoxContentSizes::Inline(compute_inline()),
- Self::None => BoxContentSizes::NoneWereRequested,
- }
- }
-}
-
#[derive(Clone, Debug, Serialize)]
pub(crate) struct ContentSizes {
pub min_content: Length,
@@ -90,27 +52,10 @@ impl ContentSizes {
}
}
-/// Optional min/max-content for storage in the box tree
-#[derive(Debug, Serialize)]
-pub(crate) enum BoxContentSizes {
- NoneWereRequested, // … during box construction
- Inline(ContentSizes),
-}
-
-impl BoxContentSizes {
- pub fn expect_inline(&self) -> &ContentSizes {
- match self {
- Self::NoneWereRequested => panic!("Accessing content size that was not requested"),
- Self::Inline(s) => s,
- }
- }
-
+impl ContentSizes {
/// 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();
- available_size
- .max(inline.min_content)
- .min(inline.max_content)
+ pub fn shrink_to_fit(&self, available_size: Length) -> Length {
+ available_size.max(self.min_content).min(self.max_content)
}
}
diff --git a/components/style/values/generics/length.rs b/components/style/values/generics/length.rs
index bed574861cb..9ae86c7d991 100644
--- a/components/style/values/generics/length.rs
+++ b/components/style/values/generics/length.rs
@@ -75,7 +75,7 @@ where
{
/// Resolves `auto` values by calling `f`.
#[inline]
- pub fn auto_is(&self, f: impl Fn() -> LengthPercentage) -> LengthPercentage {
+ pub fn auto_is(&self, f: impl FnOnce() -> LengthPercentage) -> LengthPercentage {
match self {
LengthPercentageOrAuto::LengthPercentage(length) => length.clone(),
LengthPercentageOrAuto::Auto => f(),