Bug 1908069 - Add border/padding/margin support to msqrt, mroot and menclose. r=emilio

See D216670 for the general approach taken.

Differential Revision: https://phabricator.services.mozilla.com/D216980
This commit is contained in:
Frédéric Wang 2024-08-07 06:00:45 +00:00
Родитель 0483682329
Коммит 8ca8f43fc4
8 изменённых файлов: 89 добавлений и 88 удалений

Просмотреть файл

@ -206,8 +206,7 @@ void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// paint the menclosed content
nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists);
nsRect mencloseRect = nsIFrame::GetRect();
mencloseRect.x = mencloseRect.y = 0;
nsRect mencloseRect = nsIFrame::GetContentRectRelativeToSelf();
if (IsToDraw(NOTATION_RADICAL)) {
mMathMLChar[mRadicalCharIndex].Display(aBuilder, this, aLists, 0);
@ -626,6 +625,11 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
// Add padding+border.
auto borderPadding = GetBorderPaddingForPlace(aFlags);
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
mBoundingMetrics);
mReference.x = 0;
mReference.y = aDesiredSize.BlockStartAscent();
@ -634,7 +638,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
// Set position and size of MathMLChars
if (IsToDraw(NOTATION_LONGDIV))
mMathMLChar[mLongDivCharIndex].SetRect(nsRect(
dx_left - bmLongdivChar.width,
dx_left - bmLongdivChar.width + borderPadding.left,
aDesiredSize.BlockStartAscent() - longdivAscent, bmLongdivChar.width,
bmLongdivChar.ascent + bmLongdivChar.descent));
@ -644,15 +648,17 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
: dx_left - bmRadicalChar.width);
mMathMLChar[mRadicalCharIndex].SetRect(nsRect(
dx, aDesiredSize.BlockStartAscent() - radicalAscent,
bmRadicalChar.width, bmRadicalChar.ascent + bmRadicalChar.descent));
dx + borderPadding.left,
aDesiredSize.BlockStartAscent() - radicalAscent, bmRadicalChar.width,
bmRadicalChar.ascent + bmRadicalChar.descent));
}
mContentWidth = bmBase.width;
//////////////////
// Finish reflowing child frames
PositionRowChildFrames(dx_left, aDesiredSize.BlockStartAscent());
PositionRowChildFrames(dx_left + borderPadding.left,
aDesiredSize.BlockStartAscent());
}
return NS_OK;

Просмотреть файл

