diff --git a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h index d620add4692..8a86443a17f 100644 --- a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h +++ b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h @@ -303,7 +303,7 @@ struct nsEmbellishData { nsIFrame* firstChild; // handy pointer on our embellished child nsIFrame* core; // pointer on the mo frame at the core of the embellished hierarchy nsStretchDirection direction; - float leftSpace, rightSpace; + nscoord leftSpace, rightSpace; nsEmbellishData() { @@ -311,7 +311,7 @@ struct nsEmbellishData { firstChild = nsnull; core = nsnull; direction = NS_STRETCH_DIRECTION_UNSUPPORTED; - leftSpace = rightSpace = 0.0f; + leftSpace = rightSpace = 0; } }; diff --git a/mozilla/layout/mathml/base/src/nsMathMLChar.h b/mozilla/layout/mathml/base/src/nsMathMLChar.h index dcdafaf9a6b..19a2c2a2f87 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLChar.h +++ b/mozilla/layout/mathml/base/src/nsMathMLChar.h @@ -141,6 +141,11 @@ public: aBoundingMetrics = mBoundingMetrics; } + void + SetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) { + mBoundingMetrics = aBoundingMetrics; + } + // Hooks to access the extra leaf style contexts given to the MathMLChars. // They provide an interface to make them acessible to the Style System via // the Get/Set AdditionalStyleContext() APIs. Owners of MathMLChars diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index ed2d85926b9..378d24a7266 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -505,7 +505,7 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIPresContext* aPresContex // compute our up-to-date size using Place() nsHTMLReflowMetrics metrics(nsnull); Place(aPresContext, aRenderingContext, PR_FALSE, metrics); - aPreferredStretchSize = mBoundingMetrics; + aPreferredStretchSize = metrics.mBoundingMetrics; } else { // compute a size that doesn't include embellishements @@ -534,7 +534,8 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIPresContext* aPresContex nsEmbellishData childData; mathMLFrame->GetEmbellishData(childData); if (NS_MATHML_IS_EMBELLISH_OPERATOR(childData.flags) && - childData.direction == aStretchDirection) { + childData.direction == aStretchDirection && + childData.firstChild) { // embellishements are not included, only consider the inner first child itself nsIMathMLFrame* mathMLchildFrame; rv = childData.firstChild->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLchildFrame); @@ -604,8 +605,6 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, // Pass the stretch to the first non-empty child ... nsIFrame* childFrame = mEmbellishData.firstChild; - NS_ASSERTION(childFrame, "Something is wrong somewhere"); - if (childFrame) { nsIMathMLFrame* mathMLFrame; rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); @@ -620,13 +619,28 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, nsHTMLReflowMetrics childSize(aDesiredStretchSize); GetReflowAndBoundingMetricsFor(childFrame, childSize, childSize.mBoundingMetrics); + // See if we should downsize and confine the stretch to us... + // XXX there may be other cases where we can downsize the stretch, + // e.g., the first ∑ might appear big in the following situation + // + // + // + // ab + // ab + // + // + // nsBoundingMetrics containerSize = aContainerSize; if (aStretchDirection != NS_STRETCH_DIRECTION_DEFAULT && aStretchDirection != mEmbellishData.direction) { - // change the direction and confine the stretch to us - GetPreferredStretchSize(aPresContext, aRenderingContext, - stretchAll ? STRETCH_CONSIDER_EMBELLISHMENTS : 0, - mEmbellishData.direction, containerSize); + if (mEmbellishData.direction == NS_STRETCH_DIRECTION_UNSUPPORTED) { + containerSize = childSize.mBoundingMetrics; + } + else { + GetPreferredStretchSize(aPresContext, aRenderingContext, + stretchAll ? STRETCH_CONSIDER_EMBELLISHMENTS : 0, + mEmbellishData.direction, containerSize); + } } // do the stretching... @@ -681,28 +695,19 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, if (!IsEmbellishOperator(mParent)) { - const nsStyleFont *font = NS_STATIC_CAST(const nsStyleFont*, - mStyleContext->GetStyleData(eStyleStruct_Font)); - nscoord em = NSToCoordRound(float(font->mFont.size)); - nsEmbellishData coreData; mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); mathMLFrame->GetEmbellishData(coreData); - // cache these values - mEmbellishData.leftSpace = coreData.leftSpace; - mEmbellishData.rightSpace = coreData.rightSpace; + mBoundingMetrics.width += coreData.leftSpace + coreData.rightSpace; + aDesiredStretchSize.width = mBoundingMetrics.width; + aDesiredStretchSize.mBoundingMetrics.width = mBoundingMetrics.width; - aDesiredStretchSize.width += - NSToCoordRound((coreData.leftSpace + coreData.rightSpace) * em); - -// XXX is this what to do ? - aDesiredStretchSize.mBoundingMetrics.width += - NSToCoordRound((coreData.leftSpace + coreData.rightSpace) * em); - - nscoord dx = nscoord( coreData.leftSpace * em ); + nscoord dx = coreData.leftSpace; if (!dx) return NS_OK; + mBoundingMetrics.leftBearing += dx; + mBoundingMetrics.rightBearing += dx; aDesiredStretchSize.mBoundingMetrics.leftBearing += dx; aDesiredStretchSize.mBoundingMetrics.rightBearing += dx; @@ -740,7 +745,15 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, // We use the information in our children rectangles to position them. // If placeOrigin==false, then Place() will not touch rect.x, and rect.y. // They will still be holding the ascent and descent for each child. - PRBool placeOrigin = !NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags); + + // The first clause caters for any non-embellished container. + // The second clause is for a container which won't fire stretch even though it is + // embellished, e.g., as in ... ... , the test is convoluted + // because it excludes the particular case of the core ... itself. + // ( needs to stretch its MathMLChar). + PRBool placeOrigin = !NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) || + (mEmbellishData.core && !mEmbellishData.firstChild && + mEmbellishData.direction == NS_STRETCH_DIRECTION_UNSUPPORTED); Place(aPresContext, aRenderingContext, placeOrigin, aDesiredSize); if (!placeOrigin) { @@ -765,9 +778,14 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, // There is nobody who will fire the stretch for us, we do it ourselves! nsBoundingMetrics defaultSize; - GetPreferredStretchSize(aPresContext, aRenderingContext, 0, - mEmbellishData.direction, defaultSize); - + if (!mEmbellishData.core) { + // case of a bare ... itself + defaultSize = aDesiredSize.mBoundingMetrics; + } + else { + GetPreferredStretchSize(aPresContext, aRenderingContext, 0, + mEmbellishData.direction, defaultSize); + } Stretch(aPresContext, aRenderingContext, NS_STRETCH_DIRECTION_DEFAULT, defaultSize, aDesiredSize); } @@ -802,7 +820,7 @@ nsMathMLContainerFrame::EmbellishOperator() firstChild->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); nsEmbellishData embellishData; mathMLFrame->GetEmbellishData(embellishData); - mEmbellishData.core = embellishData.core; + mEmbellishData.core = embellishData.core ? embellishData.core : firstChild; mEmbellishData.direction = embellishData.direction; } else { diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp index 7af26acf768..edae9ff7aa2 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp @@ -238,11 +238,33 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) +{ + return doReflow(aPresContext, aReflowState, aDesiredSize, aStatus, this, + mOpenChar, mCloseChar, mSeparatorsChar, mSeparatorsCount); +} + +// exported routine that both mfenced and mfrac share. +// mfrac uses this when its bevelled attribute is set. +/*static*/ nsresult +nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, + nsReflowStatus& aStatus, + nsIFrame* aForFrame, + nsMathMLChar* aOpenChar, + nsMathMLChar* aCloseChar, + nsMathMLChar* aSeparatorsChar, + PRInt32 aSeparatorsCount) + { nsresult rv; aDesiredSize.width = aDesiredSize.height = 0; aDesiredSize.ascent = aDesiredSize.descent = 0; + aDesiredSize.mBoundingMetrics.Clear(); + nsMathMLContainerFrame* mathMLFrame = + NS_STATIC_CAST(nsMathMLContainerFrame*, aForFrame); + ///////////// // Reflow children // Asking each child to cache its bounding metrics @@ -253,16 +275,19 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, // method here, our stretchy frames will be stretched and placed, and we may // end up stretching our fences/separators with a different aDesiredSize. + PRInt32 count = 0; nsReflowStatus childStatus; nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight); nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize, aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS); - nsIFrame* childFrame = mFrames.FirstChild(); + nsIFrame* fisrtChild; + aForFrame->FirstChild(aPresContext, nsnull, &fisrtChild); + nsIFrame* childFrame = fisrtChild; while (childFrame) { nsHTMLReflowState childReflowState(aPresContext, aReflowState, childFrame, availSize); - rv = ReflowChild(childFrame, aPresContext, childDesiredSize, - childReflowState, childStatus); + rv = mathMLFrame->ReflowChild(childFrame, aPresContext, childDesiredSize, + childReflowState, childStatus); //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); if (NS_FAILED(rv)) return rv; @@ -273,48 +298,58 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, nsRect(childDesiredSize.descent, childDesiredSize.ascent, childDesiredSize.width, childDesiredSize.height)); + // compute the bounding metrics right now for mfrac + if (aDesiredSize.descent < childDesiredSize.descent) + aDesiredSize.descent = childDesiredSize.descent; + if (aDesiredSize.ascent < childDesiredSize.ascent) + aDesiredSize.ascent = childDesiredSize.ascent; + if (0 == count++) + aDesiredSize.mBoundingMetrics = childDesiredSize.mBoundingMetrics; + else + aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics; + childFrame->GetNextSibling(&childFrame); } - // get our bounding metrics using a tentative Place() - Place(aPresContext, *aReflowState.rendContext, PR_FALSE, aDesiredSize); - - // What size should we use to stretch our stretchy children - // XXX tune this - nsBoundingMetrics containerSize = mBoundingMetrics; - ///////////// // Ask stretchy children to stretch themselves - + + nsBoundingMetrics containerSize; nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL; - nsRect rect; - - childFrame = mFrames.FirstChild(); - while (childFrame) { - nsIMathMLFrame* mathMLFrame; - rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (NS_SUCCEEDED(rv) && mathMLFrame) { - // retrieve the metrics that was stored at the previous pass - childFrame->GetRect(rect); - mathMLFrame->GetBoundingMetrics(childDesiredSize.mBoundingMetrics); - childDesiredSize.descent = rect.x; - childDesiredSize.ascent = rect.y; - childDesiredSize.height = rect.height; - childDesiredSize.width = rect.width; - mathMLFrame->Stretch(aPresContext, *aReflowState.rendContext, - stretchDir, containerSize, childDesiredSize); - // store the updated metrics - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent, childDesiredSize.ascent, - childDesiredSize.width, childDesiredSize.height)); + nsEmbellishData embellishData; + mathMLFrame->GetEmbellishData(embellishData); + if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(embellishData.flags)) { + // case when the call is made for mfrac, we only need to stretch the '/' separator + containerSize = aDesiredSize.mBoundingMetrics; // computed earlier + } + else { + // case when the call is made for mfenced + mathMLFrame->GetPreferredStretchSize(aPresContext, *aReflowState.rendContext, + 0, /* i.e., without embellishments */ + stretchDir, containerSize); + childFrame = fisrtChild; + while (childFrame) { + nsIMathMLFrame* mathmlChild; + rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathmlChild); + if (NS_SUCCEEDED(rv) && mathmlChild) { + // retrieve the metrics that was stored at the previous pass + GetReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics); - if (aDesiredSize.descent < childDesiredSize.descent) - aDesiredSize.descent = childDesiredSize.descent; - if (aDesiredSize.ascent < childDesiredSize.ascent) - aDesiredSize.ascent = childDesiredSize.ascent; + mathmlChild->Stretch(aPresContext, *aReflowState.rendContext, + stretchDir, containerSize, childDesiredSize); + // store the updated metrics + childFrame->SetRect(aPresContext, + nsRect(childDesiredSize.descent, childDesiredSize.ascent, + childDesiredSize.width, childDesiredSize.height)); + + if (aDesiredSize.descent < childDesiredSize.descent) + aDesiredSize.descent = childDesiredSize.descent; + if (aDesiredSize.ascent < childDesiredSize.ascent) + aDesiredSize.ascent = childDesiredSize.ascent; + } + childFrame->GetNextSibling(&childFrame); } - childFrame->GetNextSibling(&childFrame); } ////////////////////////////////////////// @@ -322,18 +357,14 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, // adjust the origin of children. PRInt32 i; - const nsStyleFont *font = NS_STATIC_CAST(const nsStyleFont*, - mStyleContext->GetStyleData(eStyleStruct_Font)); + const nsStyleFont* font; + aForFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font); nsCOMPtr fm; aReflowState.rendContext->SetFont(font->mFont); aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); nscoord axisHeight, em; GetAxisHeight(*aReflowState.rendContext, fm, axisHeight); - em = NSToCoordRound(float(font->mFont.size)); - - nscoord fontAscent, fontDescent; - fm->GetMaxAscent(fontAscent); - fm->GetMaxDescent(fontDescent); + GetEmHeight(fm, em); // we need to center around the axis nscoord delta = PR_MAX(containerSize.ascent - axisHeight, @@ -341,26 +372,26 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, containerSize.ascent = delta + axisHeight; containerSize.descent = delta - axisHeight; + nsPresentationData presentationData; + mathMLFrame->GetPresentationData(presentationData); + ///////////////// // opening fence ... - ReflowChar(aPresContext, *aReflowState.rendContext, mOpenChar, - NS_MATHML_OPERATOR_FORM_PREFIX, mPresentationData.scriptLevel, - fontAscent, fontDescent, axisHeight, em, - containerSize, aDesiredSize); + ReflowChar(aPresContext, *aReflowState.rendContext, aOpenChar, + NS_MATHML_OPERATOR_FORM_PREFIX, presentationData.scriptLevel, + axisHeight, em, containerSize, aDesiredSize); ///////////////// // separators ... - for (i = 0; i < mSeparatorsCount; i++) { - ReflowChar(aPresContext, *aReflowState.rendContext, &mSeparatorsChar[i], - NS_MATHML_OPERATOR_FORM_INFIX, mPresentationData.scriptLevel, - fontAscent, fontDescent, axisHeight, em, - containerSize, aDesiredSize); + for (i = 0; i < aSeparatorsCount; i++) { + ReflowChar(aPresContext, *aReflowState.rendContext, &aSeparatorsChar[i], + NS_MATHML_OPERATOR_FORM_INFIX, presentationData.scriptLevel, + axisHeight, em, containerSize, aDesiredSize); } ///////////////// // closing fence ... - ReflowChar(aPresContext, *aReflowState.rendContext, mCloseChar, - NS_MATHML_OPERATOR_FORM_POSTFIX, mPresentationData.scriptLevel, - fontAscent, fontDescent, axisHeight, em, - containerSize, aDesiredSize); + ReflowChar(aPresContext, *aReflowState.rendContext, aCloseChar, + NS_MATHML_OPERATOR_FORM_POSTFIX, presentationData.scriptLevel, + axisHeight, em, containerSize, aDesiredSize); ////////////////// // Adjust the origins of each child. @@ -370,71 +401,66 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, nscoord dx = 0; nsBoundingMetrics bm; PRBool firstTime = PR_TRUE; - mBoundingMetrics.Clear(); - if (mOpenChar) { - PlaceChar(mOpenChar, fontAscent, aDesiredSize.ascent, bm, dx); - mBoundingMetrics = bm; + if (aOpenChar) { + PlaceChar(aOpenChar, aDesiredSize.ascent, bm, dx); + aDesiredSize.mBoundingMetrics = bm; firstTime = PR_FALSE; } - childFrame = mFrames.FirstChild(); + childFrame = fisrtChild; while (childFrame) { nsHTMLReflowMetrics childSize(nsnull); GetReflowAndBoundingMetricsFor(childFrame, childSize, bm); if (firstTime) { firstTime = PR_FALSE; - mBoundingMetrics = bm; + aDesiredSize.mBoundingMetrics = bm; } else - mBoundingMetrics += bm; + aDesiredSize.mBoundingMetrics += bm; - FinishReflowChild(childFrame, aPresContext, nsnull, childSize, - dx, aDesiredSize.ascent - childSize.ascent, 0); + mathMLFrame->FinishReflowChild(childFrame, aPresContext, nsnull, childSize, + dx, aDesiredSize.ascent - childSize.ascent, 0); dx += childSize.width; - if (i < mSeparatorsCount) { - PlaceChar(&mSeparatorsChar[i], fontAscent, aDesiredSize.ascent, bm, dx); - mBoundingMetrics += bm; + if (i < aSeparatorsCount) { + PlaceChar(&aSeparatorsChar[i], aDesiredSize.ascent, bm, dx); + aDesiredSize.mBoundingMetrics += bm; } i++; childFrame->GetNextSibling(&childFrame); } - if (mCloseChar) { - PlaceChar(mCloseChar, fontAscent, aDesiredSize.ascent, bm, dx); + if (aCloseChar) { + PlaceChar(aCloseChar, aDesiredSize.ascent, bm, dx); if (firstTime) - mBoundingMetrics = bm; + aDesiredSize.mBoundingMetrics = bm; else - mBoundingMetrics += bm; + aDesiredSize.mBoundingMetrics += bm; } - aDesiredSize.width = mBoundingMetrics.width; - aDesiredSize.mBoundingMetrics = mBoundingMetrics; + aDesiredSize.width = aDesiredSize.mBoundingMetrics.width; aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; - aDesiredSize.mBoundingMetrics = mBoundingMetrics; - - mReference.x = 0; - mReference.y = aDesiredSize.ascent; if (aDesiredSize.maxElementSize) { aDesiredSize.maxElementSize->width = aDesiredSize.width; aDesiredSize.maxElementSize->height = aDesiredSize.height; } + mathMLFrame->SetBoundingMetrics(aDesiredSize.mBoundingMetrics); + mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent)); + aStatus = NS_FRAME_COMPLETE; return NS_OK; } // helper functions to perform the common task of formatting our chars -nsresult +/*static*/ nsresult nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nsMathMLChar* aMathMLChar, nsOperatorFlags aForm, PRInt32 aScriptLevel, - nscoord fontAscent, - nscoord fontDescent, nscoord axisHeight, nscoord em, nsBoundingMetrics& aContainerSize, @@ -471,14 +497,17 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, charSize.descent = height - charSize.ascent; } else { - charSize.ascent = fontAscent; - charSize.descent = fontDescent; - if (NS_FAILED(res) && charSize.width == 0) { - // gracefully handle cases where stretching the char failed (i.e., GetBoundingMetrics failed) - // we need to get the width - aRenderingContext.GetWidth(data, charSize.width); - // Note: the bounding metrics of the MathMLChar is not updated, but PlaceChar() - // will do the right thing by leaving the necessary room to paint the char. + // either it hasn't changed or stretching the char failed (i.e., + // GetBoundingMetrics failed) + if (NS_FAILED(res)) { + nsTextDimensions dimensions; + aRenderingContext.GetTextDimensions(data.get(), data.Length(), dimensions); + charSize.ascent = dimensions.ascent; + charSize.descent = dimensions.descent; + charSize.width = dimensions.width; + // Set this as the bounding metrics of the MathMLChar to leave + // the necessary room to paint the char. + aMathMLChar->SetBoundingMetrics(charSize); } } @@ -499,9 +528,8 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, return NS_OK; } -void +/*static*/ void nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar, - nscoord aFontAscent, nscoord aDesiredAscent, nsBoundingMetrics& bm, nscoord& dx) @@ -514,12 +542,7 @@ nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar, aMathMLChar->GetRect(rect); nscoord dy = aDesiredAscent - rect.y; - if (aMathMLChar->GetStretchDirection() == NS_STRETCH_DIRECTION_UNSUPPORTED) - { - // normal char, nsMathMLChar::Paint() will substract this later - dy += (aFontAscent - bm.ascent); - } - else + if (aMathMLChar->GetStretchDirection() != NS_STRETCH_DIRECTION_UNSUPPORTED) { // the stretchy char will be centered around the axis // so we adjust the returned bounding metrics accordingly @@ -535,7 +558,6 @@ nsMathMLmfencedFrame::PlaceChar(nsMathMLChar* aMathMLChar, // return rect.width since it includes lspace and rspace bm.width = rect.width; - dx += rect.width; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.h index fcad1fa258e..e7763caea09 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.h @@ -66,6 +66,37 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + // exported routine that both mfenced and mfrac share. + // mfrac uses this when its bevelled attribute is set. + static nsresult + doReflow(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, + nsReflowStatus& aStatus, + nsIFrame* aForFrame, + nsMathMLChar* aOpenChar, + nsMathMLChar* aCloseChar, + nsMathMLChar* aSeparatorsChar, + PRInt32 aSeparatorsCount); + + // helper routines to format the MathMLChars involved here + static nsresult + ReflowChar(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsMathMLChar* aMathMLChar, + nsOperatorFlags aForm, + PRInt32 aScriptLevel, + nscoord axisHeight, + nscoord em, + nsBoundingMetrics& aContainerSize, + nsHTMLReflowMetrics& aDesiredSize); + + static void + PlaceChar(nsMathMLChar* aMathMLChar, + nscoord aDesiredSize, + nsBoundingMetrics& bm, + nscoord& dx); + protected: nsMathMLmfencedFrame(); virtual ~nsMathMLmfencedFrame(); @@ -77,27 +108,6 @@ protected: nsMathMLChar* mSeparatorsChar; PRInt32 mSeparatorsCount; - // helper routines to format the MathMLChars involved here - static nsresult - ReflowChar(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsMathMLChar* aMathMLChar, - nsOperatorFlags aForm, - PRInt32 aScriptLevel, - nscoord fontAscent, - nscoord fontDescent, - nscoord axisHeight, - nscoord em, - nsBoundingMetrics& aContainerSize, - nsHTMLReflowMetrics& aDesiredSize); - - static void - PlaceChar(nsMathMLChar* aMathMLChar, - nscoord aFontAscent, - nscoord aDesiredAscent, - nsBoundingMetrics& bm, - nscoord& dx); - // clean up void RemoveFencesAndSeparators(); diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp index 30304183ac6..3eda6023054 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp @@ -38,6 +38,7 @@ #include "nsIFontMetrics.h" #include "nsStyleUtil.h" +#include "nsMathMLmfencedFrame.h" #include "nsMathMLmfracFrame.h" // @@ -55,6 +56,11 @@ #define THICK_FRACTION_LINE 2.0f #define THICK_FRACTION_LINE_MINIMUM_PIXELS 4 // minimum of 4 pixels +// additional style context to be used by our MathMLChar. +#define NS_SLASH_CHAR_STYLE_CONTEXT_INDEX 0 + +static const PRUnichar kSlashChar = PRUnichar('/'); + nsresult NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { @@ -70,13 +76,16 @@ NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsMathMLmfracFrame::nsMathMLmfracFrame() : - mLineRect() +nsMathMLmfracFrame::nsMathMLmfracFrame() { } nsMathMLmfracFrame::~nsMathMLmfracFrame() { + if (mSlashChar) { + delete mSlashChar; + mSlashChar = nsnull; + } } NS_IMETHODIMP @@ -93,6 +102,16 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext, return rv; } + if (IsBevelled()) { + // enable the bevelled rendering + mSlashChar = new nsMathMLChar(); + if (mSlashChar) { + nsAutoString slashChar; slashChar.Assign(kSlashChar); + mSlashChar->SetData(aPresContext, slashChar); + ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar); + } + } + #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS; #endif @@ -160,25 +179,18 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { - //////////// - // paint the fraction line - if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) && - !NS_MATHML_HAS_ERROR(mPresentationData.flags) && - !mLineRect.IsEmpty()) { -/* -// line looking like
- const nsStyleColor* color; - nscolor colors[2]; - color = nsStyleUtil::FindNonTransparentBackground(mStyleContext); - NS_Get3DColors(colors, color->mBackgroundColor); - aRenderingContext.SetColor(colors[0]); -*/ -// solid line with the current text color + if (mSlashChar) { + // bevelled rendering + mSlashChar->Paint(aPresContext, aRenderingContext, + aDirtyRect, aWhichLayer, this); + } + else if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) && + !NS_MATHML_HAS_ERROR(mPresentationData.flags) && + !mLineRect.IsEmpty()) { + // paint the fraction line with the current text color const nsStyleColor *color = NS_STATIC_CAST(const nsStyleColor*, mStyleContext->GetStyleData(eStyleStruct_Color)); aRenderingContext.SetColor(color->mColor); - -// draw the line, there is 1 pixel padding at either end aRenderingContext.FillRect(mLineRect.x, mLineRect.y, mLineRect.width, mLineRect.height); } @@ -189,11 +201,29 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, aWhichLayer); } +NS_IMETHODIMP +nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (mSlashChar) { + // bevelled rendering + return nsMathMLmfencedFrame::doReflow(aPresContext, aReflowState, + aDesiredSize, aStatus, this, + nsnull, nsnull, mSlashChar, 1); + } + + // default rendering + return nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize, + aReflowState, aStatus); +} + NS_IMETHODIMP nsMathMLmfracFrame::Place(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - PRBool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize) + nsIRenderingContext& aRenderingContext, + PRBool aPlaceOrigin, + nsHTMLReflowMetrics& aDesiredSize) { //////////////////////////////////// // Get the children's desired sizes @@ -243,6 +273,21 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext, nscoord defaultRuleThickness; GetRuleThickness(aRenderingContext, fm, defaultRuleThickness); + // by default, leave at least one-pixel padding at either end, or use + // lspace & rspace from if we are an embellished container + nscoord leftSpace = onePixel; + nscoord rightSpace = onePixel; + if (mEmbellishData.core) { + nsEmbellishData coreData; + nsIMathMLFrame* mathMLFrame; + mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + mathMLFrame->GetEmbellishData(coreData); + leftSpace = coreData.leftSpace; + rightSpace = coreData.rightSpace; + } + if (leftSpace < onePixel) leftSpace = onePixel; + if (rightSpace < onePixel) rightSpace = onePixel; + // see if the linethickness attribute is there nsAutoString value; GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::linethickness_, value); @@ -323,38 +368,38 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext, ////////////////// // Place Children - // there is 1 pixel padding at either end of the fraction // XXX Need revisiting the width. TeX uses the exact width // e.g. in $$\huge\frac{\displaystyle\int}{i}$$ - nscoord width = 2*onePixel + PR_MAX(bmNum.width, bmDen.width); - nscoord dxNum = (width - sizeNum.width)/2; - nscoord dxDen = (width - sizeDen.width)/2; + nscoord width = PR_MAX(bmNum.width, bmDen.width); + nscoord dxNum = leftSpace + (width - sizeNum.width)/2; + nscoord dxDen = leftSpace + (width - sizeDen.width)/2; + width += leftSpace + rightSpace; // see if the numalign attribute is there if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::numalign_, value)) { if (value.Equals(NS_LITERAL_STRING("left"))) - dxNum = onePixel; + dxNum = leftSpace; else if (value.Equals(NS_LITERAL_STRING("right"))) - dxNum = width - onePixel - sizeNum.width; + dxNum = width - rightSpace - sizeNum.width; } // see if the denomalign attribute is there if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::denomalign_, value)) { if (value.Equals(NS_LITERAL_STRING("left"))) - dxDen = onePixel; + dxDen = leftSpace; else if (value.Equals(NS_LITERAL_STRING("right"))) - dxDen = width - onePixel - sizeDen.width; + dxDen = width - rightSpace - sizeDen.width; } mBoundingMetrics.rightBearing = PR_MAX(dxNum + bmNum.rightBearing, dxDen + bmDen.rightBearing); - if (mBoundingMetrics.rightBearing < width - onePixel) - mBoundingMetrics.rightBearing = width - onePixel; + if (mBoundingMetrics.rightBearing < width - rightSpace) + mBoundingMetrics.rightBearing = width - rightSpace; mBoundingMetrics.leftBearing = PR_MIN(dxNum + bmNum.leftBearing, dxDen + bmDen.leftBearing); - if (mBoundingMetrics.leftBearing > onePixel) - mBoundingMetrics.leftBearing = onePixel; + if (mBoundingMetrics.leftBearing > leftSpace) + mBoundingMetrics.leftBearing = leftSpace; mBoundingMetrics.ascent = bmNum.ascent + numShift; mBoundingMetrics.descent = bmDen.descent + denShift; mBoundingMetrics.width = width; @@ -378,8 +423,77 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext, FinishReflowChild(frameDen, aPresContext, nsnull, sizeDen, dxDen, dy, 0); // place the fraction bar - dy is top of bar dy = aDesiredSize.ascent - (axisHeight + actualRuleThickness/2); - mLineRect.SetRect(onePixel, dy, width - 2*onePixel, actualRuleThickness); + mLineRect.SetRect(leftSpace, dy, width - (leftSpace + rightSpace), actualRuleThickness); } return NS_OK; } + +NS_IMETHODIMP +nsMathMLmfracFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint) +{ + if (nsMathMLAtoms::bevelled_ == aAttribute) { + if (!IsBevelled()) { + // disable the bevelled rendering + if (mSlashChar) { + delete mSlashChar; + mSlashChar = nsnull; + } + } + else { + // enable the bevelled rendering + if (!mSlashChar) { + mSlashChar = new nsMathMLChar(); + if (mSlashChar) { + nsAutoString slashChar; slashChar.Assign(kSlashChar); + mSlashChar->SetData(aPresContext, slashChar); + ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar); + } + } + } + } + return nsMathMLContainerFrame:: + AttributeChanged(aPresContext, aContent,aNameSpaceID, + aAttribute, aModType, aHint); +} + +// ---------------------- +// the Style System will use these to pass the proper style context to our MathMLChar +NS_IMETHODIMP +nsMathMLmfracFrame::GetAdditionalStyleContext(PRInt32 aIndex, + nsIStyleContext** aStyleContext) const +{ + NS_PRECONDITION(aStyleContext, "null OUT ptr"); + if (!mSlashChar || aIndex < 0) { + return NS_ERROR_INVALID_ARG; + } + *aStyleContext = nsnull; + switch (aIndex) { + case NS_SLASH_CHAR_STYLE_CONTEXT_INDEX: + mSlashChar->GetStyleContext(aStyleContext); + break; + default: + return NS_ERROR_INVALID_ARG; + } + return NS_OK; +} + +NS_IMETHODIMP +nsMathMLmfracFrame::SetAdditionalStyleContext(PRInt32 aIndex, + nsIStyleContext* aStyleContext) +{ + if (!mSlashChar || aIndex < 0) { + return NS_ERROR_INVALID_ARG; + } + switch (aIndex) { + case NS_SLASH_CHAR_STYLE_CONTEXT_INDEX: + mSlashChar->SetStyleContext(aStyleContext); + break; + } + return NS_OK; +} diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h index 68d2c6b7a6f..a37ef752b8d 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h @@ -71,6 +71,21 @@ class nsMathMLmfracFrame : public nsMathMLContainerFrame { public: friend nsresult NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + NS_IMETHOD + SetAdditionalStyleContext(PRInt32 aIndex, + nsIStyleContext* aStyleContext); + NS_IMETHOD + GetAdditionalStyleContext(PRInt32 aIndex, + nsIStyleContext** aStyleContext) const; + + NS_IMETHOD + AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint); + NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -78,6 +93,12 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + NS_IMETHOD + Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + NS_IMETHOD Place(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -113,6 +134,12 @@ public: NS_MATHML_COMPRESSED); // check whether or not this is an embellished operator EmbellishOperator(); + // even when embellished, we need to record that won't fire + // Stretch() on its embellished child + mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED; + // break the embellished hierarchy to stop propagating the stretching + // process, but keep access to mEmbellishData.core for convenience + mEmbellishData.firstChild = nsnull; return rv; } @@ -129,8 +156,23 @@ protected: virtual ~nsMathMLmfracFrame(); virtual PRIntn GetSkipSides() const { return 0; } - + + PRBool + IsBevelled() + { + nsAutoString value; + if (NS_CONTENT_ATTR_HAS_VALUE == + GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::bevelled_, value)) { + if (value.Equals(NS_LITERAL_STRING("true"))) { + return PR_TRUE; + } + } + return PR_FALSE; + } + nsRect mLineRect; + nsMathMLChar* mSlashChar; }; #endif /* nsMathMLmfracFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp index 6dd8d48c56d..1e482f48120 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp @@ -157,8 +157,6 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext, // Init our local attributes mFlags = 0; - mLeftSpace = 0.0f; // .27777f; - mRightSpace = 0.0f; // .27777f; mMinSize = float(NS_UNCONSTRAINEDSIZE); mMaxSize = float(NS_UNCONSTRAINEDSIZE); @@ -204,13 +202,12 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext, // fill our mEmbellishData member variable nsIFrame* firstChild = mFrames.FirstChild(); if (firstChild) { - mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR; - mEmbellishData.core = this; mEmbellishData.direction = mMathMLChar.GetStretchDirection(); - - // for consistency, set the first non-empty child as the embellished child - mEmbellishData.firstChild = firstChild; - + mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR; + // IMPORTANT: these two NULL tell us the core of the embellished hierarchy. + mEmbellishData.firstChild = nsnull; + mEmbellishData.core = nsnull; + // there are two extra things that we need to record so that if our // parent is , , or , they will treat us properly: // 1) do we have accent="true" @@ -300,47 +297,36 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) nsOperatorFlags form = NS_MATHML_OPERATOR_FORM_INFIX; nsIMathMLFrame* mathMLFrame = nsnull; + nsIFrame* embellishAncestor = this; nsEmbellishData embellishData; + // Get our outermost embellished container and its parent. + // We ensure that we are the core, not just a sibling of the core + nsIFrame* parentAncestor = this; + do { + embellishAncestor = parentAncestor; + embellishAncestor->GetParent(&parentAncestor); + rv = parentAncestor->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); + } + else { + embellishData.core = nsnull; + } + } while (embellishData.core == this); + // flag if we have an embellished ancestor + if (embellishAncestor != this) { + mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR; + } + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::form_, value)) { if (value.Equals(NS_LITERAL_STRING("prefix"))) form = NS_MATHML_OPERATOR_FORM_PREFIX; else if (value.Equals(NS_LITERAL_STRING("postfix"))) form = NS_MATHML_OPERATOR_FORM_POSTFIX; - - // see if we have an embellished ancestor, and check that we are really - // the 'core' of the ancestor, not just a sibling of the core - rv = mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (NS_SUCCEEDED(rv) && mathMLFrame) { - mathMLFrame->GetEmbellishData(embellishData); - if (embellishData.core == this) { - // flag if we have an embellished ancestor - mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR; - } - } } else { - // Get our outermost embellished container and its parent - nsIFrame* embellishAncestor; - nsIFrame* parent = this; - do { - embellishAncestor = parent; - embellishAncestor->GetParent(&parent); - rv = parent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (NS_SUCCEEDED(rv) && mathMLFrame) { - mathMLFrame->GetEmbellishData(embellishData); - } - else { - embellishData.core = nsnull; - } - } while (embellishData.core == this); - // flag if we have an embellished ancestor - if (embellishAncestor != this) - { - mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR; - } - // Find the position of our outermost embellished container w.r.t // its siblings (frames are singly-linked together). nsIFrame* prev = nsnull; @@ -348,7 +334,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) nsIFrame* frame; embellishAncestor->GetNextSibling(&next); - parent->FirstChild(aPresContext, nsnull, &frame); + parentAncestor->FirstChild(aPresContext, nsnull, &frame); while (frame) { if (frame == embellishAncestor) break; prev = frame; @@ -366,16 +352,26 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) nsAutoString data; mMathMLChar.GetData(data); mMathMLChar.SetData(aPresContext, data); // XXX hack to reset, bug 45010 - PRBool found = nsMathMLOperators::LookupOperator(data, form, - &mFlags, &mLeftSpace, &mRightSpace); + float lspace, rspace; + PRBool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace); // If we don't want too much extra space when we are a script if ((0 < mPresentationData.scriptLevel) && !NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) { - mLeftSpace /= 2.0f; - mRightSpace /= 2.0f; + lspace /= 2.0f; + rspace /= 2.0f; } + // Since these values are relative to the 'em' unit, convert to twips now + nscoord leftSpace, rightSpace, em; + const nsStyleFont* font; + GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font); + nsCOMPtr fm; + aPresContext->GetMetricsFor(font->mFont, getter_AddRefs(fm)); + GetEmHeight(fm, em); + leftSpace = NSToCoordRound(lspace * em); + rightSpace = NSToCoordRound(rspace * em); + // Now see if there are user-defined attributes that override the dictionary. // XXX If an attribute can be forced to be true when it is false in the // dictionary, then the following code has to change... @@ -424,11 +420,6 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) // If we are an accent without explicit lspace="." or rspace=".", // ignore our default left/right space - // Get the value of 'em' - const nsStyleFont *font = NS_STATIC_CAST(const nsStyleFont*, - mStyleContext->GetStyleData(eStyleStruct_Font)); - float em = float(font->mFont.size); - // lspace = number h-unit | namedspace if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::lspace_, value)) { @@ -437,13 +428,13 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) { if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue()) - mLeftSpace = 0.0f; + leftSpace = 0; else if (cssValue.IsLengthUnit()) - mLeftSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em; + leftSpace = CalcLength(aPresContext, mStyleContext, cssValue); } } else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) { - mLeftSpace = 0.0f; + leftSpace = 0; } // rspace = number h-unit | namedspace @@ -454,15 +445,19 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) { if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue()) - mRightSpace = 0.0f; + rightSpace = 0; else if (cssValue.IsLengthUnit()) - mRightSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em; + rightSpace = CalcLength(aPresContext, mStyleContext, cssValue); } } else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) { - mRightSpace = 0.0f; + rightSpace = 0; } + // cache these values + mEmbellishData.leftSpace = leftSpace; + mEmbellishData.rightSpace = rightSpace; + // minsize = number [ v-unit | h-unit ] | namedspace if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::minsize_, value)) { @@ -544,7 +539,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) (ch == 0x00D7)) { // × mFlags |= NS_MATHML_OPERATOR_CENTERED; } - } + } } // NOTE: aDesiredStretchSize is an IN/OUT parameter @@ -732,8 +727,9 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, // get the leading to be left at the top and the bottom of the stretched char // this seems more reliable than using fm->GetLeading() on suspicious fonts - float em = float(font->mFont.size); - leading = nscoord(0.2f * em); + nscoord em; + GetEmHeight(fm, em); + leading = NSToCoordRound(0.2f * em); aDesiredStretchSize.ascent = mBoundingMetrics.ascent + leading; aDesiredStretchSize.descent = mBoundingMetrics.descent + leading; @@ -744,8 +740,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent; mMathMLChar.SetRect( - nsRect(0, dy, charSize.width, - charSize.ascent + charSize.descent)); + nsRect(0, dy, charSize.width, charSize.ascent + charSize.descent)); mReference.x = 0; mReference.y = aDesiredStretchSize.ascent; @@ -765,20 +760,19 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) { - // Get the value of 'em' - nscoord em = NSToCoordRound(float(font->mFont.size)); - // Account the spacing - aDesiredStretchSize.width += nscoord((mLeftSpace + mRightSpace) * em); - mBoundingMetrics.width = aDesiredStretchSize.width; - nscoord dx = nscoord(mLeftSpace * em); + mBoundingMetrics.width += mEmbellishData.leftSpace + mEmbellishData.rightSpace; + aDesiredStretchSize.width = mBoundingMetrics.width; + aDesiredStretchSize.mBoundingMetrics.width = mBoundingMetrics.width; + nscoord dx = mEmbellishData.leftSpace; if (!dx) return NS_OK; // adjust the offsets mBoundingMetrics.leftBearing += dx; mBoundingMetrics.rightBearing += dx; - aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics; + aDesiredStretchSize.mBoundingMetrics.leftBearing += dx; + aDesiredStretchSize.mBoundingMetrics.rightBearing += dx; nsRect rect; if (NS_MATHML_OPERATOR_GET_FORM(mFlags)) { diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.h index 47170afcc0a..7705f61b003 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.h @@ -95,8 +95,6 @@ protected: nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator. nsOperatorFlags mFlags; - float mLeftSpace; - float mRightSpace; float mMinSize; float mMaxSize; };