mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
layout: Unify layout logic for replaced and non-replaced grid items (#37985)
Laying out a grid item 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 (but hard to say since and I don't understand Taffy). Testing: Unneeded (no behavior change) This part of #37942 Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
55fd7b862f
commit
b7133478e1
2 changed files with 82 additions and 238 deletions
|
@ -29,9 +29,9 @@ use crate::dom::NodeExt;
|
|||
use crate::fragment_tree::{
|
||||
BaseFragmentInfo, CollapsedBlockMargins, Fragment, IFrameFragment, ImageFragment,
|
||||
};
|
||||
use crate::geom::{LazySize, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes};
|
||||
use crate::geom::{LazySize, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize};
|
||||
use crate::layout_box_base::{CacheableLayoutResult, LayoutBoxBase};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::sizing::{ComputeInlineContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, LayoutStyle};
|
||||
use crate::{ConstraintSpace, ContainingBlock, SizeConstraint};
|
||||
|
||||
|
@ -474,103 +474,6 @@ impl ReplacedContents {
|
|||
.unwrap_or_else(|| Self::default_block_size(writing_mode))
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css2/visudet.html#inline-replaced-width>
|
||||
/// <https://drafts.csswg.org/css2/visudet.html#inline-replaced-height>
|
||||
///
|
||||
/// Also used in other cases, for example
|
||||
/// <https://drafts.csswg.org/css2/visudet.html#block-replaced-width>
|
||||
///
|
||||
/// The logic differs from CSS2 in order to properly handle `aspect-ratio` and keyword sizes.
|
||||
/// Each axis can have preferred, min and max sizing constraints, plus constraints transferred
|
||||
/// from the other axis if there is an aspect ratio, plus a natural and default size.
|
||||
/// In case of conflict, the order of precedence (from highest to lowest) is:
|
||||
/// 1. Non-transferred min constraint
|
||||
/// 2. Non-transferred max constraint
|
||||
/// 3. Non-transferred preferred constraint
|
||||
/// 4. Transferred min constraint
|
||||
/// 5. Transferred max constraint
|
||||
/// 6. Transferred preferred constraint
|
||||
/// 7. Natural size
|
||||
/// 8. Default object size
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers>
|
||||
/// <https://github.com/w3c/csswg-drafts/issues/6071#issuecomment-2243986313>
|
||||
pub(crate) fn used_size_as_if_inline_element_from_content_box_sizes(
|
||||
&self,
|
||||
containing_block: &ContainingBlock,
|
||||
style: &ComputedValues,
|
||||
preferred_aspect_ratio: Option<AspectRatio>,
|
||||
sizes: LogicalVec2<&Sizes>,
|
||||
automatic_size: LogicalVec2<Size<Au>>,
|
||||
pbm_sums: LogicalVec2<Au>,
|
||||
) -> LogicalVec2<Au> {
|
||||
// <https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing>
|
||||
let inline_stretch_size = Au::zero().max(containing_block.size.inline - pbm_sums.inline);
|
||||
let block_stretch_size = containing_block
|
||||
.size
|
||||
.block
|
||||
.to_definite()
|
||||
.map(|block_size| Au::zero().max(block_size - pbm_sums.block));
|
||||
|
||||
let writing_mode = style.writing_mode;
|
||||
let resolve_inline_size = |get_block_size: &dyn Fn() -> SizeConstraint| {
|
||||
let get_inline_content_size = || {
|
||||
self.content_size(
|
||||
Direction::Inline,
|
||||
preferred_aspect_ratio,
|
||||
get_block_size,
|
||||
&|| self.fallback_inline_size(writing_mode),
|
||||
)
|
||||
.into()
|
||||
};
|
||||
sizes.inline.resolve(
|
||||
Direction::Inline,
|
||||
automatic_size.inline,
|
||||
Au::zero,
|
||||
Some(inline_stretch_size),
|
||||
get_inline_content_size,
|
||||
false, /* is_table */
|
||||
)
|
||||
};
|
||||
let resolve_block_size = |get_inline_size: &dyn Fn() -> SizeConstraint| {
|
||||
let get_block_content_size = || -> ContentSizes {
|
||||
self.content_size(
|
||||
Direction::Block,
|
||||
preferred_aspect_ratio,
|
||||
get_inline_size,
|
||||
&|| self.fallback_block_size(writing_mode),
|
||||
)
|
||||
.into()
|
||||
};
|
||||
sizes.block.resolve(
|
||||
Direction::Block,
|
||||
automatic_size.block,
|
||||
Au::zero,
|
||||
block_stretch_size,
|
||||
get_block_content_size,
|
||||
false, /* is_table */
|
||||
)
|
||||
};
|
||||
|
||||
// First, compute the inline size. Intrinsic values depend on the block sizing properties
|
||||
// through the aspect ratio, but these can also be intrinsic and depend on the inline size.
|
||||
// Therefore, when there is an aspect ratio, we may need to:
|
||||
// 1. Tentatively resolve the inline size, ignoring sizing properties in both axes
|
||||
// (i.e. resulting in the inline fallback size).
|
||||
// 2. Tentatively resolve the block size, resolving intrinsic keywords by transferring (1).
|
||||
// 3. Resolve the final inline size, resolving intrinsic keywords by transferring (2).
|
||||
// 4. Resolve the final block size, resolving intrinsic keywords by transferring (3).
|
||||
let inline_size = resolve_inline_size(&|| {
|
||||
SizeConstraint::Definite(resolve_block_size(&|| {
|
||||
SizeConstraint::Definite(self.fallback_inline_size(writing_mode))
|
||||
}))
|
||||
});
|
||||
LogicalVec2 {
|
||||
inline: inline_size,
|
||||
block: resolve_block_size(&|| SizeConstraint::Definite(inline_size)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn layout_style<'a>(&self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
|
||||
LayoutStyle::Default(&base.style)
|
||||
|
|
|
@ -16,15 +16,12 @@ use super::{
|
|||
};
|
||||
use crate::cell::ArcRefCell;
|
||||
use crate::context::LayoutContext;
|
||||
use crate::formatting_contexts::{
|
||||
Baselines, IndependentFormattingContext, IndependentFormattingContextContents,
|
||||
};
|
||||
use crate::formatting_contexts::{Baselines, IndependentFormattingContext};
|
||||
use crate::fragment_tree::{
|
||||
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, SpecificLayoutInfo,
|
||||
};
|
||||
use crate::geom::{
|
||||
LazySize, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
|
||||
SizeConstraint, Sizes,
|
||||
LazySize, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, SizeConstraint,
|
||||
};
|
||||
use crate::layout_box_base::CacheableLayoutResult;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
|
@ -123,13 +120,6 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
let mut child = (*self.source_child_nodes[usize::from(node_id)]).borrow_mut();
|
||||
let child = &mut *child;
|
||||
|
||||
fn option_f32_to_size(input: Option<f32>) -> Size<Au> {
|
||||
match input {
|
||||
None => Size::Initial,
|
||||
Some(length) => Size::Numeric(Au::from_f32_px(length)),
|
||||
}
|
||||
}
|
||||
|
||||
with_independant_formatting_context(
|
||||
&mut child.taffy_level_box,
|
||||
|independent_context| -> taffy::LayoutOutput {
|
||||
|
@ -158,54 +148,6 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
let preferred_aspect_ratio =
|
||||
independent_context.preferred_aspect_ratio(&pbm.padding_border_sums);
|
||||
|
||||
// TODO: unify the replaced and non-replaced logic.
|
||||
if let IndependentFormattingContextContents::Replaced(replaced) =
|
||||
&independent_context.contents
|
||||
{
|
||||
let content_box_size = replaced
|
||||
.used_size_as_if_inline_element_from_content_box_sizes(
|
||||
containing_block,
|
||||
style,
|
||||
preferred_aspect_ratio,
|
||||
LogicalVec2 {
|
||||
block: &Sizes::new(
|
||||
option_f32_to_size(content_box_known_dimensions.height),
|
||||
Size::Initial,
|
||||
Size::Initial,
|
||||
),
|
||||
inline: &Sizes::new(
|
||||
option_f32_to_size(content_box_known_dimensions.width),
|
||||
Size::Initial,
|
||||
Size::Initial,
|
||||
),
|
||||
},
|
||||
Size::FitContent.into(),
|
||||
pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
.to_physical_size(writing_mode);
|
||||
|
||||
// Create fragments if the RunMode if PerformLayout
|
||||
// If the RunMode is ComputeSize then only the returned size will be used
|
||||
if inputs.run_mode == RunMode::PerformLayout {
|
||||
child.child_fragments =
|
||||
replaced.make_fragments(self.layout_context, style, content_box_size);
|
||||
}
|
||||
|
||||
let computed_size =
|
||||
taffy::Size {
|
||||
width: inputs.known_dimensions.width.unwrap_or_else(|| {
|
||||
content_box_size.width.to_f32_px() + pb_sum.inline
|
||||
}),
|
||||
height: inputs.known_dimensions.height.unwrap_or_else(|| {
|
||||
content_box_size.height.to_f32_px() + pb_sum.block
|
||||
}),
|
||||
};
|
||||
let size = inputs.known_dimensions.unwrap_or(computed_size);
|
||||
taffy::LayoutOutput {
|
||||
size,
|
||||
..taffy::LayoutOutput::DEFAULT
|
||||
}
|
||||
} else {
|
||||
// TODO: pass min- and max- size
|
||||
let tentative_block_size = content_box_known_dimensions
|
||||
.height
|
||||
|
@ -289,7 +231,6 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
},
|
||||
..taffy::LayoutOutput::DEFAULT
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue