Bumping manifests a=b2g-bump
[gecko.git] / layout / mathml / nsMathMLmfencedFrame.cpp
blobce36c29043a482ee3c94376a4e68d197ec0aec0b
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 "nsMathMLmfencedFrame.h"
8 #include "nsRenderingContext.h"
9 #include "nsMathMLChar.h"
10 #include <algorithm>
12 using namespace mozilla;
15 // <mfenced> -- surround content with a pair of fences
18 nsIFrame*
19 NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
21 return new (aPresShell) nsMathMLmfencedFrame(aContext);
24 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmfencedFrame)
26 nsMathMLmfencedFrame::~nsMathMLmfencedFrame()
28 RemoveFencesAndSeparators();
31 NS_IMETHODIMP
32 nsMathMLmfencedFrame::InheritAutomaticData(nsIFrame* aParent)
34 // let the base class get the default from our parent
35 nsMathMLContainerFrame::InheritAutomaticData(aParent);
37 mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
39 RemoveFencesAndSeparators();
40 CreateFencesAndSeparators(PresContext());
42 return NS_OK;
45 void
46 nsMathMLmfencedFrame::SetInitialChildList(ChildListID aListID,
47 nsFrameList& aChildList)
49 // First, let the base class do its work
50 nsMathMLContainerFrame::SetInitialChildList(aListID, aChildList);
52 // InheritAutomaticData will not get called if our parent is not a mathml
53 // frame, so initialize NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY for
54 // GetPreferredStretchSize() from Reflow().
55 mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
56 // No need to track the style contexts given to our MathML chars.
57 // The Style System will use Get/SetAdditionalStyleContext() to keep them
58 // up-to-date if dynamic changes arise.
59 CreateFencesAndSeparators(PresContext());
62 nsresult
63 nsMathMLmfencedFrame::AttributeChanged(int32_t aNameSpaceID,
64 nsIAtom* aAttribute,
65 int32_t aModType)
67 RemoveFencesAndSeparators();
68 CreateFencesAndSeparators(PresContext());
70 return nsMathMLContainerFrame::
71 AttributeChanged(aNameSpaceID, aAttribute, aModType);
74 nsresult
75 nsMathMLmfencedFrame::ChildListChanged(int32_t aModType)
77 RemoveFencesAndSeparators();
78 CreateFencesAndSeparators(PresContext());
80 return nsMathMLContainerFrame::ChildListChanged(aModType);
83 void
84 nsMathMLmfencedFrame::RemoveFencesAndSeparators()
86 delete mOpenChar;
87 delete mCloseChar;
88 if (mSeparatorsChar) delete[] mSeparatorsChar;
90 mOpenChar = nullptr;
91 mCloseChar = nullptr;
92 mSeparatorsChar = nullptr;
93 mSeparatorsCount = 0;
96 void
97 nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext)
99 nsAutoString value;
101 //////////////
102 // see if the opening fence is there ...
103 if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::open, value)) {
104 value = char16_t('('); // default as per the MathML REC
105 } else {
106 value.CompressWhitespace();
109 if (!value.IsEmpty()) {
110 mOpenChar = new nsMathMLChar;
111 mOpenChar->SetData(aPresContext, value);
112 ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar);
115 //////////////
116 // see if the closing fence is there ...
117 if(!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::close, value)) {
118 value = char16_t(')'); // default as per the MathML REC
119 } else {
120 value.CompressWhitespace();
123 if (!value.IsEmpty()) {
124 mCloseChar = new nsMathMLChar;
125 mCloseChar->SetData(aPresContext, value);
126 ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar);
129 //////////////
130 // see if separators are there ...
131 if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::separators_, value)) {
132 value = char16_t(','); // default as per the MathML REC
133 } else {
134 value.StripWhitespace();
137 mSeparatorsCount = value.Length();
138 if (0 < mSeparatorsCount) {
139 int32_t sepCount = mFrames.GetLength() - 1;
140 if (0 < sepCount) {
141 mSeparatorsChar = new nsMathMLChar[sepCount];
142 nsAutoString sepChar;
143 for (int32_t i = 0; i < sepCount; i++) {
144 if (i < mSeparatorsCount) {
145 sepChar = value[i];
147 else {
148 sepChar = value[mSeparatorsCount-1];
150 mSeparatorsChar[i].SetData(aPresContext, sepChar);
151 ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i]);
153 mSeparatorsCount = sepCount;
154 } else {
155 // No separators. Note that sepCount can be -1 here, so don't
156 // set mSeparatorsCount to it.
157 mSeparatorsCount = 0;
162 void
163 nsMathMLmfencedFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
164 const nsRect& aDirtyRect,
165 const nsDisplayListSet& aLists)
167 /////////////
168 // display the content
169 nsMathMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
171 ////////////
172 // display fences and separators
173 uint32_t count = 0;
174 if (mOpenChar) {
175 mOpenChar->Display(aBuilder, this, aLists, count++);
178 if (mCloseChar) {
179 mCloseChar->Display(aBuilder, this, aLists, count++);
182 for (int32_t i = 0; i < mSeparatorsCount; i++) {
183 mSeparatorsChar[i].Display(aBuilder, this, aLists, count++);
187 void
188 nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext,
189 nsHTMLReflowMetrics& aDesiredSize,
190 const nsHTMLReflowState& aReflowState,
191 nsReflowStatus& aStatus)
193 aDesiredSize.ClearSize();
194 aDesiredSize.SetBlockStartAscent(0);
195 aDesiredSize.mBoundingMetrics = nsBoundingMetrics();
197 int32_t i;
198 const nsStyleFont* font = StyleFont();
199 nsRefPtr<nsFontMetrics> fm;
200 nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
201 aReflowState.rendContext->SetFont(fm);
202 nscoord axisHeight, em;
203 GetAxisHeight(*aReflowState.rendContext, fm, axisHeight);
204 GetEmHeight(fm, em);
205 // leading to be left at the top and the bottom of stretched chars
206 nscoord leading = NSToCoordRound(0.2f * em);
208 /////////////
209 // Reflow children
210 // Asking each child to cache its bounding metrics
212 // Note that we don't use the base method nsMathMLContainerFrame::Reflow()
213 // because we want to stretch our fences, separators and stretchy frames using
214 // the *same* initial aDesiredSize.mBoundingMetrics. If we were to use the base
215 // method here, our stretchy frames will be stretched and placed, and we may
216 // end up stretching our fences/separators with a different aDesiredSize.
217 // XXX The above decision was revisited in bug 121748 and this code can be
218 // refactored to use nsMathMLContainerFrame::Reflow() at some stage.
220 nsReflowStatus childStatus;
221 nsIFrame* firstChild = GetFirstPrincipalChild();
222 nsIFrame* childFrame = firstChild;
223 nscoord ascent = 0, descent = 0;
224 if (firstChild || mOpenChar || mCloseChar || mSeparatorsCount > 0) {
225 // We use the ASCII metrics to get our minimum height. This way,
226 // if we have borders or a background, they will fit better with
227 // other elements on the line.
228 ascent = fm->MaxAscent();
229 descent = fm->MaxDescent();
231 while (childFrame) {
232 nsHTMLReflowMetrics childDesiredSize(aReflowState,
233 aDesiredSize.mFlags
234 | NS_REFLOW_CALC_BOUNDING_METRICS);
235 WritingMode wm = childFrame->GetWritingMode();
236 LogicalSize availSize = aReflowState.ComputedSize(wm);
237 availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
238 nsHTMLReflowState childReflowState(aPresContext, aReflowState,
239 childFrame, availSize);
240 ReflowChild(childFrame, aPresContext, childDesiredSize,
241 childReflowState, childStatus);
242 //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
243 SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
244 childDesiredSize.mBoundingMetrics);
246 mozilla::WritingMode outerWM = aReflowState.GetWritingMode();
247 nscoord childDescent = childDesiredSize.BSize(outerWM) -
248 childDesiredSize.BlockStartAscent();
249 if (descent < childDescent)
250 descent = childDescent;
251 if (ascent < childDesiredSize.BlockStartAscent())
252 ascent = childDesiredSize.BlockStartAscent();
254 childFrame = childFrame->GetNextSibling();
257 /////////////
258 // Ask stretchy children to stretch themselves
260 nsBoundingMetrics containerSize;
261 nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
263 GetPreferredStretchSize(*aReflowState.rendContext,
264 0, /* i.e., without embellishments */
265 stretchDir, containerSize);
266 childFrame = firstChild;
267 while (childFrame) {
268 nsIMathMLFrame* mathmlChild = do_QueryFrame(childFrame);
269 if (mathmlChild) {
270 nsHTMLReflowMetrics childDesiredSize(aReflowState);
271 // retrieve the metrics that was stored at the previous pass
272 GetReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
273 childDesiredSize.mBoundingMetrics);
275 mathmlChild->Stretch(*aReflowState.rendContext,
276 stretchDir, containerSize, childDesiredSize);
277 // store the updated metrics
278 SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize,
279 childDesiredSize.mBoundingMetrics);
281 nscoord childDescent = childDesiredSize.Height() - childDesiredSize.BlockStartAscent();
282 if (descent < childDescent)
283 descent = childDescent;
284 if (ascent < childDesiredSize.BlockStartAscent())
285 ascent = childDesiredSize.BlockStartAscent();
287 childFrame = childFrame->GetNextSibling();
290 // bug 121748: for surrounding fences & separators, use a size that covers everything
291 GetPreferredStretchSize(*aReflowState.rendContext,
292 STRETCH_CONSIDER_EMBELLISHMENTS,
293 stretchDir, containerSize);
295 //////////////////////////////////////////
296 // Prepare the opening fence, separators, and closing fence, and
297 // adjust the origin of children.
299 // we need to center around the axis
300 nscoord delta = std::max(containerSize.ascent - axisHeight,
301 containerSize.descent + axisHeight);
302 containerSize.ascent = delta + axisHeight;
303 containerSize.descent = delta - axisHeight;
305 bool isRTL = StyleVisibility()->mDirection;
307 /////////////////
308 // opening fence ...
309 ReflowChar(aPresContext, *aReflowState.rendContext, mOpenChar,
310 NS_MATHML_OPERATOR_FORM_PREFIX, font->mScriptLevel,
311 axisHeight, leading, em, containerSize, ascent, descent, isRTL);
312 /////////////////
313 // separators ...
314 for (i = 0; i < mSeparatorsCount; i++) {
315 ReflowChar(aPresContext, *aReflowState.rendContext, &mSeparatorsChar[i],
316 NS_MATHML_OPERATOR_FORM_INFIX, font->mScriptLevel,
317 axisHeight, leading, em, containerSize, ascent, descent, isRTL);
319 /////////////////
320 // closing fence ...
321 ReflowChar(aPresContext, *aReflowState.rendContext, mCloseChar,
322 NS_MATHML_OPERATOR_FORM_POSTFIX, font->mScriptLevel,
323 axisHeight, leading, em, containerSize, ascent, descent, isRTL);
325 //////////////////
326 // Adjust the origins of each child.
327 // and update our bounding metrics
329 i = 0;
330 nscoord dx = 0;
331 nsBoundingMetrics bm;
332 bool firstTime = true;
333 nsMathMLChar *leftChar, *rightChar;
334 if (isRTL) {
335 leftChar = mCloseChar;
336 rightChar = mOpenChar;
337 } else {
338 leftChar = mOpenChar;
339 rightChar = mCloseChar;
342 if (leftChar) {
343 PlaceChar(leftChar, ascent, bm, dx);
344 aDesiredSize.mBoundingMetrics = bm;
345 firstTime = false;
348 if (isRTL) {
349 childFrame = this->GetLastChild(nsIFrame::kPrincipalList);
350 } else {
351 childFrame = firstChild;
353 while (childFrame) {
354 nsHTMLReflowMetrics childSize(aReflowState);
355 GetReflowAndBoundingMetricsFor(childFrame, childSize, bm);
356 if (firstTime) {
357 firstTime = false;
358 aDesiredSize.mBoundingMetrics = bm;
360 else
361 aDesiredSize.mBoundingMetrics += bm;
363 FinishReflowChild(childFrame, aPresContext, childSize, nullptr,
364 dx, ascent - childSize.BlockStartAscent(), 0);
365 dx += childSize.Width();
367 if (i < mSeparatorsCount) {
368 PlaceChar(&mSeparatorsChar[isRTL ? mSeparatorsCount - 1 - i : i],
369 ascent, bm, dx);
370 aDesiredSize.mBoundingMetrics += bm;
372 i++;
374 if (isRTL) {
375 childFrame = childFrame->GetPrevSibling();
376 } else {
377 childFrame = childFrame->GetNextSibling();
381 if (rightChar) {
382 PlaceChar(rightChar, ascent, bm, dx);
383 if (firstTime)
384 aDesiredSize.mBoundingMetrics = bm;
385 else
386 aDesiredSize.mBoundingMetrics += bm;
389 aDesiredSize.Width() = aDesiredSize.mBoundingMetrics.width;
390 aDesiredSize.Height() = ascent + descent;
391 aDesiredSize.SetBlockStartAscent(ascent);
393 SetBoundingMetrics(aDesiredSize.mBoundingMetrics);
394 SetReference(nsPoint(0, aDesiredSize.BlockStartAscent()));
396 // see if we should fix the spacing
397 FixInterFrameSpacing(aDesiredSize);
399 // Finished with these:
400 ClearSavedChildMetrics();
402 // Set our overflow area
403 GatherAndStoreOverflow(&aDesiredSize);
405 aStatus = NS_FRAME_COMPLETE;
406 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
409 static void
410 GetCharSpacing(nsMathMLChar* aMathMLChar,
411 nsOperatorFlags aForm,
412 int32_t aScriptLevel,
413 nscoord em,
414 nscoord& aLeftSpace,
415 nscoord& aRightSpace)
417 nsAutoString data;
418 aMathMLChar->GetData(data);
419 nsOperatorFlags flags = 0;
420 float lspace = 0.0f;
421 float rspace = 0.0f;
422 bool found = nsMathMLOperators::LookupOperator(data, aForm,
423 &flags, &lspace, &rspace);
425 // We don't want extra space when we are a script
426 if (found && aScriptLevel > 0) {
427 lspace /= 2.0f;
428 rspace /= 2.0f;
431 aLeftSpace = NSToCoordRound(lspace * em);
432 aRightSpace = NSToCoordRound(rspace * em);
435 // helper functions to perform the common task of formatting our chars
436 /*static*/ nsresult
437 nsMathMLmfencedFrame::ReflowChar(nsPresContext* aPresContext,
438 nsRenderingContext& aRenderingContext,
439 nsMathMLChar* aMathMLChar,
440 nsOperatorFlags aForm,
441 int32_t aScriptLevel,
442 nscoord axisHeight,
443 nscoord leading,
444 nscoord em,
445 nsBoundingMetrics& aContainerSize,
446 nscoord& aAscent,
447 nscoord& aDescent,
448 bool aRTL)
450 if (aMathMLChar && 0 < aMathMLChar->Length()) {
451 nscoord leftSpace;
452 nscoord rightSpace;
453 GetCharSpacing(aMathMLChar, aForm, aScriptLevel, em, leftSpace, rightSpace);
455 // stretch the char to the appropriate height if it is not big enough.
456 nsBoundingMetrics charSize;
457 nsresult res = aMathMLChar->Stretch(aPresContext, aRenderingContext,
458 NS_STRETCH_DIRECTION_VERTICAL,
459 aContainerSize, charSize,
460 NS_STRETCH_NORMAL, aRTL);
462 if (NS_STRETCH_DIRECTION_UNSUPPORTED != aMathMLChar->GetStretchDirection()) {
463 // has changed... so center the char around the axis
464 nscoord height = charSize.ascent + charSize.descent;
465 charSize.ascent = height/2 + axisHeight;
466 charSize.descent = height - charSize.ascent;
468 else {
469 // either it hasn't changed or stretching the char failed (i.e.,
470 // GetBoundingMetrics failed)
471 leading = 0;
472 if (NS_FAILED(res)) {
473 nsAutoString data;
474 aMathMLChar->GetData(data);
475 nsBoundingMetrics metrics =
476 aRenderingContext.GetBoundingMetrics(data.get(), data.Length());
477 charSize.ascent = metrics.ascent;
478 charSize.descent = metrics.descent;
479 charSize.width = metrics.width;
480 // Set this as the bounding metrics of the MathMLChar to leave
481 // the necessary room to paint the char.
482 aMathMLChar->SetBoundingMetrics(charSize);
486 if (aAscent < charSize.ascent + leading)
487 aAscent = charSize.ascent + leading;
488 if (aDescent < charSize.descent + leading)
489 aDescent = charSize.descent + leading;
491 // account the spacing
492 charSize.width += leftSpace + rightSpace;
494 // x-origin is used to store lspace ...
495 // y-origin is used to stored the ascent ...
496 aMathMLChar->SetRect(nsRect(leftSpace,
497 charSize.ascent, charSize.width,
498 charSize.ascent + charSize.descent));
500 return NS_OK;
503 /*static*/ void
504 nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar,
505 nscoord aDesiredAscent,
506 nsBoundingMetrics& bm,
507 nscoord& dx)
509 aMathMLChar->GetBoundingMetrics(bm);
511 // the char's x-origin was used to store lspace ...
512 // the char's y-origin was used to store the ascent ...
513 // the char's width was used to store the advance with (with spacing) ...
514 nsRect rect;
515 aMathMLChar->GetRect(rect);
517 nscoord dy = aDesiredAscent - rect.y;
518 if (aMathMLChar->GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED) {
519 // the stretchy char will be centered around the axis
520 // so we adjust the returned bounding metrics accordingly
521 bm.descent = (bm.ascent + bm.descent) - rect.y;
522 bm.ascent = rect.y;
525 aMathMLChar->SetRect(nsRect(dx + rect.x, dy, bm.width, rect.height));
527 bm.leftBearing += rect.x;
528 bm.rightBearing += rect.x;
530 // return rect.width since it includes lspace and rspace
531 bm.width = rect.width;
532 dx += rect.width;
535 static nscoord
536 GetMaxCharWidth(nsPresContext* aPresContext,
537 nsRenderingContext* aRenderingContext,
538 nsMathMLChar* aMathMLChar,
539 nsOperatorFlags aForm,
540 int32_t aScriptLevel,
541 nscoord em)
543 nscoord width = aMathMLChar->GetMaxWidth(aPresContext, *aRenderingContext);
545 if (0 < aMathMLChar->Length()) {
546 nscoord leftSpace;
547 nscoord rightSpace;
548 GetCharSpacing(aMathMLChar, aForm, aScriptLevel, em, leftSpace, rightSpace);
550 width += leftSpace + rightSpace;
553 return width;
556 /* virtual */ void
557 nsMathMLmfencedFrame::GetIntrinsicISizeMetrics(nsRenderingContext* aRenderingContext, nsHTMLReflowMetrics& aDesiredSize)
559 nscoord width = 0;
561 nsPresContext* presContext = PresContext();
562 const nsStyleFont* font = StyleFont();
563 nsRefPtr<nsFontMetrics> fm;
564 nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
565 nscoord em;
566 GetEmHeight(fm, em);
568 if (mOpenChar) {
569 width +=
570 GetMaxCharWidth(presContext, aRenderingContext, mOpenChar,
571 NS_MATHML_OPERATOR_FORM_PREFIX, font->mScriptLevel, em);
574 int32_t i = 0;
575 nsIFrame* childFrame = GetFirstPrincipalChild();
576 while (childFrame) {
577 // XXX This includes margin while Reflow currently doesn't consider
578 // margin, so we may end up with too much space, but, with stretchy
579 // characters, this is an approximation anyway.
580 width += nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
581 nsLayoutUtils::PREF_ISIZE);
583 if (i < mSeparatorsCount) {
584 width +=
585 GetMaxCharWidth(presContext, aRenderingContext, &mSeparatorsChar[i],
586 NS_MATHML_OPERATOR_FORM_INFIX, font->mScriptLevel, em);
588 i++;
590 childFrame = childFrame->GetNextSibling();
593 if (mCloseChar) {
594 width +=
595 GetMaxCharWidth(presContext, aRenderingContext, mCloseChar,
596 NS_MATHML_OPERATOR_FORM_POSTFIX, font->mScriptLevel, em);
599 aDesiredSize.Width() = width;
600 aDesiredSize.mBoundingMetrics.width = width;
601 aDesiredSize.mBoundingMetrics.leftBearing = 0;
602 aDesiredSize.mBoundingMetrics.rightBearing = width;
605 nscoord
606 nsMathMLmfencedFrame::FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize)
608 nscoord gap = nsMathMLContainerFrame::FixInterFrameSpacing(aDesiredSize);
609 if (!gap) return 0;
611 nsRect rect;
612 if (mOpenChar) {
613 mOpenChar->GetRect(rect);
614 rect.MoveBy(gap, 0);
615 mOpenChar->SetRect(rect);
617 if (mCloseChar) {
618 mCloseChar->GetRect(rect);
619 rect.MoveBy(gap, 0);
620 mCloseChar->SetRect(rect);
622 for (int32_t i = 0; i < mSeparatorsCount; i++) {
623 mSeparatorsChar[i].GetRect(rect);
624 rect.MoveBy(gap, 0);
625 mSeparatorsChar[i].SetRect(rect);
627 return gap;
630 // ----------------------
631 // the Style System will use these to pass the proper style context to our MathMLChar
632 nsStyleContext*
633 nsMathMLmfencedFrame::GetAdditionalStyleContext(int32_t aIndex) const
635 int32_t openIndex = -1;
636 int32_t closeIndex = -1;
637 int32_t lastIndex = mSeparatorsCount-1;
639 if (mOpenChar) {
640 lastIndex++;
641 openIndex = lastIndex;
643 if (mCloseChar) {
644 lastIndex++;
645 closeIndex = lastIndex;
647 if (aIndex < 0 || aIndex > lastIndex) {
648 return nullptr;
651 if (aIndex < mSeparatorsCount) {
652 return mSeparatorsChar[aIndex].GetStyleContext();
654 else if (aIndex == openIndex) {
655 return mOpenChar->GetStyleContext();
657 else if (aIndex == closeIndex) {
658 return mCloseChar->GetStyleContext();
660 return nullptr;
663 void
664 nsMathMLmfencedFrame::SetAdditionalStyleContext(int32_t aIndex,
665 nsStyleContext* aStyleContext)
667 int32_t openIndex = -1;
668 int32_t closeIndex = -1;
669 int32_t lastIndex = mSeparatorsCount-1;
671 if (mOpenChar) {
672 lastIndex++;
673 openIndex = lastIndex;
675 if (mCloseChar) {
676 lastIndex++;
677 closeIndex = lastIndex;
679 if (aIndex < 0 || aIndex > lastIndex) {
680 return;
683 if (aIndex < mSeparatorsCount) {
684 mSeparatorsChar[aIndex].SetStyleContext(aStyleContext);
686 else if (aIndex == openIndex) {
687 mOpenChar->SetStyleContext(aStyleContext);
689 else if (aIndex == closeIndex) {
690 mCloseChar->SetStyleContext(aStyleContext);