mirror of
https://github.com/servo/servo.git
synced 2025-07-25 08:10:21 +01:00
Add content sizes computation for block containers
This commit is contained in:
parent
78bfa45eab
commit
303b36f17b
3 changed files with 73 additions and 29 deletions
|
@ -10,6 +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::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;
|
||||||
|
@ -25,6 +26,8 @@ impl BlockFormattingContext {
|
||||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (contents, contains_floats) = BlockContainer::construct(context, style, contents);
|
let (contents, contains_floats) = BlockContainer::construct(context, style, contents);
|
||||||
|
// FIXME: add contribution to `content_sizes` of floats in this formatting context
|
||||||
|
// https://dbaron.org/css/intrinsic/#intrinsic
|
||||||
Self {
|
Self {
|
||||||
contents,
|
contents,
|
||||||
contains_floats: contains_floats == ContainsFloats::Yes,
|
contains_floats: contains_floats == ContainsFloats::Yes,
|
||||||
|
@ -127,16 +130,17 @@ 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>>,
|
||||||
//intrinsic_sizes_requested: bool,
|
//request_content_sizes: bool,
|
||||||
) -> (BlockContainer, ContainsFloats) {
|
) -> (BlockContainer, ContainsFloats) {
|
||||||
|
let request_content_sizes = false; // FIXME
|
||||||
let mut builder = BlockContainerBuilder {
|
let mut builder = BlockContainerBuilder {
|
||||||
context,
|
context,
|
||||||
block_container_style,
|
block_container_style,
|
||||||
block_level_boxes: Default::default(),
|
block_level_boxes: Vec::new(),
|
||||||
ongoing_inline_formatting_context: Default::default(),
|
ongoing_inline_formatting_context: InlineFormattingContext::default(),
|
||||||
ongoing_inline_boxes_stack: Default::default(),
|
ongoing_inline_boxes_stack: Vec::new(),
|
||||||
anonymous_style: Default::default(),
|
anonymous_style: None,
|
||||||
contains_floats: Default::default(),
|
contains_floats: ContainsFloats::No,
|
||||||
};
|
};
|
||||||
|
|
||||||
contents.traverse(block_container_style, context, &mut builder);
|
contents.traverse(block_container_style, context, &mut builder);
|
||||||
|
@ -158,25 +162,46 @@ impl BlockContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Intermediate<Node> = IntermediateBlockLevelBox<Node>;
|
type Intermediate<Node> = IntermediateBlockLevelBox<Node>;
|
||||||
#[derive(Default)]
|
|
||||||
struct Target {
|
struct Target {
|
||||||
contains_floats: ContainsFloats,
|
contains_floats: ContainsFloats,
|
||||||
|
outer_content_sizes_of_children: ContentSizes,
|
||||||
|
}
|
||||||
|
impl Default for Target {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
contains_floats: ContainsFloats::No,
|
||||||
|
outer_content_sizes_of_children: ContentSizes::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mut target = Target {
|
let mut target = Target {
|
||||||
contains_floats: builder.contains_floats,
|
contains_floats: builder.contains_floats,
|
||||||
|
outer_content_sizes_of_children: ContentSizes::zero(),
|
||||||
};
|
};
|
||||||
let request_content_sizes = false; // FIXME
|
let request_childrens_outer_content_sizes = request_content_sizes;
|
||||||
let iter = builder.block_level_boxes.into_par_iter();
|
let iter = builder.block_level_boxes.into_par_iter();
|
||||||
let iter = iter.mapfold_reduce_into(
|
let iter = iter.mapfold_reduce_into(
|
||||||
&mut target,
|
&mut target,
|
||||||
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
||||||
let (block_level_box, box_contains_floats) =
|
let (block_level_box, box_contains_floats) = intermediate.finish(
|
||||||
intermediate.finish(context, request_content_sizes);
|
context,
|
||||||
|
if request_childrens_outer_content_sizes {
|
||||||
|
Some(&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()));
|
||||||
block_level_box
|
block_level_box
|
||||||
},
|
},
|
||||||
|left, right| left.contains_floats |= right.contains_floats,
|
|left, right| {
|
||||||
|
left.contains_floats |= right.contains_floats;
|
||||||
|
if request_content_sizes {
|
||||||
|
left.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());
|
||||||
(container, target.contains_floats)
|
(container, target.contains_floats)
|
||||||
|
@ -548,11 +573,18 @@ where
|
||||||
fn finish(
|
fn finish(
|
||||||
self,
|
self,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
parent_requests_outer_content_sizes: bool,
|
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
|
||||||
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => {
|
||||||
let (contents, contains_floats) = contents.finish(context, &style);
|
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);
|
||||||
|
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()))
|
||||||
|
}
|
||||||
let block_level_box =
|
let block_level_box =
|
||||||
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
|
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
|
||||||
(block_level_box, contains_floats)
|
(block_level_box, contains_floats)
|
||||||
|
@ -563,7 +595,8 @@ where
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => {
|
||||||
let request_content_sizes =
|
let request_content_sizes =
|
||||||
parent_requests_outer_content_sizes && 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,
|
||||||
|
@ -571,6 +604,10 @@ where
|
||||||
contents,
|
contents,
|
||||||
request_content_sizes,
|
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()))
|
||||||
|
}
|
||||||
(
|
(
|
||||||
Arc::new(BlockLevelBox::Independent(contents)),
|
Arc::new(BlockLevelBox::Independent(contents)),
|
||||||
ContainsFloats::No,
|
ContainsFloats::No,
|
||||||
|
@ -608,6 +645,7 @@ where
|
||||||
self,
|
self,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
|
_request_content_sizes: bool,
|
||||||
) -> (BlockContainer, ContainsFloats) {
|
) -> (BlockContainer, ContainsFloats) {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockContainer::Deferred { contents } => {
|
IntermediateBlockContainer::Deferred { contents } => {
|
||||||
|
@ -639,9 +677,3 @@ impl std::ops::BitOrAssign for ContainsFloats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ContainsFloats {
|
|
||||||
fn default() -> Self {
|
|
||||||
ContainsFloats::No
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::fragments::CollapsedBlockMargins;
|
||||||
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
|
use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment};
|
||||||
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment};
|
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment};
|
||||||
use crate::sizing::{outer_inline_content_sizes, ContentSizes};
|
use crate::sizing::{outer_inline_content_sizes_and_percentages, ContentSizes};
|
||||||
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
|
use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside};
|
||||||
use crate::{relative_adjustement, ContainingBlock};
|
use crate::{relative_adjustement, ContainingBlock};
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
@ -148,14 +148,11 @@ impl InlineFormattingContext {
|
||||||
},
|
},
|
||||||
InlineLevelBox::Atomic(atomic) => {
|
InlineLevelBox::Atomic(atomic) => {
|
||||||
let inner = || {
|
let inner = || {
|
||||||
// atomic
|
// &atomic.inline_content_sizes
|
||||||
// .inline_content_sizes
|
|
||||||
// .as_ref()
|
|
||||||
// .expect("Accessing content size that was not requested")
|
|
||||||
// .clone()
|
|
||||||
todo!()
|
todo!()
|
||||||
};
|
};
|
||||||
let (outer, pc) = outer_inline_content_sizes(&atomic.style, &inner);
|
let (outer, pc) = outer_inline_content_sizes_and_percentages(
|
||||||
|
&atomic.style, inner());
|
||||||
self.current_line.min_content += outer.min_content;
|
self.current_line.min_content += outer.min_content;
|
||||||
self.current_line.max_content += outer.max_content;
|
self.current_line.max_content += outer.max_content;
|
||||||
self.current_line_percentages += pc;
|
self.current_line_percentages += pc;
|
||||||
|
|
|
@ -24,6 +24,11 @@ impl ContentSizes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn max_assign(&mut self, other: &Self) {
|
||||||
|
self.min_content.max_assign(other.min_content);
|
||||||
|
self.max_content.max_assign(other.max_content);
|
||||||
|
}
|
||||||
|
|
||||||
/// Relevant to outer intrinsic inline sizes, for percentages from padding and margin.
|
/// Relevant to outer intrinsic inline sizes, for percentages from padding and margin.
|
||||||
pub fn adjust_for_pbm_percentages(&mut self, percentages: Percentage) {
|
pub fn adjust_for_pbm_percentages(&mut self, percentages: Percentage) {
|
||||||
// " Note that this may yield an infinite result, but undefined results
|
// " Note that this may yield an infinite result, but undefined results
|
||||||
|
@ -41,7 +46,17 @@ impl ContentSizes {
|
||||||
/// https://dbaron.org/css/intrinsic/#outer-intrinsic
|
/// https://dbaron.org/css/intrinsic/#outer-intrinsic
|
||||||
pub(crate) fn outer_inline_content_sizes(
|
pub(crate) fn outer_inline_content_sizes(
|
||||||
style: &ComputedValues,
|
style: &ComputedValues,
|
||||||
get_inner_intrinsic_sizes: &dyn Fn() -> ContentSizes,
|
inner_content_sizes: &Option<ContentSizes>,
|
||||||
|
) -> ContentSizes {
|
||||||
|
let (mut outer, percentages) =
|
||||||
|
outer_inline_content_sizes_and_percentages(style, inner_content_sizes);
|
||||||
|
outer.adjust_for_pbm_percentages(percentages);
|
||||||
|
outer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn outer_inline_content_sizes_and_percentages(
|
||||||
|
style: &ComputedValues,
|
||||||
|
inner_content_sizes: &Option<ContentSizes>,
|
||||||
) -> (ContentSizes, Percentage) {
|
) -> (ContentSizes, Percentage) {
|
||||||
// FIXME: account for 'min-width', 'max-width', 'box-sizing'
|
// FIXME: account for 'min-width', 'max-width', 'box-sizing'
|
||||||
|
|
||||||
|
@ -50,7 +65,7 @@ pub(crate) fn outer_inline_content_sizes(
|
||||||
let specified = specified.map(|lp| lp.as_length());
|
let specified = specified.map(|lp| lp.as_length());
|
||||||
// The (inner) min/max-content are only used for 'auto'
|
// The (inner) min/max-content are only used for 'auto'
|
||||||
let mut outer = match specified.non_auto().flatten() {
|
let mut outer = match specified.non_auto().flatten() {
|
||||||
None => get_inner_intrinsic_sizes(),
|
None => inner_content_sizes.as_ref().expect("Accessing content size that was not requested").clone(),
|
||||||
Some(length) => ContentSizes {
|
Some(length) => ContentSizes {
|
||||||
min_content: length,
|
min_content: length,
|
||||||
max_content: length,
|
max_content: length,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue