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::formatting_contexts::IndependentFormattingContext;
|
||||
use crate::positioned::AbsolutelyPositionedBox;
|
||||
use crate::sizing::{outer_inline_content_sizes, ContentSizes};
|
||||
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||
use rayon_croissant::ParallelIteratorExt;
|
||||
|
@ -25,6 +26,8 @@ impl BlockFormattingContext {
|
|||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
||||
) -> Self {
|
||||
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 {
|
||||
contents,
|
||||
contains_floats: contains_floats == ContainsFloats::Yes,
|
||||
|
@ -127,16 +130,17 @@ impl BlockContainer {
|
|||
context: &LayoutContext,
|
||||
block_container_style: &Arc<ComputedValues>,
|
||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
||||
//intrinsic_sizes_requested: bool,
|
||||
//request_content_sizes: bool,
|
||||
) -> (BlockContainer, ContainsFloats) {
|
||||
let request_content_sizes = false; // FIXME
|
||||
let mut builder = BlockContainerBuilder {
|
||||
context,
|
||||
block_container_style,
|
||||
block_level_boxes: Default::default(),
|
||||
ongoing_inline_formatting_context: Default::default(),
|
||||
ongoing_inline_boxes_stack: Default::default(),
|
||||
anonymous_style: Default::default(),
|
||||
contains_floats: Default::default(),
|
||||
block_level_boxes: Vec::new(),
|
||||
ongoing_inline_formatting_context: InlineFormattingContext::default(),
|
||||
ongoing_inline_boxes_stack: Vec::new(),
|
||||
anonymous_style: None,
|
||||
contains_floats: ContainsFloats::No,
|
||||
};
|
||||
|
||||
contents.traverse(block_container_style, context, &mut builder);
|
||||
|
@ -158,25 +162,46 @@ impl BlockContainer {
|
|||
}
|
||||
|
||||
type Intermediate<Node> = IntermediateBlockLevelBox<Node>;
|
||||
#[derive(Default)]
|
||||
struct Target {
|
||||
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 {
|
||||
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 = iter.mapfold_reduce_into(
|
||||
&mut target,
|
||||
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
||||
let (block_level_box, box_contains_floats) =
|
||||
intermediate.finish(context, request_content_sizes);
|
||||
let (block_level_box, box_contains_floats) = intermediate.finish(
|
||||
context,
|
||||
if request_childrens_outer_content_sizes {
|
||||
Some(&mut target.outer_content_sizes_of_children)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
);
|
||||
target.contains_floats |= box_contains_floats;
|
||||
box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
|
||||
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());
|
||||
(container, target.contains_floats)
|
||||
|
@ -548,11 +573,18 @@ where
|
|||
fn finish(
|
||||
self,
|
||||
context: &LayoutContext,
|
||||
parent_requests_outer_content_sizes: bool,
|
||||
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
|
||||
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
||||
match self {
|
||||
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 =
|
||||
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
|
||||
(block_level_box, contains_floats)
|
||||
|
@ -563,7 +595,8 @@ where
|
|||
contents,
|
||||
} => {
|
||||
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(
|
||||
context,
|
||||
style,
|
||||
|
@ -571,6 +604,10 @@ where
|
|||
contents,
|
||||
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)),
|
||||
ContainsFloats::No,
|
||||
|
@ -608,6 +645,7 @@ where
|
|||
self,
|
||||
context: &LayoutContext,
|
||||
style: &Arc<ComputedValues>,
|
||||
_request_content_sizes: bool,
|
||||
) -> (BlockContainer, ContainsFloats) {
|
||||
match self {
|
||||
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::geom::flow_relative::{Rect, Sides, Vec2};
|
||||
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::{relative_adjustement, ContainingBlock};
|
||||
use app_units::Au;
|
||||
|
@ -148,14 +148,11 @@ impl InlineFormattingContext {
|
|||
},
|
||||
InlineLevelBox::Atomic(atomic) => {
|
||||
let inner = || {
|
||||
// atomic
|
||||
// .inline_content_sizes
|
||||
// .as_ref()
|
||||
// .expect("Accessing content size that was not requested")
|
||||
// .clone()
|
||||
// &atomic.inline_content_sizes
|
||||
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.max_content += outer.max_content;
|
||||
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.
|
||||
pub fn adjust_for_pbm_percentages(&mut self, percentages: Percentage) {
|
||||
// " Note that this may yield an infinite result, but undefined results
|
||||
|
@ -41,7 +46,17 @@ impl ContentSizes {
|
|||
/// https://dbaron.org/css/intrinsic/#outer-intrinsic
|
||||
pub(crate) fn outer_inline_content_sizes(
|
||||
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) {
|
||||
// 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());
|
||||
// The (inner) min/max-content are only used for 'auto'
|
||||
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 {
|
||||
min_content: length,
|
||||
max_content: length,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue