From d2d546b1467b294389e3fdb4c9ca39b23c234f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Wang?= Date: Tue, 5 Jan 2010 11:22:31 +0100 Subject: [PATCH] Overall Directionality of formulas (bug 534963). r=karlt --- layout/mathml/mathml.css | 14 +++++ layout/mathml/nsMathMLContainerFrame.cpp | 41 +++++++++---- layout/mathml/nsMathMLContainerFrame.h | 8 +++ layout/mathml/nsMathMLmencloseFrame.cpp | 19 ++++-- layout/mathml/nsMathMLmfencedFrame.cpp | 33 ++++++++--- layout/mathml/nsMathMLmfracFrame.cpp | 56 ++++++++++++------ layout/mathml/nsMathMLmmultiscriptsFrame.cpp | 22 +++++-- layout/mathml/nsMathMLmpaddedFrame.cpp | 62 ++++++++++++-------- layout/mathml/nsMathMLmpaddedFrame.h | 6 +- layout/mathml/nsMathMLmrootFrame.cpp | 48 ++++++++------- layout/mathml/nsMathMLmsubFrame.cpp | 6 +- layout/mathml/nsMathMLmsubsupFrame.cpp | 9 ++- layout/mathml/nsMathMLmsupFrame.cpp | 6 +- 13 files changed, 227 insertions(+), 103 deletions(-) diff --git a/layout/mathml/mathml.css b/layout/mathml/mathml.css index 4e0f937d491e..d3cfa5e408cc 100644 --- a/layout/mathml/mathml.css +++ b/layout/mathml/mathml.css @@ -467,3 +467,17 @@ msub > :not(:first-child), msup > :not(:first-child), msubsup > :not(:first-child), mmultiscripts > :not(:first-child) { -moz-script-level:+1; } + +/*****************************************/ +/* Controlling directionality */ +/*****************************************/ + +math[dir="rtl"], mstyle[dir="rtl"], mrow[dir="rtl"], +mi[dir="rtl"], mn[dir="rtl"], mo[dir="rtl"], mtext[dir="rtl"], ms[dir="rtl"] { + direction: rtl; +} + +math[dir="ltr"], mstyle[dir="ltr"], mrow[dir="ltr"], +mi[dir="ltr"], mn[dir="ltr"], mo[dir="ltr"], mtext[dir="ltr"], ms[dir="ltr"] { + direction: ltr; +} diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index 4d6fa6d76e27..939880390cb7 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -1193,20 +1193,21 @@ class nsMathMLContainerFrame::RowChildFrameIterator { public: explicit RowChildFrameIterator(nsMathMLContainerFrame* aParentFrame) : mParentFrame(aParentFrame), - mChildFrame(aParentFrame->mFrames.FirstChild()), mX(0), mCarrySpace(0), - mFromFrameType(eMathMLFrameType_UNKNOWN) + mFromFrameType(eMathMLFrameType_UNKNOWN), + mRTL(NS_MATHML_IS_RTL(aParentFrame->mPresentationData.flags)) { + if (!mRTL) { + mChildFrame = aParentFrame->mFrames.FirstChild(); + } else { + mChildFrame = aParentFrame->mFrames.LastChild(); + } + if (!mChildFrame) return; InitMetricsForChild(); - // Remove left correction in because the sqrt glyph itself is - // there first. - if (mParentFrame->GetContent()->Tag() == nsGkAtoms::msqrt_) { - mX = 0; - } } RowChildFrameIterator& operator++() @@ -1214,7 +1215,12 @@ public: // add child size + italic correction mX += mSize.mBoundingMetrics.width + mItalicCorrection; - mChildFrame = mChildFrame->GetNextSibling(); + if (!mRTL) { + mChildFrame = mChildFrame->GetNextSibling(); + } else { + mChildFrame = mChildFrame->GetPrevSibling(); + } + if (!mChildFrame) return *this; @@ -1251,16 +1257,29 @@ private: PRInt32 mCarrySpace; eMathMLFrameType mFromFrameType; + bool mRTL; + void InitMetricsForChild() { GetReflowAndBoundingMetricsFor(mChildFrame, mSize, mSize.mBoundingMetrics, &mChildFrameType); - nscoord leftCorrection; - GetItalicCorrection(mSize.mBoundingMetrics, leftCorrection, - mItalicCorrection); + nscoord leftCorrection, rightCorrection; + GetItalicCorrection(mSize.mBoundingMetrics, + leftCorrection, rightCorrection); + if (!mChildFrame->GetPrevSibling() && + mParentFrame->GetContent()->Tag() == nsGkAtoms::msqrt_) { + // Remove leading correction in because the sqrt glyph itself is + // there first. + if (!mRTL) { + leftCorrection = 0; + } else { + rightCorrection = 0; + } + } // add left correction -- this fixes the problem of the italic 'f' // e.g., q f I mX += leftCorrection; + mItalicCorrection = rightCorrection; } }; diff --git a/layout/mathml/nsMathMLContainerFrame.h b/layout/mathml/nsMathMLContainerFrame.h index 272424fff176..343f8ed28f9e 100644 --- a/layout/mathml/nsMathMLContainerFrame.h +++ b/layout/mathml/nsMathMLContainerFrame.h @@ -193,6 +193,14 @@ public: nsIAtom* aAttribute, PRInt32 aModType); + // helper function to apply mirroring to a horizontal coordinate, if needed. + nscoord + MirrorIfRTL(nscoord aParentWidth, nscoord aChildWidth, nscoord aChildLeading) + { + return (NS_MATHML_IS_RTL(mPresentationData.flags) ? + aParentWidth - aChildWidth - aChildLeading : aChildLeading); + } + // -------------------------------------------------------------------------- // Additional methods diff --git a/layout/mathml/nsMathMLmencloseFrame.cpp b/layout/mathml/nsMathMLmencloseFrame.cpp index 8d6f8c1d60d9..81ef101de8aa 100644 --- a/layout/mathml/nsMathMLmencloseFrame.cpp +++ b/layout/mathml/nsMathMLmencloseFrame.cpp @@ -241,7 +241,8 @@ nsMathMLmencloseFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, nsRect rect; mMathMLChar[mRadicalCharIndex].GetRect(rect); - rect.MoveBy(rect.width, 0); + rect.MoveBy(NS_MATHML_IS_RTL(mPresentationData.flags) ? + -mContentWidth : rect.width, 0); rect.SizeTo(mContentWidth, mRuleThickness); rv = DisplayBar(aBuilder, this, rect, aLists); NS_ENSURE_SUCCESS(rv, rv); @@ -518,12 +519,15 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext, /////////////// // radical notation: if (IsToDraw(NOTATION_RADICAL)) { + nscoord *dx_leading = + NS_MATHML_IS_RTL(mPresentationData.flags) ? &dx_right : &dx_left; + if (aWidthOnly) { nscoord radical_width = mMathMLChar[mRadicalCharIndex]. GetMaxWidth(PresContext(), aRenderingContext); // Update horizontal parameters - dx_left = NS_MAX(dx_left, radical_width); + *dx_leading = NS_MAX(*dx_leading, radical_width); } else { // Stretch the radical symbol to the appropriate height if it is not // big enough. @@ -539,7 +543,7 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext, mMathMLChar[mRadicalCharIndex].GetBoundingMetrics(bmRadicalChar); // Update horizontal parameters - dx_left = NS_MAX(dx_left, bmRadicalChar.width); + *dx_leading = NS_MAX(*dx_leading, bmRadicalChar.width); // Update vertical parameters radicalAscent = bmBase.ascent + psi + mRuleThickness; @@ -653,14 +657,17 @@ nsMathMLmencloseFrame::PlaceInternal(nsRenderingContext& aRenderingContext, bmLongdivChar.ascent + bmLongdivChar.descent)); - if (IsToDraw(NOTATION_RADICAL)) - mMathMLChar[mRadicalCharIndex].SetRect(nsRect(dx_left - - bmRadicalChar.width, + if (IsToDraw(NOTATION_RADICAL)) { + nscoord dx = NS_MATHML_IS_RTL(mPresentationData.flags) ? + dx_left + bmBase.width : dx_left - bmRadicalChar.width; + + mMathMLChar[mRadicalCharIndex].SetRect(nsRect(dx, aDesiredSize.ascent - radicalAscent, bmRadicalChar.width, bmRadicalChar.ascent + bmRadicalChar.descent)); + } mContentWidth = bmBase.width; diff --git a/layout/mathml/nsMathMLmfencedFrame.cpp b/layout/mathml/nsMathMLmfencedFrame.cpp index fcadba532e6b..02aeeee64b2d 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -383,13 +383,27 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext, nscoord dx = 0; nsBoundingMetrics bm; bool firstTime = true; - if (mOpenChar) { - PlaceChar(mOpenChar, ascent, bm, dx); + nsMathMLChar *leftChar, *rightChar; + bool isRTL = NS_MATHML_IS_RTL(mPresentationData.flags); + if (isRTL) { + leftChar = mCloseChar; + rightChar = mOpenChar; + } else { + leftChar = mOpenChar; + rightChar = mCloseChar; + } + + if (leftChar) { + PlaceChar(leftChar, ascent, bm, dx); aDesiredSize.mBoundingMetrics = bm; firstTime = false; } - childFrame = firstChild; + if (isRTL) { + childFrame = this->GetLastChild(nsIFrame::kPrincipalList); + } else { + childFrame = firstChild; + } while (childFrame) { nsHTMLReflowMetrics childSize; GetReflowAndBoundingMetricsFor(childFrame, childSize, bm); @@ -405,16 +419,21 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext, dx += childSize.width; if (i < mSeparatorsCount) { - PlaceChar(&mSeparatorsChar[i], ascent, bm, dx); + PlaceChar(&mSeparatorsChar[isRTL ? mSeparatorsCount - 1 - i : i], + ascent, bm, dx); aDesiredSize.mBoundingMetrics += bm; } i++; - childFrame = childFrame->GetNextSibling(); + if (isRTL) { + childFrame = childFrame->GetPrevSibling(); + } else { + childFrame = childFrame->GetNextSibling(); + } } - if (mCloseChar) { - PlaceChar(mCloseChar, ascent, bm, dx); + if (rightChar) { + PlaceChar(rightChar, ascent, bm, dx); if (firstTime) aDesiredSize.mBoundingMetrics = bm; else diff --git a/layout/mathml/nsMathMLmfracFrame.cpp b/layout/mathml/nsMathMLmfracFrame.cpp index ca544d952e95..da170f5548df 100644 --- a/layout/mathml/nsMathMLmfracFrame.cpp +++ b/layout/mathml/nsMathMLmfracFrame.cpp @@ -501,18 +501,26 @@ nsMathMLmfracFrame::PlaceInternal(nsRenderingContext& aRenderingContext, mReference.y = aDesiredSize.ascent; if (aPlaceOrigin) { - FinishReflowChild(frameNum, presContext, nsnull, sizeNum, - leftSpace, - aDesiredSize.ascent - numShift - sizeNum.ascent, 0); + nscoord dx, dy; - mLineRect.SetRect(leftSpace + bmNum.width, - aDesiredSize.ascent - mBoundingMetrics.ascent, - mLineRect.width, - aDesiredSize.height - 2 * padding); + // place numerator + dx = MirrorIfRTL(aDesiredSize.width, sizeNum.width, + leftSpace); + dy = aDesiredSize.ascent - numShift - sizeNum.ascent; + FinishReflowChild(frameNum, presContext, nsnull, sizeNum, dx, dy, 0); - FinishReflowChild(frameDen, presContext, nsnull, sizeDen, - leftSpace + bmNum.width + mLineRect.width, - aDesiredSize.ascent + denShift - sizeDen.ascent, 0); + // place the fraction bar + dx = MirrorIfRTL(aDesiredSize.width, mLineRect.width, + leftSpace + bmNum.width); + dy = aDesiredSize.ascent - mBoundingMetrics.ascent; + mLineRect.SetRect(dx, dy, + mLineRect.width, aDesiredSize.height - 2 * padding); + + // place denominator + dx = MirrorIfRTL(aDesiredSize.width, sizeDen.width, + leftSpace + bmNum.width + mLineRect.width); + dy = aDesiredSize.ascent + denShift - sizeDen.ascent; + FinishReflowChild(frameDen, presContext, nsnull, sizeDen, dx, dy, 0); } } @@ -549,8 +557,9 @@ class nsDisplayMathMLSlash : public nsDisplayItem { public: nsDisplayMathMLSlash(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aRect, - nscoord aThickness) - : nsDisplayItem(aBuilder, aFrame), mRect(aRect), mThickness(aThickness) { + nscoord aThickness, bool aRTL) + : nsDisplayItem(aBuilder, aFrame), mRect(aRect), mThickness(aThickness), + mRTL(aRTL) { MOZ_COUNT_CTOR(nsDisplayMathMLSlash); } #ifdef NS_BUILD_REFCNT_LOGGING @@ -565,6 +574,7 @@ public: private: nsRect mRect; nscoord mThickness; + bool mRTL; }; void nsDisplayMathMLSlash::Paint(nsDisplayListBuilder* aBuilder, @@ -581,10 +591,19 @@ void nsDisplayMathMLSlash::Paint(nsDisplayListBuilder* aBuilder, gfxContext *gfxCtx = aCtx->ThebesContext(); gfxPoint delta = gfxPoint(presContext->AppUnitsToGfxUnits(mThickness), 0); gfxCtx->NewPath(); - gfxCtx->MoveTo(rect.BottomLeft()); - gfxCtx->LineTo(rect.BottomLeft() + delta); - gfxCtx->LineTo(rect.TopRight()); - gfxCtx->LineTo(rect.TopRight() - delta); + + if (mRTL) { + gfxCtx->MoveTo(rect.TopLeft()); + gfxCtx->LineTo(rect.TopLeft() + delta); + gfxCtx->LineTo(rect.BottomRight()); + gfxCtx->LineTo(rect.BottomRight() - delta); + } else { + gfxCtx->MoveTo(rect.BottomLeft()); + gfxCtx->LineTo(rect.BottomLeft() + delta); + gfxCtx->LineTo(rect.TopRight()); + gfxCtx->LineTo(rect.TopRight() - delta); + } + gfxCtx->ClosePath(); gfxCtx->Fill(); } @@ -596,7 +615,8 @@ nsMathMLmfracFrame::DisplaySlash(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { if (!aFrame->GetStyleVisibility()->IsVisible() || aRect.IsEmpty()) return NS_OK; - + return aLists.Content()->AppendNewToTop(new (aBuilder) - nsDisplayMathMLSlash(aBuilder, aFrame, aRect, aThickness)); + nsDisplayMathMLSlash(aBuilder, aFrame, aRect, aThickness, + NS_MATHML_IS_RTL(mPresentationData.flags))); } diff --git a/layout/mathml/nsMathMLmmultiscriptsFrame.cpp b/layout/mathml/nsMathMLmmultiscriptsFrame.cpp index 0dc08ac01eb5..8991866fccba 100644 --- a/layout/mathml/nsMathMLmmultiscriptsFrame.cpp +++ b/layout/mathml/nsMathMLmmultiscriptsFrame.cpp @@ -417,7 +417,11 @@ nsMathMLmmultiscriptsFrame::Place(nsRenderingContext& aRenderingContext, // place the base ... childFrame = baseFrame; dy = aDesiredSize.ascent - baseSize.ascent; - FinishReflowChild (baseFrame, PresContext(), nsnull, baseSize, dx, dy, 0); + FinishReflowChild (baseFrame, PresContext(), nsnull, baseSize, + MirrorIfRTL(aDesiredSize.width, + baseSize.width, + dx), + dy, 0); dx += bmBase.width + italicCorrection; } else if (mprescriptsFrame != childFrame) { @@ -440,13 +444,21 @@ nsMathMLmmultiscriptsFrame::Place(nsRenderingContext& aRenderingContext, dy = aDesiredSize.ascent - subScriptSize.ascent + maxSubScriptShift; - FinishReflowChild (subScriptFrame, PresContext(), nsnull, subScriptSize, - dx + (width-subScriptSize.width)/2, dy, 0); + FinishReflowChild (subScriptFrame, PresContext(), nsnull, + subScriptSize, + MirrorIfRTL(aDesiredSize.width, + subScriptSize.width, + dx + (width-subScriptSize.width)/2), + dy, 0); dy = aDesiredSize.ascent - supScriptSize.ascent - maxSupScriptShift; - FinishReflowChild (supScriptFrame, PresContext(), nsnull, supScriptSize, - dx + (width-supScriptSize.width)/2, dy, 0); + FinishReflowChild (supScriptFrame, PresContext(), nsnull, + supScriptSize, + MirrorIfRTL(aDesiredSize.width, + supScriptSize.width, + dx + (width-supScriptSize.width)/2), + dy, 0); dx += width + scriptSpace; } diff --git a/layout/mathml/nsMathMLmpaddedFrame.cpp b/layout/mathml/nsMathMLmpaddedFrame.cpp index cd730dbd4aad..ad7a0df09fa4 100644 --- a/layout/mathml/nsMathMLmpaddedFrame.cpp +++ b/layout/mathml/nsMathMLmpaddedFrame.cpp @@ -133,10 +133,11 @@ nsMathMLmpaddedFrame::ProcessAttributes() } // lspace - mLeftSpaceSign = NS_MATHML_SIGN_INVALID; + mLeadingSpaceSign = NS_MATHML_SIGN_INVALID; GetAttribute(mContent, nsnull, nsGkAtoms::lspace_, value); if (!value.IsEmpty()) { - ParseAttribute(value, mLeftSpaceSign, mLeftSpace, mLeftSpacePseudoUnit); + ParseAttribute(value, mLeadingSpaceSign, mLeadingSpace, + mLeadingSpacePseudoUnit); } // voffset @@ -380,23 +381,28 @@ nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext, nscoord height = mBoundingMetrics.ascent; nscoord depth = mBoundingMetrics.descent; - // In MathML2 (http://www.w3.org/TR/MathML2/chapter3.html#presm.mpadded), - // lspace is "the amount of space between the left edge of a bounding box - // and the start of the rendering of its contents' bounding box" and the - // default is zero. + // The REC says: // - // In MathML3 draft - // http://www.w3.org/TR/2007/WD-MathML3-20070427/chapter3.html#id.3.3.6.2, - // lspace is "the amount of space between the left edge of the bounding box - // and the positioning poin [sic] of the mpadded element" and the default is - // "same as content". + // "The lspace attribute ('leading' space) specifies the horizontal location + // of the positioning point of the child content with respect to the + // positioning point of the mpadded element. By default they coincide, and + // therefore absolute values for lspace have the same effect as relative + // values." // - // In both cases, "MathML renderers should ensure that, except for the - // effects of the attributes, relative spacing between the contents of - // mpadded and surrounding MathML elements is not modified by replacing an - // mpadded element with an mrow element with the same content." + // "MathML renderers should ensure that, except for the effects of the + // attributes, the relative spacing between the contents of the mpadded + // element and surrounding MathML elements would not be modified by replacing + // an mpadded element with an mrow element with the same content, even if + // linebreaking occurs within the mpadded element." + // + // (http://www.w3.org/TR/MathML/chapter3.html#presm.mpadded) + // + // "In those discussions, the terms leading and trailing are used to specify + // a side of an object when which side to use depends on the directionality; + // ie. leading means left in LTR but right in RTL." + // (http://www.w3.org/TR/MathML/chapter3.html#presm.bidi.math) nscoord lspace = 0; - // In MATHML3, "width" will be the bounding box width and "advancewidth" will + // In MathML3, "width" will be the bounding box width and "advancewidth" will // refer "to the horizontal distance between the positioning point of the // mpadded and the positioning point for the following content". MathML2 // doesn't make the distinction. @@ -404,6 +410,7 @@ nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext, nscoord voffset = 0; PRInt32 pseudoUnit; + nscoord initialWidth = width; // update width pseudoUnit = (mWidthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF) @@ -427,9 +434,9 @@ nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext, depth = NS_MAX(0, depth); // update lspace - if (mLeftSpacePseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) { - pseudoUnit = mLeftSpacePseudoUnit; - UpdateValue(mLeftSpaceSign, pseudoUnit, mLeftSpace, + if (mLeadingSpacePseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) { + pseudoUnit = mLeadingSpacePseudoUnit; + UpdateValue(mLeadingSpaceSign, pseudoUnit, mLeadingSpace, mBoundingMetrics, lspace); } @@ -445,20 +452,25 @@ nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext, // attributes, tweak our metrics and move children to achieve the desired visual // effects. - if (mLeftSpaceSign != NS_MATHML_SIGN_INVALID) { // there was padding on the left - // dismiss the left italic correction now (so that our parent won't correct us) + if ((NS_MATHML_IS_RTL(mPresentationData.flags) ? + mWidthSign : mLeadingSpaceSign) != NS_MATHML_SIGN_INVALID) { + // there was padding on the left. dismiss the left italic correction now + // (so that our parent won't correct us) mBoundingMetrics.leftBearing = 0; } - if (mWidthSign != NS_MATHML_SIGN_INVALID) { // there was padding on the right - // dismiss the right italic correction now (so that our parent won't correct us) + if ((NS_MATHML_IS_RTL(mPresentationData.flags) ? + mLeadingSpaceSign : mWidthSign) != NS_MATHML_SIGN_INVALID) { + // there was padding on the right. dismiss the right italic correction now + // (so that our parent won't correct us) mBoundingMetrics.width = width; mBoundingMetrics.rightBearing = mBoundingMetrics.width; } nscoord dy = height - mBoundingMetrics.ascent; - nscoord dx = lspace; - + nscoord dx = NS_MATHML_IS_RTL(mPresentationData.flags) ? + width - initialWidth - lspace : lspace; + aDesiredSize.ascent += dy; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.height += dy + depth - mBoundingMetrics.descent; diff --git a/layout/mathml/nsMathMLmpaddedFrame.h b/layout/mathml/nsMathMLmpaddedFrame.h index 168cb92d0a4a..00235f014d1a 100644 --- a/layout/mathml/nsMathMLmpaddedFrame.h +++ b/layout/mathml/nsMathMLmpaddedFrame.h @@ -83,19 +83,19 @@ private: nsCSSValue mWidth; nsCSSValue mHeight; nsCSSValue mDepth; - nsCSSValue mLeftSpace; + nsCSSValue mLeadingSpace; nsCSSValue mVerticalOffset; PRInt32 mWidthSign; PRInt32 mHeightSign; PRInt32 mDepthSign; - PRInt32 mLeftSpaceSign; + PRInt32 mLeadingSpaceSign; PRInt32 mVerticalOffsetSign; PRInt32 mWidthPseudoUnit; PRInt32 mHeightPseudoUnit; PRInt32 mDepthPseudoUnit; - PRInt32 mLeftSpacePseudoUnit; + PRInt32 mLeadingSpacePseudoUnit; PRInt32 mVerticalOffsetPseudoUnit; // helpers to process the attributes diff --git a/layout/mathml/nsMathMLmrootFrame.cpp b/layout/mathml/nsMathMLmrootFrame.cpp index b9513fea9c02..e12f4fb98b3e 100644 --- a/layout/mathml/nsMathMLmrootFrame.cpp +++ b/layout/mathml/nsMathMLmrootFrame.cpp @@ -356,35 +356,41 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext, nscoord dxIndex, dxSqr; GetRadicalXOffsets(bmIndex.width, bmSqr.width, fm, &dxIndex, &dxSqr); - // place the index - nscoord dx = dxIndex; - nscoord dy = aDesiredSize.ascent - (indexRaisedAscent + indexSize.ascent - bmIndex.ascent); - FinishReflowChild(indexFrame, aPresContext, nsnull, indexSize, dx, dy, 0); - - // place the radical symbol and the radical bar - dx = dxSqr; - dy = indexClearance + leading; // leave a leading at the top - mSqrChar.SetRect(nsRect(dx, dy, bmSqr.width, bmSqr.ascent + bmSqr.descent)); - dx += bmSqr.width; - mBarRect.SetRect(dx, dy, bmBase.width, ruleThickness); - - // place the base - dy = aDesiredSize.ascent - baseSize.ascent; - FinishReflowChild(baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0); - - mReference.x = 0; - mReference.y = aDesiredSize.ascent; - - mBoundingMetrics.width = dx + bmBase.width; + mBoundingMetrics.width = dxSqr + bmSqr.width + bmBase.width; mBoundingMetrics.leftBearing = NS_MIN(dxIndex + bmIndex.leftBearing, dxSqr + bmSqr.leftBearing); - mBoundingMetrics.rightBearing = dx + + mBoundingMetrics.rightBearing = dxSqr + bmSqr.width + NS_MAX(bmBase.width, bmBase.rightBearing); aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; GatherAndStoreOverflow(&aDesiredSize); + // place the index + nscoord dx = dxIndex; + nscoord dy = aDesiredSize.ascent - (indexRaisedAscent + indexSize.ascent - bmIndex.ascent); + FinishReflowChild(indexFrame, aPresContext, nsnull, indexSize, + MirrorIfRTL(aDesiredSize.width, indexSize.width, dx), + dy, 0); + + // place the radical symbol and the radical bar + dx = dxSqr; + dy = indexClearance + leading; // leave a leading at the top + mSqrChar.SetRect(nsRect(MirrorIfRTL(aDesiredSize.width, bmSqr.width, dx), + dy, bmSqr.width, bmSqr.ascent + bmSqr.descent)); + dx += bmSqr.width; + mBarRect.SetRect(MirrorIfRTL(aDesiredSize.width, bmBase.width, dx), + dy, bmBase.width, ruleThickness); + + // place the base + dy = aDesiredSize.ascent - baseSize.ascent; + FinishReflowChild(baseFrame, aPresContext, nsnull, baseSize, + MirrorIfRTL(aDesiredSize.width, baseSize.width, dx), + dy, 0); + + mReference.x = 0; + mReference.y = aDesiredSize.ascent; + aStatus = NS_FRAME_COMPLETE; NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; diff --git a/layout/mathml/nsMathMLmsubFrame.cpp b/layout/mathml/nsMathMLmsubFrame.cpp index 5916380269af..d1608f3a0a3a 100644 --- a/layout/mathml/nsMathMLmsubFrame.cpp +++ b/layout/mathml/nsMathMLmsubFrame.cpp @@ -203,10 +203,12 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext, if (aPlaceOrigin) { nscoord dx, dy; // now place the base ... - dx = 0; dy = aDesiredSize.ascent - baseSize.ascent; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, baseSize.width, 0); + dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0); // ... and subscript - dx = bmBase.width; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, subScriptSize.width, + bmBase.width); dy = aDesiredSize.ascent - (subScriptSize.ascent - actualSubScriptShift); FinishReflowChild (subScriptFrame, aPresContext, nsnull, subScriptSize, dx, dy, 0); } diff --git a/layout/mathml/nsMathMLmsubsupFrame.cpp b/layout/mathml/nsMathMLmsubsupFrame.cpp index 44a1ba5b8e46..d312dce5b2cb 100644 --- a/layout/mathml/nsMathMLmsubsupFrame.cpp +++ b/layout/mathml/nsMathMLmsubsupFrame.cpp @@ -336,16 +336,19 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext, if (aPlaceOrigin) { nscoord dx, dy; // now place the base ... - dx = 0; dy = aDesiredSize.ascent - baseSize.ascent; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, baseSize.width, 0); + dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild(baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0); // ... and subscript - dx = bmBase.width; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, subScriptSize.width, + bmBase.width); dy = aDesiredSize.ascent - (subScriptSize.ascent - subScriptShift); FinishReflowChild(subScriptFrame, aPresContext, nsnull, subScriptSize, dx, dy, 0); // ... and the superscript - dx = bmBase.width + italicCorrection; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, supScriptSize.width, + bmBase.width + italicCorrection); dy = aDesiredSize.ascent - (supScriptSize.ascent + supScriptShift); FinishReflowChild(supScriptFrame, aPresContext, nsnull, supScriptSize, dx, dy, 0); diff --git a/layout/mathml/nsMathMLmsupFrame.cpp b/layout/mathml/nsMathMLmsupFrame.cpp index e361569981a5..f9e5bb769acd 100644 --- a/layout/mathml/nsMathMLmsupFrame.cpp +++ b/layout/mathml/nsMathMLmsupFrame.cpp @@ -241,10 +241,12 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext, if (aPlaceOrigin) { nscoord dx, dy; // now place the base ... - dx = 0; dy = aDesiredSize.ascent - baseSize.ascent; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, baseSize.width, 0); + dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0); // ... and supscript - dx = bmBase.width + italicCorrection; + dx = aFrame->MirrorIfRTL(aDesiredSize.width, supScriptSize.width, + bmBase.width + italicCorrection); dy = aDesiredSize.ascent - (supScriptSize.ascent + actualSupScriptShift); FinishReflowChild (supScriptFrame, aPresContext, nsnull, supScriptSize, dx, dy, 0); }