Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 05a4ad5

Browse files
committed
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
1 parent 39615f7 commit 05a4ad5

File tree

8 files changed

+88
-89
lines changed

8 files changed

+88
-89
lines changed

layout/mathml/nsMathMLmencloseFrame.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ void nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
206206
// paint the menclosed content
207207
nsMathMLContainerFrame::BuildDisplayList(aBuilder, aLists);
208208

209-
nsRect mencloseRect = nsIFrame::GetRect();
210-
mencloseRect.x = mencloseRect.y = 0;
209+
nsRect mencloseRect = nsIFrame::GetContentRectRelativeToSelf();
211210

212211
if (IsToDraw(NOTATION_RADICAL)) {
213212
mMathMLChar[mRadicalCharIndex].Display(aBuilder, this, aLists, 0);
@@ -629,6 +628,11 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
629628

630629
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
631630

631+
// Add padding+border.
632+
auto borderPadding = GetBorderPaddingForPlace(aFlags);
633+
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
634+
mBoundingMetrics);
635+
632636
mReference.x = 0;
633637
mReference.y = aDesiredSize.BlockStartAscent();
634638

@@ -637,7 +641,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
637641
// Set position and size of MathMLChars
638642
if (IsToDraw(NOTATION_LONGDIV))
639643
mMathMLChar[mLongDivCharIndex].SetRect(nsRect(
640-
dx_left - bmLongdivChar.width,
644+
dx_left - bmLongdivChar.width + borderPadding.left,
641645
aDesiredSize.BlockStartAscent() - longdivAscent, bmLongdivChar.width,
642646
bmLongdivChar.ascent + bmLongdivChar.descent));
643647

@@ -647,15 +651,17 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
647651
: dx_left - bmRadicalChar.width);
648652

649653
mMathMLChar[mRadicalCharIndex].SetRect(nsRect(
650-
dx, aDesiredSize.BlockStartAscent() - radicalAscent,
651-
bmRadicalChar.width, bmRadicalChar.ascent + bmRadicalChar.descent));
654+
dx + borderPadding.left,
655+
aDesiredSize.BlockStartAscent() - radicalAscent, bmRadicalChar.width,
656+
bmRadicalChar.ascent + bmRadicalChar.descent));
652657
}
653658

654659
mContentWidth = bmBase.width;
655660

656661
//////////////////
657662
// Finish reflowing child frames
658-
PositionRowChildFrames(dx_left, aDesiredSize.BlockStartAscent());
663+
PositionRowChildFrames(dx_left + borderPadding.left,
664+
aDesiredSize.BlockStartAscent());
659665
}
660666

661667
return NS_OK;

layout/mathml/nsMathMLmrootFrame.cpp

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
148148
aDesiredSize.SetBlockStartAscent(0);
149149

150150
nsBoundingMetrics bmSqr, bmBase, bmIndex;
151+
nsMargin baseMargin, indexMargin;
151152
DrawTarget* drawTarget = aReflowInput.mRenderingContext->GetDrawTarget();
152153

153154
//////////////////
@@ -175,11 +176,13 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
175176
baseFrame = childFrame;
176177
baseSize = childDesiredSize;
177178
bmBase = childDesiredSize.mBoundingMetrics;
179+
baseMargin = baseFrame->GetUsedMargin();
178180
} else if (1 == count) {
179181
// index
180182
indexFrame = childFrame;
181183
indexSize = childDesiredSize;
182184
bmIndex = childDesiredSize.mBoundingMetrics;
185+
indexMargin = indexFrame->GetUsedMargin();
183186
}
184187
count++;
185188
childFrame = childFrame->GetNextSibling();
@@ -201,7 +204,9 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
201204
char16_t one = '1';
202205
nsBoundingMetrics bmOne =
203206
nsLayoutUtils::AppUnitBoundsOfString(&one, 1, *fm, drawTarget);
204-
if (bmOne.ascent > bmBase.ascent) psi += bmOne.ascent - bmBase.ascent;
207+
if (bmOne.ascent > bmBase.ascent + baseMargin.top) {
208+
psi += bmOne.ascent - bmBase.ascent - baseMargin.top;
209+
}
205210

