diff --git a/components/layout/replaced.rs b/components/layout/replaced.rs index 6c77a056676..af9c7162704 100644 --- a/components/layout/replaced.rs +++ b/components/layout/replaced.rs @@ -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)) } - /// - /// - /// - /// Also used in other cases, for example - /// - /// - /// 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 - /// - /// - /// - pub(crate) fn used_size_as_if_inline_element_from_content_box_sizes( - &self, - containing_block: &ContainingBlock, - style: &ComputedValues, - preferred_aspect_ratio: Option, - sizes: LogicalVec2<&Sizes>, - automatic_size: LogicalVec2>, - pbm_sums: LogicalVec2, - ) -> LogicalVec2 { - // - 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) diff --git a/components/layout/taffy/layout.rs b/components/layout/taffy/layout.rs index 167a29d3d5a..fa40f2547a2 100644 --- a/components/layout/taffy/layout.rs +++ b/components/layout/taffy/layout.rs @@ -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) -> Size { - 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,137 +148,88 @@ 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); + // TODO: pass min- and max- size + let tentative_block_size = content_box_known_dimensions + .height + .map(Au::from_f32_px) + .map_or_else(SizeConstraint::default, SizeConstraint::Definite); - // 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 - .map(Au::from_f32_px) - .map_or_else(SizeConstraint::default, SizeConstraint::Definite); - - // Compute inline size - let inline_size = content_box_known_dimensions.width.unwrap_or_else(|| { - let constraint_space = ConstraintSpace { - block_size: tentative_block_size, - writing_mode, - preferred_aspect_ratio, - }; - - // TODO: pass min- and max- size - let result = independent_context - .inline_content_sizes(self.layout_context, &constraint_space); - let adjusted_available_space = inputs - .available_space - .width - .map_definite_value(|width| width - content_box_inset.inline); - - resolve_content_size(adjusted_available_space, result.sizes) - }); - - // Return early if only inline content sizes are requested - if inputs.run_mode == RunMode::ComputeSize && - inputs.axis == RequestedAxis::Horizontal - { - return taffy::LayoutOutput::from_outer_size(taffy::Size { - width: inline_size + pb_sum.inline, - // If RequestedAxis is Horizontal then height will be ignored. - height: 0.0, - }); - } - - let content_box_size_override = ContainingBlock { - size: ContainingBlockSize { - inline: Au::from_f32_px(inline_size), - block: tentative_block_size, - }, - style, - }; - - let lazy_block_size = match content_box_known_dimensions.height { - // FIXME: use the correct min/max sizes. - None => LazySize::intrinsic(), - Some(height) => Au::from_f32_px(height).into(), - }; - - child.positioning_context = PositioningContext::default(); - let layout = independent_context.layout_without_caching( - self.layout_context, - &mut child.positioning_context, - &content_box_size_override, - containing_block, + // Compute inline size + let inline_size = content_box_known_dimensions.width.unwrap_or_else(|| { + let constraint_space = ConstraintSpace { + block_size: tentative_block_size, + writing_mode, preferred_aspect_ratio, - false, /* depends_on_block_constraints */ - &lazy_block_size, - ); - - child.child_fragments = layout.fragments; - self.child_specific_layout_infos[usize::from(node_id)] = - layout.specific_layout_info; - - let block_size = lazy_block_size - .resolve(|| layout.content_block_size) - .to_f32_px(); - - let computed_size = taffy::Size { - width: inline_size + pb_sum.inline, - height: block_size + pb_sum.block, }; - let size = inputs.known_dimensions.unwrap_or(computed_size); - taffy::LayoutOutput { - size, - first_baselines: taffy::Point { - x: None, - y: layout.baselines.first.map(|au| au.to_f32_px()), - }, - ..taffy::LayoutOutput::DEFAULT - } + // TODO: pass min- and max- size + let result = independent_context + .inline_content_sizes(self.layout_context, &constraint_space); + let adjusted_available_space = inputs + .available_space + .width + .map_definite_value(|width| width - content_box_inset.inline); + + resolve_content_size(adjusted_available_space, result.sizes) + }); + + // Return early if only inline content sizes are requested + if inputs.run_mode == RunMode::ComputeSize && + inputs.axis == RequestedAxis::Horizontal + { + return taffy::LayoutOutput::from_outer_size(taffy::Size { + width: inline_size + pb_sum.inline, + // If RequestedAxis is Horizontal then height will be ignored. + height: 0.0, + }); + } + + let content_box_size_override = ContainingBlock { + size: ContainingBlockSize { + inline: Au::from_f32_px(inline_size), + block: tentative_block_size, + }, + style, + }; + + let lazy_block_size = match content_box_known_dimensions.height { + // FIXME: use the correct min/max sizes. + None => LazySize::intrinsic(), + Some(height) => Au::from_f32_px(height).into(), + }; + + child.positioning_context = PositioningContext::default(); + let layout = independent_context.layout_without_caching( + self.layout_context, + &mut child.positioning_context, + &content_box_size_override, + containing_block, + preferred_aspect_ratio, + false, /* depends_on_block_constraints */ + &lazy_block_size, + ); + + child.child_fragments = layout.fragments; + self.child_specific_layout_infos[usize::from(node_id)] = + layout.specific_layout_info; + + let block_size = lazy_block_size + .resolve(|| layout.content_block_size) + .to_f32_px(); + + let computed_size = taffy::Size { + width: inline_size + pb_sum.inline, + height: block_size + pb_sum.block, + }; + let size = inputs.known_dimensions.unwrap_or(computed_size); + + taffy::LayoutOutput { + size, + first_baselines: taffy::Point { + x: None, + y: layout.baselines.first.map(|au| au.to_f32_px()), + }, + ..taffy::LayoutOutput::DEFAULT } }, )