1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsMathMLmfracFrame.h"
10 #include "mozilla/gfx/2D.h"
11 #include "mozilla/RefPtr.h"
12 #include "nsLayoutUtils.h"
13 #include "nsPresContext.h"
14 #include "nsRenderingContext.h"
15 #include "nsDisplayList.h"
16 #include "gfxContext.h"
17 #include "nsMathMLElement.h"
20 using namespace mozilla
;
21 using namespace mozilla::gfx
;
24 // <mfrac> -- form a fraction from two subexpressions - implementation
27 // various fraction line thicknesses (multiplicative values of the default rule thickness)
29 #define THIN_FRACTION_LINE 0.5f
30 #define THIN_FRACTION_LINE_MINIMUM_PIXELS 1 // minimum of 1 pixel
32 #define THICK_FRACTION_LINE 2.0f
33 #define THICK_FRACTION_LINE_MINIMUM_PIXELS 2 // minimum of 2 pixels
36 NS_NewMathMLmfracFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
38 return new (aPresShell
) nsMathMLmfracFrame(aContext
);
41 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmfracFrame
)
43 nsMathMLmfracFrame::~nsMathMLmfracFrame()
48 nsMathMLmfracFrame::GetMathMLFrameType()
50 // frac is "inner" in TeXBook, Appendix G, rule 15e. See also page 170.
51 return eMathMLFrameType_Inner
;
55 nsMathMLmfracFrame::ScriptIncrement(nsIFrame
* aFrame
)
57 if (!StyleFont()->mMathDisplay
&&
58 aFrame
&& (mFrames
.FirstChild() == aFrame
||
59 mFrames
.LastChild() == aFrame
)) {
66 nsMathMLmfracFrame::TransmitAutomaticData()
68 // The TeXbook (Ch 17. p.141) says the numerator inherits the compression
69 // while the denominator is compressed
70 UpdatePresentationDataFromChildAt(1, 1,
72 NS_MATHML_COMPRESSED
);
74 // If displaystyle is false, then scriptlevel is incremented, so notify the
76 if (!StyleFont()->mMathDisplay
) {
77 PropagateFrameFlagFor(mFrames
.FirstChild(),
78 NS_FRAME_MATHML_SCRIPT_DESCENDANT
);
79 PropagateFrameFlagFor(mFrames
.LastChild(),
80 NS_FRAME_MATHML_SCRIPT_DESCENDANT
);
83 // if our numerator is an embellished operator, let its state bubble to us
84 GetEmbellishDataFrom(mFrames
.FirstChild(), mEmbellishData
);
85 if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData
.flags
)) {
86 // even when embellished, we need to record that <mfrac> won't fire
87 // Stretch() on its embellished child
88 mEmbellishData
.direction
= NS_STRETCH_DIRECTION_UNSUPPORTED
;
95 nsMathMLmfracFrame::CalcLineThickness(nsPresContext
* aPresContext
,
96 nsStyleContext
* aStyleContext
,
97 nsString
& aThicknessAttribute
,
99 nscoord aDefaultRuleThickness
,
100 float aFontSizeInflation
)
102 nscoord defaultThickness
= aDefaultRuleThickness
;
103 nscoord lineThickness
= aDefaultRuleThickness
;
104 nscoord minimumThickness
= onePixel
;
108 // "Specifies the thickness of the horizontal 'fraction bar', or 'rule'. The
109 // default value is 'medium', 'thin' is thinner, but visible, 'thick' is
110 // thicker; the exact thickness of these is left up to the rendering agent."
112 // values: length | "thin" | "medium" | "thick"
115 if (!aThicknessAttribute
.IsEmpty()) {
116 if (aThicknessAttribute
.EqualsLiteral("thin")) {
117 lineThickness
= NSToCoordFloor(defaultThickness
* THIN_FRACTION_LINE
);
118 minimumThickness
= onePixel
* THIN_FRACTION_LINE_MINIMUM_PIXELS
;
119 // should visually decrease by at least one pixel, if default is not a pixel
120 if (defaultThickness
> onePixel
&& lineThickness
> defaultThickness
- onePixel
)
121 lineThickness
= defaultThickness
- onePixel
;
123 else if (aThicknessAttribute
.EqualsLiteral("medium")) {
126 else if (aThicknessAttribute
.EqualsLiteral("thick")) {
127 lineThickness
= NSToCoordCeil(defaultThickness
* THICK_FRACTION_LINE
);
128 minimumThickness
= onePixel
* THICK_FRACTION_LINE_MINIMUM_PIXELS
;
129 // should visually increase by at least one pixel
130 if (lineThickness
< defaultThickness
+ onePixel
)
131 lineThickness
= defaultThickness
+ onePixel
;
135 lineThickness
= defaultThickness
;
136 ParseNumericValue(aThicknessAttribute
, &lineThickness
,
137 nsMathMLElement::PARSE_ALLOW_UNITLESS
,
138 aPresContext
, aStyleContext
, aFontSizeInflation
);
142 // use minimum if the lineThickness is a non-zero value less than minimun
143 if (lineThickness
&& lineThickness
< minimumThickness
)
144 lineThickness
= minimumThickness
;
146 return lineThickness
;
150 nsMathMLmfracFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
151 const nsRect
& aDirtyRect
,
152 const nsDisplayListSet
& aLists
)
155 // paint the numerator and denominator
156 nsMathMLContainerFrame::BuildDisplayList(aBuilder
, aDirtyRect
, aLists
);
159 // paint the fraction line
161 DisplaySlash(aBuilder
, this, mLineRect
, mLineThickness
, aLists
);
163 DisplayBar(aBuilder
, this, mLineRect
, aLists
);
167 /* virtual */ nsresult
168 nsMathMLmfracFrame::MeasureForWidth(DrawTarget
* aDrawTarget
,
169 nsHTMLReflowMetrics
& aDesiredSize
)
171 return PlaceInternal(aDrawTarget
, false, aDesiredSize
, true);
175 nsMathMLmfracFrame::FixInterFrameSpacing(nsHTMLReflowMetrics
& aDesiredSize
)
177 nscoord gap
= nsMathMLContainerFrame::FixInterFrameSpacing(aDesiredSize
);
180 mLineRect
.MoveBy(gap
, 0);
184 /* virtual */ nsresult
185 nsMathMLmfracFrame::Place(DrawTarget
* aDrawTarget
,
187 nsHTMLReflowMetrics
& aDesiredSize
)
189 return PlaceInternal(aDrawTarget
, aPlaceOrigin
, aDesiredSize
, false);
193 nsMathMLmfracFrame::PlaceInternal(DrawTarget
* aDrawTarget
,
195 nsHTMLReflowMetrics
& aDesiredSize
,
198 ////////////////////////////////////
199 // Get the children's desired sizes
200 nsBoundingMetrics bmNum
, bmDen
;
201 nsHTMLReflowMetrics
sizeNum(aDesiredSize
.GetWritingMode());
202 nsHTMLReflowMetrics
sizeDen(aDesiredSize
.GetWritingMode());
203 nsIFrame
* frameDen
= nullptr;
204 nsIFrame
* frameNum
= mFrames
.FirstChild();
206 frameDen
= frameNum
->GetNextSibling();
207 if (!frameNum
|| !frameDen
|| frameDen
->GetNextSibling()) {
208 // report an error, encourage people to get their markups in order
210 ReportChildCountError();
212 return ReflowError(aDrawTarget
, aDesiredSize
);
214 GetReflowAndBoundingMetricsFor(frameNum
, sizeNum
, bmNum
);
215 GetReflowAndBoundingMetricsFor(frameDen
, sizeDen
, bmDen
);
217 nsPresContext
* presContext
= PresContext();
218 nscoord onePixel
= nsPresContext::CSSPixelsToAppUnits(1);
220 float fontSizeInflation
= nsLayoutUtils::FontSizeInflationFor(this);
221 RefPtr
<nsFontMetrics
> fm
;
222 nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm
),
225 nscoord defaultRuleThickness
, axisHeight
;
226 nscoord oneDevPixel
= fm
->AppUnitsPerDevPixel();
227 gfxFont
* mathFont
= fm
->GetThebesFontGroup()->GetFirstMathFont();
229 defaultRuleThickness
=
230 mathFont
->GetMathConstant(gfxFontEntry::FractionRuleThickness
,
233 GetRuleThickness(aDrawTarget
, fm
, defaultRuleThickness
);
235 GetAxisHeight(aDrawTarget
, fm
, axisHeight
);
237 bool outermostEmbellished
= false;
238 if (mEmbellishData
.coreFrame
) {
239 nsEmbellishData parentData
;
240 GetEmbellishDataFrom(GetParent(), parentData
);
241 outermostEmbellished
= parentData
.coreFrame
!= mEmbellishData
.coreFrame
;
244 // see if the linethickness attribute is there
246 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::linethickness_
, value
);
247 mLineThickness
= CalcLineThickness(presContext
, mStyleContext
, value
,
248 onePixel
, defaultRuleThickness
,
251 // bevelled attribute
252 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::bevelled_
, value
);
253 mIsBevelled
= value
.EqualsLiteral("true");
255 bool displayStyle
= StyleFont()->mMathDisplay
== NS_MATHML_DISPLAYSTYLE_BLOCK
;
258 mLineRect
.height
= mLineThickness
;
260 // by default, leave at least one-pixel padding at either end, and add
261 // lspace & rspace that may come from <mo> if we are an outermost
262 // embellished container (we fetch values from the core since they may use
263 // units that depend on style data, and style changes could have occurred
264 // in the core since our last visit there)
265 nscoord leftSpace
= onePixel
;
266 nscoord rightSpace
= onePixel
;
267 if (outermostEmbellished
) {
268 nsEmbellishData coreData
;
269 GetEmbellishDataFrom(mEmbellishData
.coreFrame
, coreData
);
270 leftSpace
+= StyleVisibility()->mDirection
?
271 coreData
.trailingSpace
: coreData
.leadingSpace
;
272 rightSpace
+= StyleVisibility()->mDirection
?
273 coreData
.leadingSpace
: coreData
.trailingSpace
;
276 nscoord actualRuleThickness
= mLineThickness
;
280 nscoord numShift
= 0;
281 nscoord denShift
= 0;
283 // Rule 15b, App. G, TeXbook
284 nscoord numShift1
, numShift2
, numShift3
;
285 nscoord denShift1
, denShift2
;
287 GetNumeratorShifts(fm
, numShift1
, numShift2
, numShift3
);
288 GetDenominatorShifts(fm
, denShift1
, denShift2
);
290 if (0 == actualRuleThickness
) {
291 numShift
= displayStyle
? numShift1
: numShift3
;
292 denShift
= displayStyle
? denShift1
: denShift2
;
294 numShift
= mathFont
->
295 GetMathConstant(displayStyle
?
296 gfxFontEntry::StackTopDisplayStyleShiftUp
:
297 gfxFontEntry::StackTopShiftUp
,
299 denShift
= mathFont
->
300 GetMathConstant(displayStyle
?
301 gfxFontEntry::StackBottomDisplayStyleShiftDown
:
302 gfxFontEntry::StackBottomShiftDown
,
306 numShift
= displayStyle
? numShift1
: numShift2
;
307 denShift
= displayStyle
? denShift1
: denShift2
;
309 numShift
= mathFont
->
310 GetMathConstant(displayStyle
?
311 gfxFontEntry::FractionNumeratorDisplayStyleShiftUp
:
312 gfxFontEntry::FractionNumeratorShiftUp
,
314 denShift
= mathFont
->
317 gfxFontEntry::FractionDenominatorDisplayStyleShiftDown
:
318 gfxFontEntry::FractionDenominatorShiftDown
,
323 if (0 == actualRuleThickness
) {
324 // Rule 15c, App. G, TeXbook
326 // min clearance between numerator and denominator
327 nscoord minClearance
= displayStyle
?
328 7 * defaultRuleThickness
: 3 * defaultRuleThickness
;
331 mathFont
->GetMathConstant(displayStyle
?
332 gfxFontEntry::StackDisplayStyleGapMin
:
333 gfxFontEntry::StackGapMin
,
336 nscoord actualClearance
=
337 (numShift
- bmNum
.descent
) - (bmDen
.ascent
- denShift
);
338 // actualClearance should be >= minClearance
339 if (actualClearance
< minClearance
) {
340 nscoord halfGap
= (minClearance
- actualClearance
)/2;
346 // Rule 15d, App. G, TeXbook
348 // min clearance between numerator or denominator and middle of bar
350 // TeX has a different interpretation of the thickness.
351 // Try $a \above10pt b$ to see. Here is what TeX does:
352 // minClearance = displayStyle ?
353 // 3 * actualRuleThickness : actualRuleThickness;
355 // we slightly depart from TeX here. We use the defaultRuleThickness instead
356 // of the value coming from the linethickness attribute, i.e., we recover what
357 // TeX does if the user hasn't set linethickness. But when the linethickness
358 // is set, we avoid the wide gap problem.
359 nscoord minClearanceNum
= displayStyle
?
360 3 * defaultRuleThickness
: defaultRuleThickness
+ onePixel
;
361 nscoord minClearanceDen
= minClearanceNum
;
363 minClearanceNum
= mathFont
->
364 GetMathConstant(displayStyle
?
365 gfxFontEntry::FractionNumDisplayStyleGapMin
:
366 gfxFontEntry::FractionNumeratorGapMin
,
368 minClearanceDen
= mathFont
->
369 GetMathConstant(displayStyle
?
370 gfxFontEntry::FractionDenomDisplayStyleGapMin
:
371 gfxFontEntry::FractionDenominatorGapMin
,
375 // adjust numShift to maintain minClearanceNum if needed
376 nscoord actualClearanceNum
=
377 (numShift
- bmNum
.descent
) - (axisHeight
+ actualRuleThickness
/2);
378 if (actualClearanceNum
< minClearanceNum
) {
379 numShift
+= (minClearanceNum
- actualClearanceNum
);
381 // adjust denShift to maintain minClearanceDen if needed
382 nscoord actualClearanceDen
=
383 (axisHeight
- actualRuleThickness
/2) - (bmDen
.ascent
- denShift
);
384 if (actualClearanceDen
< minClearanceDen
) {
385 denShift
+= (minClearanceDen
- actualClearanceDen
);
392 // XXX Need revisiting the width. TeX uses the exact width
393 // e.g. in $$\huge\frac{\displaystyle\int}{i}$$
394 nscoord width
= std::max(bmNum
.width
, bmDen
.width
);
395 nscoord dxNum
= leftSpace
+ (width
- sizeNum
.Width())/2;
396 nscoord dxDen
= leftSpace
+ (width
- sizeDen
.Width())/2;
397 width
+= leftSpace
+ rightSpace
;
399 // see if the numalign attribute is there
400 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::numalign_
, value
);
401 if (value
.EqualsLiteral("left"))
403 else if (value
.EqualsLiteral("right"))
404 dxNum
= width
- rightSpace
- sizeNum
.Width();
406 // see if the denomalign attribute is there
407 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::denomalign_
, value
);
408 if (value
.EqualsLiteral("left"))
410 else if (value
.EqualsLiteral("right"))
411 dxDen
= width
- rightSpace
- sizeDen
.Width();
413 mBoundingMetrics
.rightBearing
=
414 std::max(dxNum
+ bmNum
.rightBearing
, dxDen
+ bmDen
.rightBearing
);
415 if (mBoundingMetrics
.rightBearing
< width
- rightSpace
)
416 mBoundingMetrics
.rightBearing
= width
- rightSpace
;
417 mBoundingMetrics
.leftBearing
=
418 std::min(dxNum
+ bmNum
.leftBearing
, dxDen
+ bmDen
.leftBearing
);
419 if (mBoundingMetrics
.leftBearing
> leftSpace
)
420 mBoundingMetrics
.leftBearing
= leftSpace
;
421 mBoundingMetrics
.ascent
= bmNum
.ascent
+ numShift
;
422 mBoundingMetrics
.descent
= bmDen
.descent
+ denShift
;
423 mBoundingMetrics
.width
= width
;
425 aDesiredSize
.SetBlockStartAscent(sizeNum
.BlockStartAscent() + numShift
);
426 aDesiredSize
.Height() = aDesiredSize
.BlockStartAscent() +
427 sizeDen
.Height() - sizeDen
.BlockStartAscent() + denShift
;
428 aDesiredSize
.Width() = mBoundingMetrics
.width
;
429 aDesiredSize
.mBoundingMetrics
= mBoundingMetrics
;
432 mReference
.y
= aDesiredSize
.BlockStartAscent();
438 FinishReflowChild(frameNum
, presContext
, sizeNum
, nullptr, dxNum
, dy
, 0);
440 dy
= aDesiredSize
.Height() - sizeDen
.Height();
441 FinishReflowChild(frameDen
, presContext
, sizeDen
, nullptr, dxDen
, dy
, 0);
442 // place the fraction bar - dy is top of bar
443 dy
= aDesiredSize
.BlockStartAscent() - (axisHeight
+ actualRuleThickness
/2);
444 mLineRect
.SetRect(leftSpace
, dy
, width
- (leftSpace
+ rightSpace
),
445 actualRuleThickness
);
448 nscoord numShift
= 0.0;
449 nscoord denShift
= 0.0;
450 nscoord padding
= 3 * defaultRuleThickness
;
451 nscoord slashRatio
= 3;
453 // Define the constant used in the expression of the maximum width
454 nscoord em
= fm
->EmHeight();
455 nscoord slashMaxWidthConstant
= 2 * em
;
457 // For large line thicknesses the minimum slash height is limited to the
458 // largest expected height of a fraction
459 nscoord slashMinHeight
= slashRatio
*
460 std::min(2 * mLineThickness
, slashMaxWidthConstant
);
462 nscoord leadingSpace
= padding
;
463 nscoord trailingSpace
= padding
;
464 if (outermostEmbellished
) {
465 nsEmbellishData coreData
;
466 GetEmbellishDataFrom(mEmbellishData
.coreFrame
, coreData
);
467 leadingSpace
+= coreData
.leadingSpace
;
468 trailingSpace
+= coreData
.trailingSpace
;
478 // ------------------------------------------------------- baseline
479 // S _____________ } denShift
481 // / |-DENOMINATOR-|}
485 // first, ensure that the top of the numerator is at least as high as the
486 // top of the denominator (and the reverse for the bottoms)
487 delta
= std::max(bmDen
.ascent
- bmNum
.ascent
,
488 bmNum
.descent
- bmDen
.descent
) / 2;
494 if (StyleFont()->mMathDisplay
== NS_MATHML_DISPLAYSTYLE_BLOCK
) {
495 delta
= std::min(bmDen
.ascent
+ bmDen
.descent
,
496 bmNum
.ascent
+ bmNum
.descent
) / 2;
500 nscoord xHeight
= fm
->XHeight();
501 numShift
+= xHeight
/ 2;
502 denShift
+= xHeight
/ 4;
505 // Set the ascent/descent of our BoundingMetrics.
506 mBoundingMetrics
.ascent
= bmNum
.ascent
+ numShift
;
507 mBoundingMetrics
.descent
= bmDen
.descent
+ denShift
;
509 // At this point the height of the slash is
510 // mBoundingMetrics.ascent + mBoundingMetrics.descent
511 // Ensure that it is greater than slashMinHeight
512 delta
= (slashMinHeight
-
513 (mBoundingMetrics
.ascent
+ mBoundingMetrics
.descent
)) / 2;
515 mBoundingMetrics
.ascent
+= delta
;
516 mBoundingMetrics
.descent
+= delta
;
519 // Set the width of the slash
521 mLineRect
.width
= mLineThickness
+ slashMaxWidthConstant
;
523 mLineRect
.width
= mLineThickness
+
524 std::min(slashMaxWidthConstant
,
525 (mBoundingMetrics
.ascent
+ mBoundingMetrics
.descent
) /
529 // Set horizontal bounding metrics
530 if (StyleVisibility()->mDirection
) {
531 mBoundingMetrics
.leftBearing
= trailingSpace
+ bmDen
.leftBearing
;
532 mBoundingMetrics
.rightBearing
= trailingSpace
+ bmDen
.width
+ mLineRect
.width
+ bmNum
.rightBearing
;
534 mBoundingMetrics
.leftBearing
= leadingSpace
+ bmNum
.leftBearing
;
535 mBoundingMetrics
.rightBearing
= leadingSpace
+ bmNum
.width
+ mLineRect
.width
+ bmDen
.rightBearing
;
537 mBoundingMetrics
.width
=
538 leadingSpace
+ bmNum
.width
+ mLineRect
.width
+ bmDen
.width
+
542 aDesiredSize
.SetBlockStartAscent(mBoundingMetrics
.ascent
+ padding
);
543 aDesiredSize
.Height() =
544 mBoundingMetrics
.ascent
+ mBoundingMetrics
.descent
+ 2 * padding
;
545 aDesiredSize
.Width() = mBoundingMetrics
.width
;
546 aDesiredSize
.mBoundingMetrics
= mBoundingMetrics
;
549 mReference
.y
= aDesiredSize
.BlockStartAscent();
555 dx
= MirrorIfRTL(aDesiredSize
.Width(), sizeNum
.Width(),
557 dy
= aDesiredSize
.BlockStartAscent() - numShift
- sizeNum
.BlockStartAscent();
558 FinishReflowChild(frameNum
, presContext
, sizeNum
, nullptr, dx
, dy
, 0);
560 // place the fraction bar
561 dx
= MirrorIfRTL(aDesiredSize
.Width(), mLineRect
.width
,
562 leadingSpace
+ bmNum
.width
);
563 dy
= aDesiredSize
.BlockStartAscent() - mBoundingMetrics
.ascent
;
564 mLineRect
.SetRect(dx
, dy
,
565 mLineRect
.width
, aDesiredSize
.Height() - 2 * padding
);
568 dx
= MirrorIfRTL(aDesiredSize
.Width(), sizeDen
.Width(),
569 leadingSpace
+ bmNum
.width
+ mLineRect
.width
);
570 dy
= aDesiredSize
.BlockStartAscent() + denShift
- sizeDen
.BlockStartAscent();
571 FinishReflowChild(frameDen
, presContext
, sizeDen
, nullptr, dx
, dy
, 0);
579 class nsDisplayMathMLSlash
: public nsDisplayItem
{
581 nsDisplayMathMLSlash(nsDisplayListBuilder
* aBuilder
,
582 nsIFrame
* aFrame
, const nsRect
& aRect
,
583 nscoord aThickness
, bool aRTL
)
584 : nsDisplayItem(aBuilder
, aFrame
), mRect(aRect
), mThickness(aThickness
),
586 MOZ_COUNT_CTOR(nsDisplayMathMLSlash
);
588 #ifdef NS_BUILD_REFCNT_LOGGING
589 virtual ~nsDisplayMathMLSlash() {
590 MOZ_COUNT_DTOR(nsDisplayMathMLSlash
);
594 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
595 nsRenderingContext
* aCtx
) override
;
596 NS_DISPLAY_DECL_NAME("MathMLSlash", TYPE_MATHML_SLASH
)
604 void nsDisplayMathMLSlash::Paint(nsDisplayListBuilder
* aBuilder
,
605 nsRenderingContext
* aCtx
)
607 DrawTarget
& aDrawTarget
= *aCtx
->GetDrawTarget();
610 nsPresContext
* presContext
= mFrame
->PresContext();
611 Rect rect
= NSRectToRect(mRect
+ ToReferenceFrame(),
612 presContext
->AppUnitsPerDevPixel());
614 ColorPattern
color(ToDeviceColor(
615 mFrame
->GetVisitedDependentColor(eCSSProperty_color
)));
617 // draw the slash as a parallelogram
618 Point delta
= Point(presContext
->AppUnitsToGfxUnits(mThickness
), 0);
619 RefPtr
<PathBuilder
> builder
= aDrawTarget
.CreatePathBuilder();
621 builder
->MoveTo(rect
.TopLeft());
622 builder
->LineTo(rect
.TopLeft() + delta
);
623 builder
->LineTo(rect
.BottomRight());
624 builder
->LineTo(rect
.BottomRight() - delta
);
626 builder
->MoveTo(rect
.BottomLeft());
627 builder
->LineTo(rect
.BottomLeft() + delta
);
628 builder
->LineTo(rect
.TopRight());
629 builder
->LineTo(rect
.TopRight() - delta
);
631 RefPtr
<Path
> path
= builder
->Finish();
632 aDrawTarget
.Fill(path
, color
);
636 nsMathMLmfracFrame::DisplaySlash(nsDisplayListBuilder
* aBuilder
,
637 nsIFrame
* aFrame
, const nsRect
& aRect
,
639 const nsDisplayListSet
& aLists
) {
640 if (!aFrame
->StyleVisibility()->IsVisible() || aRect
.IsEmpty())
643 aLists
.Content()->AppendNewToTop(new (aBuilder
)
644 nsDisplayMathMLSlash(aBuilder
, aFrame
, aRect
, aThickness
,
645 StyleVisibility()->mDirection
));