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
+ //
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;
};