206211
// make sure that the rule appears on on screen
207212
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
@@ -217,7 +222,8 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
217222
// Stretch the radical symbol to the appropriate height if it is not big
218223
// enough.
219224
nsBoundingMetrics contSize = bmBase;
220-
contSize.descent = bmBase.ascent + bmBase.descent + psi;
225+
contSize.descent =
226+
bmBase.ascent + bmBase.descent + baseMargin.TopBottom() + psi;
221227
contSize.ascent = ruleThickness;
222228

223229
// height(radical) should be >= height(base) + psi + ruleThickness
@@ -232,15 +238,18 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
232238

233239
// Update the desired size for the container (like msqrt, index is not yet
234240
// included) the baseline will be that of the base.
235-
mBoundingMetrics.ascent = bmBase.ascent + psi + ruleThickness;
236-
mBoundingMetrics.descent = std::max(
237-
bmBase.descent, (bmSqr.ascent + bmSqr.descent - mBoundingMetrics.ascent));
238-
mBoundingMetrics.width = bmSqr.width + bmBase.width;
241+
mBoundingMetrics.ascent =
242+
bmBase.ascent + baseMargin.top + psi + ruleThickness;
243+
mBoundingMetrics.descent =
244+
std::max(bmBase.descent + baseMargin.bottom,
245+
(bmSqr.ascent + bmSqr.descent - mBoundingMetrics.ascent));
246+
mBoundingMetrics.width = bmSqr.width + bmBase.width + baseMargin.LeftRight();
239247
mBoundingMetrics.leftBearing = bmSqr.leftBearing;
240248
mBoundingMetrics.rightBearing =
241249
bmSqr.width +
242-
std::max(bmBase.width,
243-
bmBase.rightBearing); // take also care of the rule
250+
std::max(
251+
bmBase.width + baseMargin.LeftRight(),
252+
bmBase.rightBearing + baseMargin.left); // take also care of the rule
244253

245254
aDesiredSize.SetBlockStartAscent(mBoundingMetrics.ascent + leading);
246255
aDesiredSize.Height() =
@@ -265,8 +274,8 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
265274
nscoord indexRaisedAscent =
266275
mBoundingMetrics.ascent // top of radical
267276
- (bmSqr.ascent + bmSqr.descent) // to bottom of radical
268-
+ raiseIndexDelta + bmIndex.ascent +
269-
bmIndex.descent; // to top of raised index
277+
+ raiseIndexDelta + bmIndex.ascent + bmIndex.descent +
278+
indexMargin.TopBottom(); // to top of raised index
270279

271280
nscoord indexClearance = 0;
272281
if (mBoundingMetrics.ascent < indexRaisedAscent) {
@@ -280,37 +289,54 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
280289
}
281290

282291
nscoord dxIndex, dxSqr;
283-
GetRadicalXOffsets(bmIndex.width, bmSqr.width, fm, &dxIndex, &dxSqr);
292+
GetRadicalXOffsets(bmIndex.width + indexMargin.LeftRight(), bmSqr.width, fm,
293+
&dxIndex, &dxSqr);
284294

285-
mBoundingMetrics.width = dxSqr + bmSqr.width + bmBase.width;
295+
mBoundingMetrics.width =
296+
dxSqr + bmSqr.width + bmBase.width + baseMargin.LeftRight();
286297
mBoundingMetrics.leftBearing =
287298
std::min(dxIndex + bmIndex.leftBearing, dxSqr + bmSqr.leftBearing);
288299
mBoundingMetrics.rightBearing =
289-
dxSqr + bmSqr.width + std::max(bmBase.width, bmBase.rightBearing);
300+
dxSqr + bmSqr.width +
301+
std::max(bmBase.width + baseMargin.LeftRight(),
302+
bmBase.rightBearing + baseMargin.left);
290303

