From b4589134c9d3a4ba20f0805d4aa93fa55ca3e99e Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Tue, 19 Aug 2025 07:09:17 -0700 Subject: [PATCH] layout: Fix mix-ups between physical and logical aspect ratios (#38778) `ComputedValuesExt::preferred_aspect_ratio()` was getting the natural aspect ratio expressed logically as inline over block, but then it was mixing it with the value of the `aspect-ratio` CSS property, which is expressed physically as width over height. Therefore, this changes `ComputedValuesExt::preferred_aspect_ratio()` to expect the physical natural ratio, and then it takes care to convert the resulting ratio logically. Testing: Unneeded. This has no effect in practice because we don't support `writing-mode` yet. Signed-off-by: Oriol Brufau --- components/layout/replaced.rs | 18 +----------------- components/layout/style_ext.rs | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/components/layout/replaced.rs b/components/layout/replaced.rs index 468b3d96c50..95c9928b77d 100644 --- a/components/layout/replaced.rs +++ b/components/layout/replaced.rs @@ -267,19 +267,6 @@ impl ReplacedContents { } } - fn inline_size_over_block_size_intrinsic_ratio( - &self, - style: &ComputedValues, - ) -> Option { - self.natural_size.ratio.map(|width_over_height| { - if style.writing_mode.is_vertical() { - 1. / width_over_height - } else { - width_over_height - } - }) - } - #[inline] fn content_size( &self, @@ -474,10 +461,7 @@ impl ReplacedContents { style: &ComputedValues, padding_border_sums: &LogicalVec2, ) -> Option { - style.preferred_aspect_ratio( - self.inline_size_over_block_size_intrinsic_ratio(style), - padding_border_sums, - ) + style.preferred_aspect_ratio(self.natural_size.ratio, padding_border_sums) } /// The inline size that would result from combining the natural size diff --git a/components/layout/style_ext.rs b/components/layout/style_ext.rs index bc327600e69..ff539716be8 100644 --- a/components/layout/style_ext.rs +++ b/components/layout/style_ext.rs @@ -225,7 +225,7 @@ impl AspectRatio { } } - pub(crate) fn from_content_ratio(i_over_b: CSSFloat) -> Self { + pub(crate) fn from_logical_content_ratio(i_over_b: CSSFloat) -> Self { Self { box_sizing_adjustment: LogicalVec2::zero(), i_over_b, @@ -891,6 +891,14 @@ impl ComputedValuesExt for ComputedValues { preferred_ratio = PreferredRatio::None; } + let to_logical_ratio = |physical_ratio| { + if self.writing_mode.is_horizontal() { + physical_ratio + } else { + 1.0 / physical_ratio + } + }; + match (auto, preferred_ratio) { // The value `auto`. Either the ratio was not specified, or was // degenerate and set to PreferredRatio::None above. @@ -899,19 +907,20 @@ impl ComputedValuesExt for ComputedValues { // ratio; otherwise the box has no preferred aspect ratio. Size // calculations involving the aspect ratio work with the content box // dimensions always." - (_, PreferredRatio::None) => natural_aspect_ratio.map(AspectRatio::from_content_ratio), + (_, PreferredRatio::None) => natural_aspect_ratio + .map(to_logical_ratio) + .map(AspectRatio::from_logical_content_ratio), // "If both auto and a are specified together, the preferred // aspect ratio is the specified ratio of width / height unless it // is a replaced element with a natural aspect ratio, in which case // that aspect ratio is used instead. In all cases, size // calculations involving the aspect ratio work with the content box // dimensions always." - (true, PreferredRatio::Ratio(preferred_ratio)) => { - Some(AspectRatio::from_content_ratio( - natural_aspect_ratio - .unwrap_or_else(|| (preferred_ratio.0).0 / (preferred_ratio.1).0), - )) - }, + (true, PreferredRatio::Ratio(preferred_ratio)) => Some({ + let physical_ratio = natural_aspect_ratio + .unwrap_or_else(|| (preferred_ratio.0).0 / (preferred_ratio.1).0); + AspectRatio::from_logical_content_ratio(to_logical_ratio(physical_ratio)) + }), // "The box’s preferred aspect ratio is the specified ratio of width // / height. Size calculations involving the aspect ratio work with @@ -924,7 +933,7 @@ impl ComputedValuesExt for ComputedValues { BoxSizing::BorderBox => *padding_border_sums, }; Some(AspectRatio { - i_over_b: (preferred_ratio.0).0 / (preferred_ratio.1).0, + i_over_b: to_logical_ratio((preferred_ratio.0).0 / (preferred_ratio.1).0), box_sizing_adjustment, }) },