Inter-spacing improvements between MathML frames, b=306543, r+sr=roc

This commit is contained in:
rbs%maths.uq.edu.au 2005-09-06 23:47:01 +00:00
parent ff54a0bf4c
commit b495f2aa64
20 changed files with 246 additions and 183 deletions

View File

@ -322,9 +322,6 @@ struct nsEmbellishData {
// bits used to mark certain properties of our embellishments
PRUint32 flags;
// handy pointer on our embellished child to descend the embellished hierarchy
nsIFrame* nextFrame;
// pointer on the <mo> frame at the core of the embellished hierarchy
nsIFrame* coreFrame;
@ -340,7 +337,6 @@ struct nsEmbellishData {
nsEmbellishData() {
flags = 0;
nextFrame = nsnull;
coreFrame = nsnull;
direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
leftSpace = 0;
@ -360,6 +356,11 @@ struct nsPresentationData {
// bits for: displaystyle, compressed, etc
PRUint32 flags;
// handy pointer on our base child (the 'nucleus' in TeX), but it may be
// null here (e.g., tags like <mrow>, <mfrac>, <mtable>, etc, won't
// pick a particular child in their child list to be the base)
nsIFrame* baseFrame;
// up-pointer on the mstyle frame, if any, that defines the scope
nsIFrame* mstyle;
@ -369,6 +370,7 @@ struct nsPresentationData {
nsPresentationData() {
flags = 0;
baseFrame = nsnull;
mstyle = nsnull;
scriptLevel = 0;
}

View File

@ -229,14 +229,16 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIRenderingContext& aRenderingC
nsIMathMLFrame* mathMLFrame;
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
nsEmbellishData childData;
mathMLFrame->GetEmbellishData(childData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(childData.flags) &&
childData.direction == aStretchDirection &&
childData.nextFrame) {
nsEmbellishData embellishData;
nsPresentationData presentationData;
mathMLFrame->GetEmbellishData(embellishData);
mathMLFrame->GetPresentationData(presentationData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) &&
embellishData.direction == aStretchDirection &&
presentationData.baseFrame) {
// embellishements are not included, only consider the inner first child itself
nsIMathMLFrame* mathMLchildFrame;
childData.nextFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLchildFrame);
presentationData.baseFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLchildFrame);
if (mathMLchildFrame) {
mathMLFrame = mathMLchildFrame;
}
@ -298,9 +300,9 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
return NS_OK;
}
// Pass the stretch to the first non-empty child ...
// Pass the stretch to the base child ...
nsIFrame* childFrame = mEmbellishData.nextFrame;
nsIFrame* childFrame = mPresentationData.baseFrame;
if (childFrame) {
nsIMathMLFrame* mathMLFrame;
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
@ -362,7 +364,7 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
childFrame = mFrames.FirstChild();
while (childFrame) {
if (childFrame != mEmbellishData.nextFrame) {
if (childFrame != mPresentationData.baseFrame) {
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
// retrieve the metrics that was stored at the previous pass
@ -449,7 +451,7 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
// because it excludes the particular case of the core <mo>...</mo> itself.
// (<mo> needs to fire stretch on its MathMLChar in any case to initialize it)
PRBool placeOrigin = !NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) ||
(mEmbellishData.coreFrame != this && !mEmbellishData.nextFrame &&
(mEmbellishData.coreFrame != this && !mPresentationData.baseFrame &&
mEmbellishData.direction == NS_STRETCH_DIRECTION_UNSUPPORTED);
Place(aRenderingContext, placeOrigin, aDesiredSize);
@ -468,7 +470,7 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(presentationData.flags) ||
(NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags)
&& embellishData.nextFrame == this))
&& presentationData.baseFrame == this))
{
parentWillFireStretch = PR_TRUE;
}
@ -598,7 +600,7 @@ nsMathMLContainerFrame::PropagateScriptStyleFor(nsIFrame* aFrame,
nsIContent* content = aFrame->GetContent();
if (!gap) {
// unset any -moz-math-font-size attribute without notifying that we want a reflow
content->UnsetAttr(kNameSpaceID_None, nsMathMLAtoms::fontsize, PR_FALSE);
content->UnsetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfontsize, PR_FALSE);
}
else {
// By default scriptminsize=8pt and scriptsizemultiplier=0.71
@ -653,7 +655,7 @@ nsMathMLContainerFrame::PropagateScriptStyleFor(nsIFrame* aFrame,
}
// set the -moz-math-font-size attribute without notifying that we want a reflow
content->SetAttr(kNameSpaceID_None, nsMathMLAtoms::fontsize,
content->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfontsize,
fontsize, PR_FALSE);
}
@ -1150,36 +1152,48 @@ nsIAtom*
nsMathMLContainerFrame::GetType() const
{
// see if this is an embellished operator (mapped to 'Op' in TeX)
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) &&
mEmbellishData.coreFrame) {
if (mEmbellishData.coreFrame) {
return mEmbellishData.coreFrame->GetType();
}
// everything else is a schematta element (mapped to 'Inner' in TeX)
return nsMathMLAtoms::schemataMathMLFrame;
// if it has a prescribed base, just fetch the type from there
if (mPresentationData.baseFrame) {
return mPresentationData.baseFrame->GetType();
}
// everything else is treated as ordinary (mapped to 'Ord' in TeX)
return nsMathMLAtoms::ordinaryMathMLFrame;
}
enum eMathMLFrameType {
eMathMLFrameType_UNKNOWN = -1,
eMathMLFrameType_Ordinary,
eMathMLFrameType_OperatorVisible,
eMathMLFrameType_OperatorOrdinary,
eMathMLFrameType_OperatorInvisible,
eMathMLFrameType_Inner
eMathMLFrameType_OperatorUserDefined,
eMathMLFrameType_Inner,
eMathMLFrameType_ItalicIdentifier,
eMathMLFrameType_UprightIdentifier,
eMathMLFrameType_COUNT
};
// see spacing table in Chapter 18, TeXBook (p.170)
// Our table isn't quite identical to TeX because operators have
// built-in values for lspace & rspace in the Operator Dictionary.
static PRInt32 kInterFrameSpacingTable[4][4] =
static PRInt32 kInterFrameSpacingTable[eMathMLFrameType_COUNT][eMathMLFrameType_COUNT] =
{
// in units of muspace.
// upper half of the byte is set if the
// spacing is not to be used for scriptlevel > 0
/* Ord OpVis OpInv Inner */
/*Ord */ {0x01, 0x00, 0x01, 0x01},
/*OpVis*/ {0x00, 0x00, 0x00, 0x00},
/*OpInv*/ {0x01, 0x00, 0x00, 0x01},
/*Inner*/ {0x01, 0x00, 0x01, 0x01}
/* Ord OpOrd OpInv OpUsr Inner Italic Upright */
/*Ord */ {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
/*OpOrd*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/*OpInv*/ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/*OpUsr*/ {0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01},
/*Inner*/ {0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00},
/*Italic*/ {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01},
/*Upright*/ {0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01}
};
#define GET_INTERSPACE(scriptlevel_, frametype1_, frametype2_, space_) \
@ -1197,12 +1211,18 @@ static PRInt32 kInterFrameSpacingTable[4][4] =
#define MAP_FRAMETYPE(atomtype_, enumtype_) \
if (atomtype_ == nsMathMLAtoms::ordinaryMathMLFrame) \
enumtype_ = eMathMLFrameType_Ordinary; \
else if (atomtype_ == nsMathMLAtoms::schemataMathMLFrame) \
enumtype_ = eMathMLFrameType_Inner; \
else if (atomtype_ == nsMathMLAtoms::operatorVisibleMathMLFrame) \
enumtype_ = eMathMLFrameType_OperatorVisible; \
else if (atomtype_ == nsMathMLAtoms::operatorOrdinaryMathMLFrame) \
enumtype_ = eMathMLFrameType_OperatorOrdinary; \
else if (atomtype_ == nsMathMLAtoms::operatorInvisibleMathMLFrame) \
enumtype_ = eMathMLFrameType_OperatorInvisible; \
else if (atomtype_ == nsMathMLAtoms::operatorUserDefinedMathMLFrame) \
enumtype_ = eMathMLFrameType_OperatorUserDefined; \
else if (atomtype_ == nsMathMLAtoms::innerMathMLFrame) \
enumtype_ = eMathMLFrameType_Inner; \
else if (atomtype_ == nsMathMLAtoms::italicIdentifierMathMLFrame) \
enumtype_ = eMathMLFrameType_ItalicIdentifier; \
else if (atomtype_ == nsMathMLAtoms::uprightIdentifierMathMLFrame) \
enumtype_ = eMathMLFrameType_UprightIdentifier; \
else \
enumtype_ = eMathMLFrameType_UNKNOWN;
@ -1244,14 +1264,33 @@ GetInterFrameSpacing(PRInt32 aScriptLevel,
else if (*aFromFrameType != eMathMLFrameType_UNKNOWN) {
// no carry-forward anymore, get the real inter-space between
// the two frames of interest
GET_INTERSPACE(aScriptLevel, *aFromFrameType, secondType, space);
firstType = *aFromFrameType;
// But... the invisible operator that we encountered earlier could
// be sitting between italic and upright identifiers, e.g.,
//
// 1. <mi>sin</mi> <mo>&ApplyFunction;</mo> <mi>x</mi>
// 2. <mi>x</mi> <mo>&InvisibileTime;</mo> <mi>sin</mi>
//
// the trick to get the inter-space in either situation
// is to promote "<mi>sin</mi><mo>&ApplyFunction;</mo>" and
// "<mo>&InvisibileTime;</mo><mi>sin</mi>" to user-defined operators...
if (firstType == eMathMLFrameType_UprightIdentifier) {
firstType = eMathMLFrameType_OperatorUserDefined;
}
else if (secondType == eMathMLFrameType_UprightIdentifier) {
secondType = eMathMLFrameType_OperatorUserDefined;
}
GET_INTERSPACE(aScriptLevel, firstType, secondType, space);
// Now, we have two values: the computed space and the space that
// has been carried forward until now. Which value do we pick?
// If the second type is an operator (e.g., fence), it already has
// built-in lspace & rspace, so we let them win. Otherwise we pick
// the max between the two values that we have.
if (secondType != eMathMLFrameType_OperatorVisible &&
if (secondType != eMathMLFrameType_OperatorOrdinary &&
space < *aCarrySpace)
space = *aCarrySpace;

View File

@ -66,13 +66,13 @@ NS_IMETHODIMP
nsMathMLFrame::InheritAutomaticData(nsIFrame* aParent)
{
mEmbellishData.flags = 0;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
mEmbellishData.leftSpace = 0;
mEmbellishData.rightSpace = 0;
mPresentationData.flags = 0;
mPresentationData.baseFrame = nsnull;
mPresentationData.mstyle = nsnull;
mPresentationData.scriptLevel = 0;
@ -147,7 +147,6 @@ nsMathMLFrame::GetEmbellishDataFrom(nsIFrame* aFrame,
{
// initialize OUT params
aEmbellishData.flags = 0;
aEmbellishData.nextFrame = nsnull;
aEmbellishData.coreFrame = nsnull;
aEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
aEmbellishData.leftSpace = 0;
@ -171,6 +170,7 @@ nsMathMLFrame::GetPresentationDataFrom(nsIFrame* aFrame,
{
// initialize OUT params
aPresentationData.flags = 0;
aPresentationData.baseFrame = nsnull;
aPresentationData.mstyle = nsnull;
aPresentationData.scriptLevel = 0;

View File

@ -80,9 +80,21 @@ nsMathMLTokenFrame::~nsMathMLTokenFrame()
nsIAtom*
nsMathMLTokenFrame::GetType() const
{
// treat everything other than <mi> as ordinary...
if (mContent->Tag() != nsMathMLAtoms::mi_) {
return nsMathMLAtoms::ordinaryMathMLFrame;
}
// for <mi>, distinguish between italic and upright...
nsAutoString value;
mContent->GetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfontstyle, value);
// treat invariant the same as italic to inherit its inter-space properties
return value.EqualsLiteral("normal")
? nsMathMLAtoms::uprightIdentifierMathMLFrame
: nsMathMLAtoms::italicIdentifierMathMLFrame;
}
static void
CompressWhitespace(nsIContent* aContent)
{
@ -316,34 +328,23 @@ nsMathMLTokenFrame::SetTextStyle(nsPresContext* aPresContext)
}
}
// attributes may override the default behavior
PRInt32 length = data.Length();
if (!length)
return;
// attributes may override the default behavior
nsAutoString fontstyle;
PRBool restyle = PR_TRUE;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::fontstyle_, fontstyle))
restyle = PR_FALSE;
if (1 == length) {
// our textual content consists of a single character
PRBool isStyleInvariant = nsMathMLOperators::LookupInvariantChar(data[0]);
if (isStyleInvariant) {
// bug 65951 - we always enforce the style to normal for a non-stylable char
// XXX also disable bold type? (makes sense to let the set IR be bold, no?)
fontstyle.AssignLiteral("normal");
restyle = PR_TRUE;
GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::fontstyle_, fontstyle);
if (1 == length && nsMathMLOperators::LookupInvariantChar(data[0])) {
// bug 65951 - a non-stylable character has its own intrinsic appearance
fontstyle.AssignLiteral("invariant");
}
else {
fontstyle.AssignLiteral("italic");
}
}
else {
// our textual content consists of multiple characters
fontstyle.AssignLiteral("normal");
if (fontstyle.IsEmpty()) {
fontstyle.AssignASCII((1 == length) ? "italic" : "normal");
}
// set the -moz-math-font-style attribute without notifying that we want a reflow
if (restyle)
mContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::fontstyle, fontstyle, PR_FALSE);
mContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfontstyle, fontstyle, PR_FALSE);
// then, re-resolve the style contexts in our subtree
nsFrameManager *fm = aPresContext->FrameManager();

View File

@ -222,10 +222,8 @@ nsMathMLmactionFrame::GetSelectedFrame()
// if the selected child is an embellished operator,
// we become embellished as well
mPresentationData.baseFrame = mSelectedFrame;
GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
mEmbellishData.nextFrame = mSelectedFrame; // yes!
}
return mSelectedFrame;
}

View File

@ -134,6 +134,13 @@ nsMathMLmfracFrame::Init(nsPresContext* aPresContext,
return rv;
}
nsIAtom*
nsMathMLmfracFrame::GetType() const
{
// frac is "inner" in TeXBook, Appendix G, rule 15e. See also page 170.
return nsMathMLAtoms::innerMathMLFrame;
}
NS_IMETHODIMP
nsMathMLmfracFrame::TransmitAutomaticData()
{
@ -158,9 +165,6 @@ nsMathMLmfracFrame::TransmitAutomaticData()
// even when embellished, we need to record that <mfrac> won't fire
// Stretch() on its embellished child
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
// break the embellished hierarchy to stop propagating the stretching
// process, but keep access to mEmbellishData.coreFrame for convenience
mEmbellishData.nextFrame = nsnull;
}
return NS_OK;

View File

@ -93,6 +93,8 @@ public:
virtual nsStyleContext*
GetAdditionalStyleContext(PRInt32 aIndex) const;
virtual nsIAtom* GetType() const;
NS_IMETHOD
AttributeChanged(nsIContent* aChild,
PRInt32 aNameSpaceID,

View File

@ -80,9 +80,8 @@ NS_IMETHODIMP
nsMathMLmmultiscriptsFrame::TransmitAutomaticData()
{
// if our base is an embellished operator, let its state bubble to us
GetEmbellishDataFrom(mFrames.FirstChild(), mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = mFrames.FirstChild();
mPresentationData.baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(mPresentationData.baseFrame, mEmbellishData);
// The REC says:
// The <mmultiscripts> element increments scriptlevel by 1, and sets
@ -132,7 +131,6 @@ nsMathMLmmultiscriptsFrame::ProcessAttributes()
{
mSubScriptShift = 0;
mSupScriptShift = 0;
mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
// check if the subscriptshift attribute is there
nsAutoString value;
@ -181,6 +179,11 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
nscoord ruleSize;
GetRuleThickness (aRenderingContext, fm, ruleSize);
// scriptspace from TeX for extra spacing after sup/subscript (0.5pt in plain TeX)
// forced to be at least 1 pixel here
nscoord onePixel = GetPresContext()->IntScaledPixelsToTwips(1);
nscoord scriptSpace = PR_MAX(NSFloatPointsToTwips(0.5f), onePixel);
/////////////////////////////////////
// first the shift for the subscript
@ -287,6 +290,8 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetItalicCorrection(bmBase, italicCorrection);
// for the superscript, we always add "a little to spare"
italicCorrection += onePixel;
// we update mBoundingMetrics.{ascent,descent} with that
// of the baseFrame only after processing all the sup/sub pairs
@ -310,8 +315,8 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
PR_MAX(mBoundingMetrics.descent,bmSubScript.descent);
aDesiredSize.descent =
PR_MAX(aDesiredSize.descent,subScriptSize.descent);
width = bmSubScript.width + mScriptSpace;
rightBearing = bmSubScript.rightBearing + mScriptSpace;
width = bmSubScript.width + scriptSpace;
rightBearing = bmSubScript.rightBearing;
}
else {
// supscript
@ -331,8 +336,8 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
PR_MAX(mBoundingMetrics.ascent,bmSupScript.ascent);
aDesiredSize.ascent =
PR_MAX(aDesiredSize.ascent,supScriptSize.ascent);
width = PR_MAX(width, bmSupScript.width + mScriptSpace);
rightBearing = PR_MAX(rightBearing, bmSupScript.rightBearing + mScriptSpace);
width = PR_MAX(width, bmSupScript.width + scriptSpace);
rightBearing = PR_MAX(rightBearing, bmSupScript.rightBearing);
if (!mprescriptsFrame) { // we are still looping over base & postscripts
mBoundingMetrics.rightBearing = mBoundingMetrics.width + rightBearing;
@ -428,7 +433,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
childFrame = baseFrame;
dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild (baseFrame, GetPresContext(), nsnull, baseSize, dx, dy, 0);
dx += bmBase.width + mScriptSpace + italicCorrection;
dx += bmBase.width + italicCorrection;
}
else if (mprescriptsFrame != childFrame) {
// process each sup/sub pair
@ -458,7 +463,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIRenderingContext& aRenderingContext,
FinishReflowChild (supScriptFrame, GetPresContext(), nsnull, supScriptSize,
dx + (width-supScriptSize.width)/2, dy, 0);
dx += mScriptSpace + width;
dx += width + scriptSpace;
}
}
childFrame = childFrame->GetNextSibling();

View File

@ -66,8 +66,6 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
private:
nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript
// = 0.5pt in plain TeX
nscoord mSubScriptShift;
nscoord mSupScriptShift;

View File

@ -89,24 +89,9 @@ static const PRUnichar kNullCh = PRUnichar('\0');
nsIAtom*
nsMathMLmoFrame::GetType() const
{
if (mFrames.GetLength() > 1) {
return nsMathMLAtoms::operatorVisibleMathMLFrame;
}
nsAutoString data;
((nsMathMLChar&)mMathMLChar).GetData(data); // VC++ insists for this cast :-(
PRInt32 length = data.Length();
PRUnichar ch = (length == 0) ? kNullCh : data[0];
if (length > 1)
return nsMathMLAtoms::operatorVisibleMathMLFrame;
if (ch == kInvisibleComma ||
ch == kApplyFunction ||
ch == kInvisibleTimes ||
ch == kNullCh)
return nsMathMLAtoms::operatorInvisibleMathMLFrame;
return nsMathMLAtoms::operatorVisibleMathMLFrame;
return NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)
? nsMathMLAtoms::operatorInvisibleMathMLFrame
: nsMathMLAtoms::operatorOrdinaryMathMLFrame;
}
// since a mouse click implies selection, we cannot just rely on the
@ -161,7 +146,8 @@ nsMathMLmoFrame::Paint(nsPresContext* aPresContext,
PRBool useMathMLChar =
(NS_MATHML_OPERATOR_GET_FORM(mFlags) &&
NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags);
NS_MATHML_OPERATOR_IS_CENTERED(mFlags) ||
NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags);
if (!useMathMLChar || NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
// let the base class paint the background, border, outline
@ -201,21 +187,12 @@ nsMathMLmoFrame::ProcessTextData(nsPresContext* aPresContext)
{
mFlags = 0;
// don't bother doing anything special if we don't have a
// single child with a text content
nsAutoString data;
if (mFrames.GetLength() != 1) {
mMathMLChar.SetData(aPresContext, data); // empty data to reset the char
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mMathMLChar, PR_FALSE);
return;
}
// kids can be comment-nodes, attribute-nodes, text-nodes...
// we use the DOM to ensure that we only look at text-nodes...
nsAutoString data;
PRUint32 numKids = mContent->GetChildCount();
for (PRUint32 kid = 0; kid < numKids; ++kid) {
nsCOMPtr<nsIDOMText> kidText(do_QueryInterface(mContent->GetChildAt(kid)));
if (kidText) {
nsAutoString kidData;
kidText->GetData(kidData);
@ -223,12 +200,29 @@ nsMathMLmoFrame::ProcessTextData(nsPresContext* aPresContext)
}
}
PRInt32 length = data.Length();
PRUnichar ch = (length == 0) ? kNullCh : data[0];
if ((length == 1) &&
(ch == kInvisibleComma ||
ch == kApplyFunction ||
ch == kInvisibleTimes)) {
mFlags |= NS_MATHML_OPERATOR_INVISIBLE;
}
// don't bother doing anything special if we don't have a
// single child with a visible text content
if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags) || mFrames.GetLength() != 1) {
data.Truncate(); // empty data to reset the char
mMathMLChar.SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mMathMLChar, PR_FALSE);
return;
}
// special... in math mode, the usual minus sign '-' looks too short, so
// what we do here is to remap <mo>-</mo> to the official Unicode minus
// sign (U+2212) which looks much better. For background on this, see
// http://groups.google.com/groups?hl=en&th=66488daf1ade7635&rnum=1
if (1 == length && data[0] == '-') {
if (1 == length && ch == '-') {
data = PRUnichar(0x2212);
mFlags |= NS_MATHML_OPERATOR_CENTERED;
}
@ -259,7 +253,6 @@ nsMathMLmoFrame::ProcessTextData(nsPresContext* aPresContext)
// see if this is an operator that should be centered to cater for
// fonts that are not math-aware
if (1 == length) {
PRUnichar ch = data[0];
if ((ch == '+') || (ch == '=') || (ch == '*') ||
(ch == 0x2264) || // &le;
(ch == 0x2265) || // &ge;
@ -300,7 +293,8 @@ nsMathMLmoFrame::ProcessOperatorData()
mFlags &= NS_MATHML_OPERATOR_MUTABLE |
NS_MATHML_OPERATOR_ACCENT |
NS_MATHML_OPERATOR_MOVABLELIMITS |
NS_MATHML_OPERATOR_CENTERED;
NS_MATHML_OPERATOR_CENTERED |
NS_MATHML_OPERATOR_INVISIBLE;
if (!mEmbellishData.coreFrame) {
// i.e., we haven't been here before, the default form is infix
@ -309,7 +303,6 @@ nsMathMLmoFrame::ProcessOperatorData()
// reset everything so that we don't keep outdated values around
// in case of dynamic changes
mEmbellishData.flags = 0;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.leftSpace = 0;
mEmbellishData.rightSpace = 0;
@ -649,7 +642,8 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
PRBool useMathMLChar =
(NS_MATHML_OPERATOR_GET_FORM(mFlags) &&
NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) ||
NS_MATHML_OPERATOR_IS_CENTERED(mFlags);
NS_MATHML_OPERATOR_IS_CENTERED(mFlags) ||
NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags);
nsBoundingMetrics charSize;
if (useMathMLChar) {
@ -960,6 +954,27 @@ nsMathMLmoFrame::Reflow(nsPresContext* aPresContext,
// certain values use units that depend on our style context, so
// it is safer to just process the whole lot here
ProcessOperatorData();
// play safe by not passing invisible operators to the font subsystem because
// some platforms risk selecting strange glyphs for them and give bad inter-space
if (NS_MATHML_OPERATOR_IS_INVISIBLE(mFlags)) {
// return empty space for now, but this is not yet final since there
// can be lspace and rspace attributes that reclaim some room.
// These will be dealt with later in Stretch().
aDesiredSize.width = 0;
aDesiredSize.height = 0;
aDesiredSize.ascent = 0;
aDesiredSize.descent = 0;
if (aDesiredSize.mComputeMEW) {
aDesiredSize.mMaxElementWidth = 0;
}
aDesiredSize.mBoundingMetrics.Clear();
aStatus = NS_FRAME_COMPLETE;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
return nsMathMLTokenFrame::Reflow(aPresContext, aDesiredSize,
aReflowState, aStatus);
}

View File

@ -197,9 +197,8 @@ XXX The winner is the outermost in conflicting settings like these:
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
mPresentationData.baseFrame = baseFrame;
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsAutoString value;

View File

@ -80,10 +80,8 @@ NS_IMETHODIMP
nsMathMLmsubFrame::TransmitAutomaticData()
{
// if our base is an embellished operator, let its state bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
mPresentationData.baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(mPresentationData.baseFrame, mEmbellishData);
// 1. The REC says:
// The <msub> element increments scriptlevel by 1, and sets displaystyle to
@ -101,7 +99,7 @@ nsMathMLmsubFrame::Place (nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
// extra spacing between base and sup/subscript
// extra spacing after sup/subscript
nscoord scriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
// check if the subscriptshift attribute is there
@ -203,16 +201,12 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
PR_MAX(bmBase.ascent, bmSubScript.ascent - actualSubScriptShift);
boundingMetrics.descent =
PR_MAX(bmBase.descent, bmSubScript.descent + actualSubScriptShift);
// add aScriptSpace between base and supscript
boundingMetrics.width =
bmBase.width
+ aScriptSpace
+ bmSubScript.width;
// add aScriptSpace to the subscript's width
boundingMetrics.width = bmBase.width + bmSubScript.width + aScriptSpace;
boundingMetrics.leftBearing = bmBase.leftBearing;
boundingMetrics.rightBearing =
bmBase.width
+ aScriptSpace
+ bmSubScript.rightBearing;
boundingMetrics.rightBearing = PR_MAX(bmBase.rightBearing, bmBase.width +
PR_MAX(bmSubScript.width + aScriptSpace, bmSubScript.rightBearing));
mathMLFrame->SetBoundingMetrics (boundingMetrics);
// reflow metrics
@ -221,7 +215,7 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
aDesiredSize.descent =
PR_MAX(baseSize.descent, subScriptSize.descent + actualSubScriptShift);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = bmBase.width + aScriptSpace + subScriptSize.width;
aDesiredSize.width = boundingMetrics.width;
aDesiredSize.mBoundingMetrics = boundingMetrics;
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
@ -232,9 +226,7 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0);
// ... and subscript
// XXX adding mScriptSpace seems to add more space than i like
// may want to remove later.
dx = bmBase.width + aScriptSpace;
dx = bmBase.width;
dy = aDesiredSize.ascent - (subScriptSize.ascent - actualSubScriptShift);
FinishReflowChild (subScriptFrame, aPresContext, nsnull, subScriptSize, dx, dy, 0);
}

View File

@ -80,10 +80,8 @@ NS_IMETHODIMP
nsMathMLmsubsupFrame::TransmitAutomaticData()
{
// if our base is an embellished operator, let its state bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
mPresentationData.baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(mPresentationData.baseFrame, mEmbellishData);
// 1. The REC says:
// The <msubsup> element increments scriptlevel by 1, and sets displaystyle to
@ -326,14 +324,17 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
boundingMetrics.descent =
PR_MAX(bmBase.descent, (bmSubScript.descent + subScriptShift));
// add aScriptSpace to both super/subscript
// add italicCorrection only to superscript
// leave aScriptSpace after both super/subscript
// add italicCorrection between base and superscript
// add "a little to spare" as well (see TeXbook Ch.11, p.64), as we
// estimate the italic creation ourselves and it isn't the same as TeX
nscoord italicCorrection;
GetItalicCorrection(bmBase, italicCorrection);
italicCorrection += onePixel;
boundingMetrics.width = bmBase.width + aScriptSpace +
PR_MAX((italicCorrection + bmSupScript.width), bmSubScript.width);
boundingMetrics.leftBearing = bmBase.leftBearing;
boundingMetrics.rightBearing = bmBase.width + aScriptSpace +
boundingMetrics.rightBearing = bmBase.width +
PR_MAX((italicCorrection + bmSupScript.rightBearing), bmSubScript.rightBearing);
mathMLFrame->SetBoundingMetrics(boundingMetrics);
@ -347,8 +348,7 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
PR_MAX(subScriptSize.descent + subScriptShift,
supScriptSize.descent - supScriptShift));
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = bmBase.width + aScriptSpace +
PR_MAX((italicCorrection + supScriptSize.width), subScriptSize.width);
aDesiredSize.width = boundingMetrics.width;
aDesiredSize.mBoundingMetrics = boundingMetrics;
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
@ -360,12 +360,12 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
FinishReflowChild(baseFrame, aPresContext, nsnull,
baseSize, dx, dy, 0);
// ... and subscript
dx = bmBase.width + aScriptSpace;
dx = bmBase.width;
dy = aDesiredSize.ascent - (subScriptSize.ascent - subScriptShift);
FinishReflowChild(subScriptFrame, aPresContext, nsnull,
subScriptSize, dx, dy, 0);
// ... and the superscript
dx = bmBase.width + aScriptSpace + italicCorrection;
dx = bmBase.width + italicCorrection;
dy = aDesiredSize.ascent - (supScriptSize.ascent + supScriptShift);
FinishReflowChild(supScriptFrame, aPresContext, nsnull,
supScriptSize, dx, dy, 0);

View File

@ -79,10 +79,8 @@ NS_IMETHODIMP
nsMathMLmsupFrame::TransmitAutomaticData()
{
// if our base is an embellished operator, its flags bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
mPresentationData.baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(mPresentationData.baseFrame, mEmbellishData);
// 1. The REC says:
// The <msup> element increments scriptlevel by 1, and sets displaystyle to
@ -101,7 +99,7 @@ nsMathMLmsupFrame::Place(nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
// extra spacing between base and sup/subscript
// extra spacing after sup/subscript
nscoord scriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
// check if the superscriptshift attribute is there
@ -236,12 +234,17 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
PR_MAX(bmBase.ascent, (bmSupScript.ascent + actualSupScriptShift));
boundingMetrics.descent =
PR_MAX(bmBase.descent, (bmSupScript.descent - actualSupScriptShift));
// add scriptSpace between base and supscript
boundingMetrics.width = bmBase.width + aScriptSpace
+ italicCorrection + bmSupScript.width;
// leave aScriptSpace after superscript
// add italicCorrection between base and superscript
// add "a little to spare" as well (see TeXbook Ch.11, p.64), as we
// estimate the italic creation ourselves and it isn't the same as TeX
italicCorrection += onePixel;
boundingMetrics.width = bmBase.width + italicCorrection +
bmSupScript.width + aScriptSpace;
boundingMetrics.leftBearing = bmBase.leftBearing;
boundingMetrics.rightBearing = bmBase.width + aScriptSpace
+ italicCorrection + bmSupScript.rightBearing;
boundingMetrics.rightBearing = bmBase.width + italicCorrection +
bmSupScript.rightBearing;
mathMLFrame->SetBoundingMetrics(boundingMetrics);
// reflow metrics
@ -250,8 +253,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
aDesiredSize.descent =
PR_MAX(baseSize.descent, (supScriptSize.descent - actualSupScriptShift));
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = bmBase.width + aScriptSpace
+ italicCorrection + supScriptSize.width;
aDesiredSize.width = boundingMetrics.width;
aDesiredSize.mBoundingMetrics = boundingMetrics;
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
@ -262,7 +264,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
dx = 0; dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild (baseFrame, aPresContext, nsnull, baseSize, dx, dy, 0);
// ... and supscript
dx = bmBase.width + aScriptSpace + italicCorrection;
dx = bmBase.width + italicCorrection;
dy = aDesiredSize.ascent - (supScriptSize.ascent + actualSupScriptShift);
FinishReflowChild (supScriptFrame, aPresContext, nsnull, supScriptSize, dx, dy, 0);
}

View File

@ -229,20 +229,20 @@ MapAttributesInto(nsPresContext* aPresContext,
// set the special -moz-math-rowline without notifying that we want a reflow
if (attr) {
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::rowline, nsDependentString(attr), PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZrowline, nsDependentString(attr), PR_FALSE);
}
}
else {
// set the special -moz-math-firstrow to annotate that we are on the first row
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::firstrow, trueStr, PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfirstrow, trueStr, PR_FALSE);
}
// if we are on the last row, set the special -moz-math-lastrow
PRInt32 rowSpan = ((nsTableFrame*)tableFrame)->GetEffectiveRowSpan(*cellFrame);
sibling = ((nsTableFrame*)tableFrame)->GetCellFrameAt(rowIndex+rowSpan, colIndex);
if (!sibling) {
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::lastrow, trueStr, PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZlastrow, trueStr, PR_FALSE);
}
//////////////////////////////////////
@ -274,20 +274,20 @@ MapAttributesInto(nsPresContext* aPresContext,
// set the special -moz-math-columnline without notifying that we want a reflow
if (attr) {
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::columnline, nsDependentString(attr), PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZcolumnline, nsDependentString(attr), PR_FALSE);
}
}
else {
// set the special -moz-math-firstcolumn to annotate that we are on the first column
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::firstcolumn, trueStr, PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZfirstcolumn, trueStr, PR_FALSE);
}
// if we are on the last column, set the special -moz-math-lastcolumn
PRInt32 colSpan = ((nsTableFrame*)tableFrame)->GetEffectiveColSpan(*cellFrame);
sibling = ((nsTableFrame*)tableFrame)->GetCellFrameAt(rowIndex, colIndex+colSpan);
if (!sibling) {
hasChanged = PR_TRUE;
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::lastcolumn, trueStr, PR_FALSE);
aCellContent->SetAttr(kNameSpaceID_None, nsMathMLAtoms::MOZlastcolumn, trueStr, PR_FALSE);
}
// now, re-resolve the style contexts in our subtree to pick up any changes

View File

@ -197,9 +197,8 @@ XXX The winner is the outermost setting in conflicting settings like these:
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
mPresentationData.baseFrame = baseFrame;
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsAutoString value;

View File

@ -201,9 +201,8 @@ nsMathMLmunderoverFrame::TransmitAutomaticData()
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
mPresentationData.baseFrame = baseFrame;
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsAutoString value;

View File

@ -79,6 +79,9 @@ math[display="inline"] {
[-moz-math-font-style="normal"] {
font-style: normal; /* if the textual content consists of multiple characters */
}
[-moz-math-font-style="invariant"] {
font-style: normal; /* a non-stylable character preserves its own style */
}
/* change of size induced by changing the scriptlevel */
[-moz-math-font-size="+1"] {
font-size: 71%;

View File

@ -54,20 +54,22 @@
******/
MATHML_ATOM(fontsize, "-moz-math-font-size") // different from fontsize_
MATHML_ATOM(fontstyle, "-moz-math-font-style") // different from fontstyle_
MATHML_ATOM(rowline, "-moz-math-rowline") // different from rowlines_
MATHML_ATOM(columnline, "-moz-math-columnline") // different from columnlines_
MATHML_ATOM(firstrow, "-moz-math-firstrow")
MATHML_ATOM(lastrow, "-moz-math-lastrow")
MATHML_ATOM(firstcolumn, "-moz-math-firstcolumn")
MATHML_ATOM(lastcolumn, "-moz-math-lastcolumn")
MATHML_ATOM(MOZfontsize, "-moz-math-font-size") // different from fontsize_
MATHML_ATOM(MOZfontstyle, "-moz-math-font-style") // different from fontstyle_
MATHML_ATOM(MOZrowline, "-moz-math-rowline") // different from rowlines_
MATHML_ATOM(MOZcolumnline, "-moz-math-columnline") // different from columnlines_
MATHML_ATOM(MOZfirstrow, "-moz-math-firstrow")
MATHML_ATOM(MOZlastrow, "-moz-math-lastrow")
MATHML_ATOM(MOZfirstcolumn, "-moz-math-firstcolumn")
MATHML_ATOM(MOZlastcolumn, "-moz-math-lastcolumn")
// Alphabetical list of MathML frame types
MATHML_ATOM(operatorVisibleMathMLFrame, "OperatorVisibleMathMLFrame")
MATHML_ATOM(operatorInvisibleMathMLFrame, "OperatorInvisibleMathMLFrame")
MATHML_ATOM(ordinaryMathMLFrame, "OrdinaryMathMLFrame")
MATHML_ATOM(schemataMathMLFrame, "SchemataMathMLFrame") // 'inner' in TeX
MATHML_ATOM(operatorOrdinaryMathMLFrame, "OperatorOrdinaryMathMLFrame")
MATHML_ATOM(operatorInvisibleMathMLFrame, "OperatorInvisibleMathMLFrame")
MATHML_ATOM(operatorUserDefinedMathMLFrame, "OperatorUserDefinedMathMLFrame")
MATHML_ATOM(innerMathMLFrame, "InnerMathMLFrame") // 'inner' in TeX
MATHML_ATOM(italicIdentifierMathMLFrame, "ItalicIdentifierMathMLFrame")
MATHML_ATOM(uprightIdentifierMathMLFrame, "UprightIdentifierMathMLFrame")
MATHML_ATOM(abs_, "abs")

View File

@ -50,13 +50,13 @@ typedef PRInt32 nsStretchDirection;
// define the bits used to handle the operator
#define NS_MATHML_OPERATOR_MUTABLE 0x80000000 // the very first bit
#define NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR 0x40000000 // the second bit
#define NS_MATHML_OPERATOR_EMBELLISH_ISOLATED 0x20000000 // the third bit
#define NS_MATHML_OPERATOR_CENTERED 0x10000000 // the fourth bit
#define NS_MATHML_OPERATOR_MUTABLE (1<<31)
#define NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR (1<<30)
#define NS_MATHML_OPERATOR_EMBELLISH_ISOLATED (1<<29)
#define NS_MATHML_OPERATOR_CENTERED (1<<28)
#define NS_MATHML_OPERATOR_INVISIBLE (1<<27)
// define the bits used in the Operator Dictionary
// XXX replace with the PR_BIT(n) macro
#define NS_MATHML_OPERATOR_FORM 0x3 // the very last two bits tell us the form
#define NS_MATHML_OPERATOR_FORM_INFIX 1
@ -164,6 +164,9 @@ public:
#define NS_MATHML_OPERATOR_IS_CENTERED(_flags) \
(NS_MATHML_OPERATOR_CENTERED == ((_flags) & NS_MATHML_OPERATOR_CENTERED))
#define NS_MATHML_OPERATOR_IS_INVISIBLE(_flags) \
(NS_MATHML_OPERATOR_INVISIBLE == ((_flags) & NS_MATHML_OPERATOR_INVISIBLE))
#define NS_MATHML_OPERATOR_GET_FORM(_flags) \
((_flags) & NS_MATHML_OPERATOR_FORM)