@ -148,6 +148,7 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
aDesiredSize.SetBlockStartAscent(0);
nsBoundingMetrics bmSqr, bmBase, bmIndex;
nsMargin baseMargin, indexMargin;
DrawTarget* drawTarget = aReflowInput.mRenderingContext->GetDrawTarget();
//////////////////
@ -175,11 +176,13 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
baseFrame = childFrame;
baseSize = childDesiredSize;
bmBase = childDesiredSize.mBoundingMetrics;
baseMargin = baseFrame->GetUsedMargin();
} else if (1 == count) {
// index
indexFrame = childFrame;
indexSize = childDesiredSize;
bmIndex = childDesiredSize.mBoundingMetrics;
indexMargin = indexFrame->GetUsedMargin();
}
count++;
childFrame = childFrame->GetNextSibling();
@ -201,7 +204,9 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
char16_t one = '1';
nsBoundingMetrics bmOne =
nsLayoutUtils::AppUnitBoundsOfString(&one, 1, *fm, drawTarget);
if (bmOne.ascent > bmBase.ascent) psi += bmOne.ascent - bmBase.ascent;
if (bmOne.ascent > bmBase.ascent + baseMargin.top) {
psi += bmOne.ascent - bmBase.ascent - baseMargin.top;
}
// make sure that the rule appears on on screen
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
@ -217,7 +222,8 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
// Stretch the radical symbol to the appropriate height if it is not big
// enough.
nsBoundingMetrics contSize = bmBase;
contSize.descent = bmBase.ascent + bmBase.descent + psi;
contSize.descent =
bmBase.ascent + bmBase.descent + baseMargin.TopBottom() + psi;
contSize.ascent = ruleThickness;
// height(radical) should be >= height(base) + psi + ruleThickness
@ -232,15 +238,18 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
// Update the desired size for the container (like msqrt, index is not yet
// included) the baseline will be that of the base.
mBoundingMetrics.ascent = bmBase.ascent + psi + ruleThickness;
mBoundingMetrics.descent = std::max(
bmBase.descent, (bmSqr.ascent + bmSqr.descent - mBoundingMetrics.ascent));
mBoundingMetrics.width = bmSqr.width + bmBase.width;
mBoundingMetrics.ascent =
bmBase.ascent + baseMargin.top + psi + ruleThickness;
mBoundingMetrics.descent =
std::max(bmBase.descent + baseMargin.bottom,
(bmSqr.ascent + bmSqr.descent - mBoundingMetrics.ascent));
mBoundingMetrics.width = bmSqr.width + bmBase.width + baseMargin.LeftRight();
mBoundingMetrics.leftBearing = bmSqr.leftBearing;
mBoundingMetrics.rightBearing =
bmSqr.width +
std::max(bmBase.width,
bmBase.rightBearing); // take also care of the rule
std::max(
bmBase.width + baseMargin.LeftRight(),
bmBase.rightBearing + baseMargin.left); // take also care of the rule
aDesiredSize.SetBlockStartAscent(mBoundingMetrics.ascent + leading);
aDesiredSize.Height() =
@ -265,8 +274,8 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
nscoord indexRaisedAscent =
mBoundingMetrics.ascent // top of radical
- (bmSqr.ascent + bmSqr.descent) // to bottom of radical
+ raiseIndexDelta + bmIndex.ascent +
bmIndex.descent; // to top of raised index
+ raiseIndexDelta + bmIndex.ascent + bmIndex.descent +
indexMargin.TopBottom(); // to top of raised index
nscoord indexClearance = 0;
if (mBoundingMetrics.ascent < indexRaisedAscent) {
@ -280,37 +289,54 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
}
nscoord dxIndex, dxSqr;
GetRadicalXOffsets(bmIndex.width, bmSqr.width, fm, &dxIndex, &dxSqr);
GetRadicalXOffsets(bmIndex.width + indexMargin.LeftRight(), bmSqr.width, fm,
&dxIndex, &dxSqr);
mBoundingMetrics.width = dxSqr + bmSqr.width + bmBase.width;
mBoundingMetrics.width =
dxSqr + bmSqr.width + bmBase.width + baseMargin.LeftRight();
mBoundingMetrics.leftBearing =
std::min(dxIndex + bmIndex.leftBearing, dxSqr + bmSqr.leftBearing);
mBoundingMetrics.rightBearing =
dxSqr + bmSqr.width + std::max(bmBase.width, bmBase.rightBearing);
dxSqr + bmSqr.width +
std::max(bmBase.width + baseMargin.LeftRight(),
bmBase.rightBearing + baseMargin.left);
aDesiredSize.Width() = mBoundingMetrics.width;
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
// Add padding+border around the final layout.
auto borderPadding = GetUsedBorderAndPadding();
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
mBoundingMetrics);
GatherAndStoreOverflow(&aDesiredSize);
// place the index
nscoord dx = dxIndex;
const bool isRTL = StyleVisibility()->mDirection == StyleDirection::Rtl;
nscoord borderPaddingInlineStart =
isRTL ? borderPadding.right : borderPadding.left;
nscoord dx = borderPaddingInlineStart + dxIndex +
indexMargin.Side(isRTL ? eSideRight : eSideLeft);
nscoord dy =
aDesiredSize.BlockStartAscent() -
(indexRaisedAscent + indexSize.BlockStartAscent() - bmIndex.ascent);
FinishReflowChild(indexFrame, aPresContext, indexSize, nullptr,
MirrorIfRTL(aDesiredSize.Width(), indexSize.Width(), dx),
dy, ReflowChildFlags::Default);
dy + indexMargin.top, ReflowChildFlags::Default);
// place the radical symbol and the radical bar
dx = dxSqr;
dy = indexClearance + leading; // leave a leading at the top
dx = borderPaddingInlineStart + dxSqr;
dy = borderPadding.top + indexClearance +
leading; // leave a leading at the top
mSqrChar.SetRect(nsRect(MirrorIfRTL(aDesiredSize.Width(), bmSqr.width, dx),
dy, bmSqr.width, bmSqr.ascent + bmSqr.descent));
dx += bmSqr.width;
mBarRect.SetRect(MirrorIfRTL(aDesiredSize.Width(), bmBase.width, dx), dy,
bmBase.width, ruleThickness);
mBarRect.SetRect(MirrorIfRTL(aDesiredSize.Width(),
bmBase.width + baseMargin.LeftRight(), dx),
dy, bmBase.width + baseMargin.LeftRight(), ruleThickness);
// place the base
dx += isRTL ? baseMargin.right : baseMargin.left;
dy = aDesiredSize.BlockStartAscent() - baseSize.BlockStartAscent();
FinishReflowChild(baseFrame, aPresContext, baseSize, nullptr,
MirrorIfRTL(aDesiredSize.Width(), baseSize.Width(), dx), dy,
@ -321,12 +347,11 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
}
/* virtual */
void nsMathMLmrootFrame::GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
ReflowOutput& aDesiredSize) {
nsresult nsMathMLmrootFrame::MeasureForWidth(DrawTarget* aDrawTarget,
ReflowOutput& aDesiredSize) {
const PlaceFlags flags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
if (ShouldUseRowFallback()) {
nsMathMLContainerFrame::GetIntrinsicISizeMetrics(aRenderingContext,
aDesiredSize);
return;
return PlaceAsMrow(aDrawTarget, flags, aDesiredSize);
}
// ShouldUseRowFallback() returned false so there are exactly two children.
@ -336,25 +361,38 @@ void nsMathMLmrootFrame::GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
MOZ_ASSERT(indexFrame);
MOZ_ASSERT(!indexFrame->GetNextSibling());
nsBoundingMetrics bmBase, bmIndex;
ReflowOutput baseSize(aDesiredSize.GetWritingMode());
ReflowOutput indexSize(aDesiredSize.GetWritingMode());
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
nscoord baseWidth = nsLayoutUtils::IntrinsicForContainer(
aRenderingContext, baseFrame, IntrinsicISizeType::PrefISize);
nscoord indexWidth = nsLayoutUtils::IntrinsicForContainer(
aRenderingContext, indexFrame, IntrinsicISizeType::PrefISize);
nscoord sqrWidth = mSqrChar.GetMaxWidth(
this, aRenderingContext->GetDrawTarget(), fontSizeInflation);
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(indexFrame, indexSize, bmIndex);
nscoord baseMargin = baseFrame->IntrinsicISizeOffsets().margin,
indexMargin = indexFrame->IntrinsicISizeOffsets().margin;
nscoord sqrWidth = mSqrChar.GetMaxWidth(this, aDrawTarget, fontSizeInflation);
nscoord dxSqr;
nscoord dxIndex, dxSqr;
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetFontMetricsForFrame(this, fontSizeInflation);
GetRadicalXOffsets(indexWidth, sqrWidth, fm, nullptr, &dxSqr);
GetRadicalXOffsets(bmIndex.width + indexMargin, sqrWidth, fm, &dxIndex,
&dxSqr);
nscoord width = dxSqr + sqrWidth + baseWidth;
mBoundingMetrics.width = dxSqr + sqrWidth + bmBase.width + baseMargin;
mBoundingMetrics.leftBearing =
std::min(dxIndex + bmIndex.leftBearing + indexMargin, dxSqr);
mBoundingMetrics.rightBearing =
dxSqr + sqrWidth +
std::max(bmBase.width + baseMargin, bmBase.rightBearing + baseMargin);
aDesiredSize.Width() = width;
aDesiredSize.mBoundingMetrics.width = width;
aDesiredSize.mBoundingMetrics.leftBearing = 0;
aDesiredSize.mBoundingMetrics.rightBearing = width;
aDesiredSize.Width() = mBoundingMetrics.width;
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
// Add border+padding.
nsMargin borderPadding = GetBorderPaddingForPlace(flags);
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
mBoundingMetrics);
return NS_OK;
}
void nsMathMLmrootFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) {

Просмотреть файл

@ -42,8 +42,8 @@ class nsMathMLmrootFrame final : public nsMathMLContainerFrame {
nsFontMetrics* aFontMetrics, nscoord* aIndexOffset,
nscoord* aSqrOffset);
virtual void GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
ReflowOutput& aDesiredSize) override;
nsresult MeasureForWidth(DrawTarget* aDrawTarget,
ReflowOutput& aDesiredSize) final;
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;

Просмотреть файл

@ -1,18 +0,0 @@
[border-002.html]
[Border properties on menclose]
expected: FAIL
[Border properties on msqrt]
expected: FAIL
[Border properties on mroot]
expected: FAIL
[Border properties on msqrt (rtl)]
expected: FAIL
[Border properties on mroot (rtl)]
expected: FAIL
[Border properties on menclose (rtl)]
expected: FAIL

Просмотреть файл

@ -1,3 +0,0 @@
[margin-003.html]
[Margin properties on the children of mroot]
expected: FAIL

Просмотреть файл

@ -1,18 +0,0 @@
[padding-002.html]
[Padding properties on msqrt]
expected: FAIL
[Padding properties on menclose]
expected: FAIL
[Padding properties on mroot]
expected: FAIL
[Padding properties on mroot (rtl)]
expected: FAIL
[Padding properties on menclose (rtl)]
expected: FAIL
[Padding properties on msqrt (rtl)]
expected: FAIL

Просмотреть файл

@ -1,2 +0,0 @@
[padding-border-margin-005.html]
expected: FAIL

Просмотреть файл

@ -1,2 +0,0 @@
[padding-border-margin-006.html]
expected: FAIL