diff options
-rw-r--r-- | components/layout_2020/flow/construct.rs | 91 | ||||
-rw-r--r-- | components/layout_2020/flow/float.rs | 5 | ||||
-rw-r--r-- | components/layout_2020/flow/root.rs | 3 | ||||
-rw-r--r-- | components/layout_2020/formatting_contexts.rs | 14 | ||||
-rw-r--r-- | components/layout_2020/positioned.rs | 10 | ||||
-rw-r--r-- | components/layout_2020/sizing.rs | 31 |
6 files changed, 92 insertions, 62 deletions
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 5d9cd433434..606628d5744 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -10,7 +10,7 @@ use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox, Te use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox}; use crate::formatting_contexts::IndependentFormattingContext; use crate::positioned::AbsolutelyPositionedBox; -use crate::sizing::{outer_inline_content_sizes, ContentSizes}; +use crate::sizing::{outer_inline_content_sizes, ContentSizes, ContentSizesRequest}; use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon_croissant::ParallelIteratorExt; @@ -24,17 +24,17 @@ impl BlockFormattingContext { context: &LayoutContext, style: &Arc<ComputedValues>, contents: NonReplacedContents<impl NodeExt<'dom>>, - request_content_sizes: bool, + content_sizes: ContentSizesRequest, ) -> (Self, Option<ContentSizes>) { - let (contents, contains_floats, content_sizes) = - BlockContainer::construct(context, style, contents, request_content_sizes); - // FIXME: add contribution to `content_sizes` of floats in this formatting context + let (contents, contains_floats, inline_content_sizes) = + BlockContainer::construct(context, style, contents, content_sizes); + // FIXME: add contribution to `inline_content_sizes` of floats in this formatting context // https://dbaron.org/css/intrinsic/#intrinsic let bfc = Self { contents, contains_floats: contains_floats == ContainsFloats::Yes, }; - (bfc, content_sizes) + (bfc, inline_content_sizes) } } @@ -133,7 +133,7 @@ impl BlockContainer { context: &LayoutContext, block_container_style: &Arc<ComputedValues>, contents: NonReplacedContents<impl NodeExt<'dom>>, - request_content_sizes: bool, + content_sizes: ContentSizesRequest, ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) { let mut builder = BlockContainerBuilder { context, @@ -155,19 +155,15 @@ impl BlockContainer { .is_empty() { if builder.block_level_boxes.is_empty() { - let content_sizes = if request_content_sizes { - Some( - builder - .ongoing_inline_formatting_context - .inline_content_sizes(context), - ) - } else { - None - }; + let inline_content_sizes = content_sizes.if_requests_inline(|| { + builder + .ongoing_inline_formatting_context + .inline_content_sizes(context) + }); let container = BlockContainer::InlineFormattingContext( builder.ongoing_inline_formatting_context, ); - return (container, builder.contains_floats, content_sizes); + return (container, builder.contains_floats, inline_content_sizes); } builder.end_ongoing_inline_formatting_context(); } @@ -195,11 +191,8 @@ impl BlockContainer { |target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| { let (block_level_box, box_contains_floats) = intermediate.finish( context, - if request_content_sizes { - Some(&mut target.outer_content_sizes_of_children) - } else { - None - }, + content_sizes + .if_requests_inline(|| &mut target.outer_content_sizes_of_children), ); target.contains_floats |= box_contains_floats; box_slot.set(LayoutBox::BlockLevel(block_level_box.clone())); @@ -207,19 +200,21 @@ impl BlockContainer { }, |left, right| { left.contains_floats |= right.contains_floats; - if request_content_sizes { + if content_sizes.requests_inline() { left.outer_content_sizes_of_children .max_assign(&right.outer_content_sizes_of_children) } }, ); let container = BlockContainer::BlockLevelBoxes(iter.collect()); - let content_sizes = if request_content_sizes { - Some(target.outer_content_sizes_of_children) - } else { - None - }; - (container, target.contains_floats, content_sizes) + + let Target { + contains_floats, + outer_content_sizes_of_children, + } = target; + let inline_content_sizes = + content_sizes.if_requests_inline(|| outer_content_sizes_of_children); + (container, contains_floats, inline_content_sizes) } } @@ -393,14 +388,13 @@ where inline_box.last_fragment = true; Arc::new(InlineLevelBox::InlineBox(inline_box)) } else { - let request_content_sizes = style.inline_size_is_auto(); Arc::new(InlineLevelBox::Atomic( IndependentFormattingContext::construct( self.context, style.clone(), display_inside, contents, - request_content_sizes, + ContentSizesRequest::inline_if(style.inline_size_is_auto()), ), )) }; @@ -592,12 +586,16 @@ where ) -> (Arc<BlockLevelBox>, ContainsFloats) { match self { IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => { - let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() && - style.inline_size_is_auto(); - let (contents, contains_floats, content_sizes) = - contents.finish(context, &style, request_content_sizes); + let (contents, contains_floats, inline_content_sizes) = contents.finish( + context, + &style, + ContentSizesRequest::inline_if( + max_assign_in_flow_outer_content_sizes_to.is_some() && + style.inline_size_is_auto(), + ), + ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - to.max_assign(&outer_inline_content_sizes(&style, &content_sizes)) + to.max_assign(&outer_inline_content_sizes(&style, &inline_content_sizes)) } let block_level_box = Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style }); @@ -608,14 +606,16 @@ where display_inside, contents, } => { - let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() && - style.inline_size_is_auto(); + let content_sizes = ContentSizesRequest::inline_if( + max_assign_in_flow_outer_content_sizes_to.is_some() && + style.inline_size_is_auto(), + ); let contents = IndependentFormattingContext::construct( context, style, display_inside, contents, - request_content_sizes, + content_sizes, ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { to.max_assign(&outer_inline_content_sizes( @@ -660,25 +660,22 @@ where self, context: &LayoutContext, style: &Arc<ComputedValues>, - request_content_sizes: bool, + content_sizes: ContentSizesRequest, ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) { match self { IntermediateBlockContainer::Deferred { contents } => { - BlockContainer::construct(context, style, contents, request_content_sizes) + BlockContainer::construct(context, style, contents, content_sizes) }, IntermediateBlockContainer::InlineFormattingContext(ifc) => { - let content_sizes = if request_content_sizes { - Some(ifc.inline_content_sizes(context)) - } else { - None - }; + let inline_content_sizes = + content_sizes.if_requests_inline(|| ifc.inline_content_sizes(context)); // 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, + inline_content_sizes, ) }, } diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index 6fcd06df0b5..2acc2095004 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -5,6 +5,7 @@ use crate::context::LayoutContext; use crate::dom_traversal::{Contents, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; +use crate::sizing::ContentSizesRequest; use crate::style_ext::{ComputedValuesExt, DisplayInside}; use servo_arc::Arc; use style::properties::ComputedValues; @@ -32,14 +33,14 @@ impl FloatBox { display_inside: DisplayInside, contents: Contents<impl NodeExt<'dom>>, ) -> Self { - let request_content_sizes = style.inline_size_is_auto(); + let content_sizes = ContentSizesRequest::inline_if(style.inline_size_is_auto()); Self { contents: IndependentFormattingContext::construct( context, style, display_inside, contents, - request_content_sizes, + content_sizes, ), } } diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index d5358fd28b5..6396b4dd658 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -14,6 +14,7 @@ use crate::geom; use crate::geom::flow_relative::Vec2; use crate::positioned::AbsolutelyPositionedBox; use crate::replaced::ReplacedContent; +use crate::sizing::ContentSizesRequest; use crate::style_ext::{Direction, Display, DisplayGeneratingBox, DisplayInside, WritingMode}; use crate::{ContainingBlock, DefiniteContainingBlock}; use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator}; @@ -83,7 +84,7 @@ fn construct_for_root_element<'dom>( style, display_inside, contents, - /* request_content_sizes */ false, + ContentSizesRequest::None, ), ))], ) diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index 0527d8eda38..8f62d3d8d6b 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -8,7 +8,7 @@ use crate::flow::BlockFormattingContext; use crate::fragments::Fragment; use crate::positioned::AbsolutelyPositionedFragment; use crate::replaced::ReplacedContent; -use crate::sizing::ContentSizes; +use crate::sizing::{ContentSizes, ContentSizesRequest}; use crate::style_ext::DisplayInside; use crate::ContainingBlock; use servo_arc::Arc; @@ -55,24 +55,24 @@ impl IndependentFormattingContext { style: Arc<ComputedValues>, display_inside: DisplayInside, contents: Contents<impl NodeExt<'dom>>, - request_content_sizes: bool, + content_sizes: ContentSizesRequest, ) -> Self { use self::IndependentFormattingContextContents as Contents; let (contents, inline_content_sizes) = match contents.try_into() { Ok(non_replaced) => match display_inside { DisplayInside::Flow | DisplayInside::FlowRoot => { - let (bfc, content_sizes) = BlockFormattingContext::construct( + let (bfc, inline_content_sizes) = BlockFormattingContext::construct( context, &style, non_replaced, - request_content_sizes, + content_sizes, ); - (Contents::Flow(bfc), content_sizes) + (Contents::Flow(bfc), inline_content_sizes) }, }, Err(replaced) => { - let content_sizes = None; // Unused by layout code - (Contents::Replaced(replaced), content_sizes) + let inline_content_sizes = None; // Unused by layout code + (Contents::Replaced(replaced), inline_content_sizes) }, }; Self { diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index b99b6b8293f..f2a6551f6c1 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -7,7 +7,7 @@ use crate::dom_traversal::{Contents, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; -use crate::sizing::shrink_to_fit; +use crate::sizing::{shrink_to_fit, ContentSizesRequest}; use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode}; use crate::{ContainingBlock, DefiniteContainingBlock}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -53,21 +53,21 @@ impl AbsolutelyPositionedBox { contents: Contents<impl NodeExt<'dom>>, ) -> Self { // "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width - let request_content_sizes = { + let content_sizes = ContentSizesRequest::inline_if( // If inline-size is non-auto, that value is used without shrink-to-fit style.inline_size_is_auto() && // 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. - !style.inline_box_offsets_are_both_non_auto() - }; + !style.inline_box_offsets_are_both_non_auto(), + ); Self { contents: IndependentFormattingContext::construct( context, style, display_inside, contents, - request_content_sizes, + content_sizes, ), } } diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs index 0fdb36d7600..1a036dbd083 100644 --- a/components/layout_2020/sizing.rs +++ b/components/layout_2020/sizing.rs @@ -9,6 +9,37 @@ 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, + } + } +} + #[derive(Clone, Debug)] pub(crate) struct ContentSizes { pub min_content: Length, |