291304
aDesiredSize.Width() = mBoundingMetrics.width;
292305
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
306+
307+
// Add padding+border around the final layout.
308+
auto borderPadding = GetUsedBorderAndPadding();
309+
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
310+
mBoundingMetrics);
311+
293312
GatherAndStoreOverflow(&aDesiredSize);
294313

295314
// place the index
296-
nscoord dx = dxIndex;
315+
const bool isRTL = StyleVisibility()->mDirection == StyleDirection::Rtl;
316+
nscoord borderPaddingInlineStart =
317+
isRTL ? borderPadding.right : borderPadding.left;
318+
nscoord dx = borderPaddingInlineStart + dxIndex +
319+
indexMargin.Side(isRTL ? eSideRight : eSideLeft);
297320
nscoord dy =
298321
aDesiredSize.BlockStartAscent() -
299322
(indexRaisedAscent + indexSize.BlockStartAscent() - bmIndex.ascent);
300323
FinishReflowChild(indexFrame, aPresContext, indexSize, nullptr,
301324
MirrorIfRTL(aDesiredSize.Width(), indexSize.Width(), dx),
302-
dy, ReflowChildFlags::Default);
325+
dy + indexMargin.top, ReflowChildFlags::Default);
303326

304327
// place the radical symbol and the radical bar
305-
dx = dxSqr;
306-
dy = indexClearance + leading; // leave a leading at the top
328+
dx = borderPaddingInlineStart + dxSqr;
329+
dy = borderPadding.top + indexClearance +
330+
leading; // leave a leading at the top
307331
mSqrChar.SetRect(nsRect(MirrorIfRTL(aDesiredSize.Width(), bmSqr.width, dx),
308332
dy, bmSqr.width, bmSqr.ascent + bmSqr.descent));
309333
dx += bmSqr.width;
310-
mBarRect.SetRect(MirrorIfRTL(aDesiredSize.Width(), bmBase.width, dx), dy,
311-
bmBase.width, ruleThickness);
334+
mBarRect.SetRect(MirrorIfRTL(aDesiredSize.Width(),
335+
bmBase.width + baseMargin.LeftRight(), dx),
336+
dy, bmBase.width + baseMargin.LeftRight(), ruleThickness);
312337

313338
// place the base
339+
dx += isRTL ? baseMargin.right : baseMargin.left;
314340
dy = aDesiredSize.BlockStartAscent() - baseSize.BlockStartAscent();
315341
FinishReflowChild(baseFrame, aPresContext, baseSize, nullptr,
316342
MirrorIfRTL(aDesiredSize.Width(), baseSize.Width(), dx), dy,
@@ -321,12 +347,12 @@ void nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
321347
}
322348

