commit 67791fd91e9488c070eb9320a7e2ce049150c8f5
parent ffb7bd5a17789fa1b0961865b6e9b945f8babde2
Author: David Shin <dshin@mozilla.com>
Date: Mon, 8 Dec 2025 16:58:10 +0000
Bug 2004040: Improve handling of orthogonal anchor-center alignment r=layout-anchor-positioning-reviewers,firefox-style-system-reviewers,layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D275135
Diffstat:
8 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp
@@ -780,9 +780,9 @@ static nscoord OffsetToAlignedStaticPos(
aKidSizeInAbsPosCBWM.ConvertTo(kidWM, aAbsPosCBWM);
const LogicalAxis kidAxis = aAbsPosCBWM.ConvertAxisTo(aAbsPosCBAxis, kidWM);
- // Build an Inset Modified rect from the anchor which can be used to align
- // to the anchor-center, if AlignJustifySelf is AnchorCenter.
- Maybe<LogicalRect> insetModifiedAnchorRect;
+ // Build an Inset Modified anchor info from the anchor which can be used to
+ // align to the anchor-center, if AlignJustifySelf is AnchorCenter.
+ Maybe<CSSAlignUtils::AnchorAlignInfo> anchorAlignInfo;
if (alignConst == StyleAlignFlags::ANCHOR_CENTER &&
aKidReflowInput.mAnchorPosResolutionCache) {
const auto* referenceData =
@@ -793,14 +793,23 @@ static nscoord OffsetToAlignedStaticPos(
if (cachedData && *cachedData) {
const auto& data = cachedData->ref();
if (data.mOffsetData) {
- nsSize containerSize = aAbsPosCBSize.GetPhysicalSize(aAbsPosCBWM);
- nsRect anchorRect(data.mOffsetData->mOrigin, data.mSize);
- LogicalRect logicalAnchorRect(kidWM, anchorRect, containerSize);
+ const nsSize containerSize =
+ aAbsPosCBSize.GetPhysicalSize(aAbsPosCBWM);
+ const nsRect anchorRect(data.mOffsetData->mOrigin, data.mSize);
+ const LogicalRect logicalAnchorRect{aAbsPosCBWM, anchorRect,
+ containerSize};
+ const auto axisInAbsPosCBWM =
+ kidWM.ConvertAxisTo(kidAxis, aAbsPosCBWM);
+ const auto anchorStart =
+ logicalAnchorRect.Start(axisInAbsPosCBWM, aAbsPosCBWM);
+ const auto anchorSize =
+ logicalAnchorRect.Size(axisInAbsPosCBWM, aAbsPosCBWM);
+ anchorAlignInfo =
+ Some(CSSAlignUtils::AnchorAlignInfo{anchorStart, anchorSize});
if (aNonAutoAlignParams) {
- logicalAnchorRect.Start(kidAxis, kidWM) -=
+ anchorAlignInfo->mAnchorStart -=
aNonAutoAlignParams->mCurrentStartInset;
}
- insetModifiedAnchorRect = Some(logicalAnchorRect);
}
}
}
@@ -808,7 +817,7 @@ static nscoord OffsetToAlignedStaticPos(
nscoord offset = CSSAlignUtils::AlignJustifySelf(
alignConst, kidAxis, flags, baselineAdjust, alignAreaSizeInAxis,
- aKidReflowInput, kidSizeInOwnWM, insetModifiedAnchorRect);
+ aKidReflowInput, kidSizeInOwnWM, anchorAlignInfo);
// Safe alignment clamping for anchor-center.
// When using anchor-center with the safe keyword, or when both insets are
diff --git a/layout/generic/CSSAlignUtils.cpp b/layout/generic/CSSAlignUtils.cpp
@@ -19,13 +19,11 @@ static nscoord SpaceToFill(WritingMode aWM, const LogicalSize& aSize,
return aCBSize - (size + aMargin);
}
-nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
- LogicalAxis aAxis,
- AlignJustifyFlags aFlags,
- nscoord aBaselineAdjust,
- nscoord aCBSize, const ReflowInput& aRI,
- const LogicalSize& aChildSize,
- const Maybe<LogicalRect>& aAnchorRect) {
+nscoord CSSAlignUtils::AlignJustifySelf(
+ const StyleAlignFlags& aAlignment, LogicalAxis aAxis,
+ AlignJustifyFlags aFlags, nscoord aBaselineAdjust, nscoord aCBSize,
+ const ReflowInput& aRI, const LogicalSize& aChildSize,
+ const Maybe<AnchorAlignInfo>& aAnchorInfo) {
MOZ_ASSERT(aAlignment != StyleAlignFlags::AUTO,
"auto values should have resolved already");
MOZ_ASSERT(aAlignment != StyleAlignFlags::LEFT &&
@@ -134,9 +132,9 @@ nscoord CSSAlignUtils::AlignJustifySelf(const StyleAlignFlags& aAlignment,
} else if (alignment == StyleAlignFlags::END) {
nscoord size = aChildSize.Size(aAxis, wm);
offset = aCBSize - (size + marginEnd);
- } else if (alignment == StyleAlignFlags::ANCHOR_CENTER && aAnchorRect) {
- const nscoord anchorSize = aAnchorRect->Size(aAxis, wm);
- const nscoord anchorStart = aAnchorRect->Start(aAxis, wm);
+ } else if (alignment == StyleAlignFlags::ANCHOR_CENTER && aAnchorInfo) {
+ const nscoord anchorSize = aAnchorInfo->mAnchorSize;
+ const nscoord anchorStart = aAnchorInfo->mAnchorStart;
const nscoord size = aChildSize.Size(aAxis, wm);
// Offset relative to the anchors center, accounting for margins
diff --git a/layout/generic/CSSAlignUtils.h b/layout/generic/CSSAlignUtils.h
@@ -47,6 +47,15 @@ class CSSAlignUtils {
using AlignJustifyFlags = EnumSet<AlignJustifyFlag>;
/**
+ * Additional information required to resolve anchor-center on a particular
+ * axis.
+ */
+ struct AnchorAlignInfo {
+ nscoord mAnchorStart;
+ nscoord mAnchorSize;
+ };
+
+ /**
* This computes the aligned offset of a CSS-aligned child within its
* alignment container. The returned offset is distance between the
* logical "start" edge of the alignment container & the logical "start" edge
@@ -62,15 +71,14 @@ class CSSAlignUtils {
* @param aCBSize The size of the alignment container, in its aAxis.
* @param aRI A ReflowInput for the child.
* @param aChildSize The child's LogicalSize (in its own writing mode).
- * @param aAnchorRect When specified, an inset-modified anchor rect (in the
- * child's writing mode) to use for anchor-center
- * alignment.
+ * @param aAnchorInfo When specified, an inset-modified anchor start and size
+ * (in the child's writing mode) to use for anchor-center alignment.
*/
static nscoord AlignJustifySelf(
const StyleAlignFlags& aAlignment, LogicalAxis aAxis,
AlignJustifyFlags aFlags, nscoord aBaselineAdjust, nscoord aCBSize,
const ReflowInput& aRI, const LogicalSize& aChildSize,
- const Maybe<LogicalRect>& aAnchorRect = Nothing());
+ const Maybe<AnchorAlignInfo>& aAnchorRect = Nothing());
};
} // namespace mozilla
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
@@ -60,7 +60,7 @@ void ComputeAnchorCenterUsage(
}
const auto* stylePos = aFrame->StylePosition();
- WritingMode wm = aFrame->GetWritingMode();
+ const auto parentWM = parent->GetWritingMode();
auto checkAxis = [&](LogicalAxis aAxis) {
StyleAlignFlags alignment =
@@ -69,12 +69,10 @@ void ComputeAnchorCenterUsage(
StyleAlignFlags::ANCHOR_CENTER) {
return false;
}
- LogicalSide startSide = aAxis == LogicalAxis::Inline ? LogicalSide::IStart
- : LogicalSide::BStart;
- LogicalSide endSide =
- aAxis == LogicalAxis::Inline ? LogicalSide::IEnd : LogicalSide::BEnd;
- return stylePos->mOffset.Get(wm.PhysicalSide(startSide)).IsAuto() ||
- stylePos->mOffset.Get(wm.PhysicalSide(endSide)).IsAuto();
+ LogicalSide startSide = MakeLogicalSide(aAxis, LogicalEdge::Start);
+ LogicalSide endSide = MakeLogicalSide(aAxis, LogicalEdge::End);
+ return stylePos->mOffset.Get(parentWM.PhysicalSide(startSide)).IsAuto() ||
+ stylePos->mOffset.Get(parentWM.PhysicalSide(endSide)).IsAuto();
};
aInlineUsesAnchorCenter = checkAxis(LogicalAxis::Inline);
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
@@ -34,6 +34,7 @@
#include "nsCOMPtr.h"
#include "nsCRTGlue.h"
#include "nsCSSProps.h"
+#include "nsContainerFrame.h"
#include "nsDeviceContext.h"
#include "nsIURI.h"
#include "nsIURIMutator.h"
@@ -1332,8 +1333,12 @@ bool AnchorResolvedInsetHelper::SideUsesAnchorCenter(
if (!frame) {
return false;
}
+ const nsIFrame* parent = frame->GetParent();
+ if (!parent) {
+ return false;
+ }
- WritingMode wm = frame->GetWritingMode();
+ WritingMode wm = parent->GetWritingMode();
LogicalSide logicalSide = wm.LogicalSideForPhysicalSide(aSide);
LogicalAxis axis = GetAxis(logicalSide);
diff --git a/testing/web-platform/meta/css/css-anchor-position/anchor-center-htb-vrl.html.ini b/testing/web-platform/meta/css/css-anchor-position/anchor-center-htb-vrl.html.ini
@@ -1,6 +0,0 @@
-[anchor-center-htb-vrl.html]
- [.target 2]
- expected: FAIL
-
- [.target 6]
- expected: FAIL
diff --git a/testing/web-platform/meta/css/css-anchor-position/anchor-center-overflow-002.html.ini b/testing/web-platform/meta/css/css-anchor-position/anchor-center-overflow-002.html.ini
@@ -1,2 +0,0 @@
-[anchor-center-overflow-002.html]
- expected: FAIL
diff --git a/testing/web-platform/meta/css/css-anchor-position/anchor-center-vrl-htb.html.ini b/testing/web-platform/meta/css/css-anchor-position/anchor-center-vrl-htb.html.ini
@@ -1,6 +0,0 @@
-[anchor-center-vrl-htb.html]
- [.target 2]
- expected: FAIL
-
- [.target 6]
- expected: FAIL