From cfdd23ac16e3923cc388c96bbf5aab7501967f5e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 3 Dec 2019 00:45:29 +0100 Subject: [PATCH] Add a `request_content_sizes` parameter to `IndependentFormattingContext::construct` --- components/layout_2020/flow/construct.rs | 53 +++++++------------ components/layout_2020/flow/float.rs | 25 +++++++++ components/layout_2020/flow/inline.rs | 2 +- components/layout_2020/flow/root.rs | 31 +++++------ components/layout_2020/formatting_contexts.rs | 1 + components/layout_2020/positioned.rs | 24 ++++++++- components/layout_2020/style_ext.rs | 14 +++++ components/layout_thread_2020/lib.rs | 3 +- 8 files changed, 101 insertions(+), 52 deletions(-) diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 79c44911f47..0ddd4a41f88 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::style_ext::{DisplayGeneratingBox, DisplayInside, DisplayOutside}; +use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon_croissant::ParallelIteratorExt; use servo_arc::Arc; @@ -158,6 +158,7 @@ impl BlockContainer { } let mut contains_floats = builder.contains_floats; + let request_content_sizes = false; // FIXME let container = BlockContainer::BlockLevelBoxes( builder .block_level_boxes @@ -165,7 +166,7 @@ impl BlockContainer { .mapfold_reduce_into( &mut contains_floats, |contains_floats, (intermediate, box_slot): (IntermediateBlockLevelBox<_>, BoxSlot<'_>)| { - let (block_level_box, box_contains_floats) = intermediate.finish(context); + let (block_level_box, box_contains_floats) = intermediate.finish(context, request_content_sizes); *contains_floats |= box_contains_floats; box_slot.set(LayoutBox::BlockLevel(block_level_box.clone())); block_level_box @@ -332,6 +333,7 @@ where style.clone(), display_inside, >::Replaced(replaced), + false, // ignored ), )), Ok(non_replaced) => match display_inside { @@ -452,14 +454,7 @@ where self.block_level_boxes.push((box_, box_slot)); } else { let box_ = Arc::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox { - contents: IndependentFormattingContext::construct( - self.context, - style, - display_inside, - contents, - ), - }, + AbsolutelyPositionedBox::construct(self.context, style, display_inside, contents), )); self.current_inline_level_boxes().push(box_.clone()); box_slot.set(LayoutBox::InlineLevel(box_)) @@ -483,14 +478,12 @@ where }; self.block_level_boxes.push((box_, box_slot)); } else { - let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox { - contents: IndependentFormattingContext::construct( - self.context, - style, - display_inside, - contents, - ), - })); + let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct( + self.context, + style, + display_inside, + contents, + ))); self.current_inline_level_boxes().push(box_.clone()); box_slot.set(LayoutBox::InlineLevel(box_)) } @@ -551,6 +544,7 @@ where fn finish( self, context: &LayoutContext, + parent_requests_outer_content_sizes: bool, ) -> (Arc, ContainsFloats) { match self { IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => { @@ -564,11 +558,14 @@ where display_inside, contents, } => { + let request_content_sizes = + parent_requests_outer_content_sizes && style.inline_size_is_auto(); let contents = IndependentFormattingContext::construct( context, style, display_inside, contents, + request_content_sizes, ); ( Arc::new(BlockLevelBox::Independent(contents)), @@ -581,14 +578,7 @@ where contents, } => { let block_level_box = Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox { - contents: IndependentFormattingContext::construct( - context, - style, - display_inside, - contents, - ), - }, + AbsolutelyPositionedBox::construct(context, style, display_inside, contents), )); (block_level_box, ContainsFloats::No) }, @@ -597,14 +587,9 @@ where display_inside, contents, } => { - let contents = IndependentFormattingContext::construct( - context, - style, - display_inside, - contents, - ); - let block_level_box = - Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox { contents })); + let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox( + FloatBox::construct(context, style, display_inside, contents), + )); (block_level_box, ContainsFloats::Yes) }, } diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index f9be366bc97..6fcd06df0b5 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -2,7 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::context::LayoutContext; +use crate::dom_traversal::{Contents, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; +use crate::style_ext::{ComputedValuesExt, DisplayInside}; +use servo_arc::Arc; +use style::properties::ComputedValues; #[derive(Debug)] pub(crate) struct FloatBox { @@ -19,3 +24,23 @@ impl FloatContext { FloatContext {} } } + +impl FloatBox { + pub fn construct<'dom>( + context: &LayoutContext, + style: Arc, + display_inside: DisplayInside, + contents: Contents>, + ) -> Self { + let request_content_sizes = style.inline_size_is_auto(); + Self { + contents: IndependentFormattingContext::construct( + context, + style, + display_inside, + contents, + request_content_sizes, + ), + } + } +} diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 8623ca7b512..ca78fbf1956 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -9,8 +9,8 @@ use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::CollapsedBlockMargins; use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; -use crate::sizing::{outer_inline_content_sizes, ContentSizes}; use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment}; +use crate::sizing::{outer_inline_content_sizes, ContentSizes}; use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside}; use crate::{relative_adjustement, ContainingBlock}; use app_units::Au; diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index e5681f21f0c..d5358fd28b5 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -59,32 +59,33 @@ fn construct_for_root_element<'dom>( Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside, }; - let position = box_style.position; - let float = box_style.float; - let contents = IndependentFormattingContext::construct( - context, - style, - display_inside, - replaced.map_or(Contents::OfElement(root_element), Contents::Replaced), - ); - if position.is_absolutely_positioned() { + let contents = replaced.map_or(Contents::OfElement(root_element), Contents::Replaced); + if box_style.position.is_absolutely_positioned() { ( ContainsFloats::No, vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox { contents }, + AbsolutelyPositionedBox::construct(context, style, display_inside, contents), ))], ) - } else if float.is_floating() { + } else if box_style.float.is_floating() { ( ContainsFloats::Yes, - vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox { - contents, - }))], + vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox( + FloatBox::construct(context, style, display_inside, contents), + ))], ) } else { ( ContainsFloats::No, - vec![Arc::new(BlockLevelBox::Independent(contents))], + vec![Arc::new(BlockLevelBox::Independent( + IndependentFormattingContext::construct( + context, + style, + display_inside, + contents, + /* request_content_sizes */ false, + ), + ))], ) } } diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index aa643c6e9c8..9b11c28246c 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -50,6 +50,7 @@ impl IndependentFormattingContext { style: Arc, display_inside: DisplayInside, contents: Contents>, + _request_content_sizes: bool, // Ignored for replaced content ) -> Self { use self::IndependentFormattingContextContents as Contents; let contents = match contents.try_into() { diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 3577a86642b..cd801e7e1c0 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -3,12 +3,15 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::context::LayoutContext; +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::style_ext::{ComputedValuesExt, Direction, WritingMode}; +use crate::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode}; use crate::{ContainingBlock, DefiniteContainingBlock}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use servo_arc::Arc; +use style::properties::ComputedValues; use style::values::computed::{Length, LengthOrAuto, LengthPercentage, LengthPercentageOrAuto}; use style::Zero; @@ -42,6 +45,25 @@ pub(crate) enum AbsoluteBoxOffsets { } impl AbsolutelyPositionedBox { + pub fn construct<'dom>( + context: &LayoutContext, + style: Arc, + display_inside: DisplayInside, + contents: Contents>, + ) -> Self { + let request_content_sizes = + style.inline_size_is_auto() && !style.inline_box_offsets_are_both_auto(); + Self { + contents: IndependentFormattingContext::construct( + context, + style, + display_inside, + contents, + request_content_sizes, + ), + } + } + pub(crate) fn layout<'a>( &'a self, initial_start_corner: Vec2, diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 6bd2e91a2f9..436058798d9 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -45,6 +45,7 @@ pub(crate) trait ComputedValuesExt { fn writing_mode(&self) -> (WritingMode, Direction); fn writing_mode_is_horizontal(&self) -> bool; fn inline_size_is_auto(&self) -> bool; + fn inline_box_offsets_are_both_auto(&self) -> bool; fn box_offsets(&self) -> flow_relative::Sides; fn box_size(&self) -> flow_relative::Vec2; fn padding(&self) -> flow_relative::Sides; @@ -77,6 +78,19 @@ impl ComputedValuesExt for ComputedValues { matches!(size, Size::Auto) } + fn inline_box_offsets_are_both_auto(&self) -> bool { + let position = self.get_position(); + let offsets = if self.writing_mode_is_horizontal() { + (position.left, position.right) + } else { + (position.top, position.bottom) + }; + matches!( + offsets, + (LengthPercentageOrAuto::Auto, LengthPercentageOrAuto::Auto) + ) + } + #[inline] fn box_offsets(&self) -> flow_relative::Sides { let position = self.get_position(); diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index f9cdbac7943..45202d51ad9 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -1082,7 +1082,8 @@ impl LayoutThread { driver::traverse_dom(&traversal, token, Some(rayon_pool)); let root_node = document.root_element().unwrap().as_node(); - let box_tree = rayon_pool.install(|| BoxTreeRoot::construct(traversal.context(), root_node)); + let box_tree = + rayon_pool.install(|| BoxTreeRoot::construct(traversal.context(), root_node)); Some(box_tree) } else { None