mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Replace boolean parameters by a new ContentSizesRequest
enum
This commit is contained in:
parent
6763e7e4ae
commit
38e8fd1e99
6 changed files with 92 additions and 62 deletions
|
@ -10,7 +10,7 @@ use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox, Te
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
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 crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use rayon_croissant::ParallelIteratorExt;
|
use rayon_croissant::ParallelIteratorExt;
|
||||||
|
@ -24,17 +24,17 @@ impl BlockFormattingContext {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
||||||
request_content_sizes: bool,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (Self, Option<ContentSizes>) {
|
) -> (Self, Option<ContentSizes>) {
|
||||||
let (contents, contains_floats, content_sizes) =
|
let (contents, contains_floats, inline_content_sizes) =
|
||||||
BlockContainer::construct(context, style, contents, request_content_sizes);
|
BlockContainer::construct(context, style, contents, content_sizes);
|
||||||
// FIXME: add contribution to `content_sizes` of floats in this formatting context
|
// FIXME: add contribution to `inline_content_sizes` of floats in this formatting context
|
||||||
// https://dbaron.org/css/intrinsic/#intrinsic
|
// https://dbaron.org/css/intrinsic/#intrinsic
|
||||||
let bfc = Self {
|
let bfc = Self {
|
||||||
contents,
|
contents,
|
||||||
contains_floats: contains_floats == ContainsFloats::Yes,
|
contains_floats: contains_floats == ContainsFloats::Yes,
|
||||||
};
|
};
|
||||||
(bfc, content_sizes)
|
(bfc, inline_content_sizes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ impl BlockContainer {
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
block_container_style: &Arc<ComputedValues>,
|
block_container_style: &Arc<ComputedValues>,
|
||||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
||||||
request_content_sizes: bool,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
|
) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
|
||||||
let mut builder = BlockContainerBuilder {
|
let mut builder = BlockContainerBuilder {
|
||||||
context,
|
context,
|
||||||
|
@ -155,19 +155,15 @@ impl BlockContainer {
|
||||||
.is_empty()
|
.is_empty()
|
||||||
{
|
{
|
||||||
if builder.block_level_boxes.is_empty() {
|
if builder.block_level_boxes.is_empty() {
|
||||||
let content_sizes = if request_content_sizes {
|
let inline_content_sizes = content_sizes.if_requests_inline(|| {
|
||||||
Some(
|
builder
|
||||||
builder
|
.ongoing_inline_formatting_context
|
||||||
.ongoing_inline_formatting_context
|
.inline_content_sizes(context)
|
||||||
.inline_content_sizes(context),
|
});
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let container = BlockContainer::InlineFormattingContext(
|
let container = BlockContainer::InlineFormattingContext(
|
||||||
builder.ongoing_inline_formatting_context,
|
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();
|
builder.end_ongoing_inline_formatting_context();
|
||||||
}
|
}
|
||||||
|
@ -195,11 +191,8 @@ impl BlockContainer {
|
||||||
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
||||||
let (block_level_box, box_contains_floats) = intermediate.finish(
|
let (block_level_box, box_contains_floats) = intermediate.finish(
|
||||||
context,
|
context,
|
||||||
if request_content_sizes {
|
content_sizes
|
||||||
Some(&mut target.outer_content_sizes_of_children)
|
.if_requests_inline(|| &mut target.outer_content_sizes_of_children),
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
target.contains_floats |= box_contains_floats;
|
target.contains_floats |= box_contains_floats;
|
||||||
box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
|
box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
|
||||||
|
@ -207,19 +200,21 @@ impl BlockContainer {
|
||||||
},
|
},
|
||||||
|left, right| {
|
|left, right| {
|
||||||
left.contains_floats |= right.contains_floats;
|
left.contains_floats |= right.contains_floats;
|
||||||
if request_content_sizes {
|
if content_sizes.requests_inline() {
|
||||||
left.outer_content_sizes_of_children
|
left.outer_content_sizes_of_children
|
||||||
.max_assign(&right.outer_content_sizes_of_children)
|
.max_assign(&right.outer_content_sizes_of_children)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let container = BlockContainer::BlockLevelBoxes(iter.collect());
|
let container = BlockContainer::BlockLevelBoxes(iter.collect());
|
||||||
let content_sizes = if request_content_sizes {
|
|
||||||
Some(target.outer_content_sizes_of_children)
|
let Target {
|
||||||
} else {
|
contains_floats,
|
||||||
None
|
outer_content_sizes_of_children,
|
||||||
};
|
} = target;
|
||||||
(container, target.contains_floats, content_sizes)
|
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;
|
inline_box.last_fragment = true;
|
||||||
Arc::new(InlineLevelBox::InlineBox(inline_box))
|
Arc::new(InlineLevelBox::InlineBox(inline_box))
|
||||||
} else {
|
} else {
|
||||||
let request_content_sizes = style.inline_size_is_auto();
|
|
||||||
Arc::new(InlineLevelBox::Atomic(
|
Arc::new(InlineLevelBox::Atomic(
|
||||||
IndependentFormattingContext::construct(
|
IndependentFormattingContext::construct(
|
||||||
self.context,
|
self.context,
|
||||||
style.clone(),
|
style.clone(),
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
request_content_sizes,
|
ContentSizesRequest::inline_if(style.inline_size_is_auto()),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
@ -592,12 +586,16 @@ where
|
||||||
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
||||||
let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
let (contents, contains_floats, inline_content_sizes) = contents.finish(
|
||||||
style.inline_size_is_auto();
|
context,
|
||||||
let (contents, contains_floats, content_sizes) =
|
&style,
|
||||||
contents.finish(context, &style, request_content_sizes);
|
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 {
|
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 =
|
let block_level_box =
|
||||||
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
|
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
|
||||||
|
@ -608,14 +606,16 @@ where
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => {
|
||||||
let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
let content_sizes = ContentSizesRequest::inline_if(
|
||||||
style.inline_size_is_auto();
|
max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
||||||
|
style.inline_size_is_auto(),
|
||||||
|
);
|
||||||
let contents = IndependentFormattingContext::construct(
|
let contents = IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
request_content_sizes,
|
content_sizes,
|
||||||
);
|
);
|
||||||
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
|
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
|
||||||
to.max_assign(&outer_inline_content_sizes(
|
to.max_assign(&outer_inline_content_sizes(
|
||||||
|
@ -660,25 +660,22 @@ where
|
||||||
self,
|
self,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
request_content_sizes: bool,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
|
) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockContainer::Deferred { contents } => {
|
IntermediateBlockContainer::Deferred { contents } => {
|
||||||
BlockContainer::construct(context, style, contents, request_content_sizes)
|
BlockContainer::construct(context, style, contents, content_sizes)
|
||||||
},
|
},
|
||||||
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
||||||
let content_sizes = if request_content_sizes {
|
let inline_content_sizes =
|
||||||
Some(ifc.inline_content_sizes(context))
|
content_sizes.if_requests_inline(|| ifc.inline_content_sizes(context));
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
// If that inline formatting context contained any float, those
|
// If that inline formatting context contained any float, those
|
||||||
// were already taken into account during the first phase of
|
// were already taken into account during the first phase of
|
||||||
// box construction.
|
// box construction.
|
||||||
(
|
(
|
||||||
BlockContainer::InlineFormattingContext(ifc),
|
BlockContainer::InlineFormattingContext(ifc),
|
||||||
ContainsFloats::No,
|
ContainsFloats::No,
|
||||||
content_sizes,
|
inline_content_sizes,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom_traversal::{Contents, NodeExt};
|
use crate::dom_traversal::{Contents, NodeExt};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
|
use crate::sizing::ContentSizesRequest;
|
||||||
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
@ -32,14 +33,14 @@ impl FloatBox {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents<impl NodeExt<'dom>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let request_content_sizes = style.inline_size_is_auto();
|
let content_sizes = ContentSizesRequest::inline_if(style.inline_size_is_auto());
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
request_content_sizes,
|
content_sizes,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::geom;
|
||||||
use crate::geom::flow_relative::Vec2;
|
use crate::geom::flow_relative::Vec2;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
use crate::replaced::ReplacedContent;
|
use crate::replaced::ReplacedContent;
|
||||||
|
use crate::sizing::ContentSizesRequest;
|
||||||
use crate::style_ext::{Direction, Display, DisplayGeneratingBox, DisplayInside, WritingMode};
|
use crate::style_ext::{Direction, Display, DisplayGeneratingBox, DisplayInside, WritingMode};
|
||||||
use crate::{ContainingBlock, DefiniteContainingBlock};
|
use crate::{ContainingBlock, DefiniteContainingBlock};
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator};
|
||||||
|
@ -83,7 +84,7 @@ fn construct_for_root_element<'dom>(
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
/* request_content_sizes */ false,
|
ContentSizesRequest::None,
|
||||||
),
|
),
|
||||||
))],
|
))],
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::flow::BlockFormattingContext;
|
||||||
use crate::fragments::Fragment;
|
use crate::fragments::Fragment;
|
||||||
use crate::positioned::AbsolutelyPositionedFragment;
|
use crate::positioned::AbsolutelyPositionedFragment;
|
||||||
use crate::replaced::ReplacedContent;
|
use crate::replaced::ReplacedContent;
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::{ContentSizes, ContentSizesRequest};
|
||||||
use crate::style_ext::DisplayInside;
|
use crate::style_ext::DisplayInside;
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
|
@ -55,24 +55,24 @@ impl IndependentFormattingContext {
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents<impl NodeExt<'dom>>,
|
||||||
request_content_sizes: bool,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
use self::IndependentFormattingContextContents as Contents;
|
use self::IndependentFormattingContextContents as Contents;
|
||||||
let (contents, inline_content_sizes) = match contents.try_into() {
|
let (contents, inline_content_sizes) = match contents.try_into() {
|
||||||
Ok(non_replaced) => match display_inside {
|
Ok(non_replaced) => match display_inside {
|
||||||
DisplayInside::Flow | DisplayInside::FlowRoot => {
|
DisplayInside::Flow | DisplayInside::FlowRoot => {
|
||||||
let (bfc, content_sizes) = BlockFormattingContext::construct(
|
let (bfc, inline_content_sizes) = BlockFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
&style,
|
&style,
|
||||||
non_replaced,
|
non_replaced,
|
||||||
request_content_sizes,
|
content_sizes,
|
||||||
);
|
);
|
||||||
(Contents::Flow(bfc), content_sizes)
|
(Contents::Flow(bfc), inline_content_sizes)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Err(replaced) => {
|
Err(replaced) => {
|
||||||
let content_sizes = None; // Unused by layout code
|
let inline_content_sizes = None; // Unused by layout code
|
||||||
(Contents::Replaced(replaced), content_sizes)
|
(Contents::Replaced(replaced), inline_content_sizes)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::dom_traversal::{Contents, NodeExt};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, CollapsedBlockMargins, Fragment};
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
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::style_ext::{ComputedValuesExt, Direction, DisplayInside, WritingMode};
|
||||||
use crate::{ContainingBlock, DefiniteContainingBlock};
|
use crate::{ContainingBlock, DefiniteContainingBlock};
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
|
@ -53,21 +53,21 @@ impl AbsolutelyPositionedBox {
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents<impl NodeExt<'dom>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
|
// "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
|
// If inline-size is non-auto, that value is used without shrink-to-fit
|
||||||
style.inline_size_is_auto() &&
|
style.inline_size_is_auto() &&
|
||||||
// If it is, then the only case where shrink-to-fit is *not* used is
|
// 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
|
// if both offsets are non-auto, leaving inline-size as the only variable
|
||||||
// in the constraint equation.
|
// in the constraint equation.
|
||||||
!style.inline_box_offsets_are_both_non_auto()
|
!style.inline_box_offsets_are_both_non_auto(),
|
||||||
};
|
);
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
request_content_sizes,
|
content_sizes,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,37 @@ use style::properties::ComputedValues;
|
||||||
use style::values::computed::{Length, LengthPercentage, Percentage};
|
use style::values::computed::{Length, LengthPercentage, Percentage};
|
||||||
use style::Zero;
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct ContentSizes {
|
pub(crate) struct ContentSizes {
|
||||||
pub min_content: Length,
|
pub min_content: Length,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue