From bcb30f8c422626babdfcd6d3dfd80b8b3d6bbd4f Mon Sep 17 00:00:00 2001 From: David Shin Date: Wed, 11 Dec 2024 18:10:42 +0000 Subject: [PATCH] Bug 1936563: Recursively ensure inline elements in an empty linebox as having zero BSize and no baseline. r=layout-reviewers,emilio Differential Revision: https://phabricator.services.mozilla.com/D231803 --- layout/generic/nsLineLayout.cpp | 41 +++++++++++++++++++++------------ layout/generic/nsLineLayout.h | 4 ++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 63d1e40755e7..9159ef9a94dc 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1486,6 +1486,30 @@ bool nsLineLayout::NotifyOptionalBreakPosition(nsIFrame* aFrame, #define VALIGN_TOP 1 #define VALIGN_BOTTOM 2 +void nsLineLayout::SetSpanForEmptyLine(PerSpanData* aPerSpanData, + WritingMode aWM, + const nsSize& aContainerSize, + nscoord aBStartEdge) { + for (PerFrameData* pfd = aPerSpanData->mFirstFrame; pfd; pfd = pfd->mNext) { + // Ideally, if the frame would collapse itself - but it depends on + // knowing that the line is empty. + if (!pfd->mFrame->IsInlineFrame() && !pfd->mFrame->IsRubyFrame() && + !pfd->mFrame->IsPlaceholderFrame()) { + continue; + } + // Collapse the physical size to 0. + pfd->mBounds.BStart(aWM) = aBStartEdge; + pfd->mBounds.BSize(aWM) = 0; + // Initialize mBlockDirAlign (though it doesn't make much difference + // because we don't align empty boxes). + pfd->mBlockDirAlign = VALIGN_OTHER; + pfd->mFrame->SetRect(aWM, pfd->mBounds, aContainerSize); + if (pfd->mSpan) { + SetSpanForEmptyLine(pfd->mSpan, aWM, aContainerSize, aBStartEdge); + } + } +} + void nsLineLayout::VerticalAlignLine() { // Partially place the children of the block frame. The baseline for // this operation is set to zero so that the y coordinates for all @@ -1494,21 +1518,8 @@ void nsLineLayout::VerticalAlignLine() { if (mLineIsEmpty) { // This line is empty, and should be consisting of only inline elements. // (inline-block elements would make the line non-empty). - WritingMode lineWM = psd->mWritingMode; - for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { - // Ideally, if the frame would collapse itself - but it depends on - // knowing that the line is empty. - if (!pfd->mFrame->IsInlineFrame() && !pfd->mFrame->IsRubyFrame()) { - continue; - } - // Collapse the physical size to 0. - pfd->mBounds.BStart(lineWM) = mBStartEdge; - pfd->mBounds.BSize(lineWM) = 0; - // Initialize mBlockDirAlign (though it doesn't make much difference - // because we don't align empty boxes). - pfd->mBlockDirAlign = VALIGN_OTHER; - pfd->mFrame->SetRect(lineWM, pfd->mBounds, ContainerSize()); - } + SetSpanForEmptyLine(psd, mRootSpan->mWritingMode, ContainerSize(), + mBStartEdge); mFinalLineBSize = 0; if (mGotLineBox) { diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index 4d695124e14e..b33ae4a99028 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -648,6 +648,10 @@ class nsLineLayout { const nsStyleText* aStyleText, float aInflation, bool* aZeroEffectiveSpanBox); + static void SetSpanForEmptyLine(PerSpanData* aPerSpanData, + mozilla::WritingMode aWM, + const nsSize& aContainerSize, + nscoord aBStartEdge); void VerticalAlignFrames(PerSpanData* psd); void PlaceTopBottomFrames(PerSpanData* psd, nscoord aDistanceFromStart,