1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Mozilla MathML Project.
17 * The Initial Developer of the Original Code is
18 * The University Of Queensland.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
23 * Roger B. Sidje <rbs@maths.uq.edu.au>
24 * David J. Fiddes <D.J.Fiddes@hw.ac.uk>
25 * Pierre Phaneuf <pp@ludusdesign.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
44 #include "nsPresContext.h"
45 #include "nsStyleContext.h"
46 #include "nsStyleConsts.h"
47 #include "nsIRenderingContext.h"
48 #include "nsIFontMetrics.h"
50 #include "nsMathMLmfencedFrame.h"
53 // <mfenced> -- surround content with a pair of fences
57 NS_NewMathMLmfencedFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
59 return new (aPresShell
) nsMathMLmfencedFrame(aContext
);
62 nsMathMLmfencedFrame::~nsMathMLmfencedFrame()
64 RemoveFencesAndSeparators();
68 nsMathMLmfencedFrame::InheritAutomaticData(nsIFrame
* aParent
)
70 // let the base class get the default from our parent
71 nsMathMLContainerFrame::InheritAutomaticData(aParent
);
73 mPresentationData
.flags
|= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY
;
79 nsMathMLmfencedFrame::SetInitialChildList(nsIAtom
* aListName
,
82 // First, let the base class do its work
83 nsresult rv
= nsMathMLContainerFrame::SetInitialChildList(aListName
, aChildList
);
84 if (NS_FAILED(rv
)) return rv
;
86 // No need to tract the style contexts given to our MathML chars.
87 // The Style System will use Get/SetAdditionalStyleContext() to keep them
88 // up-to-date if dynamic changes arise.
89 return CreateFencesAndSeparators(PresContext());
93 nsMathMLmfencedFrame::AttributeChanged(PRInt32 aNameSpaceID
,
97 RemoveFencesAndSeparators();
98 CreateFencesAndSeparators(PresContext());
100 return nsMathMLContainerFrame::
101 AttributeChanged(aNameSpaceID
, aAttribute
, aModType
);
105 nsMathMLmfencedFrame::ChildListChanged(PRInt32 aModType
)
107 RemoveFencesAndSeparators();
108 CreateFencesAndSeparators(PresContext());
110 return nsMathMLContainerFrame::ChildListChanged(aModType
);
114 nsMathMLmfencedFrame::RemoveFencesAndSeparators()
116 if (mOpenChar
) delete mOpenChar
;
117 if (mCloseChar
) delete mCloseChar
;
118 if (mSeparatorsChar
) delete[] mSeparatorsChar
;
122 mSeparatorsChar
= nsnull
;
123 mSeparatorsCount
= 0;
127 nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext
* aPresContext
)
130 PRBool isMutable
= PR_FALSE
;
133 // see if the opening fence is there ...
134 if (!GetAttribute(mContent
, mPresentationData
.mstyle
, nsGkAtoms::open
,
136 value
= PRUnichar('('); // default as per the MathML REC
142 if (!value
.IsEmpty()) {
143 mOpenChar
= new nsMathMLChar
;
144 if (!mOpenChar
) return NS_ERROR_OUT_OF_MEMORY
;
145 mOpenChar
->SetData(aPresContext
, value
);
146 isMutable
= nsMathMLOperators::IsMutableOperator(value
);
147 ResolveMathMLCharStyle(aPresContext
, mContent
, mStyleContext
, mOpenChar
, isMutable
);
151 // see if the closing fence is there ...
152 if(!GetAttribute(mContent
, mPresentationData
.mstyle
,
153 nsGkAtoms::close
, value
)) {
154 value
= PRUnichar(')'); // default as per the MathML REC
160 if (!value
.IsEmpty()) {
161 mCloseChar
= new nsMathMLChar
;
162 if (!mCloseChar
) return NS_ERROR_OUT_OF_MEMORY
;
163 mCloseChar
->SetData(aPresContext
, value
);
164 isMutable
= nsMathMLOperators::IsMutableOperator(value
);
165 ResolveMathMLCharStyle(aPresContext
, mContent
, mStyleContext
, mCloseChar
, isMutable
);
169 // see if separators are there ...
170 if(!GetAttribute(mContent
, mPresentationData
.mstyle
,
171 nsGkAtoms::separators_
, value
)) {
172 value
= PRUnichar(','); // default as per the MathML REC
178 mSeparatorsCount
= value
.Length();
179 if (0 < mSeparatorsCount
) {
180 PRInt32 sepCount
= mFrames
.GetLength() - 1;
182 mSeparatorsChar
= new nsMathMLChar
[sepCount
];
183 if (!mSeparatorsChar
) return NS_ERROR_OUT_OF_MEMORY
;
184 nsAutoString sepChar
;
185 for (PRInt32 i
= 0; i
< sepCount
; i
++) {
186 if (i
< mSeparatorsCount
) {
188 isMutable
= nsMathMLOperators::IsMutableOperator(sepChar
);
191 sepChar
= value
[mSeparatorsCount
-1];
192 // keep the value of isMutable that was set earlier
194 mSeparatorsChar
[i
].SetData(aPresContext
, sepChar
);
195 ResolveMathMLCharStyle(aPresContext
, mContent
, mStyleContext
, &mSeparatorsChar
[i
], isMutable
);
197 mSeparatorsCount
= sepCount
;
199 // No separators. Note that sepCount can be -1 here, so don't
200 // set mSeparatorsCount to it.
201 mSeparatorsCount
= 0;
208 nsMathMLmfencedFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
209 const nsRect
& aDirtyRect
,
210 const nsDisplayListSet
& aLists
)
213 // display the content
214 nsresult rv
= nsMathMLContainerFrame::BuildDisplayList(aBuilder
, aDirtyRect
, aLists
);
215 NS_ENSURE_SUCCESS(rv
, rv
);
218 // display fences and separators
220 rv
= mOpenChar
->Display(aBuilder
, this, aLists
);
221 NS_ENSURE_SUCCESS(rv
, rv
);
225 rv
= mCloseChar
->Display(aBuilder
, this, aLists
);
226 NS_ENSURE_SUCCESS(rv
, rv
);
229 for (PRInt32 i
= 0; i
< mSeparatorsCount
; i
++) {
230 rv
= mSeparatorsChar
[i
].Display(aBuilder
, this, aLists
);
231 NS_ENSURE_SUCCESS(rv
, rv
);
237 nsMathMLmfencedFrame::Reflow(nsPresContext
* aPresContext
,
238 nsHTMLReflowMetrics
& aDesiredSize
,
239 const nsHTMLReflowState
& aReflowState
,
240 nsReflowStatus
& aStatus
)
242 return doReflow(aPresContext
, aReflowState
, aDesiredSize
, aStatus
, this,
243 mOpenChar
, mCloseChar
, mSeparatorsChar
, mSeparatorsCount
);
246 /* virtual */ nscoord
247 nsMathMLmfencedFrame::GetIntrinsicWidth(nsIRenderingContext
* aRenderingContext
)
249 return doGetIntrinsicWidth(aRenderingContext
, this, mOpenChar
, mCloseChar
,
250 mSeparatorsChar
, mSeparatorsCount
);
253 // exported routine that both mfenced and mfrac share.
254 // mfrac uses this when its bevelled attribute is set.
256 nsMathMLmfencedFrame::doReflow(nsPresContext
* aPresContext
,
257 const nsHTMLReflowState
& aReflowState
,
258 nsHTMLReflowMetrics
& aDesiredSize
,
259 nsReflowStatus
& aStatus
,
260 nsMathMLContainerFrame
* aForFrame
,
261 nsMathMLChar
* aOpenChar
,
262 nsMathMLChar
* aCloseChar
,
263 nsMathMLChar
* aSeparatorsChar
,
264 PRInt32 aSeparatorsCount
)
268 aDesiredSize
.width
= aDesiredSize
.height
= 0;
269 aDesiredSize
.ascent
= 0;
270 aDesiredSize
.mBoundingMetrics
.Clear();
273 nsCOMPtr
<nsIFontMetrics
> fm
;
274 const nsStyleFont
* font
= aForFrame
->GetStyleFont();
275 aReflowState
.rendContext
->SetFont(font
->mFont
, nsnull
,
276 aPresContext
->GetUserFontSet());
277 aReflowState
.rendContext
->GetFontMetrics(*getter_AddRefs(fm
));
278 nscoord axisHeight
, em
;
279 GetAxisHeight(*aReflowState
.rendContext
, fm
, axisHeight
);
281 // leading to be left at the top and the bottom of stretched chars
282 nscoord leading
= NSToCoordRound(0.2f
* em
);
286 // Asking each child to cache its bounding metrics
288 // Note that we don't use the base method nsMathMLContainerFrame::Reflow()
289 // because we want to stretch our fences, separators and stretchy frames using
290 // the *same* initial aDesiredSize.mBoundingMetrics. If we were to use the base
291 // method here, our stretchy frames will be stretched and placed, and we may
292 // end up stretching our fences/separators with a different aDesiredSize.
293 // XXX The above decision was revisited in bug 121748 and this code can be
294 // refactored to use nsMathMLContainerFrame::Reflow() at some stage.
296 nsReflowStatus childStatus
;
297 nsSize
availSize(aReflowState
.ComputedWidth(), NS_UNCONSTRAINEDSIZE
);
298 nsIFrame
* firstChild
= aForFrame
->GetFirstChild(nsnull
);
299 nsIFrame
* childFrame
= firstChild
;
300 nscoord ascent
= 0, descent
= 0;
301 if (firstChild
|| aOpenChar
|| aCloseChar
|| aSeparatorsCount
> 0) {
302 // We use the ASCII metrics to get our minimum height. This way, if we have
303 // borders or a background, they will fit better with other elements on the line
304 fm
->GetMaxAscent(ascent
);
305 fm
->GetMaxDescent(descent
);
308 nsHTMLReflowMetrics
childDesiredSize(aDesiredSize
.mFlags
309 | NS_REFLOW_CALC_BOUNDING_METRICS
);
310 nsHTMLReflowState
childReflowState(aPresContext
, aReflowState
,
311 childFrame
, availSize
);
312 rv
= aForFrame
->ReflowChild(childFrame
, aPresContext
, childDesiredSize
,
313 childReflowState
, childStatus
);
314 //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
316 // Call DidReflow() for the child frames we successfully did reflow.
317 aForFrame
->DidReflowChildren(firstChild
, childFrame
);
321 SaveReflowAndBoundingMetricsFor(childFrame
, childDesiredSize
,
322 childDesiredSize
.mBoundingMetrics
);
324 // compute the bounding metrics right now for mfrac
325 nscoord childDescent
= childDesiredSize
.height
- childDesiredSize
.ascent
;
326 if (descent
< childDescent
)
327 descent
= childDescent
;
328 if (ascent
< childDesiredSize
.ascent
)
329 ascent
= childDesiredSize
.ascent
;
330 aDesiredSize
.mBoundingMetrics
+= childDesiredSize
.mBoundingMetrics
;
332 childFrame
= childFrame
->GetNextSibling();
336 // Ask stretchy children to stretch themselves
338 nsBoundingMetrics containerSize
;
339 nsStretchDirection stretchDir
= NS_STRETCH_DIRECTION_VERTICAL
;
341 nsPresentationData presentationData
;
342 aForFrame
->GetPresentationData(presentationData
);
343 if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData
.flags
)) {
344 // case when the call is made for mfrac, we only need to stretch the '/' separator
345 containerSize
= aDesiredSize
.mBoundingMetrics
; // computed earlier
348 // case when the call is made for mfenced
349 aForFrame
->GetPreferredStretchSize(*aReflowState
.rendContext
,
350 0, /* i.e., without embellishments */
351 stretchDir
, containerSize
);
352 childFrame
= firstChild
;
354 nsIMathMLFrame
* mathmlChild
;
355 childFrame
->QueryInterface(NS_GET_IID(nsIMathMLFrame
), (void**)&mathmlChild
);
357 nsHTMLReflowMetrics childDesiredSize
;
358 // retrieve the metrics that was stored at the previous pass
359 GetReflowAndBoundingMetricsFor(childFrame
, childDesiredSize
,
360 childDesiredSize
.mBoundingMetrics
);
362 mathmlChild
->Stretch(*aReflowState
.rendContext
,
363 stretchDir
, containerSize
, childDesiredSize
);
364 // store the updated metrics
365 SaveReflowAndBoundingMetricsFor(childFrame
, childDesiredSize
,
366 childDesiredSize
.mBoundingMetrics
);
368 nscoord childDescent
= childDesiredSize
.height
- childDesiredSize
.ascent
;
369 if (descent
< childDescent
)
370 descent
= childDescent
;
371 if (ascent
< childDesiredSize
.ascent
)
372 ascent
= childDesiredSize
.ascent
;
374 childFrame
= childFrame
->GetNextSibling();
376 // bug 121748: for surrounding fences & separators, use a size that covers everything
377 aForFrame
->GetPreferredStretchSize(*aReflowState
.rendContext
,
378 STRETCH_CONSIDER_EMBELLISHMENTS
,
379 stretchDir
, containerSize
);
382 //////////////////////////////////////////
383 // Prepare the opening fence, separators, and closing fence, and
384 // adjust the origin of children.
386 // we need to center around the axis
387 if (firstChild
) { // do nothing for an empty <mfenced></mfenced>
388 nscoord delta
= PR_MAX(containerSize
.ascent
- axisHeight
,
389 containerSize
.descent
+ axisHeight
);
390 containerSize
.ascent
= delta
+ axisHeight
;
391 containerSize
.descent
= delta
- axisHeight
;
396 ReflowChar(aPresContext
, *aReflowState
.rendContext
, aOpenChar
,
397 NS_MATHML_OPERATOR_FORM_PREFIX
, font
->mScriptLevel
,
398 axisHeight
, leading
, em
, containerSize
, ascent
, descent
);
401 for (i
= 0; i
< aSeparatorsCount
; i
++) {
402 ReflowChar(aPresContext
, *aReflowState
.rendContext
, &aSeparatorsChar
[i
],
403 NS_MATHML_OPERATOR_FORM_INFIX
, font
->mScriptLevel
,
404 axisHeight
, leading
, em
, containerSize
, ascent
, descent
);
408 ReflowChar(aPresContext
, *aReflowState
.rendContext
, aCloseChar
,
409 NS_MATHML_OPERATOR_FORM_POSTFIX
, font
->mScriptLevel
,
410 axisHeight
, leading
, em
, containerSize
, ascent
, descent
);
413 // Adjust the origins of each child.
414 // and update our bounding metrics
418 nsBoundingMetrics bm
;
419 PRBool firstTime
= PR_TRUE
;
421 PlaceChar(aOpenChar
, ascent
, bm
, dx
);
422 aDesiredSize
.mBoundingMetrics
= bm
;
423 firstTime
= PR_FALSE
;
426 childFrame
= firstChild
;
428 nsHTMLReflowMetrics childSize
;
429 GetReflowAndBoundingMetricsFor(childFrame
, childSize
, bm
);
431 firstTime
= PR_FALSE
;
432 aDesiredSize
.mBoundingMetrics
= bm
;
435 aDesiredSize
.mBoundingMetrics
+= bm
;
437 aForFrame
->FinishReflowChild(childFrame
, aPresContext
, nsnull
, childSize
,
438 dx
, ascent
- childSize
.ascent
, 0);
439 dx
+= childSize
.width
;
441 if (i
< aSeparatorsCount
) {
442 PlaceChar(&aSeparatorsChar
[i
], ascent
, bm
, dx
);
443 aDesiredSize
.mBoundingMetrics
+= bm
;
447 childFrame
= childFrame
->GetNextSibling();
451 PlaceChar(aCloseChar
, ascent
, bm
, dx
);
453 aDesiredSize
.mBoundingMetrics
= bm
;
455 aDesiredSize
.mBoundingMetrics
+= bm
;
458 aDesiredSize
.width
= aDesiredSize
.mBoundingMetrics
.width
;
459 aDesiredSize
.height
= ascent
+ descent
;
460 aDesiredSize
.ascent
= ascent
;
462 aForFrame
->SetBoundingMetrics(aDesiredSize
.mBoundingMetrics
);
463 aForFrame
->SetReference(nsPoint(0, aDesiredSize
.ascent
));
465 // see if we should fix the spacing
466 aForFrame
->FixInterFrameSpacing(aDesiredSize
);
468 // Finished with these:
469 aForFrame
->ClearSavedChildMetrics();
471 // Set our overflow area
472 aForFrame
->GatherAndStoreOverflow(&aDesiredSize
);
474 aStatus
= NS_FRAME_COMPLETE
;
475 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
480 GetCharSpacing(nsMathMLChar
* aMathMLChar
,
481 nsOperatorFlags aForm
,
482 PRInt32 aScriptLevel
,
485 nscoord
& aRightSpace
)
488 aMathMLChar
->GetData(data
);
489 nsOperatorFlags flags
= 0;
492 PRBool found
= nsMathMLOperators::LookupOperator(data
, aForm
,
493 &flags
, &lspace
, &rspace
);
495 // We don't want extra space when we are a script
496 if (found
&& aScriptLevel
> 0) {
501 aLeftSpace
= NSToCoordRound(lspace
* em
);
502 aRightSpace
= NSToCoordRound(rspace
* em
);
505 // helper functions to perform the common task of formatting our chars
507 nsMathMLmfencedFrame::ReflowChar(nsPresContext
* aPresContext
,
508 nsIRenderingContext
& aRenderingContext
,
509 nsMathMLChar
* aMathMLChar
,
510 nsOperatorFlags aForm
,
511 PRInt32 aScriptLevel
,
515 nsBoundingMetrics
& aContainerSize
,
519 if (aMathMLChar
&& 0 < aMathMLChar
->Length()) {
522 GetCharSpacing(aMathMLChar
, aForm
, aScriptLevel
, em
, leftSpace
, rightSpace
);
524 // stretch the char to the appropriate height if it is not big enough.
525 nsBoundingMetrics charSize
;
526 nsresult res
= aMathMLChar
->Stretch(aPresContext
, aRenderingContext
,
527 NS_STRETCH_DIRECTION_VERTICAL
,
528 aContainerSize
, charSize
);
530 if (NS_STRETCH_DIRECTION_UNSUPPORTED
!= aMathMLChar
->GetStretchDirection()) {
531 // has changed... so center the char around the axis
532 nscoord height
= charSize
.ascent
+ charSize
.descent
;
533 charSize
.ascent
= height
/2 + axisHeight
;
534 charSize
.descent
= height
- charSize
.ascent
;
537 // either it hasn't changed or stretching the char failed (i.e.,
538 // GetBoundingMetrics failed)
540 if (NS_FAILED(res
)) {
542 aMathMLChar
->GetData(data
);
543 nsTextDimensions dimensions
;
544 aRenderingContext
.GetTextDimensions(data
.get(), data
.Length(), dimensions
);
545 charSize
.ascent
= dimensions
.ascent
;
546 charSize
.descent
= dimensions
.descent
;
547 charSize
.width
= dimensions
.width
;
548 // Set this as the bounding metrics of the MathMLChar to leave
549 // the necessary room to paint the char.
550 aMathMLChar
->SetBoundingMetrics(charSize
);
554 if (aAscent
< charSize
.ascent
+ leading
)
555 aAscent
= charSize
.ascent
+ leading
;
556 if (aDescent
< charSize
.descent
+ leading
)
557 aDescent
= charSize
.descent
+ leading
;
559 // account the spacing
560 charSize
.width
+= leftSpace
+ rightSpace
;
562 // x-origin is used to store lspace ...
563 // y-origin is used to stored the ascent ...
564 aMathMLChar
->SetRect(nsRect(leftSpace
,
565 charSize
.ascent
, charSize
.width
,
566 charSize
.ascent
+ charSize
.descent
));
572 nsMathMLmfencedFrame::PlaceChar(nsMathMLChar
* aMathMLChar
,
573 nscoord aDesiredAscent
,
574 nsBoundingMetrics
& bm
,
577 aMathMLChar
->GetBoundingMetrics(bm
);
579 // the char's x-origin was used to store lspace ...
580 // the char's y-origin was used to store the ascent ...
581 // the char's width was used to store the advance with (with spacing) ...
583 aMathMLChar
->GetRect(rect
);
585 nscoord dy
= aDesiredAscent
- rect
.y
;
586 if (aMathMLChar
->GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED
) {
587 // the stretchy char will be centered around the axis
588 // so we adjust the returned bounding metrics accordingly
589 bm
.descent
= (bm
.ascent
+ bm
.descent
) - rect
.y
;
593 aMathMLChar
->SetRect(nsRect(dx
+ rect
.x
, dy
, bm
.width
, rect
.height
));
595 bm
.leftBearing
+= rect
.x
;
596 bm
.rightBearing
+= rect
.x
;
598 // return rect.width since it includes lspace and rspace
599 bm
.width
= rect
.width
;
604 GetMaxCharWidth(nsPresContext
* aPresContext
,
605 nsIRenderingContext
* aRenderingContext
,
606 nsMathMLChar
* aMathMLChar
,
607 nsOperatorFlags aForm
,
608 PRInt32 aScriptLevel
,
611 nscoord width
= aMathMLChar
->GetMaxWidth(aPresContext
, *aRenderingContext
);
613 if (0 < aMathMLChar
->Length()) {
616 GetCharSpacing(aMathMLChar
, aForm
, aScriptLevel
, em
, leftSpace
, rightSpace
);
618 width
+= leftSpace
+ rightSpace
;
624 /* virtual */ nscoord
625 nsMathMLmfencedFrame::doGetIntrinsicWidth(nsIRenderingContext
* aRenderingContext
,
626 nsMathMLContainerFrame
* aForFrame
,
627 nsMathMLChar
* aOpenChar
,
628 nsMathMLChar
* aCloseChar
,
629 nsMathMLChar
* aSeparatorsChar
,
630 PRInt32 aSeparatorsCount
)
634 nsPresContext
* presContext
= aForFrame
->PresContext();
635 const nsStyleFont
* font
= aForFrame
->GetStyleFont();
636 nsCOMPtr
<nsIFontMetrics
> fm
= presContext
->GetMetricsFor(font
->mFont
);
642 GetMaxCharWidth(presContext
, aRenderingContext
, aOpenChar
,
643 NS_MATHML_OPERATOR_FORM_PREFIX
, font
->mScriptLevel
, em
);
647 nsIFrame
* childFrame
= aForFrame
->GetFirstChild(nsnull
);
649 // XXX This includes margin while Reflow currently doesn't consider
650 // margin, so we may end up with too much space, but, with stretchy
651 // characters, this is an approximation anyway.
652 width
+= nsLayoutUtils::IntrinsicForContainer(aRenderingContext
, childFrame
,
653 nsLayoutUtils::PREF_WIDTH
);
655 if (i
< aSeparatorsCount
) {
657 GetMaxCharWidth(presContext
, aRenderingContext
, &aSeparatorsChar
[i
],
658 NS_MATHML_OPERATOR_FORM_INFIX
, font
->mScriptLevel
, em
);
662 childFrame
= childFrame
->GetNextSibling();
667 GetMaxCharWidth(presContext
, aRenderingContext
, aCloseChar
,
668 NS_MATHML_OPERATOR_FORM_POSTFIX
, font
->mScriptLevel
, em
);
675 nsMathMLmfencedFrame::FixInterFrameSpacing(nsHTMLReflowMetrics
& aDesiredSize
)
677 nscoord gap
= nsMathMLContainerFrame::FixInterFrameSpacing(aDesiredSize
);
682 mOpenChar
->GetRect(rect
);
684 mOpenChar
->SetRect(rect
);
687 mCloseChar
->GetRect(rect
);
689 mCloseChar
->SetRect(rect
);
691 for (PRInt32 i
= 0; i
< mSeparatorsCount
; i
++) {
692 mSeparatorsChar
[i
].GetRect(rect
);
694 mSeparatorsChar
[i
].SetRect(rect
);
699 // ----------------------
700 // the Style System will use these to pass the proper style context to our MathMLChar
702 nsMathMLmfencedFrame::GetAdditionalStyleContext(PRInt32 aIndex
) const
704 PRInt32 openIndex
= -1;
705 PRInt32 closeIndex
= -1;
706 PRInt32 lastIndex
= mSeparatorsCount
-1;
710 openIndex
= lastIndex
;
714 closeIndex
= lastIndex
;
716 if (aIndex
< 0 || aIndex
> lastIndex
) {
720 if (aIndex
< mSeparatorsCount
) {
721 return mSeparatorsChar
[aIndex
].GetStyleContext();
723 else if (aIndex
== openIndex
) {
724 return mOpenChar
->GetStyleContext();
726 else if (aIndex
== closeIndex
) {
727 return mCloseChar
->GetStyleContext();
733 nsMathMLmfencedFrame::SetAdditionalStyleContext(PRInt32 aIndex
,
734 nsStyleContext
* aStyleContext
)
736 PRInt32 openIndex
= -1;
737 PRInt32 closeIndex
= -1;
738 PRInt32 lastIndex
= mSeparatorsCount
-1;
742 openIndex
= lastIndex
;
746 closeIndex
= lastIndex
;
748 if (aIndex
< 0 || aIndex
> lastIndex
) {
752 if (aIndex
< mSeparatorsCount
) {
753 mSeparatorsChar
[aIndex
].SetStyleContext(aStyleContext
);
755 else if (aIndex
== openIndex
) {
756 mOpenChar
->SetStyleContext(aStyleContext
);
758 else if (aIndex
== closeIndex
) {
759 mCloseChar
->SetStyleContext(aStyleContext
);