Skip to content

Commit 5f1924b

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 0db59bb commit 5f1924b

File tree

8 files changed

+90
-89
lines changed

8 files changed

+90
-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);
@@ -626,6 +625,11 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
626625

627626
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
628627

628+
// Add padding+border.
629+
auto borderPadding = GetBorderPaddingForPlace(aFlags);
630+
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
631+
mBoundingMetrics);
632+
629633
mReference.x = 0;
630634
mReference.y = aDesiredSize.BlockStartAscent();
631635

@@ -634,7 +638,7 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
634638
// Set position and size of MathMLChars
635639
if (IsToDraw(NOTATION_LONGDIV))
636640
mMathMLChar[mLongDivCharIndex].SetRect(nsRect(
637-
dx_left - bmLongdivChar.width,
641+
dx_left - bmLongdivChar.width + borderPadding.left,
638642
aDesiredSize.BlockStartAscent() - longdivAscent, bmLongdivChar.width,
639643
bmLongdivChar.ascent + bmLongdivChar.descent));
640644

@@ -644,15 +648,17 @@ nsresult nsMathMLmencloseFrame::PlaceInternal(DrawTarget* aDrawTarget,
644648
: dx_left - bmRadicalChar.width);
645649

646650
mMathMLChar[mRadicalCharIndex].SetRect(nsRect(
647-
dx, aDesiredSize.BlockStartAscent() - radicalAscent,
648-
bmRadicalChar.width, bmRadicalChar.ascent + bmRadicalChar.descent));
651+
dx + borderPadding.left,
652+
aDesiredSize.BlockStartAscent() - radicalAscent, bmRadicalChar.width,
653+
bmRadicalChar.ascent + bmRadicalChar.descent));
649654
}
650655

651656
mContentWidth = bmBase.width;
652657

653658
//////////////////
654659
// Finish reflowing child frames
655-
PositionRowChildFrames(dx_left, aDesiredSize.BlockStartAscent());
660+
PositionRowChildFrames(dx_left + borderPadding.left,
661+
aDesiredSize.BlockStartAscent());
656662
}
657663

658664
return NS_OK;

layout/mathml/nsMathMLmrootFrame.cpp

Lines changed: 76 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,11 @@ 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(PlaceFlag::IntrinsicSize, PlaceFlag::MeasureOnly);
326353
if (ShouldUseRowFallback()) {
327-
nsMathMLContainerFrame::GetIntrinsicISizeMetrics(aRenderingContext,
328-
aDesiredSize);
329-
return;
354+
return PlaceAsMrow(aDrawTarget, flags, aDesiredSize);
330355
}
331356

332357
// ShouldUseRowFallback() returned false so there are exactly two children.
@@ -336,25 +361,38 @@ void nsMathMLmrootFrame::GetIntrinsicISizeMetrics(gfxContext* aRenderingContext,
336361
MOZ_ASSERT(indexFrame);
337362
MOZ_ASSERT(!indexFrame->GetNextSibling());
338363

364+
nsBoundingMetrics bmBase, bmIndex;
365+
ReflowOutput baseSize(aDesiredSize.GetWritingMode());
366+
ReflowOutput indexSize(aDesiredSize.GetWritingMode());
339367
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;
368+
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
369+
GetReflowAndBoundingMetricsFor(indexFrame, indexSize, bmIndex);
370+
nscoord baseMargin = baseFrame->IntrinsicISizeOffsets().margin,
371+
indexMargin = indexFrame->IntrinsicISizeOffsets().margin;
372+
nscoord sqrWidth = mSqrChar.GetMaxWidth(this, aDrawTarget, fontSizeInflation);
373+
374+
nscoord dxIndex, dxSqr;
348375
RefPtr<nsFontMetrics> fm =
349376
nsLayoutUtils::GetFontMetricsForFrame(this, fontSizeInflation);
350-
GetRadicalXOffsets(indexWidth, sqrWidth, fm, nullptr, &dxSqr);
377+
GetRadicalXOffsets(bmIndex.width + indexMargin, sqrWidth, fm, &dxIndex,
378+
&dxSqr);
351379

352-
nscoord width = dxSqr + sqrWidth + baseWidth;
380+
mBoundingMetrics.width = dxSqr + sqrWidth + bmBase.width + baseMargin;
381+
mBoundingMetrics.leftBearing =
382+
std::min(dxIndex + bmIndex.leftBearing + indexMargin, dxSqr);
383+
mBoundingMetrics.rightBearing =
384+
dxSqr + sqrWidth +
385+
std::max(bmBase.width + baseMargin, bmBase.rightBearing + baseMargin);
386+
387+
aDesiredSize.Width() = mBoundingMetrics.width;
388+
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
389+
390+
// Add border+padding.
391+
nsMargin borderPadding = GetBorderPaddingForPlace(flags);
392+
InflateReflowAndBoundingMetrics(borderPadding, aDesiredSize,
393+
mBoundingMetrics);
353394

354-
aDesiredSize.Width() = width;
355-
aDesiredSize.mBoundingMetrics.width = width;
356-
aDesiredSize.mBoundingMetrics.leftBearing = 0;
357-
aDesiredSize.mBoundingMetrics.rightBearing = width;
395+
return NS_OK;
358396
}
359397

360398
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)