mirror of
https://github.com/servo/servo.git
synced 2025-07-16 03:43:38 +01:00
layout: Unify layout logic for replaced and non-replaced floats&atomics (#37897)
Laying out a float or atomic inline will now use the same logic regardless of whether it's replaced or not. This reduces the amount of code, and should have no observable effect. Testing: Unneeded (no behavior change) This part of #37942 Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
70c57c6136
commit
47c56d8d74
4 changed files with 94 additions and 146 deletions
|
@ -2226,7 +2226,7 @@ fn block_size_is_zero_or_intrinsic(size: &StyleSize, containing_block: &Containi
|
|||
|
||||
pub(crate) struct IndependentFloatOrAtomicLayoutResult {
|
||||
pub fragment: BoxFragment,
|
||||
pub baselines: Option<Baselines>,
|
||||
pub baselines: Baselines,
|
||||
pub pbm_sums: LogicalSides<Au>,
|
||||
}
|
||||
|
||||
|
@ -2238,6 +2238,7 @@ impl IndependentFormattingContext {
|
|||
containing_block: &ContainingBlock,
|
||||
) -> IndependentFloatOrAtomicLayoutResult {
|
||||
let style = self.style();
|
||||
let writing_mode = style.writing_mode;
|
||||
let container_writing_mode = containing_block.style.writing_mode;
|
||||
let layout_style = self.layout_style();
|
||||
let content_box_sizes_and_pbm =
|
||||
|
@ -2245,115 +2246,97 @@ impl IndependentFormattingContext {
|
|||
let pbm = &content_box_sizes_and_pbm.pbm;
|
||||
let margin = pbm.margin.auto_is(Au::zero);
|
||||
let pbm_sums = pbm.padding + pbm.border + margin;
|
||||
let preferred_aspect_ratio = self.preferred_aspect_ratio(&pbm.padding_border_sums);
|
||||
let is_table = self.is_table();
|
||||
|
||||
let (fragments, content_rect, baselines, specific_layout_info) = match &self.contents {
|
||||
IndependentFormattingContextContents::Replaced(replaced) => {
|
||||
// Floats and atomic inlines can't collapse margins with their parent,
|
||||
// so don't ignore block margins when resolving a stretch block size.
|
||||
// https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
|
||||
let ignore_block_margins_for_stretch = LogicalSides1D::new(false, false);
|
||||
let available_inline_size =
|
||||
Au::zero().max(containing_block.size.inline - pbm_sums.inline_sum());
|
||||
let available_block_size = containing_block
|
||||
.size
|
||||
.block
|
||||
.to_definite()
|
||||
.map(|block_size| Au::zero().max(block_size - pbm_sums.block_sum()));
|
||||
|
||||
// https://drafts.csswg.org/css2/visudet.html#float-replaced-width
|
||||
// https://drafts.csswg.org/css2/visudet.html#inline-replaced-height
|
||||
let content_size = replaced
|
||||
.used_size_as_if_inline_element(
|
||||
containing_block,
|
||||
style,
|
||||
&content_box_sizes_and_pbm,
|
||||
ignore_block_margins_for_stretch,
|
||||
)
|
||||
.to_physical_size(container_writing_mode);
|
||||
let fragments = replaced.make_fragments(layout_context, style, content_size);
|
||||
|
||||
let content_rect = PhysicalRect::new(PhysicalPoint::zero(), content_size);
|
||||
(fragments, content_rect, None, None)
|
||||
},
|
||||
IndependentFormattingContextContents::NonReplaced(non_replaced) => {
|
||||
let writing_mode = self.style().writing_mode;
|
||||
let available_inline_size =
|
||||
Au::zero().max(containing_block.size.inline - pbm_sums.inline_sum());
|
||||
let available_block_size = containing_block
|
||||
.size
|
||||
.block
|
||||
.to_definite()
|
||||
.map(|block_size| Au::zero().max(block_size - pbm_sums.block_sum()));
|
||||
let tentative_block_size = content_box_sizes_and_pbm
|
||||
.content_box_sizes
|
||||
.block
|
||||
.resolve_extrinsic(Size::FitContent, Au::zero(), available_block_size);
|
||||
|
||||
let get_content_size = || {
|
||||
let constraint_space = ConstraintSpace::new(
|
||||
tentative_block_size,
|
||||
writing_mode,
|
||||
non_replaced.preferred_aspect_ratio(),
|
||||
);
|
||||
self.inline_content_sizes(layout_context, &constraint_space)
|
||||
.sizes
|
||||
};
|
||||
|
||||
let is_table = layout_style.is_table();
|
||||
let inline_size = content_box_sizes_and_pbm.content_box_sizes.inline.resolve(
|
||||
Direction::Inline,
|
||||
Size::FitContent,
|
||||
Au::zero,
|
||||
Some(available_inline_size),
|
||||
get_content_size,
|
||||
is_table,
|
||||
);
|
||||
|
||||
let containing_block_for_children = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: inline_size,
|
||||
block: tentative_block_size,
|
||||
},
|
||||
style: self.style(),
|
||||
};
|
||||
assert_eq!(
|
||||
container_writing_mode.is_horizontal(),
|
||||
writing_mode.is_horizontal(),
|
||||
"Mixed horizontal and vertical writing modes are not supported yet"
|
||||
);
|
||||
|
||||
let lazy_block_size = LazySize::new(
|
||||
&content_box_sizes_and_pbm.content_box_sizes.block,
|
||||
Direction::Block,
|
||||
Size::FitContent,
|
||||
Au::zero,
|
||||
available_block_size,
|
||||
is_table,
|
||||
);
|
||||
|
||||
let independent_layout = non_replaced.layout(
|
||||
layout_context,
|
||||
child_positioning_context,
|
||||
&containing_block_for_children,
|
||||
containing_block,
|
||||
&self.base,
|
||||
false, /* depends_on_block_constraints */
|
||||
&lazy_block_size,
|
||||
);
|
||||
let inline_size = independent_layout
|
||||
.content_inline_size_for_table
|
||||
.unwrap_or(inline_size);
|
||||
let block_size = lazy_block_size.resolve(|| independent_layout.content_block_size);
|
||||
|
||||
let content_size = LogicalVec2 {
|
||||
block: block_size,
|
||||
inline: inline_size,
|
||||
}
|
||||
.to_physical_size(container_writing_mode);
|
||||
let content_rect = PhysicalRect::new(PhysicalPoint::zero(), content_size);
|
||||
|
||||
(
|
||||
independent_layout.fragments,
|
||||
content_rect,
|
||||
Some(independent_layout.baselines),
|
||||
independent_layout.specific_layout_info,
|
||||
)
|
||||
},
|
||||
let tentative_block_content_size =
|
||||
self.tentative_block_content_size(preferred_aspect_ratio);
|
||||
let tentative_block_size = if let Some(block_content_size) = tentative_block_content_size {
|
||||
SizeConstraint::Definite(content_box_sizes_and_pbm.content_box_sizes.block.resolve(
|
||||
Direction::Block,
|
||||
Size::FitContent,
|
||||
Au::zero,
|
||||
available_block_size,
|
||||
|| block_content_size,
|
||||
is_table,
|
||||
))
|
||||
} else {
|
||||
content_box_sizes_and_pbm
|
||||
.content_box_sizes
|
||||
.block
|
||||
.resolve_extrinsic(Size::FitContent, Au::zero(), available_block_size)
|
||||
};
|
||||
|
||||
let get_content_size = || {
|
||||
let constraint_space =
|
||||
ConstraintSpace::new(tentative_block_size, writing_mode, preferred_aspect_ratio);
|
||||
self.inline_content_sizes(layout_context, &constraint_space)
|
||||
.sizes
|
||||
};
|
||||
|
||||
let inline_size = content_box_sizes_and_pbm.content_box_sizes.inline.resolve(
|
||||
Direction::Inline,
|
||||
Size::FitContent,
|
||||
Au::zero,
|
||||
Some(available_inline_size),
|
||||
get_content_size,
|
||||
is_table,
|
||||
);
|
||||
|
||||
let containing_block_for_children = ContainingBlock {
|
||||
size: ContainingBlockSize {
|
||||
inline: inline_size,
|
||||
block: tentative_block_size,
|
||||
},
|
||||
style,
|
||||
};
|
||||
assert_eq!(
|
||||
container_writing_mode.is_horizontal(),
|
||||
writing_mode.is_horizontal(),
|
||||
"Mixed horizontal and vertical writing modes are not supported yet"
|
||||
);
|
||||
|
||||
let lazy_block_size = LazySize::new(
|
||||
&content_box_sizes_and_pbm.content_box_sizes.block,
|
||||
Direction::Block,
|
||||
Size::FitContent,
|
||||
Au::zero,
|
||||
available_block_size,
|
||||
is_table,
|
||||
);
|
||||
|
||||
let CacheableLayoutResult {
|
||||
content_inline_size_for_table,
|
||||
content_block_size,
|
||||
fragments,
|
||||
baselines,
|
||||
specific_layout_info,
|
||||
..
|
||||
} = self.layout(
|
||||
layout_context,
|
||||
child_positioning_context,
|
||||
&containing_block_for_children,
|
||||
containing_block,
|
||||
preferred_aspect_ratio,
|
||||
false, /* depends_on_block_constraints */
|
||||
&lazy_block_size,
|
||||
);
|
||||
|
||||
let content_size = LogicalVec2 {
|
||||
inline: content_inline_size_for_table.unwrap_or(inline_size),
|
||||
block: lazy_block_size.resolve(|| content_block_size),
|
||||
}
|
||||
.to_physical_size(container_writing_mode);
|
||||
let content_rect = PhysicalRect::new(PhysicalPoint::zero(), content_size);
|
||||
|
||||
let mut base_fragment_info = self.base_fragment_info();
|
||||
if content_box_sizes_and_pbm.depends_on_block_constraints {
|
||||
base_fragment_info.flags.insert(
|
||||
|
@ -2366,7 +2349,7 @@ impl IndependentFormattingContext {
|
|||
// And atomic inlines don't have clearance.
|
||||
let fragment = BoxFragment::new(
|
||||
base_fragment_info,
|
||||
self.style().clone(),
|
||||
style.clone(),
|
||||
fragments,
|
||||
content_rect,
|
||||
pbm.padding.to_physical(container_writing_mode),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue