mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
[MATHML] Finally, here goes Shyjan Mahamud's TeX alignment rules. Part I: for superscript/subscript schematta
This commit is contained in:
parent
838f5bcd4f
commit
25576d106c
@ -333,6 +333,12 @@ struct nsEmbellishData {
|
||||
// a core <mo>) for which the movablelimits attribute is set to true
|
||||
#define NS_MATHML_MOVABLELIMITS 0x00000040
|
||||
|
||||
// This bit is used for visual debug. When set, the bounding box
|
||||
// of your frame is painted. You should therefore ensure that you
|
||||
// have properly filled your mReference and mBoundingMetrics in
|
||||
// Place().
|
||||
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x80000000
|
||||
|
||||
// Macros that retrieve those bits
|
||||
#define NS_MATHML_IS_DISPLAYSTYLE(_flags) \
|
||||
(NS_MATHML_DISPLAYSTYLE == ((_flags) & NS_MATHML_DISPLAYSTYLE))
|
||||
@ -355,6 +361,9 @@ struct nsEmbellishData {
|
||||
#define NS_MATHML_IS_MOVABLELIMITS(_flags) \
|
||||
(NS_MATHML_MOVABLELIMITS == ((_flags) & NS_MATHML_MOVABLELIMITS))
|
||||
|
||||
#define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
|
||||
(NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
|
||||
|
||||
// --------------
|
||||
// Bits used for the embellish flags -- these bits are set
|
||||
// in their relevant situation as they become available
|
||||
@ -405,4 +414,3 @@ struct nsEmbellishData {
|
||||
(NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
|
||||
|
||||
#endif /* nsIMathMLFrame_h___ */
|
||||
|
||||
|
@ -391,8 +391,8 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
||||
if (aContainerSize.height <= aDesiredStretchSize.height) {
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char later behaves like a normal char
|
||||
rv = aRenderingContext.GetBoundingMetrics(mData.GetUnicode(),
|
||||
PRUint32(mData.Length()),
|
||||
mBoundingMetrics);
|
||||
PRUint32(mData.Length()),
|
||||
mBoundingMetrics);
|
||||
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", mData[0], mData[0]&0x00FF); /*getchar();*/ return rv; }
|
||||
return NS_OK;
|
||||
}
|
||||
@ -467,6 +467,19 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
||||
nscoord a, d;
|
||||
h = w = a = d = 0;
|
||||
float flex[3] = {0.7f, 0.3f, 0.7f}; // XXX hack!
|
||||
|
||||
// get metrics data to be re-used later
|
||||
nsBoundingMetrics bmdata[4];
|
||||
for (i = 0; i < 4; i++) {
|
||||
ch = gMathMLCharGlyph[index+i];
|
||||
rv = aRenderingContext.GetBoundingMetrics(&ch, PRUint32(1), bm);
|
||||
if (NS_FAILED(rv)) {
|
||||
printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/
|
||||
return rv;
|
||||
}
|
||||
bmdata[i] = bm;
|
||||
}
|
||||
|
||||
if (aDirection == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
// default is to fill-up the area given to us
|
||||
width = aDesiredStretchSize.width;
|
||||
@ -475,9 +488,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
||||
descent = aContainerSize.descent;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ch = gMathMLCharGlyph[index+i];
|
||||
rv = aRenderingContext.GetBoundingMetrics(&ch, PRUint32(1), bm);
|
||||
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/ return rv; }
|
||||
bm = bmdata[i];
|
||||
if (w < bm.width) w = bm.width;
|
||||
if (i < 3) {
|
||||
h += nscoord(flex[i]*(bm.ascent+bm.descent)); // sum heights of the parts...
|
||||
@ -507,9 +518,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
||||
descent = aDesiredStretchSize.descent;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ch = gMathMLCharGlyph[index+i];
|
||||
rv = aRenderingContext.GetBoundingMetrics(&ch, PRUint32(1), bm);
|
||||
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/ return rv; }
|
||||
bm = bmdata[i];
|
||||
if (0 == i) bm0 = bm;
|
||||
if (a < bm.ascent) a = bm.ascent;
|
||||
if (d < bm.descent) d = bm.descent;
|
||||
@ -527,6 +536,8 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
||||
// ascent = a;
|
||||
// height = a + d;
|
||||
mBoundingMetrics.width = aContainerSize.width;
|
||||
mBoundingMetrics.leftBearing = 0;
|
||||
mBoundingMetrics.rightBearing = aContainerSize.width;
|
||||
} else { // sum of parts doesn't fit in the space... will use a single glyph
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char behaves like a normal char
|
||||
mBoundingMetrics = bm0;
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
GetBoundingMetrics(nsBoundingMetrics aBoundingMetrics) {
|
||||
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
|
||||
aBoundingMetrics = mBoundingMetrics;
|
||||
}
|
||||
|
||||
|
@ -176,40 +176,46 @@ nsMathMLContainerFrame::SetReference(const nsPoint& aReference)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// helper methods to facilitate getting/setting the bounding metrics
|
||||
nsresult
|
||||
nsMathMLContainerFrame::GetBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsBoundingMetrics& aBoundingMetrics)
|
||||
// helper method to facilitate getting the reflow and bounding metrics
|
||||
void
|
||||
nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsHTMLReflowMetrics& aReflowMetrics,
|
||||
nsBoundingMetrics& aBoundingMetrics)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "null arg");
|
||||
|
||||
// IMPORTANT: This function is only meant to be called in Place() methods
|
||||
// where it is assumed that the frame's rect is still acting as place holder
|
||||
// for the frame's ascent and descent information
|
||||
|
||||
nsRect aRect;
|
||||
aFrame->GetRect(aRect);
|
||||
aReflowMetrics.descent = aRect.x;
|
||||
aReflowMetrics.ascent = aRect.y;
|
||||
aReflowMetrics.width = aRect.width;
|
||||
aReflowMetrics.height = aRect.height;
|
||||
|
||||
aBoundingMetrics.Clear();
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = aFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
aMathMLFrame->GetBoundingMetrics(aBoundingMetrics);
|
||||
return NS_OK;
|
||||
#if 0
|
||||
nsFrame::ListTag(stdout, aFrame);
|
||||
printf(" subItalicCorrection:%d supItalicCorrection:%d\n",
|
||||
aBoundingMetrics.subItalicCorrection, aBoundingMetrics.supItalicCorrection);
|
||||
#endif
|
||||
}
|
||||
// if we reach here, aFrame is not a MathML frame, let the caller know that
|
||||
printf("GetBoundingMetrics() failed for: "); /* getchar(); */
|
||||
nsFrame::ListTag(stdout, aFrame);
|
||||
printf("\n");
|
||||
// NS_ASSERTION(0, "GetBoundingMetrics() failed!!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMathMLContainerFrame::SetBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsBoundingMetrics& aBoundingMetrics)
|
||||
{
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = aFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
aMathMLFrame->SetBoundingMetrics(aBoundingMetrics);
|
||||
return NS_OK;
|
||||
else { // aFrame is not a MathML frame, just return the reflow metrics
|
||||
aBoundingMetrics.descent = aReflowMetrics.descent;
|
||||
aBoundingMetrics.ascent = aReflowMetrics.ascent;
|
||||
aBoundingMetrics.width = aReflowMetrics.width;
|
||||
#if 0
|
||||
printf("GetBoundingMetrics() failed for: "); /* getchar(); */
|
||||
nsFrame::ListTag(stdout, aFrame);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
// if we reach here, aFrame is not a MathML frame, let the caller know that
|
||||
printf("SetBoundingMetrics() failed!! ...\n"); /* getchar(); */
|
||||
// NS_ASSERTION(0, "SetBoundingMetrics() failed!!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* /////////////
|
||||
@ -514,6 +520,29 @@ nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsMathMLContainerFrame::FindSmallestFontSizeFor(nsIFrame* aFrame)
|
||||
{
|
||||
nsStyleFont aFont;
|
||||
nsCOMPtr<nsIStyleContext> aStyleContext;
|
||||
aFrame->GetStyleContext(getter_AddRefs(aStyleContext));
|
||||
aStyleContext->GetStyle(eStyleStruct_Font, aFont);
|
||||
// PRInt32 fontSize = NSTwipsToFloorIntPoints(aFont.mFont.size);
|
||||
PRInt32 fontSize = aFont.mFont.size;
|
||||
|
||||
PRInt32 childSize;
|
||||
nsIFrame* childFrame;
|
||||
aFrame->FirstChild(nsnull, &childFrame);
|
||||
while (nsnull != childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
childSize = FindSmallestFontSizeFor(childFrame);
|
||||
if (fontSize > childSize) fontSize = childSize;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
// helper method to alter the style context
|
||||
// This method is used for switching the font to a subscript/superscript font in
|
||||
// mfrac, msub, msup, msubsup, munder, mover, munderover, mmultiscripts
|
||||
@ -544,6 +573,71 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
||||
|
||||
PRInt32 gap = childData.scriptLevel - mPresentationData.scriptLevel;
|
||||
if (0 != gap) {
|
||||
// We are about to change the font-size... We first see if we
|
||||
// are in the scope of a <mstyle> that tells us what to do.
|
||||
// This is one of the most obscure part to implement in the spec...
|
||||
/*
|
||||
The REC says:
|
||||
|
||||
Whenever the scriptlevel is changed, either automatically or by being
|
||||
explicitly incremented, decremented, or set, the current font size is
|
||||
multiplied by the value of scriptsizemultiplier to the power of the
|
||||
change in scriptlevel. For example, if scriptlevel is increased by 2,
|
||||
the font size is multiplied by scriptsizemultiplier twice in succession;
|
||||
if scriptlevel is explicitly set to 2 when it had been 3, the font size
|
||||
is divided by scriptsizemultiplier.
|
||||
|
||||
The default value of scriptsizemultiplier is less than one (in fact, it
|
||||
is approximately the square root of 1/2), resulting in a smaller font size
|
||||
with increasing scriptlevel. To prevent scripts from becoming unreadably
|
||||
small, the font size is never allowed to go below the value of
|
||||
scriptminsize as a result of a change to scriptlevel, though it can be
|
||||
set to a lower value using the fontsize attribute on <mstyle> or on
|
||||
token elements. If a change to scriptlevel would cause the font size to
|
||||
become lower than scriptminsize using the above formula, the font size
|
||||
is instead set equal to scriptminsize within the subexpression for which
|
||||
scriptlevel was changed.
|
||||
|
||||
In the syntax for scriptminsize, v-unit represents a unit of vertical
|
||||
length. The most common unit for specifying font sizes in typesetting
|
||||
is pt (points).
|
||||
*/
|
||||
|
||||
// default scriptsizemultiplier = 0.71
|
||||
// default scriptminsize = 8pt
|
||||
|
||||
// here we only consider scriptminsize, and use the default
|
||||
// smaller-font-size algorithm of the style system
|
||||
PRInt32 scriptminsize = NSIntPointsToTwips(8);
|
||||
|
||||
// see if the scriptminsize attribute is on <mstyle> that wraps us
|
||||
nsAutoString value;
|
||||
nsIFrame* mstyleFrame = mPresentationData.mstyle;
|
||||
if (mstyleFrame) {
|
||||
nsCOMPtr<nsIContent> mstyleContent;
|
||||
mstyleFrame->GetContent(getter_AddRefs(mstyleContent));
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mstyleContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::scriptminsize_, value))
|
||||
{
|
||||
PRInt32 errorCode;
|
||||
PRInt32 userValue = value.ToInteger(&errorCode);
|
||||
if (NS_SUCCEEDED(errorCode)) {
|
||||
// assume unit is point
|
||||
// XXX need consistent, default unit throughout the code
|
||||
scriptminsize = NSIntPointsToTwips(userValue);
|
||||
}
|
||||
else {
|
||||
// XXX TODO: try to see if it is a h/v-unit like 1ex, 2px, 1em
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get Nav's magic font scaler
|
||||
PRInt32 scaler;
|
||||
aPresContext->GetFontScaler(&scaler);
|
||||
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
|
||||
const nsFont& defaultFont = aPresContext->GetDefaultFontDeprecated();
|
||||
|
||||
nsCOMPtr<nsIContent> childContent;
|
||||
childFrame->GetContent(getter_AddRefs(childContent));
|
||||
|
||||
@ -555,13 +649,37 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
||||
nsIStyleContext* lastStyleContext = mStyleContext;
|
||||
nsCOMPtr<nsIStyleContext> newStyleContext;
|
||||
|
||||
// XXX seems not to decrease when the initail font-size is large (100pt)
|
||||
nsAutoString fontSize = (0 < gap)
|
||||
? ":-moz-math-font-size-smaller"
|
||||
: ":-moz-math-font-size-larger";
|
||||
nsCOMPtr<nsIAtom> fontAtom(getter_AddRefs(NS_NewAtom(fontSize)));
|
||||
if (0 > gap) gap = -gap; // absolute value
|
||||
|
||||
PRBool isSmaller = PR_TRUE;
|
||||
if (0 > gap) { isSmaller = PR_FALSE; gap = -gap; } // absolute value
|
||||
|
||||
PRInt32 smallestFontSize, smallestFontIndex;
|
||||
if (isSmaller) {
|
||||
// find the smallest font-size in this subtree
|
||||
smallestFontSize = FindSmallestFontSizeFor(childFrame);
|
||||
}
|
||||
|
||||
while (0 < gap--) {
|
||||
|
||||
if (isSmaller) {
|
||||
// look ahead for the next smallest font size that will be in the subtree
|
||||
smallestFontIndex = nsStyleUtil::FindNextSmallerFontSize(smallestFontSize, (PRInt32)defaultFont.size, scaleFactor);
|
||||
smallestFontSize = nsStyleUtil::CalcFontPointSize(smallestFontIndex, (PRInt32)defaultFont.size, scaleFactor);
|
||||
//printf("About to move to fontsize:%dpt(%dtwips)\n",
|
||||
//NSTwipsToFloorIntPoints(smallestFontSize), smallestFontSize);
|
||||
if (smallestFontSize < scriptminsize) {
|
||||
// don't bother doing any work
|
||||
//printf("..... stopping ......\n");
|
||||
// XXX there should be a mechanism so that we never try this subtree again
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aPresContext->ResolvePseudoStyleContextFor(childContent, fontAtom, lastStyleContext,
|
||||
PR_FALSE, getter_AddRefs(newStyleContext));
|
||||
if (newStyleContext && newStyleContext.get() != lastStyleContext) {
|
||||
@ -620,7 +738,43 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
||||
* Frame construction
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsFramePaintLayer aWhichLayer)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = nsHTMLContainerFrame::Paint(aPresContext,
|
||||
aRenderingContext,
|
||||
aDirtyRect,
|
||||
aWhichLayer);
|
||||
#ifdef SHOW_BOUNDING_BOX
|
||||
// for visual debug
|
||||
// ----------------
|
||||
// if you want to see your bounding box, make sure to properly fill
|
||||
// your mBoundingMetrics and mReference point, and set
|
||||
// mPresentationData.flags |= NS_MATHML_BOUNDING_METRICS
|
||||
// in the Init() of your sub-class
|
||||
|
||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
|
||||
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
|
||||
{
|
||||
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
||||
|
||||
nscoord x = mReference.x + mBoundingMetrics.leftBearing;
|
||||
nscoord y = mReference.y;
|
||||
nscoord w = mBoundingMetrics.rightBearing - mBoundingMetrics.leftBearing;
|
||||
nscoord h = mBoundingMetrics.ascent + mBoundingMetrics.descent;
|
||||
|
||||
aRenderingContext.DrawRect(x,y,w,h);
|
||||
}
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
@ -847,7 +1001,7 @@ nsMathMLContainerFrame::ReflowTokenFor(nsIFrame* aFrame,
|
||||
|
||||
// helper function to place token elements
|
||||
// mBoundingMetrics is computed at the ReflowToken pass, it is
|
||||
// not computed here because if our children may be text frames that
|
||||
// not computed here because our children may be text frames that
|
||||
// do not implement the GetBoundingMetrics() interface.
|
||||
nsresult
|
||||
nsMathMLContainerFrame::PlaceTokenFor(nsIFrame* aFrame,
|
||||
@ -893,6 +1047,11 @@ nsMathMLContainerFrame::PlaceTokenFor(nsIFrame* aFrame,
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
nsBoundingMetrics bm;
|
||||
NS_STATIC_CAST(nsMathMLContainerFrame*,
|
||||
aFrame)->GetBoundingMetrics(bm);
|
||||
NS_STATIC_CAST(nsMathMLContainerFrame*,
|
||||
aFrame)->SetReference(nsPoint(0,aDesiredSize.ascent-bm.ascent));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1087,23 +1246,18 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
PRInt32 count = 0;
|
||||
nsRect rect;
|
||||
nsBoundingMetrics bm;
|
||||
nsHTMLReflowMetrics childSize(nsnull);
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
childFrame->GetRect(rect);
|
||||
GetReflowAndBoundingMetricsFor(childFrame, childSize, bm);
|
||||
|
||||
aDesiredSize.width += rect.width;
|
||||
if (aDesiredSize.descent < rect.x) aDesiredSize.descent = rect.x;
|
||||
if (aDesiredSize.ascent < rect.y) aDesiredSize.ascent = rect.y;
|
||||
aDesiredSize.width += childSize.width;
|
||||
if (aDesiredSize.descent < childSize.descent) aDesiredSize.descent = childSize.descent;
|
||||
if (aDesiredSize.ascent < childSize.ascent) aDesiredSize.ascent = childSize.ascent;
|
||||
|
||||
// Compute and cache our bounding metrics
|
||||
nsBoundingMetrics bm;
|
||||
if (NS_FAILED(GetBoundingMetricsFor(childFrame, bm))) {
|
||||
bm.ascent = rect.y;
|
||||
bm.descent = -rect.x;
|
||||
bm.width = rect.width;
|
||||
}
|
||||
if (0 == count)
|
||||
mBoundingMetrics = bm;
|
||||
else
|
||||
@ -1116,13 +1270,14 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nsRect rect;
|
||||
|
||||
nscoord dy;
|
||||
nscoord dx = 0;
|
||||
childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
childFrame->GetRect(rect);
|
||||
|
||||
nsHTMLReflowMetrics childSize(nsnull);
|
||||
childSize.width = rect.width;
|
||||
childSize.height = rect.height;
|
||||
|
||||
@ -1134,6 +1289,9 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,12 @@ public:
|
||||
return nsHTMLContainerFrame::DidReflow(aPresContext, aStatus);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nsFramePaintLayer aWhichLayer);
|
||||
|
||||
// helper function to reflow token elements
|
||||
static nsresult
|
||||
ReflowTokenFor(nsIFrame* aFrame,
|
||||
@ -223,6 +229,12 @@ public:
|
||||
NS_IMETHOD
|
||||
InsertScriptLevelStyleContext(nsIPresContext* aPresContext);
|
||||
|
||||
// helper to find the smallest font-size on a tree so that we don't insert
|
||||
// scriptlevel fonts that lead to unreadable results on deeper nodes below us.
|
||||
// XXX expensive recursive function, need something better, with cache
|
||||
static PRInt32
|
||||
FindSmallestFontSizeFor(nsIFrame* aFrame);
|
||||
|
||||
// helper to check if a frame is an embellished container
|
||||
static PRBool
|
||||
IsEmbellishOperator(nsIFrame* aFrame);
|
||||
@ -230,19 +242,19 @@ public:
|
||||
// helper methods for processing empty MathML frames (with whitespace only)
|
||||
static PRBool
|
||||
IsOnlyWhitespace(nsIFrame* aFrame);
|
||||
|
||||
|
||||
static void
|
||||
ReflowEmptyChild(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
// helper methods to facilitate getting/setting the bounding metrics
|
||||
static nsresult
|
||||
GetBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsBoundingMetrics& aBoundingMetrics);
|
||||
|
||||
static nsresult
|
||||
SetBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsBoundingMetrics& aBoundingMetrics);
|
||||
// helper method to facilitate getting the reflow and bounding metrics
|
||||
// IMPORTANT: This function is only meant to be called in Place() methods
|
||||
// where it is assumed that the frame's rect is still acting as place holder
|
||||
// for the frame's ascent and descent information
|
||||
static void
|
||||
GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
|
||||
nsHTMLReflowMetrics& aReflowMetrics,
|
||||
nsBoundingMetrics& aBoundingMetrics);
|
||||
|
||||
// helper methods for getting sup/subdrop's from a child
|
||||
static void
|
||||
@ -297,6 +309,7 @@ public:
|
||||
}
|
||||
|
||||
// these are TeX specific params not found in ordinary fonts
|
||||
#if 0
|
||||
static void
|
||||
GetSubDrop (nsIFontMetrics *fm, nscoord& aSubDrop)
|
||||
{
|
||||
@ -312,6 +325,124 @@ public:
|
||||
fm->GetXHeight (xHeight);
|
||||
aSupDrop = NSToCoordRound(0.3f * xHeight);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
GetSubDrop (nsIFontMetrics *fm, nscoord& aSubDrop)
|
||||
{
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSubDrop = NSToCoordRound(50.000f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSupDrop (nsIFontMetrics *fm, nscoord& aSupDrop)
|
||||
{
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSupDrop = NSToCoordRound(386.108f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSubShifts (nsIFontMetrics *fm,
|
||||
nscoord& aSubShift1,
|
||||
nscoord& aSubShift2)
|
||||
{
|
||||
nscoord xHeight = 0;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSubShift1 = NSToCoordRound (150.000f/430.556f * xHeight);
|
||||
aSubShift2 = NSToCoordRound (247.217f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSupShifts (nsIFontMetrics *fm,
|
||||
nscoord& aSupShift1,
|
||||
nscoord& aSupShift2,
|
||||
nscoord& aSupShift3)
|
||||
{
|
||||
nscoord xHeight = 0;
|
||||
fm->GetXHeight (xHeight);
|
||||
aSupShift1 = NSToCoordRound (412.892f/430.556f * xHeight);
|
||||
aSupShift2 = NSToCoordRound (362.892f/430.556f * xHeight);
|
||||
aSupShift3 = NSToCoordRound (288.889f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetNumShifts (nsIFontMetrics *fm,
|
||||
nscoord& numShift1,
|
||||
nscoord& numShift2,
|
||||
nscoord& numShift3)
|
||||
{
|
||||
nscoord xHeight = 0;
|
||||
fm->GetXHeight (xHeight);
|
||||
numShift1 = NSToCoordRound (676.508f/430.556f * xHeight);
|
||||
numShift2 = NSToCoordRound (393.732f/430.556f * xHeight);
|
||||
numShift3 = NSToCoordRound (443.731f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetDenShifts (nsIFontMetrics *fm,
|
||||
nscoord& denShift1,
|
||||
nscoord& denShift2)
|
||||
{
|
||||
nscoord xHeight = 0;
|
||||
fm->GetXHeight (xHeight);
|
||||
denShift1 = NSToCoordRound (685.951f/430.556f * xHeight);
|
||||
denShift2 = NSToCoordRound (344.841f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetAxisHeight (nsIFontMetrics *fm,
|
||||
nscoord& axisHeight)
|
||||
{
|
||||
fm->GetXHeight (axisHeight);
|
||||
axisHeight = NSToCoordRound (250.000f/430.556f * axisHeight);
|
||||
}
|
||||
|
||||
static void
|
||||
GetBigOpSpacings (nsIFontMetrics *fm,
|
||||
nscoord& bigOpSpacing1,
|
||||
nscoord& bigOpSpacing2,
|
||||
nscoord& bigOpSpacing3,
|
||||
nscoord& bigOpSpacing4,
|
||||
nscoord& bigOpSpacing5)
|
||||
{
|
||||
nscoord xHeight = 0;
|
||||
fm->GetXHeight (xHeight);
|
||||
bigOpSpacing1 = NSToCoordRound (111.111f/430.556f * xHeight);
|
||||
bigOpSpacing2 = NSToCoordRound (166.667f/430.556f * xHeight);
|
||||
bigOpSpacing3 = NSToCoordRound (200.000f/430.556f * xHeight);
|
||||
bigOpSpacing4 = NSToCoordRound (600.000f/430.556f * xHeight);
|
||||
bigOpSpacing5 = NSToCoordRound (100.000f/430.556f * xHeight);
|
||||
}
|
||||
|
||||
#if 0
|
||||
NS_IMETHOD
|
||||
GetItalicCorrection (nscoord& italicCorrection)
|
||||
{
|
||||
italicCorrection = mItalicCorrection;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
SetItalicCorrection (nscoord italicCorrection)
|
||||
{
|
||||
mItalicCorrection = italicCorrection;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHOD
|
||||
GetRuleThickness (nsIFontMetrics *fm, nscoord& ruleThickness)
|
||||
{
|
||||
nscoord xHeight;
|
||||
fm->GetXHeight (xHeight);
|
||||
ruleThickness = NSToCoordRound (40.000f/430.556f * xHeight);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -257,9 +257,9 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// XXX Fix me!
|
||||
mBoundingMetrics.ascent = aDesiredSize.ascent;
|
||||
mBoundingMetrics.descent = -aDesiredSize.descent;
|
||||
mBoundingMetrics.width = aDesiredSize.width;
|
||||
mBoundingMetrics.ascent = aDesiredSize.ascent;
|
||||
mBoundingMetrics.descent = aDesiredSize.descent;
|
||||
mBoundingMetrics.width = aDesiredSize.width;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ nsMathMLmmultiscriptsFrame::Init(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -118,7 +119,6 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
////////////////////////////////////
|
||||
// Get the children's desired sizes
|
||||
|
||||
nscoord italicCorrection = 0;
|
||||
nscoord minShiftFromXHeight, aSubDrop, aSupDrop;
|
||||
|
||||
////////////////////////////////////////
|
||||
@ -134,9 +134,9 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetXHeight (xHeight);
|
||||
|
||||
nscoord aRuleSize, dummy;
|
||||
nscoord aRuleSize = 0;
|
||||
// XXX need to do update this ...
|
||||
fm->GetStrikeout (dummy, aRuleSize);
|
||||
GetRuleThickness (fm, aRuleSize);
|
||||
|
||||
/////////////////////////////////////
|
||||
// first the shift for the subscript
|
||||
@ -201,7 +201,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
// Get the children's sizes
|
||||
////////////////////////////////////
|
||||
|
||||
nscoord width = 0;
|
||||
nscoord width = 0, prescriptsWidth = 0, rightBearing = 0;
|
||||
nsIFrame* mprescriptsFrame = nsnull; // frame of <mprescripts/>, if there.
|
||||
PRBool isSubScript = PR_FALSE;
|
||||
PRBool isSubScriptPresent = PR_TRUE;
|
||||
@ -212,7 +212,6 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
nscoord maxSubScriptShift = aSubScriptShift;
|
||||
nscoord maxSupScriptShift = aSupScriptShift;
|
||||
PRInt32 count = 0;
|
||||
nsRect aRect;
|
||||
nsHTMLReflowMetrics baseSize (nsnull);
|
||||
nsHTMLReflowMetrics subScriptSize (nsnull);
|
||||
nsHTMLReflowMetrics supScriptSize (nsnull);
|
||||
@ -220,8 +219,14 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIFrame* subScriptFrame;
|
||||
nsIFrame* supScriptFrame;
|
||||
|
||||
PRBool firstPrescriptsPair = PR_FALSE;
|
||||
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
|
||||
|
||||
// XXX is there an NSPR macro for int_max ???
|
||||
aDesiredSize.ascent = aDesiredSize.descent = -100000;
|
||||
mBoundingMetrics.ascent = mBoundingMetrics.descent = -10000000;
|
||||
mBoundingMetrics.width = 0;
|
||||
|
||||
aDesiredSize.ascent = aDesiredSize.descent = -10000000;
|
||||
aDesiredSize.width = aDesiredSize.height = 0;
|
||||
|
||||
nsIFrame* aChildFrame = mFrames.FirstChild();
|
||||
@ -235,32 +240,36 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
|
||||
if (childTag.get() == nsMathMLAtoms::mprescripts_) {
|
||||
mprescriptsFrame = aChildFrame;
|
||||
firstPrescriptsPair = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
|
||||
if (childTag.get() == nsMathMLAtoms::none_) {
|
||||
// we need to record the presence of none tag explicitly
|
||||
// for correct negotiation between sup/sub shifts later
|
||||
if (isSubScript) {
|
||||
isSubScriptPresent = PR_FALSE;
|
||||
bmSubScript.Clear();
|
||||
bmSubScript.leftBearing = 10000000;
|
||||
}
|
||||
else {
|
||||
isSupScriptPresent = PR_FALSE;
|
||||
bmSupScript.Clear();
|
||||
bmSupScript.leftBearing = 10000000;
|
||||
}
|
||||
aRect = nsRect (0, 0, 0, 0);
|
||||
}
|
||||
else {
|
||||
aChildFrame->GetRect(aRect);
|
||||
}
|
||||
|
||||
if (0 == count) {
|
||||
// base
|
||||
baseFrame = aChildFrame;
|
||||
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
|
||||
baseSize.width = aRect.width;
|
||||
baseSize.height = aRect.height;
|
||||
// we update aDesiredSize.{ascent,descent} with that
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
|
||||
// we update mBoundingMetrics.{ascent,descent} with that
|
||||
// of the baseFrame only after processing all the sup/sub pairs
|
||||
// XXX need italic correction here
|
||||
aDesiredSize.width = aRect.width + italicCorrection;
|
||||
// XXX need italic correction only *if* there are postscripts ?
|
||||
mBoundingMetrics.width = bmBase.width + bmBase.supItalicCorrection;
|
||||
mBoundingMetrics.rightBearing = bmBase.rightBearing;
|
||||
mBoundingMetrics.leftBearing = bmBase.leftBearing; // until overwritten
|
||||
}
|
||||
else {
|
||||
// super/subscript block
|
||||
@ -268,54 +277,66 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
if (isSubScriptPresent) {
|
||||
// subscript
|
||||
subScriptFrame = aChildFrame;
|
||||
subScriptSize.descent = aRect.x;
|
||||
subScriptSize.ascent = aRect.y;
|
||||
subScriptSize.width = aRect.width;
|
||||
subScriptSize.height = aRect.height;
|
||||
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
|
||||
// get the subdrop from the subscript font
|
||||
GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop);
|
||||
// parameter v, Rule 18a, App. G, TeXbook
|
||||
minSubScriptShift = baseSize.descent + aSubDrop;
|
||||
minSubScriptShift = bmBase.descent + aSubDrop;
|
||||
trySubScriptShift = PR_MAX(minSubScriptShift,aSubScriptShift);
|
||||
mBoundingMetrics.descent =
|
||||
PR_MAX(mBoundingMetrics.descent,bmSubScript.descent);
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(aDesiredSize.descent,subScriptSize.descent);
|
||||
width = subScriptSize.width + mScriptSpace;
|
||||
PR_MAX(aDesiredSize.descent,subScriptSize.ascent);
|
||||
width = bmSubScript.width + mScriptSpace;
|
||||
rightBearing = bmSubScript.rightBearing + mScriptSpace;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isSupScriptPresent) {
|
||||
// supscript
|
||||
supScriptFrame = aChildFrame;
|
||||
supScriptSize.descent = aRect.x;
|
||||
supScriptSize.ascent = aRect.y;
|
||||
supScriptSize.width = aRect.width;
|
||||
supScriptSize.height = aRect.height;
|
||||
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
|
||||
// get the supdrop from the supscript font
|
||||
GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop);
|
||||
// parameter u, Rule 18a, App. G, TeXbook
|
||||
minSupScriptShift = baseSize.ascent - aSupDrop;
|
||||
minSupScriptShift = bmBase.ascent - aSupDrop;
|
||||
// get min supscript shift limit from x-height
|
||||
// = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook
|
||||
minShiftFromXHeight = NSToCoordRound
|
||||
((supScriptSize.descent + (1.0f/4.0f) * xHeight));
|
||||
((bmSupScript.descent + (1.0f/4.0f) * xHeight));
|
||||
trySupScriptShift =
|
||||
PR_MAX(minSupScriptShift,PR_MAX(minShiftFromXHeight,aSupScriptShift));
|
||||
mBoundingMetrics.ascent =
|
||||
PR_MAX(mBoundingMetrics.ascent,bmSupScript.ascent);
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(aDesiredSize.ascent,supScriptSize.ascent);
|
||||
width = PR_MAX(width, supScriptSize.width + mScriptSpace);
|
||||
width = PR_MAX(width, bmSupScript.width + mScriptSpace);
|
||||
rightBearing = PR_MAX(rightBearing, bmSupScript.rightBearing + mScriptSpace);
|
||||
}
|
||||
|
||||
NS_ASSERTION((isSubScriptPresent || isSupScriptPresent),"mmultiscripts : both sup/subscripts are absent");
|
||||
aDesiredSize.width += width;
|
||||
width = 0;
|
||||
|
||||
|
||||
if (!mprescriptsFrame) { // we are still looping over base & postscripts
|
||||
mBoundingMetrics.rightBearing = mBoundingMetrics.width + rightBearing;
|
||||
mBoundingMetrics.width += width;
|
||||
}
|
||||
else {
|
||||
prescriptsWidth += width;
|
||||
if (firstPrescriptsPair) {
|
||||
firstPrescriptsPair = PR_FALSE;
|
||||
mBoundingMetrics.leftBearing =
|
||||
PR_MIN(bmSubScript.leftBearing, bmSupScript.leftBearing);
|
||||
}
|
||||
}
|
||||
width = rightBearing = 0;
|
||||
|
||||
if (isSubScriptPresent && isSupScriptPresent) {
|
||||
// negotiate between the various shifts so that
|
||||
// there is enough gap between the sup and subscripts
|
||||
// Rule 18e, App. G, TeXbook
|
||||
nscoord gap =
|
||||
(trySupScriptShift - supScriptSize.descent) -
|
||||
(subScriptSize.ascent - trySubScriptShift);
|
||||
(trySupScriptShift - bmSupScript.descent) -
|
||||
(bmSubScript.ascent - trySubScriptShift);
|
||||
if (gap < 4.0f * aRuleSize) {
|
||||
// adjust trySubScriptShift to get a gap of (4.0 * aRuleSize)
|
||||
trySubScriptShift += NSToCoordRound ((4.0f * aRuleSize) - gap);
|
||||
@ -324,7 +345,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
// 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 - supScriptSize.descent));
|
||||
(trySupScriptShift - bmSupScript.descent));
|
||||
if (gap > 0.0f) {
|
||||
trySupScriptShift += gap;
|
||||
trySubScriptShift -= gap;
|
||||
@ -348,13 +369,28 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
rv = aChildFrame->GetNextSibling(&aChildFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
// we left out base during our bounding box updates, so ...
|
||||
|
||||
// we left out the width of prescripts, so ...
|
||||
mBoundingMetrics.rightBearing += prescriptsWidth;
|
||||
mBoundingMetrics.width += prescriptsWidth;
|
||||
|
||||
// we left out the base during our bounding box updates, so ...
|
||||
mBoundingMetrics.ascent =
|
||||
PR_MAX(mBoundingMetrics.ascent+maxSupScriptShift,bmBase.ascent);
|
||||
mBoundingMetrics.descent =
|
||||
PR_MAX(mBoundingMetrics.descent+maxSubScriptShift,bmBase.descent);
|
||||
|
||||
// get the reflow metrics ...
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(aDesiredSize.ascent+maxSupScriptShift,baseSize.ascent);
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(aDesiredSize.descent+maxSubScriptShift,baseSize.descent);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
aDesiredSize.width = mBoundingMetrics.width;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
@ -364,6 +400,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx = 0, dy = 0;
|
||||
nsRect aRect;
|
||||
|
||||
count = 0;
|
||||
aChildFrame = mprescriptsFrame;
|
||||
@ -371,9 +408,10 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
if (nsnull == aChildFrame) { // end of prescripts,
|
||||
// place the base ...
|
||||
aChildFrame = baseFrame;
|
||||
dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
|
||||
dx += baseSize.width + italicCorrection;
|
||||
// dy = mBoundingMetrics.ascent - bmBase.ascent;
|
||||
dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
|
||||
dx += baseSize.width + bmBase.supItalicCorrection;
|
||||
}
|
||||
else if (mprescriptsFrame != aChildFrame) {
|
||||
// process each sup/sub pair
|
||||
@ -386,7 +424,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
supScriptFrame = aChildFrame;
|
||||
count = 0;
|
||||
|
||||
// get the bounding boxes of sup/subscripts stored in their rects
|
||||
// get the ascent/descent of sup/subscripts stored in their rects
|
||||
// rect.x = descent, rect.y = ascent
|
||||
subScriptFrame->GetRect (aRect);
|
||||
subScriptSize.ascent = aRect.y;
|
||||
@ -401,25 +439,30 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
// XXX should we really center the boxes
|
||||
// XXX i'm leaving it as left-justified
|
||||
// XXX which is consistent with what's done for <msubsup>
|
||||
|
||||
// reverting to center. It looks much nicer and adds a bit
|
||||
// of variety to the engine. At least we have two functions
|
||||
// doing two different things.
|
||||
|
||||
width = PR_MAX(subScriptSize.width, supScriptSize.width);
|
||||
|
||||
dy = aDesiredSize.ascent -
|
||||
subScriptSize.ascent +
|
||||
maxSubScriptShift;
|
||||
FinishReflowChild (subScriptFrame, aPresContext,
|
||||
subScriptSize, dx, dy, 0);
|
||||
FinishReflowChild (subScriptFrame, aPresContext, subScriptSize,
|
||||
dx + (width-subScriptSize.width)/2, dy, 0);
|
||||
|
||||
dy = aDesiredSize.ascent -
|
||||
supScriptSize.ascent -
|
||||
maxSupScriptShift;
|
||||
FinishReflowChild (supScriptFrame, aPresContext,
|
||||
supScriptSize, dx, dy, 0);
|
||||
FinishReflowChild (supScriptFrame, aPresContext, supScriptSize,
|
||||
dx + (width-supScriptSize.width)/2, dy, 0);
|
||||
|
||||
width = mScriptSpace +
|
||||
PR_MAX(subScriptSize.width, supScriptSize.width);
|
||||
dx += width;
|
||||
}
|
||||
dx += mScriptSpace + width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rv = aChildFrame->GetNextSibling(&aChildFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
} while (mprescriptsFrame != aChildFrame);
|
||||
|
@ -119,6 +119,19 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
|
||||
rv = mMathMLChar.Paint(aPresContext,
|
||||
aRenderingContext,
|
||||
mStyleContext);
|
||||
#ifdef SHOW_BOUNDING_BOX
|
||||
// for visual debug
|
||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
|
||||
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
|
||||
{
|
||||
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
||||
nscoord x = mReference.x + mBoundingMetrics.leftBearing;
|
||||
nscoord y = mReference.y;
|
||||
nscoord w = mBoundingMetrics.rightBearing - mBoundingMetrics.leftBearing;
|
||||
nscoord h = mBoundingMetrics.ascent + mBoundingMetrics.descent;
|
||||
aRenderingContext.DrawRect(x,y,w,h);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else { // let the base class worry about the painting
|
||||
rv = nsMathMLContainerFrame::Paint(aPresContext,
|
||||
@ -144,6 +157,7 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
|
||||
mLeftSpace = 0.0f; // .27777f;
|
||||
mRightSpace = 0.0f; // .27777f;
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -487,10 +501,6 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
||||
if (old == aDesiredStretchSize) { // hasn't changed !
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
|
||||
}
|
||||
else {
|
||||
// update our bounding metrics... it becomes that of our MathML char
|
||||
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
/////////
|
||||
@ -499,7 +509,9 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
||||
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
// The rendering will be handled by our MathML char
|
||||
mMathMLChar.SetRect(nsRect(0, 0, aDesiredStretchSize.width,
|
||||
aDesiredStretchSize.height));
|
||||
aDesiredStretchSize.height));
|
||||
// update our bounding metrics... it becomes that of our MathML char
|
||||
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
|
||||
}
|
||||
else {
|
||||
nsHTMLReflowMetrics aReflowMetrics(nsnull);
|
||||
@ -514,6 +526,9 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
||||
aDesiredStretchSize.leftSpace = mLeftSpace;
|
||||
aDesiredStretchSize.rightSpace = mRightSpace;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
|
||||
|
||||
// Before we leave... there is a last item in the check-list:
|
||||
// If our parent is not embellished, it means we are the outermost embellished
|
||||
// container and so we put the spacing, otherwise we don't include the spacing,
|
||||
@ -532,6 +547,8 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
||||
if (0 == dx) return NS_OK;
|
||||
|
||||
// adjust the offsets
|
||||
mReference.x = dx;
|
||||
|
||||
nsRect rect;
|
||||
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
mMathMLChar.GetRect(rect);
|
||||
|
@ -268,9 +268,9 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// XXX Fix me!
|
||||
mBoundingMetrics.ascent = aDesiredSize.ascent;
|
||||
mBoundingMetrics.descent = -aDesiredSize.descent;
|
||||
mBoundingMetrics.width = aDesiredSize.width;
|
||||
mBoundingMetrics.ascent = aDesiredSize.ascent;
|
||||
mBoundingMetrics.descent = aDesiredSize.descent;
|
||||
mBoundingMetrics.width = aDesiredSize.width;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ nsMathMLmsubFrame::Init(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -108,7 +109,6 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
||||
// Get the children's desired sizes
|
||||
|
||||
PRInt32 count = 0;
|
||||
nsRect aRect;
|
||||
nsHTMLReflowMetrics baseSize (nsnull);
|
||||
nsHTMLReflowMetrics subScriptSize (nsnull);
|
||||
nsIFrame* baseFrame;
|
||||
@ -116,39 +116,26 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
||||
// parameter v, Rule 18a, Appendix G of the TeXbook
|
||||
nscoord minSubScriptShift = 0;
|
||||
|
||||
nsBoundingMetrics baseBounds, subScriptBounds;
|
||||
nsBoundingMetrics bmBase, bmSubScript;
|
||||
|
||||
nsIFrame* aChildFrame = mFrames.FirstChild();
|
||||
while (nsnull != aChildFrame)
|
||||
{
|
||||
if (!IsOnlyWhitespace(aChildFrame)) {
|
||||
aChildFrame->GetRect(aRect);
|
||||
if (0 == count) {
|
||||
// base
|
||||
baseFrame = aChildFrame;
|
||||
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
|
||||
baseSize.width = aRect.width; baseSize.height = aRect.height;
|
||||
if (NS_FAILED(GetBoundingMetricsFor(baseFrame, baseBounds))) {
|
||||
baseBounds.descent = baseSize.descent;
|
||||
baseBounds.ascent = baseSize.ascent;
|
||||
baseBounds.width = baseSize.width;
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
}
|
||||
else if (1 == count) {
|
||||
// subscript
|
||||
subScriptFrame = aChildFrame;
|
||||
subScriptSize.descent = aRect.x; subScriptSize.ascent = aRect.y;
|
||||
subScriptSize.width = aRect.width; subScriptSize.height = aRect.height;
|
||||
if (NS_FAILED(GetBoundingMetricsFor(subScriptFrame, subScriptBounds))) {
|
||||
subScriptBounds.descent = subScriptSize.descent;
|
||||
subScriptBounds.ascent = subScriptSize.ascent;
|
||||
subScriptBounds.width = subScriptSize.width;
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
|
||||
// get the subdrop from the subscript font
|
||||
nscoord aSubDrop;
|
||||
GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop);
|
||||
// parameter v, Rule 18a, App. G, TeXbook
|
||||
minSubScriptShift = baseSize.descent + aSubDrop;
|
||||
minSubScriptShift = bmBase.descent + aSubDrop;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION((count < 2),"nsMathMLmsubFrame : invalid markup");
|
||||
@ -167,12 +154,17 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
||||
// = h(x) - 4/5 * sigma_5, Rule 18b, App. G, TeXbook
|
||||
nscoord xHeight = 0;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
// const nsStyleFont* aFont =
|
||||
// (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
const nsStyleFont* aFont;
|
||||
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)aFont);
|
||||
|
||||
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetXHeight (xHeight);
|
||||
nscoord minShiftFromXHeight = (nscoord)
|
||||
(subScriptSize.ascent - (4.0f/5.0f) * xHeight);
|
||||
(bmSubScript.ascent - (4.0f/5.0f) * xHeight);
|
||||
|
||||
// aSubScriptShift
|
||||
// = minimum amount to shift the subscript down set by user or from the font
|
||||
@ -181,51 +173,55 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
||||
nscoord aSubScriptShift, dummy;
|
||||
// get aSubScriptShift default from font
|
||||
GetSubScriptShifts (fm, aSubScriptShift, dummy);
|
||||
if (mUserSetFlag == PR_TRUE) {
|
||||
if (mUserSetFlag) {
|
||||
// the user has set the subscriptshift attribute
|
||||
aSubScriptShift = NSToCoordRound(mSubScriptShiftFactor * xHeight);
|
||||
//XXX shouldn't this be
|
||||
// aSubScriptShift =
|
||||
// PR_MAX(aSubScriptShift, NSToCoordRound(mSubScriptShiftFactor * xHeight));
|
||||
}
|
||||
|
||||
// get actual subscriptshift to be used
|
||||
// Rule 18b, App. G, TeXbook
|
||||
nscoord actualSubScriptShift =
|
||||
PR_MAX(minSubScriptShift,PR_MAX(aSubScriptShift,minShiftFromXHeight));
|
||||
#if 0
|
||||
// get bounding box for base + subscript
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseSize.ascent,(subScriptSize.ascent-actualSubScriptShift));
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.descent,(actualSubScriptShift+subScriptSize.descent));
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
// add mScriptSpace between base and subscript
|
||||
aDesiredSize.width = baseSize.width + mScriptSpace + subScriptSize.width;
|
||||
#endif
|
||||
|
||||
mBoundingMetrics.ascent =
|
||||
PR_MAX(baseBounds.ascent, subScriptBounds.ascent - actualSubScriptShift);
|
||||
PR_MAX(bmBase.ascent, bmSubScript.ascent - actualSubScriptShift);
|
||||
mBoundingMetrics.descent =
|
||||
PR_MAX(baseBounds.descent, subScriptBounds.descent + actualSubScriptShift);
|
||||
PR_MAX(bmBase.descent, bmSubScript.descent + actualSubScriptShift);
|
||||
// add mScriptSpace between base and supscript
|
||||
mBoundingMetrics.width = baseBounds.width + mScriptSpace + subScriptBounds.width;
|
||||
mBoundingMetrics.width = bmBase.width + mScriptSpace + bmSubScript.width;
|
||||
|
||||
// to be simplified
|
||||
nscoord dyBase = mBoundingMetrics.ascent - bmBase.ascent;
|
||||
nscoord dySubScript = mBoundingMetrics.ascent - bmSubScript.ascent + actualSubScriptShift;
|
||||
|
||||
nscoord baseTop = mBoundingMetrics.ascent - dyBase - bmBase.ascent + baseSize.ascent;
|
||||
nscoord subScriptTop = mBoundingMetrics.ascent - dySubScript - bmSubScript.ascent + subScriptSize.ascent;
|
||||
|
||||
aDesiredSize.ascent = PR_MAX(baseTop, subScriptTop);
|
||||
aDesiredSize.descent = PR_MAX(baseSize.height-baseTop, subScriptSize.height-subScriptTop);
|
||||
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseSize.ascent, subScriptSize.ascent - actualSubScriptShift);
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.descent, subScriptSize.descent + actualSubScriptShift);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
aDesiredSize.width = baseSize.width + mScriptSpace + subScriptSize.width;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
|
||||
mBoundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
mBoundingMetrics.rightBearing = baseSize.width + mScriptSpace + bmSubScript.rightBearing;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
// now place the base ...
|
||||
dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
dx = 0; dy = aDesiredSize.ascent - baseTop;
|
||||
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
|
||||
// ... and subscript
|
||||
dx = baseSize.width;
|
||||
dy = aDesiredSize.ascent - subScriptSize.ascent + actualSubScriptShift;
|
||||
dy = aDesiredSize.ascent - subScriptTop;
|
||||
FinishReflowChild (subScriptFrame, aPresContext, subScriptSize, dx, dy, 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,7 @@ nsMathMLmsubsupFrame::Init(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -118,7 +119,6 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// Get the children's desired sizes
|
||||
|
||||
PRInt32 count = 0;
|
||||
nsRect aRect;
|
||||
nsHTMLReflowMetrics baseSize (nsnull);
|
||||
nsHTMLReflowMetrics subScriptSize (nsnull);
|
||||
nsHTMLReflowMetrics supScriptSize (nsnull);
|
||||
@ -130,38 +130,36 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// parameter u in Rule 18a, Appendix G of the TeXbook
|
||||
nscoord minSupScriptShift = 0;
|
||||
|
||||
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
|
||||
|
||||
nsIFrame* aChildFrame = mFrames.FirstChild();
|
||||
while (nsnull != aChildFrame)
|
||||
{
|
||||
if (!IsOnlyWhitespace(aChildFrame)) {
|
||||
aChildFrame->GetRect(aRect);
|
||||
if (0 == count) {
|
||||
// base
|
||||
baseFrame = aChildFrame;
|
||||
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
|
||||
baseSize.width = aRect.width; baseSize.height = aRect.height;
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
}
|
||||
else if (1 == count) {
|
||||
// subscript
|
||||
subScriptFrame = aChildFrame;
|
||||
subScriptSize.descent = aRect.x; subScriptSize.ascent = aRect.y;
|
||||
subScriptSize.width = aRect.width; subScriptSize.height = aRect.height;
|
||||
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
|
||||
// get the subdrop from the subscript font
|
||||
nscoord aSubDrop;
|
||||
GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop);
|
||||
// parameter v, Rule 18a, App. G, TeXbook
|
||||
minSubScriptShift = baseSize.descent + aSubDrop;
|
||||
minSubScriptShift = bmBase.descent + aSubDrop;
|
||||
}
|
||||
else if (2 == count) {
|
||||
// superscript
|
||||
supScriptFrame = aChildFrame;
|
||||
supScriptSize.descent = aRect.x; supScriptSize.ascent = aRect.y;
|
||||
supScriptSize.width = aRect.width; supScriptSize.height = aRect.height;
|
||||
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
|
||||
// get the supdrop from the supscript font
|
||||
nscoord aSupDrop;
|
||||
GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop);
|
||||
// parameter u, Rule 18a, App. G, TeXbook
|
||||
minSupScriptShift = baseSize.ascent - aSupDrop;
|
||||
minSupScriptShift = bmBase.ascent - aSupDrop;
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION((count < 2),"nsMathMLmsubFrame : invalid markup");
|
||||
@ -191,8 +189,13 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// get x-height (an ex)
|
||||
nscoord xHeight = 0;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
// const nsStyleFont* aFont =
|
||||
// (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
const nsStyleFont* aFont;
|
||||
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)aFont);
|
||||
|
||||
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetXHeight (xHeight);
|
||||
|
||||
@ -219,7 +222,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// get min supscript shift limit from x-height
|
||||
// = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook
|
||||
nscoord minShiftFromXHeight = (nscoord)
|
||||
(supScriptSize.descent + (1.0f/4.0f) * xHeight);
|
||||
(bmSupScript.descent + (1.0f/4.0f) * xHeight);
|
||||
|
||||
// aSupScriptShift{1,2,3}
|
||||
// = minimum amount to shift the supscript up
|
||||
@ -273,8 +276,8 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// XXX need to do update this ...
|
||||
fm->GetStrikeout (dummy, aRuleSize);
|
||||
nscoord gap =
|
||||
(aSupScriptShift - supScriptSize.descent) -
|
||||
(subScriptSize.ascent - aSubScriptShift);
|
||||
(aSupScriptShift - bmSupScript.descent) -
|
||||
(bmSubScript.ascent - aSubScriptShift);
|
||||
if (gap < 4.0f * aRuleSize) {
|
||||
// adjust aSubScriptShift to get a gap of (4.0 * aRuleSize)
|
||||
aSubScriptShift += NSToCoordRound ((4.0f * aRuleSize) - gap);
|
||||
@ -283,7 +286,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// 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 -
|
||||
(aSupScriptShift - supScriptSize.descent));
|
||||
(aSupScriptShift - bmSupScript.descent));
|
||||
if (gap > 0.0f) {
|
||||
aSupScriptShift += gap;
|
||||
aSubScriptShift -= gap;
|
||||
@ -292,32 +295,58 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
//////////////////////////////////////////////////
|
||||
// Do the Placing
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
// get bounding box for base + subscript + superscript
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseSize.ascent,(supScriptSize.ascent+aSupScriptShift));
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.descent,(supScriptSize.descent+aSubScriptShift));
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
mBoundingMetrics.ascent =
|
||||
PR_MAX(bmBase.ascent,(bmSupScript.ascent+aSupScriptShift));
|
||||
mBoundingMetrics.descent =
|
||||
PR_MAX(bmBase.descent,(bmSubScript.descent+aSubScriptShift));
|
||||
|
||||
// add mScriptSpace to both super/subscript
|
||||
// add italicCorrection only to superscript
|
||||
// XXX this will be handled properly later ...
|
||||
nscoord italicCorrection = 0;
|
||||
aDesiredSize.width = baseSize.width + mScriptSpace +
|
||||
PR_MAX((supScriptSize.width + italicCorrection),subScriptSize.width);
|
||||
|
||||
mBoundingMetrics.width = bmBase.width + mScriptSpace +
|
||||
PR_MAX((bmBase.supItalicCorrection + bmSupScript.width),
|
||||
(bmBase.subItalicCorrection + bmSubScript.width));
|
||||
|
||||
// to be simplfied later
|
||||
nscoord dyBase = mBoundingMetrics.ascent - bmBase.ascent;
|
||||
nscoord dySubScript = mBoundingMetrics.ascent - bmSubScript.ascent + aSubScriptShift;
|
||||
nscoord dySupScript = mBoundingMetrics.ascent - bmSupScript.ascent - aSupScriptShift;
|
||||
|
||||
nscoord baseTop = mBoundingMetrics.ascent - dyBase - bmBase.ascent + baseSize.ascent;
|
||||
nscoord subScriptTop = mBoundingMetrics.ascent - dySubScript - bmSubScript.ascent + subScriptSize.ascent;
|
||||
nscoord supScriptTop = mBoundingMetrics.ascent - dySupScript - bmSupScript.ascent + supScriptSize.ascent;
|
||||
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseTop, PR_MAX(subScriptTop, supScriptTop));
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.height-baseTop,
|
||||
PR_MAX(subScriptSize.height-subScriptTop, supScriptSize.height-supScriptTop));
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
|
||||
mBoundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
mBoundingMetrics.rightBearing = bmBase.width + mScriptSpace +
|
||||
PR_MAX((bmBase.supItalicCorrection + bmSupScript.rightBearing),
|
||||
(bmBase.subItalicCorrection + bmSubScript.rightBearing));
|
||||
|
||||
aDesiredSize.width = mBoundingMetrics.width;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
// now place the base ...
|
||||
dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
dx = 0; dy = aDesiredSize.ascent - baseTop;
|
||||
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
|
||||
// ... and subscript
|
||||
dx = baseSize.width;
|
||||
dy = aDesiredSize.ascent - subScriptSize.ascent + aSubScriptShift;
|
||||
dx = bmBase.width + bmBase.subItalicCorrection;
|
||||
dy = aDesiredSize.ascent - subScriptTop;
|
||||
FinishReflowChild (subScriptFrame, aPresContext, subScriptSize, dx, dy, 0);
|
||||
// ... and the superscript
|
||||
dx = baseSize.width + italicCorrection;
|
||||
dy = aDesiredSize.ascent - supScriptSize.ascent - aSupScriptShift;
|
||||
dx = bmBase.width + bmBase.supItalicCorrection;
|
||||
dy = aDesiredSize.ascent - supScriptTop;
|
||||
FinishReflowChild (supScriptFrame, aPresContext, supScriptSize, dx, dy, 0);
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ nsMathMLmsupFrame::Init(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -121,28 +122,15 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
||||
while (nsnull != aChildFrame)
|
||||
{
|
||||
if (!IsOnlyWhitespace(aChildFrame)) {
|
||||
aChildFrame->GetRect(aRect);
|
||||
if (0 == count) {
|
||||
// base
|
||||
baseFrame = aChildFrame;
|
||||
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
|
||||
baseSize.width = aRect.width; baseSize.height = aRect.height;
|
||||
if (NS_FAILED(GetBoundingMetricsFor(baseFrame, bmBase))) {
|
||||
bmBase.descent = baseSize.descent;
|
||||
bmBase.ascent = baseSize.ascent;
|
||||
bmBase.width = baseSize.width;
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
|
||||
}
|
||||
else if (1 == count) {
|
||||
// superscript
|
||||
supScriptFrame = aChildFrame;
|
||||
supScriptSize.descent = aRect.x; supScriptSize.ascent = aRect.y;
|
||||
supScriptSize.width = aRect.width; supScriptSize.height = aRect.height;
|
||||
if (NS_FAILED(GetBoundingMetricsFor(supScriptFrame, bmSupScript))) {
|
||||
bmSupScript.descent = supScriptSize.descent;
|
||||
bmSupScript.ascent = supScriptSize.ascent;
|
||||
bmSupScript.width = supScriptSize.width;
|
||||
}
|
||||
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
|
||||
// get the supdrop from the supscript font
|
||||
nscoord aSupDrop;
|
||||
GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop);
|
||||
@ -165,12 +153,17 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
||||
// = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook
|
||||
nscoord xHeight = 0;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
// const nsStyleFont* aFont =
|
||||
// (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
|
||||
|
||||
const nsStyleFont *aFont;
|
||||
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)aFont);
|
||||
|
||||
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetXHeight (xHeight);
|
||||
nscoord minShiftFromXHeight = (nscoord)
|
||||
(supScriptSize.descent + (1.0f/4.0f) * xHeight);
|
||||
(bmSupScript.descent + (1.0f/4.0f) * xHeight);
|
||||
|
||||
// aSupScriptShift{1,2,3}
|
||||
// = minimum amount to shift the supscript up
|
||||
@ -187,6 +180,9 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
||||
float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1;
|
||||
float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1;
|
||||
aSupScriptShift1 = NSToCoordRound(mSupScriptShiftFactor * xHeight);
|
||||
//XXX shouldn't this be
|
||||
// aSupScriptShift1 =
|
||||
// PR_MAX(aSupScriptShift1, NSToCoordRound(mSupScriptShiftFactor * xHeight));
|
||||
aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1);
|
||||
aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1);
|
||||
}
|
||||
@ -214,66 +210,39 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
||||
nscoord actualSupScriptShift =
|
||||
PR_MAX(minSupScriptShift,PR_MAX(aSupScriptShift,minShiftFromXHeight));
|
||||
|
||||
// get bounding box for base + supscript
|
||||
#if 0
|
||||
const nsStyleFont *font;
|
||||
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
|
||||
PRInt32 baseStyle = font->mFont.style;
|
||||
supScriptFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
|
||||
PRInt32 supScriptStyle = font->mFont.style;
|
||||
if (baseStyle == NS_STYLE_FONT_STYLE_ITALIC &&
|
||||
supScriptStyle != NS_STYLE_FONT_STYLE_ITALIC) {
|
||||
// take care of italic correction
|
||||
...
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseSize.ascent,(supScriptSize.ascent+actualSupScriptShift));
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.descent,(supScriptSize.descent-actualSupScriptShift));
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
// add mScriptSpace between base and supscript
|
||||
aDesiredSize.width = baseSize.width + mScriptSpace + supScriptSize.width;
|
||||
#endif
|
||||
|
||||
mBoundingMetrics.ascent =
|
||||
PR_MAX(bmBase.ascent, bmSupScript.ascent + actualSupScriptShift);
|
||||
PR_MAX(bmBase.ascent, (bmSupScript.ascent + actualSupScriptShift));
|
||||
mBoundingMetrics.descent =
|
||||
PR_MAX(bmBase.descent, bmSupScript.descent - actualSupScriptShift);
|
||||
PR_MAX(bmBase.descent, (bmSupScript.descent - actualSupScriptShift));
|
||||
// add mScriptSpace between base and supscript
|
||||
mBoundingMetrics.width = bmBase.width + mScriptSpace + bmSupScript.width;
|
||||
|
||||
#if 0
|
||||
printf("bmBase.width:%d + mScriptSpace:%d + bmSupScript.width:%d = mBoundingMetrics.width:%d\n",
|
||||
bmBase.width, mScriptSpace, bmSupScript.width, mBoundingMetrics.width);
|
||||
#endif
|
||||
// to be simplified ...
|
||||
nscoord dyBase = mBoundingMetrics.ascent - bmBase.ascent;
|
||||
nscoord dySupScript = mBoundingMetrics.ascent - bmSupScript.ascent - actualSupScriptShift;
|
||||
|
||||
aDesiredSize.ascent =
|
||||
PR_MAX(baseSize.ascent, supScriptSize.ascent + actualSupScriptShift);
|
||||
aDesiredSize.descent =
|
||||
PR_MAX(baseSize.descent, supScriptSize.descent - actualSupScriptShift);
|
||||
nscoord baseTop = mBoundingMetrics.ascent - dyBase - bmBase.ascent + baseSize.ascent;
|
||||
nscoord supScriptTop = mBoundingMetrics.ascent - dySupScript - bmSupScript.ascent + supScriptSize.ascent;
|
||||
|
||||
aDesiredSize.ascent = PR_MAX(baseTop, supScriptTop);
|
||||
aDesiredSize.descent = PR_MAX(baseSize.height-baseTop, supScriptSize.height-supScriptTop);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
aDesiredSize.width = baseSize.width + mScriptSpace + supScriptSize.width;
|
||||
aDesiredSize.width = mBoundingMetrics.width;
|
||||
|
||||
mReference.x = 0;
|
||||
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
|
||||
mBoundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
mBoundingMetrics.rightBearing = baseSize.width + mScriptSpace + bmSupScript.rightBearing;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
// now place the base ...
|
||||
dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
|
||||
dx = 0; dy = aDesiredSize.ascent - baseTop;
|
||||
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
|
||||
// ... and supscript
|
||||
|
||||
#if 0
|
||||
float t2p;
|
||||
aPresContext->GetTwipsToPixels(&t2p);
|
||||
PRInt32 scriptspace = NSTwipsToIntPixels(mScriptSpace, t2p);
|
||||
printf("mScriptSpace in twips:%d pixel:%d\n", mScriptSpace, scriptspace);
|
||||
#endif
|
||||
|
||||
dx = baseSize.width + mScriptSpace;
|
||||
dy = aDesiredSize.ascent - supScriptSize.ascent - actualSupScriptShift;
|
||||
dy = aDesiredSize.ascent - supScriptTop;
|
||||
FinishReflowChild (supScriptFrame, aPresContext, supScriptSize, dx, dy, 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user