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 <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-08-19 07:09:17 -07:00 committed by GitHub
parent f31edc5d6a
commit b4589134c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 26 deletions

View file

@ -267,19 +267,6 @@ impl ReplacedContents {
} }
} }
fn inline_size_over_block_size_intrinsic_ratio(
&self,
style: &ComputedValues,
) -> Option<CSSFloat> {
self.natural_size.ratio.map(|width_over_height| {
if style.writing_mode.is_vertical() {
1. / width_over_height
} else {
width_over_height
}
})
}
#[inline] #[inline]
fn content_size( fn content_size(
&self, &self,
@ -474,10 +461,7 @@ impl ReplacedContents {
style: &ComputedValues, style: &ComputedValues,
padding_border_sums: &LogicalVec2<Au>, padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> { ) -> Option<AspectRatio> {
style.preferred_aspect_ratio( style.preferred_aspect_ratio(self.natural_size.ratio, padding_border_sums)
self.inline_size_over_block_size_intrinsic_ratio(style),
padding_border_sums,
)
} }
/// The inline size that would result from combining the natural size /// The inline size that would result from combining the natural size

View file

@ -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 { Self {
box_sizing_adjustment: LogicalVec2::zero(), box_sizing_adjustment: LogicalVec2::zero(),
i_over_b, i_over_b,
@ -891,6 +891,14 @@ impl ComputedValuesExt for ComputedValues {
preferred_ratio = PreferredRatio::None; 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) { match (auto, preferred_ratio) {
// The value `auto`. Either the ratio was not specified, or was // The value `auto`. Either the ratio was not specified, or was
// degenerate and set to PreferredRatio::None above. // 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 // ratio; otherwise the box has no preferred aspect ratio. Size
// calculations involving the aspect ratio work with the content box // calculations involving the aspect ratio work with the content box
// dimensions always." // 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 <ratio> are specified together, the preferred // "If both auto and a <ratio> are specified together, the preferred
// aspect ratio is the specified ratio of width / height unless it // aspect ratio is the specified ratio of width / height unless it
// is a replaced element with a natural aspect ratio, in which case // is a replaced element with a natural aspect ratio, in which case
// that aspect ratio is used instead. In all cases, size // that aspect ratio is used instead. In all cases, size
// calculations involving the aspect ratio work with the content box // calculations involving the aspect ratio work with the content box
// dimensions always." // dimensions always."
(true, PreferredRatio::Ratio(preferred_ratio)) => { (true, PreferredRatio::Ratio(preferred_ratio)) => Some({
Some(AspectRatio::from_content_ratio( let physical_ratio = natural_aspect_ratio
natural_aspect_ratio .unwrap_or_else(|| (preferred_ratio.0).0 / (preferred_ratio.1).0);
.unwrap_or_else(|| (preferred_ratio.0).0 / (preferred_ratio.1).0), AspectRatio::from_logical_content_ratio(to_logical_ratio(physical_ratio))
)) }),
},
// "The boxs preferred aspect ratio is the specified ratio of width // "The boxs preferred aspect ratio is the specified ratio of width
// / height. Size calculations involving the aspect ratio work with // / height. Size calculations involving the aspect ratio work with
@ -924,7 +933,7 @@ impl ComputedValuesExt for ComputedValues {
BoxSizing::BorderBox => *padding_border_sums, BoxSizing::BorderBox => *padding_border_sums,
}; };
Some(AspectRatio { 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, box_sizing_adjustment,
}) })
}, },