diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp index fcb0f7a4a61..2b86d719b36 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp @@ -291,6 +291,10 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + //////////////////// // Place Children @@ -310,11 +314,12 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, // whether we want an accented overscript or not nscoord correction = 0; + GetItalicCorrection (bmBase, correction); + nscoord delta1 = 0; // gap between base and overscript nscoord delta2 = 0; // extra space above overscript if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook - GetItalicCorrection (bmBase, correction); nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy; GetBigOpSpacings (fm, bigOpSpacing1, dummy, @@ -331,7 +336,6 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, } else { // Rule 12, App. G, TeXbook - GetSkewCorrectionFromChild (aPresContext, baseFrame, correction); // We are going to modify this rule to make it more general. // The idea behind Rule 12 in the TeXBook is to keep the accent // as close to the base as possible, while ensuring that the @@ -360,9 +364,9 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, // we try to keep the *bottom* of the accent char atleast x-height // from the baseline of the base char. we also slap on an extra // padding between the accent and base chars. - delta1 = ruleThickness; // we have atleast the padding + delta1 = ruleThickness + onePixel/2; // we have at least the padding if (bmBase.ascent < xHeight) { - // also ensure atleast x-height above the baseline of the base + // also ensure at least x-height above the baseline of the base delta1 += xHeight - bmBase.ascent; } delta2 = ruleThickness; @@ -370,13 +374,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, // empty over? if (!(bmOver.ascent + bmOver.descent)) delta1 = 0; - mBoundingMetrics.ascent = - bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent; - - mBoundingMetrics.descent = bmBase.descent; - nscoord dxBase, dxOver = 0; - nscoord dyBase, dyOver; // Ad-hoc - This is to override fonts which have ready-made _accent_ // glyphs with negative lbearing and rbearing. We want to position @@ -388,13 +386,22 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, } if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { - mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth); + mBoundingMetrics.width = bmBase.width; + dxOver += correction + (mBoundingMetrics.width - overWidth)/2; } else { - mBoundingMetrics.width = - PR_MAX(bmBase.width/2,(overWidth + correction/2)/2) + - PR_MAX(bmBase.width/2,(overWidth - correction/2)/2); + mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth); + dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; } + dxBase = (mBoundingMetrics.width - bmBase.width) / 2; + + mBoundingMetrics.ascent = + bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent; + mBoundingMetrics.descent = bmBase.descent; + mBoundingMetrics.leftBearing = + PR_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); + mBoundingMetrics.rightBearing = + PR_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing); aDesiredSize.descent = baseSize.descent; aDesiredSize.ascent = @@ -402,34 +409,19 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, overSize.ascent + bmOver.descent + delta1 + bmBase.ascent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; - - dxBase = (mBoundingMetrics.width - bmBase.width) / 2; - dyBase = aDesiredSize.ascent - baseSize.ascent; - - if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { - dxOver += correction + (mBoundingMetrics.width - overWidth)/2; - } - else { - dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; - } - - dyOver = aDesiredSize.ascent - - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent; + aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; mReference.y = aDesiredSize.ascent; - mBoundingMetrics.leftBearing = - PR_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); - mBoundingMetrics.rightBearing = - PR_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing); - aDesiredSize.mBoundingMetrics = mBoundingMetrics; - if (aPlaceOrigin) { // place base - FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dxBase, dyBase, 0); + nscoord dy = aDesiredSize.ascent - baseSize.ascent; + FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dxBase, dy, 0); // place overscript - FinishReflowChild (overFrame, aPresContext, nsnull, overSize, dxOver, dyOver, 0); + dy = aDesiredSize.ascent - + mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent; + FinishReflowChild (overFrame, aPresContext, nsnull, overSize, dxOver, dy, 0); } return NS_OK; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp index 2db8125f6d8..687a2cca9f7 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp @@ -288,6 +288,10 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + //////////////////// // Place Children @@ -306,12 +310,13 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, // there are 2 different types of placement depending on // whether we want an accented under or not - nscoord italicCorrection = 0; + nscoord correction = 0; + GetItalicCorrection (bmBase, correction); + nscoord delta1 = 0; // gap between base and underscript nscoord delta2 = 0; // extra space beneath underscript if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook - GetItalicCorrection (bmBase, italicCorrection); nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy; GetBigOpSpacings (fm, dummy, bigOpSpacing2, @@ -325,22 +330,27 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, // XXX tune the gap delta between base and underscript // Should we use Rule 10 like \underline does? - delta1 = ruleThickness; + delta1 = ruleThickness + onePixel/2; delta2 = ruleThickness; } // empty under? if (!(bmUnder.ascent + bmUnder.descent)) delta1 = 0; + nscoord dxBase, dxUnder; + nscoord maxWidth = PR_MAX(bmBase.width, bmUnder.width); + if (NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { + dxUnder = (maxWidth - bmUnder.width)/2; + } + else { + dxUnder = -correction/2 + (maxWidth - bmUnder.width)/2; + } + dxBase = (maxWidth - bmBase.width)/2; + + mBoundingMetrics.width = + PR_MAX(dxBase + bmBase.width, dxUnder + bmUnder.width); mBoundingMetrics.ascent = bmBase.ascent; mBoundingMetrics.descent = bmBase.descent + delta1 + bmUnder.ascent + bmUnder.descent; - mBoundingMetrics.width = - PR_MAX(bmBase.width/2,(bmUnder.width + italicCorrection/2)/2) + - PR_MAX(bmBase.width/2,(bmUnder.width - italicCorrection/2)/2); - - nscoord dxBase = (mBoundingMetrics.width - bmBase.width) / 2; - nscoord dxUnder = (mBoundingMetrics.width - (bmUnder.width + italicCorrection/2)) / 2; - mBoundingMetrics.leftBearing = PR_MIN(dxBase + bmBase.leftBearing, dxUnder + bmUnder.leftBearing); mBoundingMetrics.rightBearing = @@ -351,9 +361,7 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, PR_MAX(mBoundingMetrics.descent + delta2, bmBase.descent + delta1 + bmUnder.ascent + underSize.descent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; - aDesiredSize.width = - PR_MAX(baseSize.width/2,(underSize.width + italicCorrection/2)/2) + - PR_MAX(baseSize.width/2,(underSize.width - italicCorrection/2)/2); + aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics; mReference.x = 0; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp index 342bf6d368f..1d8638a40ac 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp @@ -331,6 +331,10 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + //////////////////// // Place Children @@ -346,16 +350,17 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, nscoord ruleThickness; GetRuleThickness (aRenderingContext, fm, ruleThickness); + nscoord correction = 0; + GetItalicCorrection (bmBase, correction); + // there are 2 different types of placement depending on // whether we want an accented under or not - nscoord italicCorrection = 0; nscoord underDelta1 = 0; // gap between base and underscript nscoord underDelta2 = 0; // extra space beneath underscript if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook - GetItalicCorrection (bmBase, italicCorrection); nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy; GetBigOpSpacings (fm, dummy, bigOpSpacing2, @@ -369,19 +374,17 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, // XXX tune the gap delta between base and underscript // Should we use Rule 10 like \underline does? - underDelta1 = ruleThickness; + underDelta1 = ruleThickness + onePixel/2; underDelta2 = ruleThickness; } // empty under? if (!(bmUnder.ascent + bmUnder.descent)) underDelta1 = 0; - nscoord correction = 0; nscoord overDelta1 = 0; // gap between base and overscript nscoord overDelta2 = 0; // extra space above overscript if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { // Rule 13a, App. G, TeXbook - GetItalicCorrection (bmBase, italicCorrection); nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy; GetBigOpSpacings (fm, bigOpSpacing1, dummy, @@ -397,9 +400,8 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, overDelta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent))); } else { - // Rule 13, App. G, TeXbook - GetSkewCorrectionFromChild (aPresContext, baseFrame, correction); - overDelta1 = ruleThickness; + // Rule 12, App. G, TeXbook + overDelta1 = ruleThickness + onePixel/2; if (bmBase.ascent < xHeight) { overDelta1 += xHeight - bmBase.ascent; } @@ -408,33 +410,78 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, // empty over? if (!(bmOver.ascent + bmOver.descent)) overDelta1 = 0; + nscoord dxBase, dxOver = 0, dxUnder = 0; + + ////////// + // pass 1, do what does: attach the overscript on the base + + // Ad-hoc - This is to override fonts which have ready-made _accent_ + // glyphs with negative lbearing and rbearing. We want to position + // the overscript ourselves + nscoord overWidth = bmOver.width; + if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) { + overWidth = bmOver.rightBearing - bmOver.leftBearing; + dxOver = -bmOver.leftBearing; + } + + if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) { + mBoundingMetrics.width = bmBase.width; + dxOver += correction + (mBoundingMetrics.width - overWidth)/2; + } + else { + mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth); + dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; + } + dxBase = (mBoundingMetrics.width - bmBase.width)/2; + mBoundingMetrics.ascent = bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent; mBoundingMetrics.descent = bmBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent; - mBoundingMetrics.width = - PR_MAX(bmBase.width/2,PR_MAX((bmUnder.width + italicCorrection/2)/2,(bmOver.width - correction/2)/2)) + - PR_MAX(bmBase.width/2,PR_MAX((bmUnder.width - italicCorrection/2)/2,(bmOver.width + correction/2)/2)); - - nscoord dxBase = (mBoundingMetrics.width - bmBase.width) / 2; - nscoord dxOver = (mBoundingMetrics.width - (bmOver.width - correction/2)) / 2; - nscoord dxUnder = (mBoundingMetrics.width - (bmUnder.width + italicCorrection/2)) / 2; - mBoundingMetrics.leftBearing = - PR_MIN(dxBase + bmBase.leftBearing, dxUnder + bmUnder.leftBearing); + PR_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing); mBoundingMetrics.rightBearing = - PR_MAX(dxBase + bmBase.rightBearing, dxUnder + bmUnder.rightBearing); - mBoundingMetrics.leftBearing = - PR_MIN(mBoundingMetrics.leftBearing, dxOver + bmOver.leftBearing); - mBoundingMetrics.rightBearing = - PR_MAX(mBoundingMetrics.rightBearing, dxOver + bmOver.rightBearing); + PR_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing); - aDesiredSize.ascent = + ////////// + // pass 2, do what does: attach the underscript on the previous + // result. We conceptually view the previous result as an "anynomous base" + // from where to attach the underscript. Hence if the underscript is empty, + // we should end up like . If the overscript is empty, we should + // end up like . + + nsBoundingMetrics bmAnonymousBase = mBoundingMetrics; + nscoord ascentAnonymousBase = PR_MAX(mBoundingMetrics.ascent + overDelta2, overSize.ascent + bmOver.descent + overDelta1 + bmBase.ascent); + + GetItalicCorrection(bmAnonymousBase, correction); + + nscoord maxWidth = PR_MAX(bmAnonymousBase.width, bmUnder.width); + if (NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) { + dxUnder = (maxWidth - bmUnder.width)/2;; + } + else { + dxUnder = -correction/2 + (maxWidth - bmUnder.width)/2; + } + nscoord dxAnonymousBase = (maxWidth - bmAnonymousBase.width)/2; + + // adjust the offsets of the real base and overscript since their + // final offsets should be relative to us... + dxOver += dxAnonymousBase; + dxBase += dxAnonymousBase; + + mBoundingMetrics.width = + PR_MAX(dxAnonymousBase + bmAnonymousBase.width, dxUnder + bmUnder.width); + mBoundingMetrics.leftBearing = + PR_MIN(dxAnonymousBase + bmAnonymousBase.leftBearing, dxUnder + bmUnder.leftBearing); + mBoundingMetrics.rightBearing = + PR_MAX(dxAnonymousBase + bmAnonymousBase.rightBearing, dxUnder + bmUnder.rightBearing); + + aDesiredSize.ascent = ascentAnonymousBase; aDesiredSize.descent = PR_MAX(mBoundingMetrics.descent + underDelta2, - bmBase.descent + underDelta1 + bmUnder.ascent + underSize.descent); + bmAnonymousBase.descent + underDelta1 + bmUnder.ascent + underSize.descent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; aDesiredSize.mBoundingMetrics = mBoundingMetrics;