Bug 961365 - Part 4: Use MATH constants for scripts. r=jfkthame

This commit is contained in:
Frédéric Wang 2014-06-17 04:09:00 -04:00
parent c9a9cf88b0
commit bbe8cb6e9f
3 changed files with 119 additions and 72 deletions

View File

@ -135,13 +135,8 @@ nsMathMLmmultiscriptsFrame::Place(nsRenderingContext& aRenderingContext,
mStyleContext);
}
}
// scriptspace from TeX for extra spacing after sup/subscript
// (0.5pt in plain TeX)
nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f);
return PlaceMultiScript(PresContext(), aRenderingContext, aPlaceOrigin,
aDesiredSize, this, subScriptShift, supScriptShift,
scriptSpace);
aDesiredSize, this, subScriptShift, supScriptShift);
}
// exported routine that both munderover and mmultiscripts share.
@ -153,8 +148,7 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nsMathMLContainerFrame* aFrame,
nscoord aUserSubScriptShift,
nscoord aUserSupScriptShift,
nscoord aScriptSpace)
nscoord aUserSupScriptShift)
{
nsIAtom* tag = aFrame->GetContent()->Tag();
@ -187,7 +181,6 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
return aFrame->ReflowError(aRenderingContext, aDesiredSize);
}
// get x-height (an ex)
const nsStyleFont* font = aFrame->StyleFont();
nsRefPtr<nsFontMetrics> fm;
@ -196,30 +189,46 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
nscoord xHeight = fm->XHeight();
nscoord ruleSize;
GetRuleThickness (aRenderingContext, fm, ruleSize);
nscoord oneDevPixel = fm->AppUnitsPerDevPixel();
gfxFont* mathFont = fm->GetThebesFontGroup()->GetFirstMathFont();
// scriptspace from TeX for extra spacing after sup/subscript
nscoord scriptSpace;
if (mathFont) {
scriptSpace =
mathFont->GetMathConstant(gfxFontEntry::SpaceAfterScript, oneDevPixel);
} else {
// (0.5pt in plain TeX)
scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f);
}
// force the scriptSpace to be at least 1 pixel
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
aScriptSpace = std::max(onePixel, aScriptSpace);
scriptSpace = std::max(onePixel, scriptSpace);
/////////////////////////////////////
// first the shift for the subscript
// subScriptShift{1,2}
// = minimum amount to shift the subscript down
// = sub{1,2} in TeXbook
// subScriptShift1 = subscriptshift attribute * x-height
nscoord subScriptShift1, subScriptShift2;
// Get subScriptShift{1,2} default from font
GetSubScriptShifts (fm, subScriptShift1, subScriptShift2);
nscoord subScriptShift;
if (tag == nsGkAtoms::msub_) {
subScriptShift = subScriptShift1;
if (mathFont) {
// Try and get the sub script shift from the MATH table. Note that contrary
// to TeX we only have one parameter.
subScriptShift =
mathFont->GetMathConstant(gfxFontEntry::SubscriptShiftDown, oneDevPixel);
} else {
subScriptShift = std::max(subScriptShift1, subScriptShift2);
// subScriptShift{1,2}
// = minimum amount to shift the subscript down
// = sub{1,2} in TeXbook
// subScriptShift1 = subscriptshift attribute * x-height
nscoord subScriptShift1, subScriptShift2;
// Get subScriptShift{1,2} default from font
GetSubScriptShifts (fm, subScriptShift1, subScriptShift2);
if (tag == nsGkAtoms::msub_) {
subScriptShift = subScriptShift1;
} else {
subScriptShift = std::max(subScriptShift1, subScriptShift2);
}
}
if (0 < aUserSubScriptShift) {
// the user has set the subscriptshift attribute
subScriptShift = std::max(subScriptShift, aUserSubScriptShift);
@ -228,32 +237,42 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
/////////////////////////////////////
// next the shift for the superscript
// supScriptShift{1,2,3}
// = minimum amount to shift the supscript up
// = sup{1,2,3} in TeX
// supScriptShift1 = superscriptshift attribute * x-height
// Note that there are THREE values for supscript shifts depending
// on the current style
nscoord supScriptShift1, supScriptShift2, supScriptShift3;
// Set supScriptShift{1,2,3} default from font
GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3);
// get sup script shift depending on current script level and display style
// Rule 18c, App. G, TeXbook
nscoord supScriptShift;
nsPresentationData presentationData;
aFrame->GetPresentationData(presentationData);
nscoord supScriptShift;
if (font->mScriptLevel == 0 &&
font->mMathDisplay == NS_MATHML_DISPLAYSTYLE_BLOCK &&
!NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
// Style D in TeXbook
supScriptShift = supScriptShift1;
} else if (NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
// Style C' in TeXbook = D',T',S',SS'
supScriptShift = supScriptShift3;
if (mathFont) {
// Try and get the super script shift from the MATH table. Note that
// contrary to TeX we only have two parameters.
supScriptShift = mathFont->
GetMathConstant(NS_MATHML_IS_COMPRESSED(presentationData.flags) ?
gfxFontEntry::SuperscriptShiftUpCramped :
gfxFontEntry::SuperscriptShiftUp,
oneDevPixel);
} else {
// everything else = T,S,SS
supScriptShift = supScriptShift2;
// supScriptShift{1,2,3}
// = minimum amount to shift the supscript up
// = sup{1,2,3} in TeX
// supScriptShift1 = superscriptshift attribute * x-height
// Note that there are THREE values for supscript shifts depending
// on the current style
nscoord supScriptShift1, supScriptShift2, supScriptShift3;
// Set supScriptShift{1,2,3} default from font
GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3);
// get sup script shift depending on current script level and display style
// Rule 18c, App. G, TeXbook
if (font->mScriptLevel == 0 &&
font->mMathDisplay == NS_MATHML_DISPLAYSTYLE_BLOCK &&
!NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
// Style D in TeXbook
supScriptShift = supScriptShift1;
} else if (NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
// Style C' in TeXbook = D',T',S',SS'
supScriptShift = supScriptShift3;
} else {
// everything else = T,S,SS
supScriptShift = supScriptShift2;
}
}
if (0 < aUserSupScriptShift) {
@ -384,17 +403,24 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
std::max(multiSubSize.Height(),
subScriptSize.Height() - subScriptSize.BlockStartAscent());
if (bmSubScript.width)
width = bmSubScript.width + aScriptSpace;
width = bmSubScript.width + scriptSpace;
rightBearing = bmSubScript.rightBearing;
if (tag == nsGkAtoms::msub_) {
boundingMetrics.rightBearing = boundingMetrics.width + rightBearing;
boundingMetrics.width += width;
// get min subscript shift limit from x-height
// = h(x) - 4/5 * sigma_5, Rule 18b, App. G, TeXbook
nscoord minShiftFromXHeight = (nscoord)
(bmSubScript.ascent - (4.0f/5.0f) * xHeight);
nscoord subscriptTopMax;
if (mathFont) {
subscriptTopMax =
mathFont->GetMathConstant(gfxFontEntry::SubscriptTopMax,
oneDevPixel);
} else {
// get min subscript shift limit from x-height
// = h(x) - 4/5 * sigma_5, Rule 18b, App. G, TeXbook
subscriptTopMax = NSToCoordRound((4.0f/5.0f) * xHeight);
}
nscoord minShiftFromXHeight = bmSubScript.ascent - subscriptTopMax;
maxSubScriptShift = std::max(trySubScriptShift,minShiftFromXHeight);
maxSubScriptShift = std::max(maxSubScriptShift, trySubScriptShift);
@ -408,10 +434,17 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
GetSupDropFromChild (supScriptFrame, supDrop);
// parameter u, Rule 18a, App. G, TeXbook
minSupScriptShift = bmBase.ascent - supDrop;
// get min supscript shift limit from x-height
// = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook
minShiftFromXHeight = NSToCoordRound
((bmSupScript.descent + (1.0f/4.0f) * xHeight));
nscoord superscriptBottomMin;
if (mathFont) {
superscriptBottomMin =
mathFont->GetMathConstant(gfxFontEntry::SuperscriptBottomMin,
oneDevPixel);
} else {
// get min supscript shift limit from x-height
// = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook
superscriptBottomMin = NSToCoordRound((1.0f / 4.0f) * xHeight);
}
minShiftFromXHeight = bmSupScript.descent + superscriptBottomMin;
trySupScriptShift = std::max(minSupScriptShift,
std::max(minShiftFromXHeight,
supScriptShift));
@ -425,7 +458,7 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
supScriptSize.Height() - supScriptSize.BlockStartAscent());
if (bmSupScript.width)
width = std::max(width, bmSupScript.width + aScriptSpace);
width = std::max(width, bmSupScript.width + scriptSpace);
if (!prescriptsFrame) { // we are still looping over base & postscripts
rightBearing = std::max(rightBearing,
@ -447,18 +480,37 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
// Rule 18e, App. G, TeXbook
if (tag == nsGkAtoms::mmultiscripts_ ||
tag == nsGkAtoms::msubsup_) {
nscoord subSuperscriptGapMin;
if (mathFont) {
subSuperscriptGapMin =
mathFont->GetMathConstant(gfxFontEntry::SubSuperscriptGapMin,
oneDevPixel);
} else {
nscoord ruleSize;
GetRuleThickness(aRenderingContext, fm, ruleSize);
subSuperscriptGapMin = 4 * ruleSize;
}
nscoord gap =
(trySupScriptShift - bmSupScript.descent) -
(bmSubScript.ascent - trySubScriptShift);
if (gap < 4.0f * ruleSize) {
// adjust trySubScriptShift to get a gap of (4.0 * ruleSize)
trySubScriptShift += NSToCoordRound ((4.0f * ruleSize) - gap);
if (gap < subSuperscriptGapMin) {
// adjust trySubScriptShift to get a gap of subSuperscriptGapMin
trySubScriptShift += subSuperscriptGapMin - gap;
}
// next we want to ensure that the bottom of the superscript
// will be > (4/5) * x-height above baseline
gap = NSToCoordRound ((4.0f/5.0f) * xHeight -
(trySupScriptShift - bmSupScript.descent));
// will be > superscriptBottomMaxWithSubscript
nscoord superscriptBottomMaxWithSubscript;
if (mathFont) {
superscriptBottomMaxWithSubscript = mathFont->
GetMathConstant(gfxFontEntry::SuperscriptBottomMaxWithSubscript,
oneDevPixel);
} else {
superscriptBottomMaxWithSubscript =
NSToCoordRound((4.0f / 5.0f) * xHeight);
}
gap = superscriptBottomMaxWithSubscript -
(trySupScriptShift - bmSupScript.descent);
if (gap > 0) {
trySupScriptShift += gap;
trySubScriptShift -= gap;
@ -628,7 +680,7 @@ nsMathMLmmultiscriptsFrame::PlaceMultiScript(nsPresContext* aPresContext,
x),
dy, 0);
}
dx += width + aScriptSpace;
dx += width + scriptSpace;
}
}
childFrame = childFrame->GetNextSibling();

View File

@ -37,8 +37,7 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
nsMathMLContainerFrame* aForFrame,
nscoord aUserSubScriptShift,
nscoord aUserSupScriptShift,
nscoord aScriptSpace);
nscoord aUserSupScriptShift);
uint8_t
ScriptIncrement(nsIFrame* aFrame) MOZ_OVERRIDE;

View File

@ -287,29 +287,25 @@ nsMathMLmunderoverFrame::Place(nsRenderingContext& aRenderingContext,
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
StyleFont()->mMathDisplay == NS_MATHML_DISPLAYSTYLE_INLINE) {
//place like sub sup or subsup
nscoord scriptSpace = nsPresContext::CSSPointsToAppUnits(0.5f);
if (tag == nsGkAtoms::munderover_) {
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
scriptSpace);
this, 0, 0);
} else if (tag == nsGkAtoms::munder_) {
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
scriptSpace);
this, 0, 0);
} else {
NS_ASSERTION(tag == nsGkAtoms::mover_, "mContent->Tag() not recognized");
return nsMathMLmmultiscriptsFrame::PlaceMultiScript(PresContext(),
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this, 0, 0,
scriptSpace);
this, 0, 0);
}
}