[MATHML] *Restructuration to put member data into a mPresentationData struct. *Added support for accent and accentunder, with provision for embellished operators. *Changed usage of GetBoundingMetrics() to the X Windows character coordinate system

This commit is contained in:
rbs%maths.uq.edu.au 2000-01-14 08:38:25 +00:00
Родитель 061d515964
Коммит 7e1f425ab7
24 изменённых файлов: 879 добавлений и 215 удалений

Просмотреть файл

@ -22,6 +22,7 @@
#ifndef nsIMathMLFrame_h___
#define nsIMathMLFrame_h___
struct nsPresentationData;
struct nsEmbellishData;
struct nsStretchMetrics;
typedef PRInt32 nsStretchDirection;
@ -162,7 +163,7 @@ public:
EmbellishOperator() = 0;
/* GetEmbellishData/SetEmbellishData :
* Get/Set the mEmbellish member data.
* Get/Set the mEmbellishData member variable.
*/
NS_IMETHOD
@ -175,12 +176,15 @@ public:
/* SUPPORT FOR SCRIPTING ELEMENTS: */
/*====================================================================*/
/* GetPresentationData :
* returns the scriptlevel and displaystyle of the frame
/* GetPresentationData/SetPresentationData :
* Get/Set the mPresentationData member variable.
*/
NS_IMETHOD
GetPresentationData(PRInt32* aScriptLevel,
PRBool* aDisplayStyle) = 0;
GetPresentationData(nsPresentationData& aPresentationData) = 0;
NS_IMETHOD
SetPresentationData(const nsPresentationData& aPresentationData) = 0;
/* UpdatePresentationData :
* Increments the scriptlevel of the frame, and set its displaystyle.
@ -259,6 +263,20 @@ struct nsStretchMetrics {
}
};
// struct used by a frame to modulate its presentation
struct nsPresentationData {
PRUint32 flags; // bits for: displaystyle, compressed, etc
nsIFrame* mstyle; // up-pointer on the mstyle frame, if any, that defines the scope
PRUint32 scriptLevel; // Relevant to nested frames within: msub, msup, msubsup, munder,
// mover, munderover, mmultiscripts, mfrac, mroot, mtable.
nsPresentationData()
{
flags = 0;
mstyle = nsnull;
scriptLevel = 0;
}
};
// struct used by an embellished container to keep track of its embellished child
struct nsEmbellishData {
PRUint32 flags;
@ -277,28 +295,114 @@ struct nsEmbellishData {
}
};
// -------------
// Bits used for the presentation flags -- these bits are set
// in their relevant situation as they become available
// This bit is set if the frame is in the *context* of displaystyle=true.
// Note: This doesn't mean that the frame has displaystyle=true as attribute,
// <mstyle> is the only tag which allows <mstyle displaystyle="true|false">.
// The bit merely tells the context of the frame. In the context of
// displaystyle="false", it is intended to slightly alter how the
// rendering is done in inline mode.
#define NS_MATHML_DISPLAYSTYLE 0x00000001
// This bit is used to emulate TeX rendering.
// Internal use only, cannot be set by the user with an attribute.
#define NS_MATHML_COMPRESSED 0x00000002
// This bit is set if the frame is actually an <mstyle> frame *and* that
// <mstyle> frame has an explicit attribute scriptlevel="value".
// Note: the flag is not set if the <mstyle> instead has an incremental +/-value.
#define NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL 0x00000004
// This bit is set if the frame is actually an <mstyle> *and* that
// <mstyle> has an explicit attribute displaystyle="true" or "false"
#define NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE 0x00000008
// This bit is set if the frame is an <mover> or <munderover> with
// an accent frame
#define NS_MATHML_ACCENTOVER 0x00000010
// This bit is set if the frame is an <munder> or <munderover> with
// an accentunder frame
#define NS_MATHML_ACCENTUNDER 0x00000020
// This bit is set if the frame is <mover>, <munder> or <munderover>
// whose base frame is a <mo> frame (or an embellished container with
// a core <mo>) for which the movablelimits attribute is set to true
#define NS_MATHML_MOVABLELIMITS 0x00000040
// Macros that retrieve those bits
#define NS_MATHML_IS_DISPLAYSTYLE(_flags) \
(NS_MATHML_DISPLAYSTYLE == ((_flags) & NS_MATHML_DISPLAYSTYLE))
#define NS_MATHML_IS_COMPRESSED(_flags) \
(NS_MATHML_COMPRESSED == ((_flags) & NS_MATHML_COMPRESSED))
#define NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(_flags) \
(NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE == ((_flags) & NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE))
#define NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(_flags) \
(NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL == ((_flags) & NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL))
#define NS_MATHML_IS_ACCENTOVER(_flags) \
(NS_MATHML_ACCENTOVER == ((_flags) & NS_MATHML_ACCENTOVER))
#define NS_MATHML_IS_ACCENTUNDER(_flags) \
(NS_MATHML_ACCENTUNDER == ((_flags) & NS_MATHML_ACCENTUNDER))
#define NS_MATHML_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_MOVABLELIMITS == ((_flags) & NS_MATHML_MOVABLELIMITS))
// --------------
// Bits used for the embellish flags -- these bits are set
// in their relevant situation as they become available
#define NS_MATHML_EMBELLISH_OPERATOR 0x1
// This bit is set if the frame is an embellished operator.
#define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
#define NS_MATHML_STRETCH_FIRST_CHILD NS_MATHML_EMBELLISH_OPERATOR
#define NS_MATHML_STRETCH_ALL_CHILDREN 0x2
// This bit is set if the frame is an embellished container that
// will fire a stretch command on its first (non-empty) child.
#define NS_MATHML_STRETCH_FIRST_CHILD NS_MATHML_EMBELLISH_OPERATOR
#define NS_MATHML_STRETCH_DONE 0x4
// This bit is set if the frame will fire a stretch command on all
// its (non-empty) children.
// Tags like <mrow> (or an inferred mrow), munderover, etc,
// will fire a stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN 0x00000002
// This bit is set if the frame is an <mo> frame that should behave
// like an accent
#define NS_MATHML_EMBELLISH_ACCENT 0x00000004
// This bit is set if the frame is an <mo> frame with the movablelimits
// attribute set to true
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000008
// a bit used for debug
#define NS_MATHML_STRETCH_DONE 0x80000000
// Macros that retrieve those bits
#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
(NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
// an embellished container will fire a stretch command to its first (non-empty) child
#define NS_MATHML_WILL_STRETCH_FIRST_CHILD(_flags) \
(NS_MATHML_STRETCH_FIRST_CHILD == ((_flags) & NS_MATHML_STRETCH_FIRST_CHILD))
// <mrow> (or an inferred mrow) will fire a stretch command to all its (non-empty) children
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN))
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
#define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
(NS_MATHML_EMBELLISH_ACCENT == ((_flags) & NS_MATHML_EMBELLISH_ACCENT))
#define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
#endif /* nsIMathMLFrame_h___ */

Просмотреть файл

@ -438,7 +438,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
// keep track of the default bounding metrics
if (index0 == index) bm0 = bm;
h = bm.ascent - bm.descent;
h = bm.ascent + bm.descent;
w = bm.rightBearing - bm.leftBearing;
// printf("height:%d width:%d ascent:%d descent:%d\n",
@ -448,9 +448,9 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
if ((aDirection == NS_STRETCH_DIRECTION_VERTICAL && h > height) ||
(aDirection == NS_STRETCH_DIRECTION_HORIZONTAL && w > width)) {
sizeOK = PR_TRUE;
descent = -bm.descent; // flip the sign, as expected by Gecko
descent = bm.descent;
ascent = bm.ascent;
height = bm.ascent - bm.descent;
height = bm.ascent + bm.descent;
width = bm.rightBearing - bm.leftBearing;
// cache all this information
@ -480,7 +480,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/ return rv; }
if (w < bm.width) w = bm.width;
if (i < 3) {
h += nscoord(flex[i]*(bm.ascent-bm.descent)); // sum heights of the parts...
h += nscoord(flex[i]*(bm.ascent+bm.descent)); // sum heights of the parts...
// compute and cache our bounding metrics (vertical stacking!)
if (mBoundingMetrics.leftBearing > bm.leftBearing)
mBoundingMetrics.leftBearing = bm.leftBearing;
@ -492,7 +492,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
width = w;
mBoundingMetrics.width = w;
mBoundingMetrics.ascent = aContainerSize.ascent;
mBoundingMetrics.descent = -aContainerSize.descent;
mBoundingMetrics.descent = aContainerSize.descent;
} 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;
@ -512,7 +512,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/ return rv; }
if (0 == i) bm0 = bm;
if (a < bm.ascent) a = bm.ascent;
if (d > bm.descent) d = bm.descent;
if (d < bm.descent) d = bm.descent;
if (i < 3) {
w += nscoord(flex[i]*(bm.rightBearing-bm.leftBearing)); // sum widths of the parts...
// compute and cache our bounding metrics (horizontal stacking)
@ -525,7 +525,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
if (w <= aContainerSize.width) { // can nicely fit in the available space...
//printf("%04X can nicely fit in the available space...\n", ch);
// ascent = a;
// height = a - d;
// height = a + d;
mBoundingMetrics.width = 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
@ -663,7 +663,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
// - bmdata[0].ascent - bmdata[2].descent + bm.ascent + bm.descent)/2;
// coord for exact fit (i.e., no leading)
dy = aRect.y + (aRect.height - (bm.ascent - bm.descent))/2
dy = aRect.y + (aRect.height - (bm.ascent + bm.descent))/2
- (fontAscent - bm.ascent);
}
else if (2 == i) { // bottom
@ -671,7 +671,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
// dy = aRect.y + aRect.height - (fontAscent + fontDescent);
// coord for exact fit (i.e., no leading)
dy = aRect.y + aRect.height - (fontAscent - bm.descent);
dy = aRect.y + aRect.height - (fontAscent + bm.descent);
}
clipRect = nsRect(dx, dy, aRect.width, aRect.height);
// abcissa that DrawString used
@ -679,7 +679,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
// *exact* abcissa where the *top-most* pixel of the glyph is painted
start[i] = dy + fontAscent - bm.ascent;
// *exact* abcissa where the *bottom-most* pixel of the glyph is painted
end[i] = dy + fontAscent - bm.descent; // note: end = start + height
end[i] = dy + fontAscent + bm.descent; // note: end = start + height
}
/////////////////////////////////////
@ -718,9 +718,9 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
aRenderingContext.DrawRect(clipRect);
#endif
bm = bmdata[i];
while (dy + fontAscent - bm.descent < start[i+1]) {
while (dy + fontAscent + bm.descent < start[i+1]) {
if (2 > count) {
stride = -bm.descent;
stride = bm.descent;
bm = bmdata[3]; // glue
stride += bm.ascent;
}

Просмотреть файл

@ -176,6 +176,41 @@ nsMathMLContainerFrame::SetReference(const nsPoint& aReference)
return NS_OK;
}
// helper methods to facilitate getting/setting the bounding metrics
nsresult
nsMathMLContainerFrame::GetBoundingMetricsFor(nsIFrame* aFrame,
nsBoundingMetrics& aBoundingMetrics)
{
aBoundingMetrics.Clear();
nsIMathMLFrame* aMathMLFrame = nsnull;
nsresult rv = aFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetBoundingMetrics(aBoundingMetrics);
return NS_OK;
}
// 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;
}
// 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;
}
/* /////////////
* nsIMathMLFrame - support methods for stretchy elements
@ -247,6 +282,7 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
// the outermost embellished container will take care of it.
if (!IsEmbellishOperator(mParent)) {
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
nscoord em = NSToCoordRound(float(font.mFont.size));
@ -429,12 +465,16 @@ nsMathMLContainerFrame::IsEmbellishOperator(nsIFrame* aFrame)
*/
NS_IMETHODIMP
nsMathMLContainerFrame::GetPresentationData(PRInt32* aScriptLevel,
PRBool* aDisplayStyle)
nsMathMLContainerFrame::GetPresentationData(nsPresentationData& aPresentationData)
{
NS_PRECONDITION(aScriptLevel && aDisplayStyle, "null arg");
*aScriptLevel = mScriptLevel;
*aDisplayStyle = mDisplayStyle;
aPresentationData = mPresentationData;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLContainerFrame::SetPresentationData(const nsPresentationData& aPresentationData)
{
mPresentationData = aPresentationData;
return NS_OK;
}
@ -442,8 +482,11 @@ NS_IMETHODIMP
nsMathMLContainerFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle)
{
mScriptLevel += aScriptLevelIncrement;
mDisplayStyle = aDisplayStyle;
mPresentationData.scriptLevel += aScriptLevelIncrement;
if (aDisplayStyle)
mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
else
mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
return NS_OK;
}
@ -491,16 +534,15 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
if (nsnull != aMathMLFrame && NS_SUCCEEDED(rv)) {
// get the scriptlevel of the child
PRInt32 childLevel;
PRBool childDisplayStyle;
aMathMLFrame->GetPresentationData(&childLevel, &childDisplayStyle);
nsPresentationData childData;
aMathMLFrame->GetPresentationData(childData);
// Iteration to set a style context for the script level font.
// Wow, here is what is happening: the style system requires that any style context
// *must* be uniquely associated to a frame. So we insert as many frames as needed
// to scale-down (or scale-up) the fontsize.
PRInt32 gap = childLevel - mScriptLevel;
PRInt32 gap = childData.scriptLevel - mPresentationData.scriptLevel;
if (0 != gap) {
nsCOMPtr<nsIContent> childContent;
childFrame->GetContent(getter_AddRefs(childContent));
@ -556,7 +598,7 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
aMathMLFrame->GetEmbellishData(embellishData);
if (0 != embellishData.flags && nsnull != embellishData.firstChild) {
do { // walk the hierarchy in a bottom-up manner
rv= lastFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
rv = lastFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
if (NS_FAILED(rv) || !aMathMLFrame) break;
embellishData.firstChild = childFrame;
@ -594,10 +636,9 @@ nsMathMLContainerFrame::Init(nsIPresContext* aPresContext,
// its scriptlevel and displaystyle. If the parent later wishes to increment
// with other values, it will do so in its SetInitialChildList() method.
mScriptLevel = 0;
mDisplayStyle = PR_TRUE;
mCompressed = PR_FALSE; // for compatibility with TeX rendering
mScriptSpace = 0; // = 0.5 pt in plain TeX
mPresentationData.flags = NS_MATHML_DISPLAYSTYLE;
mPresentationData.scriptLevel = 0;
mPresentationData.mstyle = nsnull;
mEmbellishData.flags = 0;
mEmbellishData.firstChild = nsnull;
@ -605,10 +646,15 @@ nsMathMLContainerFrame::Init(nsIPresContext* aPresContext,
nsIMathMLFrame* aMathMLFrame = nsnull;
nsresult res = aParent->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(res) && nsnull != aMathMLFrame) {
PRInt32 aScriptLevel = 0;
PRBool aDisplayStyle = PR_TRUE;
aMathMLFrame->GetPresentationData(&aScriptLevel, &aDisplayStyle);
UpdatePresentationData(aScriptLevel, aDisplayStyle);
nsPresentationData parentData;
aMathMLFrame->GetPresentationData(parentData);
mPresentationData.mstyle = parentData.mstyle;
mPresentationData.scriptLevel = parentData.scriptLevel;
if (NS_MATHML_IS_DISPLAYSTYLE(parentData.flags))
mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
else
mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
}
return rv;
}

Просмотреть файл

@ -111,8 +111,10 @@ public:
SetEmbellishData(const nsEmbellishData& aEmbellishData);
NS_IMETHOD
GetPresentationData(PRInt32* aScriptLevel,
PRBool* aDisplayStyle);
GetPresentationData(nsPresentationData& aPresentationData);
NS_IMETHOD
SetPresentationData(const nsPresentationData& aPresentationData);
NS_IMETHOD
UpdatePresentationData(PRInt32 aScriptLevelIncrement,
@ -160,7 +162,7 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// helper function to palce token elements
// helper function to place token elements
static nsresult
PlaceTokenFor(nsIFrame* aFrame,
nsIPresContext* aPresContext,
@ -236,34 +238,11 @@ public:
// helper methods to facilitate getting/setting the bounding metrics
static nsresult
GetBoundingMetricsFor(nsIFrame* aFrame,
nsBoundingMetrics& aBoundingMetrics)
{
aBoundingMetrics.Clear();
nsIMathMLFrame* aMathMLFrame = nsnull;
nsresult rv = aFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetBoundingMetrics(aBoundingMetrics);
return NS_OK;
}
// if we reach here, aFrame is not a MathML frame, let the caller know that
printf("GetBoundingMetrics() failed!! ...\n"); /* getchar(); */
return NS_ERROR_FAILURE;
}
nsBoundingMetrics& aBoundingMetrics);
static nsresult
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;
}
// if we reach here, aFrame is not a MathML frame, let the caller know that
printf("SetBoundingMetrics() failed!! ...\n"); /* getchar(); */
return NS_ERROR_FAILURE;
}
nsBoundingMetrics& aBoundingMetrics);
// helper methods for getting sup/subdrop's from a child
static void
@ -336,23 +315,18 @@ public:
protected:
PRInt32 mScriptLevel; // Relevant to nested frames within: msub, msup, msubsup, munder,
// mover, munderover, mmultiscripts, mfrac, mroot, mtable.
// information about the presentation policy of the frame
nsPresentationData mPresentationData;
PRBool mDisplayStyle; // displaystyle="false" is intended to slightly alter how the
// rendering is done in inline mode.
// information about a container that is an embellished operator
nsEmbellishData mEmbellishData;
// Metrics that _exactly_ enclose the text of the frame
nsBoundingMetrics mBoundingMetrics;
// Reference point of the frame: mReference.y is the baseline
nsPoint mReference;
PRBool mCompressed; // for compatibility with TeX rendering
// for internal use only, cannot be set by the user.
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
nsEmbellishData mEmbellishData; // information about a container that is an embellished operator
nsBoundingMetrics mBoundingMetrics; // Metrics that _exactly_ enclose the text of the frame
nsPoint mReference; // Reference point of the frame: mReference.y is the baseline
virtual PRIntn GetSkipSides() const { return 0; }
};

Просмотреть файл

@ -320,7 +320,7 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
/////////////////
// opening fence ...
ReflowChar(aPresContext, renderingContext, mStyleContext, mOpenChar, NS_MATHML_OPERATOR_FORM_PREFIX,
mScriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
/////////////////
// separators ...
PRInt32 i = 0;
@ -332,7 +332,7 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
dx += rect.width;
if (i < mSeparatorsCount) {
ReflowChar(aPresContext, renderingContext, mStyleContext, &mSeparatorsChar[i], NS_MATHML_OPERATOR_FORM_INFIX,
mScriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
i++;
}
}
@ -341,7 +341,7 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
/////////////////
// closing fence ...
ReflowChar(aPresContext, renderingContext, mStyleContext, mCloseChar, NS_MATHML_OPERATOR_FORM_POSTFIX,
mScriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;

Просмотреть файл

@ -20,7 +20,6 @@
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
*/
#include "nsCOMPtr.h"
#include "nsHTMLParts.h"
#include "nsIHTMLContent.h"
@ -82,7 +81,6 @@ nsMathMLmiFrame::Init(nsIPresContext* aPresContext,
return rv;
}
// if our content is a single character, we turn the font to italic
// if our content is not a single character, we turn the font to normal
// XXX TrimWhitespace / CompressWhitespace?
@ -102,7 +100,7 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext,
PRInt32 aLength = 0;
PRInt32 numKids;
mContent->ChildCount(numKids);
nsAutoString aData;
//nsAutoString aData;
for (PRInt32 kid=0; kid<numKids; kid++) {
nsCOMPtr<nsIContent> kidContent;
mContent->ChildAt(kid, *getter_AddRefs(kidContent));
@ -112,27 +110,42 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext,
PRUint32 kidLength;
kidText->GetLength(&kidLength);
aLength += kidLength;
nsAutoString kidData;
kidText->GetData(kidData);
aData += kidData;
//nsAutoString kidData;
//kidText->GetData(kidData);
//aData += kidData;
}
}
}
// Insert a new pseudo frame between our children and us, i.e., the new frame
// becomes our sole child, and our children become children of the new frame.
nsIFrame* firstChild = mFrames.FirstChild();
if (firstChild) {
// Get a pseudo style context for the appropriate style font
// XXX how important is the PseudoStyleContext?
nsAutoString fontStyle = (1 == aLength)
? ":-moz-math-font-style-italic"
: ":-moz-math-font-style-normal";
if (firstChild && 1 < aLength) {
// we are going to switch the font to normal ...
// we don't switch if we are in the scope of a mstyle frame with an
// explicit fontstyle="italic" ...
nsAutoString fontStyle;
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::fontstyle_, fontStyle))
{
if (fontStyle == "italic")
return rv;
}
}
// Get a pseudo style context for the appropriate style font
fontStyle = ":-moz-math-font-style-normal";
nsCOMPtr<nsIAtom> fontAtom(getter_AddRefs(NS_NewAtom(fontStyle)));
nsCOMPtr<nsIStyleContext> newStyleContext;
aPresContext->ResolvePseudoStyleContextFor(mContent, fontAtom, mStyleContext,
PR_FALSE, getter_AddRefs(newStyleContext));
// Insert a new pseudo frame between our children and us, i.e., the new frame
// becomes our sole child, and our children become children of the new frame.
if (newStyleContext && newStyleContext.get() != mStyleContext) {
nsCOMPtr<nsIPresShell> shell;

Просмотреть файл

@ -182,11 +182,13 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
// get sup script shift depending on current script level and display style
// Rule 18c, App. G, TeXbook
nscoord aSupScriptShift;
if (mScriptLevel == 0 && mDisplayStyle && !mCompressed) {
if ( mPresentationData.scriptLevel == 0 &&
NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) &&
!NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style D in TeXbook
aSupScriptShift = aSupScriptShift1;
}
else if (mCompressed) {
else if (NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style C' in TeXbook = D',T',S',SS'
aSupScriptShift = aSupScriptShift3;
}

Просмотреть файл

@ -69,10 +69,11 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
private:
private:
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
float mSubScriptShiftFactor, mSupScriptShiftFactor;
PRBool mSubUserSetFlag, mSupUserSetFlag;
};
#endif /* nsMathMLmmultiscriptsFrame_h___ */

Просмотреть файл

@ -180,14 +180,82 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
// cache the operator
mMathMLChar.SetData(aData);
// for consistency, set the first non-empty child as the embellished child
// fill our mEmbellishData member variable
nsIFrame* firstChild = mFrames.FirstChild();
while (firstChild) {
if (!IsOnlyWhitespace(firstChild)) {
mEmbellishData.flags = NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.firstChild = 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;
// there are two extra things that we need to record so that if our
// parent is <mover>, <munder>, or <munderover>, they will treat us properly:
// 1) do we have accent="true"
// 2) do we have movablelimits="true"
// they need the extra information to decide how to treat their scripts/limits
// (note: <mover>, <munder>, or <munderover> need not necessarily be our
// direct parent -- case of embellished operators)
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; // default is false
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_MOVABLELIMITS; // default is false
nsAutoString value;
PRBool accentAttribute = PR_FALSE;
PRBool movablelimitsAttribute = PR_FALSE;
// see if the accent attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
accentAttribute = PR_TRUE;
if (value == "true")
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
}
}
// see if the movablelimits attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value))
{
movablelimitsAttribute = PR_TRUE;
if (value == "true")
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
}
if (!accentAttribute || !movablelimitsAttribute) {
// If we reach here, it means one or both attributes are missing
// Unfortunately, we have to lookup the dictionary to see who
// we are, i.e., two lookups, counting also the one in Stretch()!
// The lookup in Stretch() assumes that the surrounding frame tree
// is already fully constructed, which is not true at this stage.
// all accent="true" in the dictionary have form="postfix"
nsOperatorFlags aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
nsOperatorFlags aFlags = 0;
float aLeftSpace, aRightSpace;
PRBool found = nsMathMLOperators::LookupOperator(aData, aForm,
&aFlags, &aLeftSpace, &aRightSpace);
if (found && !accentAttribute && NS_MATHML_OPERATOR_IS_ACCENT(aFlags))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
}
// all movablemits="true" in the dictionary have form="prefix",
// but this doesn't matter here, as the lookup has returned whatever
// is in the dictionary
if (found && !movablelimitsAttribute && NS_MATHML_OPERATOR_IS_MOVABLELIMITS(aFlags))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
}
break;
}
firstChild->GetNextSibling(&firstChild);
@ -205,6 +273,7 @@ nsMathMLmoFrame::InitData()
nsAutoString value;
nsOperatorFlags aForm = NS_MATHML_OPERATOR_FORM_INFIX;
nsIMathMLFrame* aMathMLFrame = nsnull;
nsIFrame* embellishAncestor = nsnull;
PRBool hasEmbellishAncestor = PR_FALSE;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::form_, value)) {
@ -214,18 +283,23 @@ nsMathMLmoFrame::InitData()
aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
// flag if we have an embellished ancestor
hasEmbellishAncestor = IsEmbellishOperator(mParent);
if (IsEmbellishOperator(mParent))
{
hasEmbellishAncestor = PR_TRUE;
embellishAncestor = mParent;
}
}
else {
// Get our outermost embellished container and its parent
nsIFrame* aParent = this;
nsIFrame* aEmbellishAncestor = this;
nsIFrame* embellishAncestor = this;
do {
aEmbellishAncestor = aParent;
embellishAncestor = aParent;
aParent->GetParent(&aParent);
} while (IsEmbellishOperator(aParent));
// flag if we have an embellished ancestor
if (aEmbellishAncestor != this) {
if (embellishAncestor != this)
{
hasEmbellishAncestor = PR_TRUE;
}
@ -234,7 +308,7 @@ nsMathMLmoFrame::InitData()
//////////////
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
// Here is the situation: we may have empty frames between us:
// [space*] [prev] [space*] [aEmbellishAncestor] [space*] [next]
// [space*] [prev] [space*] [embellishAncestor] [space*] [next]
// We want to skip them...
// The problem looks like a regexp, we ask a little flag to help us.
PRInt32 state = 0;
@ -244,7 +318,7 @@ nsMathMLmoFrame::InitData()
aParent->FirstChild(nsnull, &aFrame);
while (aFrame) {
if (aFrame == aEmbellishAncestor) { // we start looking for next
if (aFrame == embellishAncestor) { // we start looking for next
state++;
}
else if (!IsOnlyWhitespace(aFrame)) {
@ -266,6 +340,17 @@ nsMathMLmoFrame::InitData()
aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
}
// Check to see if we are really the 'core' of the ancestor, not just a sibling of the core
if (hasEmbellishAncestor && embellishAncestor) {
hasEmbellishAncestor = PR_FALSE;
rv = embellishAncestor->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
nsEmbellishData embellishData;
aMathMLFrame->GetEmbellishData(embellishData);
if (embellishData.core == this) hasEmbellishAncestor = PR_TRUE;
}
}
// Lookup the operator dictionary
nsAutoString aData;
mMathMLChar.GetData(aData);
@ -275,7 +360,7 @@ nsMathMLmoFrame::InitData()
// All operators are symmetric. But this symmetric flag is *not* stored in
// the operator dictionary and operators are treated as non-symmetric...
// Uncomment the folllowing line to change this behavior.
// mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
//mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
// If the operator exists in the dictionary and is stretchy, it is mutable
if (found && NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
@ -288,7 +373,7 @@ nsMathMLmoFrame::InitData()
}
// If we don't want too much extra space when we are a script
if (!hasEmbellishAncestor && 0 < mScriptLevel) {
if (!hasEmbellishAncestor && 0 < mPresentationData.scriptLevel) {
mLeftSpace /= 2.0f;
mRightSpace /= 2.0f;
}
@ -342,11 +427,17 @@ nsMathMLmoFrame::InitData()
// TODO: add also lspace and rspace, minsize, maxsize, later ...
// If we are an accent without explicit lspace="." or rspace=".",
// ignore our default left/right space
if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
mLeftSpace = 0.0f;
mRightSpace = 0.0f;
}
// If the stretchy attribute has been disabled, the operator is not mutable
if (!found || !NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
}
}
// NOTE: aDesiredStretchSize is an IN/OUT parameter
@ -397,7 +488,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
}
else {
// update our bounding metrics... it becomes that our MathML char
// update our bounding metrics... it becomes that of our MathML char
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
}
}
@ -427,8 +518,9 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
// 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,
// the outermost embellished container will take care of it.
if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
// Get the value of 'em'
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);

Просмотреть файл

@ -80,6 +80,126 @@ nsMathMLmoverFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsMathMLmoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accent flag
/* The REC says:
The default value of accent is false, unless overscript
is an <mo> element or an embellished operator. If overscript is
an <mo> element, the value of its accent attribute is used as
the default value of accent. If overscript is an embellished
operator, the accent attribute of the <mo> element at its
core is used as the default value. As with all attributes, an
explicitly given value overrides the default.
XXX The winner is the outermost in conflicting settings like these:
<mover accent='true'>
<mi>...</mi>
<mo accent='false'> ... </mo>
</mover>
*/
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* overscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
count++;
if (1 == count) baseFrame = childFrame;
if (2 == count) { overscriptFrame = childFrame; break; }
}
childFrame->GetNextSibling(&childFrame);
}
nsIMathMLFrame* overscriptMathMLFrame = nsnull;
nsIMathMLFrame* aMathMLFrame = nsnull;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTOVER; // default of accent is false
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value == "true") {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
rv = mEmbellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
}
// see if the overscriptFrame is <mo> or an embellished operator
if (overscriptFrame) {
rv = overscriptFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&overscriptMathMLFrame);
if (NS_SUCCEEDED(rv) && overscriptMathMLFrame) {
overscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the overscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) {
rv = embellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
// if we have the accent attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
// sync the presentation data: record whether we have an accent
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTOVER;
}
}
}
}
//The REC says:
/*
Within overscript, <mover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
*/
PRInt32 incrementScriptLevel;
if (overscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)? 0 : 1;
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
}
// switch the style of the overscript
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
NS_IMETHODIMP
nsMathMLmoverFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -109,6 +229,23 @@ nsMathMLmoverFrame::Reflow(nsIPresContext* aPresContext,
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or an embellished
operator whose <mo> element core has movablelimits="true"), and
displaystyle="false", then overscript is drawn in a superscript
position. In this case, the accent attribute is ignored. This is
often used for limits on symbols such as &sum;.
TODO:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like superscript
}
else {
// place like accent
}
*/
NS_IMETHODIMP
nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
@ -192,8 +329,8 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
}
// 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;
}

