diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2019-12-03 02:19:48 +0100 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2019-12-03 15:11:35 +0100 |
commit | c056e5b6b0dcd3a0226c02b6ffbe544a085da567 (patch) | |
tree | 27a9a434a4308efb1bddff489691f6c2cbc81fa5 /components | |
parent | da36fcddb05da8a4370c006f937ab43682d057c0 (diff) | |
download | servo-c056e5b6b0dcd3a0226c02b6ffbe544a085da567.tar.gz servo-c056e5b6b0dcd3a0226c02b6ffbe544a085da567.zip |
Finish plumbing intrinsic min/max-content through box construction
Diffstat (limited to 'components')
-rw-r--r-- | components/layout_2020/dom_traversal.rs | 3 | ||||
-rw-r--r-- | components/layout_2020/flow/construct.rs | 68 | ||||
-rw-r--r-- | components/layout_2020/flow/inline.rs | 11 | ||||
-rw-r--r-- | components/layout_2020/formatting_contexts.rs | 32 | ||||
-rw-r--r-- | components/layout_2020/sizing.rs | 5 |
5 files changed, 80 insertions, 39 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index b71395cf1f4..056103d7205 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -192,8 +192,7 @@ impl<Node> Contents<Node> { /// Returns true iff the `try_from` impl below would return `Err(_)` pub fn is_replaced(&self) -> bool { match self { - Contents::OfElement(_) | - Contents::OfPseudoElement(_) => false, + Contents::OfElement(_) | Contents::OfPseudoElement(_) => false, Contents::Replaced(_) => true, } } diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index f7490f4c605..80f44b2ff81 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -24,14 +24,17 @@ impl BlockFormattingContext { context: &LayoutContext, style: &Arc<ComputedValues>, contents: NonReplacedContents<impl NodeExt<'dom>>, - ) -> Self { - let (contents, contains_floats) = BlockContainer::construct(context, style, contents); + request_content_sizes: bool, + ) -> (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 // https://dbaron.org/css/intrinsic/#intrinsic - Self { + let bfc = Self { contents, contains_floats: contains_floats == ContainsFloats::Yes, - } + }; + (bfc, content_sizes) } } @@ -130,9 +133,8 @@ impl BlockContainer { context: &LayoutContext, block_container_style: &Arc<ComputedValues>, contents: NonReplacedContents<impl NodeExt<'dom>>, - //request_content_sizes: bool, - ) -> (BlockContainer, ContainsFloats) { - let request_content_sizes = false; // FIXME + request_content_sizes: bool, + ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) { let mut builder = BlockContainerBuilder { context, block_container_style, @@ -153,10 +155,19 @@ 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 container = BlockContainer::InlineFormattingContext( builder.ongoing_inline_formatting_context, ); - return (container, builder.contains_floats); + return (container, builder.contains_floats, content_sizes); } builder.end_ongoing_inline_formatting_context(); } @@ -204,7 +215,12 @@ impl BlockContainer { }, ); let container = BlockContainer::BlockLevelBoxes(iter.collect()); - (container, target.contains_floats) + let content_sizes = if request_content_sizes { + Some(target.outer_content_sizes_of_children) + } else { + None + }; + (container, target.contains_floats, content_sizes) } } @@ -367,7 +383,9 @@ where }); // `unwrap` doesn’t panic here because `is_replaced` returned `false`. - NonReplacedContents::try_from(contents).unwrap().traverse(&style, self.context, self); + NonReplacedContents::try_from(contents) + .unwrap() + .traverse(&style, self.context, self); let mut inline_box = self .ongoing_inline_boxes_stack @@ -575,13 +593,12 @@ where ) -> (Arc<BlockLevelBox>, ContainsFloats) { match self { IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => { - let request_content_sizes = - max_assign_in_flow_outer_content_sizes_to.is_some() && + let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() && style.inline_size_is_auto(); - let (contents, contains_floats) = contents.finish(context, &style, request_content_sizes); + let (contents, contains_floats, content_sizes) = + contents.finish(context, &style, request_content_sizes); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - let get_content_size = || todo!(); - to.max_assign(&outer_inline_content_sizes(&style, get_content_size())) + to.max_assign(&outer_inline_content_sizes(&style, &content_sizes)) } let block_level_box = Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style }); @@ -592,8 +609,7 @@ where display_inside, contents, } => { - let request_content_sizes = - max_assign_in_flow_outer_content_sizes_to.is_some() && + let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() && style.inline_size_is_auto(); let contents = IndependentFormattingContext::construct( context, @@ -603,8 +619,10 @@ where request_content_sizes, ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - let get_content_size = || todo!(); - to.max_assign(&outer_inline_content_sizes(&contents.style, get_content_size())) + to.max_assign(&outer_inline_content_sizes( + &contents.style, + &contents.inline_content_sizes, + )) } ( Arc::new(BlockLevelBox::Independent(contents)), @@ -643,19 +661,25 @@ where self, context: &LayoutContext, style: &Arc<ComputedValues>, - _request_content_sizes: bool, - ) -> (BlockContainer, ContainsFloats) { + request_content_sizes: bool, + ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) { match self { IntermediateBlockContainer::Deferred { contents } => { - BlockContainer::construct(context, style, contents) + BlockContainer::construct(context, style, contents, request_content_sizes) }, IntermediateBlockContainer::InlineFormattingContext(ifc) => { + let content_sizes = if request_content_sizes { + Some(ifc.inline_content_sizes(context)) + } else { + None + }; // 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/inline.rs b/components/layout_2020/flow/inline.rs index 605b87e3699..53cc3ad2ec2 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -84,8 +84,7 @@ impl InlineFormattingContext { // This works on an already-constructed `InlineFormattingContext`, // Which would have to change if/when // `BlockContainer::construct` parallelize their construction. - #[allow(unused)] - pub(super) fn content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes { + pub(super) fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes { struct Computation { paragraph: ContentSizes, current_line: ContentSizes, @@ -147,12 +146,10 @@ impl InlineFormattingContext { } }, InlineLevelBox::Atomic(atomic) => { - let inner = || { - // &atomic.inline_content_sizes - todo!() - }; let (outer, pc) = outer_inline_content_sizes_and_percentages( - &atomic.style, inner()); + &atomic.style, + &atomic.inline_content_sizes, + ); self.current_line.min_content += outer.min_content; self.current_line.max_content += outer.max_content; self.current_line_percentages += pc; diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index 9b11c28246c..c6e4611db56 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -8,6 +8,7 @@ use crate::flow::BlockFormattingContext; use crate::fragments::Fragment; use crate::positioned::AbsolutelyPositionedFragment; use crate::replaced::ReplacedContent; +use crate::sizing::ContentSizes; use crate::style_ext::DisplayInside; use crate::ContainingBlock; use servo_arc::Arc; @@ -19,6 +20,10 @@ use style::values::computed::Length; #[derive(Debug)] pub(crate) struct IndependentFormattingContext { pub style: Arc<ComputedValues>, + + /// If it was requested during construction + pub inline_content_sizes: Option<ContentSizes>, + contents: IndependentFormattingContextContents, } @@ -50,18 +55,31 @@ impl IndependentFormattingContext { style: Arc<ComputedValues>, display_inside: DisplayInside, contents: Contents<impl NodeExt<'dom>>, - _request_content_sizes: bool, // Ignored for replaced content + request_content_sizes: bool, ) -> Self { use self::IndependentFormattingContextContents as Contents; - let contents = match contents.try_into() { + let (contents, inline_content_sizes) = match contents.try_into() { Ok(non_replaced) => match display_inside { - DisplayInside::Flow | DisplayInside::FlowRoot => Contents::Flow( - BlockFormattingContext::construct(context, &style, non_replaced), - ), + DisplayInside::Flow | DisplayInside::FlowRoot => { + let (bfc, content_sizes) = BlockFormattingContext::construct( + context, + &style, + non_replaced, + request_content_sizes, + ); + (Contents::Flow(bfc), content_sizes) + }, + }, + Err(replaced) => { + let content_sizes = None; // Unused by layout code + (Contents::Replaced(replaced), content_sizes) }, - Err(replaced) => Contents::Replaced(replaced), }; - Self { style, contents } + Self { + style, + contents, + inline_content_sizes, + } } pub fn as_replaced(&self) -> Result<&ReplacedContent, NonReplacedIFC> { diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs index 998c2e2b419..a58602d23fd 100644 --- a/components/layout_2020/sizing.rs +++ b/components/layout_2020/sizing.rs @@ -65,7 +65,10 @@ pub(crate) fn outer_inline_content_sizes_and_percentages( let specified = specified.map(|lp| lp.as_length()); // The (inner) min/max-content are only used for 'auto' let mut outer = match specified.non_auto().flatten() { - None => inner_content_sizes.as_ref().expect("Accessing content size that was not requested").clone(), + None => inner_content_sizes + .as_ref() + .expect("Accessing content size that was not requested") + .clone(), Some(length) => ContentSizes { min_content: length, max_content: length, |