323349
/* virtual */
324-
void nsMathMLmrootFrame::GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
325-
ReflowOutput& aDesiredSize) {
350+
nsresult nsMathMLmrootFrame::MeasureForWidth(DrawTarget* aDrawTarget,
351+
ReflowOutput& aDesiredSize) {
352+
const PlaceFlags flags =
353+
PlaceFlags(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
326354
if (ShouldUseRowFallback()) {
327-
nsMathMLContainerFrame::GetIntrinsicISizeMetrics(aRenderingContext,
328-
aDesiredSize);
329-
return;
355+
return PlaceAsMrow(aDrawTarget, flags, aDesiredSize);
330356
}
331357

332358
// ShouldUseRowFallback() returned false so there are exactly two children.
@@ -336,25 +362,35 @@ void nsMathMLmrootFrame::GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
336362
MOZ_ASSERT(indexFrame);
337363
MOZ_ASSERT(!indexFrame->GetNextSibling());
338364

365+
nsBoundingMetrics bmBase, bmIndex;
366+
ReflowOutput baseSize(aDesiredSize.GetWritingMode());
367+
ReflowOutput indexSize(aDesiredSize.GetWritingMode());
339368
float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
340-
nscoord baseWidth = nsLayoutUtils::IntrinsicForContainer(
341-
aRenderingContext, baseFrame, IntrinsicISizeType::PrefISize);
342-
nscoord indexWidth = nsLayoutUtils::IntrinsicForContainer(
343-
aRenderingContext, indexFrame, IntrinsicISizeType::PrefISize);
344-
nscoord sqrWidth = mSqrChar.GetMaxWidth(
345-
this, aRenderingContext->GetDrawTarget(), fontSizeInflation);
346-
347-
nscoord dxSqr;
369+
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
370+
GetReflowAndBoundingMetricsFor(indexFrame, indexSize, bmIndex);
371+
nscoord baseMargin = baseFrame->IntrinsicISizeOffsets().margin,
372+
indexMargin = indexFrame->IntrinsicISizeOffsets().margin;
373+
nscoord sqrWidth = mSqrChar.GetMaxWidth(this, aDrawTarget, fontSizeInflation);
374+
375+
nscoord dxIndex, dxSqr;
348376
RefPtr<nsFontMetrics> fm =
349377
nsLayoutUtils::GetFontMetricsForFrame(this, fontSizeInflation);
350-
GetRadicalXOffsets(indexWidth, sqrWidth, fm, nullptr, &dxSqr);
378+
GetRadicalXOffsets(bmIndex.width + indexMargin, sqrWidth, fm, &dxIndex,
379+
&dxSqr);
351380

352-
nscoord width = dxSqr + sqrWidth + baseWidth;
381+
mBoundingMetrics.width = dxSqr + sqrWidth + bmBase.width + baseMargin;
382+
mBoundingMetrics.leftBearing =
383+
std::min(dxIndex + bmIndex.leftBearing + indexMargin, dxSqr);
384+
mBoundingMetrics.rightBearing =
385+
dxSqr + sqrWidth +
386+
std::max(bmBase.width + baseMargin, bmBase.rightBearing + baseMargin);
353387

354-
aDesiredSize.Width() = width;
355-
aDesiredSize.mBoundingMetrics.width = width;
356-
aDesiredSize.mBoundingMetrics.leftBearing = 0;
357-
aDesiredSize.mBoundingMetrics.rightBearing = width;
388+
// Add border+padding.
389+
nsMargin borderPadding = GetBorderPaddingForPlace(flags);
390+
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
391+
mBoundingMetrics);
392+
393+
return NS_OK;
358394
}
359395

360396
void nsMathMLmrootFrame::DidSetComputedStyle(ComputedStyle* aOldStyle) {

layout/mathml/nsMathMLmrootFrame.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class nsMathMLmrootFrame final : public nsMathMLContainerFrame {
4242
nsFontMetrics* aFontMetrics, nscoord* aIndexOffset,
4343
nscoord* aSqrOffset);
4444

45-
virtual void GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
46-
ReflowOutput& aDesiredSize) override;
45+
nsresult MeasureForWidth(DrawTarget* aDrawTarget,
46+
ReflowOutput& aDesiredSize) final;
4747

4848
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
4949
const nsDisplayListSet& aLists) override;

testing/web-platform/meta/mathml/relations/css-styling/padding-border-margin/border-002.html.ini

Lines changed: 0 additions & 18 deletions
This file was deleted.

testing/web-platform/meta/mathml/relations/css-styling/padding-border-margin/margin-003.html.ini

Lines changed: 0 additions & 3 deletions
This file was deleted.

testing/web-platform/meta/mathml/relations/css-styling/padding-border-margin/padding-002.html.ini

Lines changed: 0 additions & 18 deletions
This file was deleted.

testing/web-platform/meta/mathml/relations/css-styling/padding-border-margin/padding-border-margin-005.html.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

testing/web-platform/meta/mathml/relations/css-styling/padding-border-margin/padding-border-margin-006.html.ini

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)