Просмотреть файл

@ -56,17 +56,7 @@ public:
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
// switch the style of the overscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
EmbellishOperator();
return rv;
}
nsIFrame* aChildList);
protected:
nsMathMLmoverFrame();

Просмотреть файл

@ -156,7 +156,7 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
// overline bar
renderingContext.GetBoundingMetrics(mBarChar.GetUnicode(), PRUint32(1), bmBar);
nscoord thickspace = bmBar.ascent - bmBar.descent; // height of the overline bar
nscoord thickspace = bmBar.ascent + bmBar.descent; // height of the overline bar
// Stretch the sqrt symbol to the appropriate height if it is not big enough.
nsStretchMetrics contSize(aDesiredSize);

Просмотреть файл

@ -76,7 +76,8 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mFlags = 0;
mPresentationData.mstyle = this;
mInnerScriptLevelIncrement = 0;
// see if the displaystyle attribute is there
@ -84,12 +85,12 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::displaystyle_, value)) {
if (value == "true") {
mDisplayStyle = PR_TRUE;
mFlags |= NS_MATHML_MSTYLE_DISPLAYSTYLE;
mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE;
mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
}
else if (value == "false") {
mDisplayStyle = PR_FALSE;
mFlags |= NS_MATHML_MSTYLE_DISPLAYSTYLE;
mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE;
mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
}
}
@ -100,8 +101,8 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
aUserValue = value.ToInteger(&aErrorCode);
if (NS_SUCCEEDED(aErrorCode)) {
if (value[0] != '+' && value[0] != '-') { // record that it is an explicit value
mFlags |= NS_MATHML_MSTYLE_SCRIPTLEVEL_EXPLICIT;
mScriptLevel = aUserValue; // explicit value...
mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL;
mPresentationData.scriptLevel = aUserValue;
}
else {
// mScriptLevel += aUserValue; // incremental value...
@ -125,12 +126,17 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement,
// Since UpdatePresentationData() can be called by a parent frame, the
// scriptlevel and displaystyle attributes of mstyle must take precedence.
// Update only if attributes are not there
if (!(NS_MATHML_MSTYLE_HAS_DISPLAYSTYLE(mFlags))) {
mDisplayStyle = aDisplayStyle;
if (!NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) {
if (aDisplayStyle)
mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
else
mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE;
}
if (!(NS_MATHML_MSTYLE_HAS_SCRIPTLEVEL_EXPLICIT(mFlags))) {
mScriptLevel += aScriptLevelIncrement;
if (!NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
mPresentationData.scriptLevel += aScriptLevelIncrement;
}
return NS_OK;
}
@ -142,15 +148,17 @@ nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
// mstyle is special...
// Since UpdatePresentationDataFromChildAt() can be called by a parent frame,
// wee need to ensure that the attributes of mstyle take precedence
if (NS_MATHML_MSTYLE_HAS_DISPLAYSTYLE(mFlags)) {
aDisplayStyle = mDisplayStyle;
PRBool displayStyle = NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags);
if (NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) {
aDisplayStyle = displayStyle;
}
if (NS_MATHML_MSTYLE_HAS_SCRIPTLEVEL_EXPLICIT(mFlags)) {
if (NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
aScriptLevelIncrement = 0;
}
if (0 == aScriptLevelIncrement && aDisplayStyle == mDisplayStyle)
if (0 == aScriptLevelIncrement && aDisplayStyle == displayStyle)
return NS_OK;
// let the base class worry about the update
return nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(aIndex,
aScriptLevelIncrement, aDisplayStyle);

Просмотреть файл

@ -30,6 +30,8 @@
// <mstyle> -- style change
//
#if 0
#define NS_MATHML_MSTYLE_SCRIPTLEVEL_EXPLICIT (1)
#define NS_MATHML_MSTYLE_DISPLAYSTYLE (1<<1)
@ -39,6 +41,7 @@
#define NS_MATHML_MSTYLE_HAS_DISPLAYSTYLE(_flags) \
(NS_MATHML_MSTYLE_DISPLAYSTYLE == ((_flags) & NS_MATHML_MSTYLE_DISPLAYSTYLE))
#endif
class nsMathMLmstyleFrame : public nsMathMLContainerFrame {
public:
@ -67,7 +70,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(0, mInnerScriptLevelIncrement, mDisplayStyle);
UpdatePresentationDataFromChildAt(0, mInnerScriptLevelIncrement, NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags));
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
@ -79,7 +82,7 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
PRInt32 mInnerScriptLevelIncrement;
PRInt32 mFlags;
// PRInt32 mFlags;
};
#endif /* nsMathMLmstyleFrame_h___ */

Просмотреть файл

@ -128,9 +128,7 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
baseFrame = aChildFrame;
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
baseSize.width = aRect.width; baseSize.height = aRect.height;
if (NS_SUCCEEDED(GetBoundingMetricsFor(baseFrame, baseBounds))) {
baseBounds.descent = -baseBounds.descent;
} else {
if (NS_FAILED(GetBoundingMetricsFor(baseFrame, baseBounds))) {
baseBounds.descent = baseSize.descent;
baseBounds.ascent = baseSize.ascent;
baseBounds.width = baseSize.width;
@ -141,9 +139,7 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
subScriptFrame = aChildFrame;
subScriptSize.descent = aRect.x; subScriptSize.ascent = aRect.y;
subScriptSize.width = aRect.width; subScriptSize.height = aRect.height;
if (NS_SUCCEEDED(GetBoundingMetricsFor(subScriptFrame, subScriptBounds))) {
subScriptBounds.descent = -subScriptBounds.descent;
} else {
if (NS_FAILED(GetBoundingMetricsFor(subScriptFrame, subScriptBounds))) {
subScriptBounds.descent = subScriptSize.descent;
subScriptBounds.ascent = subScriptSize.ascent;
subScriptBounds.width = subScriptSize.width;
@ -218,9 +214,7 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
PR_MAX(baseSize.descent, subScriptSize.descent + actualSubScriptShift);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
//XXX wrong aDesiredSize.width = mBoundingMetrics.width;
mBoundingMetrics.descent = -mBoundingMetrics.descent;
aDesiredSize.width = baseSize.width + mScriptSpace + subScriptSize.width;
if (aPlaceOrigin) {
nscoord dx, dy;

Просмотреть файл

@ -69,7 +69,9 @@ public:
virtual PRIntn GetSkipSides() const { return 0; }
private:
private:
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
float mSubScriptShiftFactor;
PRBool mUserSetFlag;
};

Просмотреть файл

@ -198,7 +198,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
// Get aSubScriptShift{1,2} default from font
GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2);
if (mSubUserSetFlag == PR_TRUE) {
if (mSubUserSetFlag) {
// the user has set the subscriptshift attribute
float aFactor = ((float) aSubScriptShift2) / aSubScriptShift1;
aSubScriptShift1 = NSToCoordRound(mSubScriptShiftFactor * xHeight);
@ -230,7 +230,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3;
// Set aSupScriptShift{1,2,3} default from font
GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3);
if (mSupUserSetFlag == PR_TRUE) {
if (mSupUserSetFlag) {
// the user has set the superscriptshift attribute
float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1;
float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1;
@ -242,13 +242,13 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
// get sup script shift depending on current script level and display style
// Rule 18c, App. G, TeXbook
nscoord aSupScriptShift;
if ((mScriptLevel == 0) &&
(mDisplayStyle == PR_TRUE) &&
(mCompressed == PR_FALSE)) {
if ( mPresentationData.scriptLevel == 0 &&
NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) &&
!NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style D in TeXbook
aSupScriptShift = aSupScriptShift1;
}
else if (mCompressed == PR_TRUE) {
else if (NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style C' in TeXbook = D',T',S',SS'
aSupScriptShift = aSupScriptShift3;
}

Просмотреть файл

@ -69,7 +69,9 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
private:
private:
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
float mSubScriptShiftFactor, mSupScriptShiftFactor;
PRBool mSubUserSetFlag, mSupUserSetFlag;
};

Просмотреть файл

@ -127,9 +127,7 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
baseFrame = aChildFrame;
baseSize.descent = aRect.x; baseSize.ascent = aRect.y;
baseSize.width = aRect.width; baseSize.height = aRect.height;
if (NS_SUCCEEDED(GetBoundingMetricsFor(baseFrame, bmBase))) {
bmBase.descent = -bmBase.descent;
} else {
if (NS_FAILED(GetBoundingMetricsFor(baseFrame, bmBase))) {
bmBase.descent = baseSize.descent;
bmBase.ascent = baseSize.ascent;
bmBase.width = baseSize.width;
@ -140,9 +138,7 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
supScriptFrame = aChildFrame;
supScriptSize.descent = aRect.x; supScriptSize.ascent = aRect.y;
supScriptSize.width = aRect.width; supScriptSize.height = aRect.height;
if (NS_SUCCEEDED(GetBoundingMetricsFor(supScriptFrame, bmSupScript))) {
bmSupScript.descent = -bmSupScript.descent;
} else {
if (NS_FAILED(GetBoundingMetricsFor(supScriptFrame, bmSupScript))) {
bmSupScript.descent = supScriptSize.descent;
bmSupScript.ascent = supScriptSize.ascent;
bmSupScript.width = supScriptSize.width;
@ -198,11 +194,13 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
// get sup script shift depending on current script level and display style
// Rule 18c, App. G, TeXbook
nscoord aSupScriptShift;
if (mScriptLevel == 0 && mDisplayStyle && !mCompressed) {
if ( mPresentationData.scriptLevel == 0 &&
NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) &&
!NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style D in TeXbook
aSupScriptShift = aSupScriptShift1;
}
else if (mCompressed) {
else if (NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) {
// Style C' in TeXbook = D',T',S',SS'
aSupScriptShift = aSupScriptShift3;
}
@ -246,17 +244,19 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
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
aDesiredSize.ascent =
PR_MAX(baseSize.ascent, supScriptSize.ascent + actualSupScriptShift);
aDesiredSize.descent =
PR_MAX(baseSize.descent, supScriptSize.descent - actualSupScriptShift);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
mBoundingMetrics.descent = -mBoundingMetrics.descent;
aDesiredSize.width = baseSize.width + mScriptSpace + supScriptSize.width;
if (aPlaceOrigin) {
nscoord dx, dy;

Просмотреть файл

@ -69,7 +69,9 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
private:
private:
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
float mSupScriptShiftFactor;
PRBool mUserSetFlag;
};

Просмотреть файл

@ -80,6 +80,125 @@ nsMathMLmunderFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsMathMLmunderFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accentunder flag
/* The REC says:
The default value of accentunder is false, unless underscript
is an <mo> element or an embellished operator. If underscript is
an <mo> element, the value of its accent attribute is used as the
default value of accentunder. If underscript is an embellished
operator, the accent attribute of the <mo> element at its
core is used as the default value. As with all attributes, an
explicitly given value overrides the default.
XXX The winner is the outermost setting in conflicting settings like these:
<munder accent='true'>
<mi>...</mi>
<mo accent='false'> ... </mo>
</munder>
*/
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* underscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
count++;
if (1 == count) baseFrame = childFrame;
if (2 == count) { underscriptFrame = childFrame; break; }
}
childFrame->GetNextSibling(&childFrame);
}
nsIMathMLFrame* underscriptMathMLFrame = nsnull;
nsIMathMLFrame* aMathMLFrame = nsnull;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTUNDER; // default of accentunder is false
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value == "true") {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
rv = mEmbellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
}
// see if the underscriptFrame is <mo> or an embellished operator
if (underscriptFrame) {
rv = underscriptFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&underscriptMathMLFrame);
if (NS_SUCCEEDED(rv) && underscriptMathMLFrame) {
underscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the underscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) {
rv = embellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
// if we have the accentunder attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
// sync the presentation data: record whether we have an accentunder
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTUNDER;
}
}
}
}
//The REC says:
/*
Within underscript, <munder> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
*/
PRInt32 incrementScriptLevel;
if (underscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
}
// switch the style of the underscript
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
NS_IMETHODIMP
nsMathMLmunderFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -111,6 +230,25 @@ nsMathMLmunderFrame::Reflow(nsIPresContext* aPresContext,
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or
an embellished operator whose <mo> element core has
movablelimits="true"), and displaystyle="false", then
underscript is drawn in a subscript position. In this case,
the accentunder attribute is ignored. This is often used
for limits on symbols such as &sum;.
TODO:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like subscript
}
else {
// place like accentunder
}
*/
NS_IMETHODIMP
nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -170,8 +308,8 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
}
// 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;
}

Просмотреть файл

@ -56,17 +56,7 @@ public:
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
// switch the style of the underscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
EmbellishOperator();
return rv;
}
nsIFrame* aChildList);
protected:
nsMathMLmunderFrame();

Просмотреть файл

@ -80,6 +80,163 @@ nsMathMLmunderoverFrame::Init(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accent and accentunder flags
/*
The REC says:
The accent and accentunder attributes have the same effect as
the attributes with the same names on <mover> and <munder>,
respectively. Their default values are also computed in the
same manner as described for those elements, with the default
value of accent depending on overscript and the default value
of accentunder depending on underscript.
*/
// get our overscript and underscript frames
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* underscriptFrame = nsnull;
nsIFrame* overscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
count++;
if (1 == count) baseFrame = childFrame;
if (2 == count) underscriptFrame = childFrame;
if (3 == count) { overscriptFrame = childFrame; break; }
}
childFrame->GetNextSibling(&childFrame);
}
nsIMathMLFrame* underscriptMathMLFrame = nsnull;
nsIMathMLFrame* overscriptMathMLFrame = nsnull;
nsIMathMLFrame* aMathMLFrame = nsnull;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTUNDER; // default of accentunder is false
mPresentationData.flags &= ~NS_MATHML_ACCENTOVER; // default of accent is false
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value == "true") {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
rv = mEmbellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
}
// see if the underscriptFrame is <mo> or an embellished operator
if (underscriptFrame) {
rv = underscriptFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&underscriptMathMLFrame);
if (NS_SUCCEEDED(rv) && underscriptMathMLFrame) {
underscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the underscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) {
rv = embellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
// if we have the accentunder attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
// sync the presentation data: record whether we have an accentunder
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTUNDER;
}
}
}
}
// see if the overscriptFrame is <mo> or an embellished operator
if (overscriptFrame) {
rv = overscriptFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&overscriptMathMLFrame);
if (NS_SUCCEEDED(rv) && overscriptMathMLFrame) {
overscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the overscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) {
rv = embellishData.core->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
aMathMLFrame->GetEmbellishData(embellishData);
// if we have the accent attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
// sync the presentation data: record whether we have an accent
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTOVER;
}
}
}
}
//The REC says:
/*
Within underscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
Within overscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
*/
PRInt32 incrementScriptLevel;
if (underscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
}
if (overscriptMathMLFrame)
{
incrementScriptLevel = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)? 0 : 1;
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
}
// switch the style of the underscript and the overscript
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -90,7 +247,7 @@ nsMathMLmunderoverFrame::Reflow(nsIPresContext* aPresContext,
nsresult rv = NS_OK;
/////////////
// Reflow children to stretch themselves
// Reflow children
ReflowChildren(1, aPresContext, aDesiredSize, aReflowState, aStatus);
@ -111,6 +268,25 @@ nsMathMLmunderoverFrame::Reflow(nsIPresContext* aPresContext,
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or an embellished
operator whose <mo> element core has movablelimits="true"), and
displaystyle="false", then underscript and overscript are drawn in
a subscript and superscript position, respectively. In this case,
the accent and accentunder attributes are ignored. This is often
used for limits on symbols such as &sum;.
TODO:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like subscript-superscript pair
}
else {
// place like accentunder-accent pair
}
*/
NS_IMETHODIMP
nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -173,9 +349,9 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
}
// 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;
}

Просмотреть файл

@ -56,17 +56,7 @@ public:
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
// switch the style of the underscript and the overscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
EmbellishOperator();
return rv;
}
nsIFrame* aChildList);
protected:
nsMathMLmunderoverFrame();