Add a request_content_sizes parameter to IndependentFormattingContext::construct

This commit is contained in:
Simon Sapin 2019-12-03 00:45:29 +01:00
parent 2c124b9d0b
commit cfdd23ac16
8 changed files with 101 additions and 52 deletions

View file

@ -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,
<Contents<Node>>::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<BlockLevelBox>, 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)
},
}

View file

@ -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<ComputedValues>,
display_inside: DisplayInside,
contents: Contents<impl NodeExt<'dom>>,
) -> Self {
let request_content_sizes = style.inline_size_is_auto();
Self {
contents: IndependentFormattingContext::construct(
context,
style,
display_inside,
contents,
request_content_sizes,
),
}
}
}

View file

@ -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;

View file

@ -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,
),
))],
)
}
}

View file

@ -50,6 +50,7 @@ impl IndependentFormattingContext {
style: Arc<ComputedValues>,
display_inside: DisplayInside,
contents: Contents<impl NodeExt<'dom>>,
_request_content_sizes: bool, // Ignored for replaced content
) -> Self {
use self::IndependentFormattingContextContents as Contents;
let contents = match contents.try_into() {

View file

@ -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<NonStatic> {
}
impl AbsolutelyPositionedBox {
pub fn construct<'dom>(
context: &LayoutContext,
style: Arc<ComputedValues>,
display_inside: DisplayInside,
contents: Contents<impl NodeExt<'dom>>,
) -> 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<Length>,

View file

@ -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<LengthPercentageOrAuto>;
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto>;
fn padding(&self) -> flow_relative::Sides<LengthPercentage>;
@ -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<LengthPercentageOrAuto> {
let position = self.get_position();

View file

@ -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