diff --git a/mozilla/layout/mathml/base/src/Makefile.in b/mozilla/layout/mathml/base/src/Makefile.in index a7add1937a1..1e61042c4cc 100644 --- a/mozilla/layout/mathml/base/src/Makefile.in +++ b/mozilla/layout/mathml/base/src/Makefile.in @@ -39,6 +39,7 @@ LOCAL_INCLUDES = \ $(NULL) CPPSRCS = nsMathMLChar.cpp \ + nsMathMLFrame.cpp \ nsMathMLContainerFrame.cpp \ nsMathMLmrowFrame.cpp \ nsMathMLmphantomFrame.cpp \ diff --git a/mozilla/layout/mathml/base/src/makefile.win b/mozilla/layout/mathml/base/src/makefile.win index f54d0f7bebf..c07ece83ce8 100644 --- a/mozilla/layout/mathml/base/src/makefile.win +++ b/mozilla/layout/mathml/base/src/makefile.win @@ -28,6 +28,7 @@ MODULE=raptor DEFINES= -DWIN32_LEAN_AND_MEAN CPPSRCS= nsMathMLChar.cpp \ + nsMathMLFrame.cpp \ nsMathMLContainerFrame.cpp \ nsMathMLmrowFrame.obj \ nsMathMLmphantomFrame.cpp \ @@ -54,6 +55,7 @@ CPPSRCS= nsMathMLChar.cpp \ $(NULL) CPP_OBJS= .\$(OBJDIR)\nsMathMLChar.obj \ + .\$(OBJDIR)\nsMathMLFrame.obj \ .\$(OBJDIR)\nsMathMLContainerFrame.obj \ .\$(OBJDIR)\nsMathMLmrowFrame.obj \ .\$(OBJDIR)\nsMathMLmphantomFrame.obj \ diff --git a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h index 757ec877245..5998ba0c1a8 100644 --- a/mozilla/layout/mathml/base/src/nsIMathMLFrame.h +++ b/mozilla/layout/mathml/base/src/nsIMathMLFrame.h @@ -33,6 +33,7 @@ struct nsEmbellishData; static NS_DEFINE_IID(kIMathMLFrameIID, NS_IMATHMLFRAME_IID); +// Abstract base class that provides additional methods for MathML frames class nsIMathMLFrame : public nsISupports { public: static const nsIID& GetIID() { static nsIID iid = NS_IMATHMLFRAME_IID; return iid; } @@ -61,7 +62,7 @@ public: SetReference(const nsPoint& aReference) = 0; - /* SUPPORT FOR STRETCHY ELEMENTS: */ + /* SUPPORT FOR STRETCHY ELEMENTS */ /*====================================================================*/ /* Stretch : @@ -166,7 +167,7 @@ public: SetEmbellishData(const nsEmbellishData& aEmbellishData) = 0; - /* SUPPORT FOR SCRIPTING ELEMENTS: */ + /* SUPPORT FOR SCRIPTING ELEMENTS */ /*====================================================================*/ /* GetPresentationData/SetPresentationData : @@ -244,18 +245,48 @@ public: * for more details about this parameter. */ NS_IMETHOD - UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) = 0; + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) = 0; + + /* ReResolveScriptStyle : + * During frame construction, the Style System gives us style contexts in + * which the sizes of the fonts are not suitable for scripting elements. + * Our expected behavior is that, when given the markup base arguments, + * we want to render the 'base' in a normal size, and the 'arguments' in a smaller + * size. This is a common functionality to tags like msub, msup, msubsup, mover, + * munder, munderover, mmultiscripts. Moreover, we want the reduction of the font + * size to happen in a top-down manner within the hierarchies of sub-expressions; + * and more importantly, we don't want the sizes to keep decreasing up to a point + * where the scripts become unreadably small. + * + * In general, this scaling effet arises when the scriptlevel changes between a + * parent and a child. Whenever the scriptlevel changes, either automatically or + * by being explicitly incremented, decremented, or set, the current font size has + * to be multiplied by the predefined value of 'scriptsizemultiplier' to the power + * of the change in the scriptlevel, and this scaling effect (downwards or upwards) + * has to be propagated down the subtrees, with the caveat that the font size is + * never allowed to go below the predefined value of 'scriptminsize' within a + * sub-expression. + * + * ReResolveScriptStyle() will walk a subtree to cause this mathml-specific behavior + * to happen. The method is recursive and only a top-level parent wishing to reflect + * the changes in its children needs to call to the method. + */ + NS_IMETHOD + ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel) = 0; }; // 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, + PRInt32 scriptLevel; // Relevant to nested frames within: msub, msup, msubsup, munder, // mover, munderover, mmultiscripts, mfrac, mroot, mtable. nsPresentationData() { @@ -283,7 +314,7 @@ struct nsEmbellishData { } }; -// ------------- +// ========================================================================== // Bits used for the presentation flags -- these bits are set // in their relevant situation as they become available @@ -333,6 +364,7 @@ struct nsEmbellishData { #define NS_MATHML_SHOW_BOUNDING_METRICS 0x40000000 // Macros that retrieve those bits + #define NS_MATHML_IS_DISPLAYSTYLE(_flags) \ (NS_MATHML_DISPLAYSTYLE == ((_flags) & NS_MATHML_DISPLAYSTYLE)) @@ -360,7 +392,7 @@ struct nsEmbellishData { #define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \ (NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS)) -// -------------- +// ========================================================================== // Bits used for the embellish flags -- these bits are set // in their relevant situation as they become available @@ -390,7 +422,6 @@ struct nsEmbellishData { // a bit used for debug #define NS_MATHML_STRETCH_DONE 0x80000000 - // Macros that retrieve those bits #define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \ diff --git a/mozilla/layout/mathml/base/src/nsMathMLChar.cpp b/mozilla/layout/mathml/base/src/nsMathMLChar.cpp index 829eb25c02a..178c831a7ae 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLChar.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLChar.cpp @@ -288,7 +288,7 @@ nsGlyphTable::ElementAt(nsMathMLChar* aChar, PRUint32 aPosition) offset += 5; child = child->mSibling; } - length = offset + 5; // stay confined in the glyphs of this child + length = offset + 4; // stay confined in the glyphs of this child } PRUint32 index = offset + aPosition; if (index >= length) return 0; @@ -305,7 +305,7 @@ nsGlyphTable::IsComposite(nsMathMLChar* aChar) // shortcut to sync the cache with this char... mCharCache = 0; mGlyphCache.Truncate(); ElementAt(aChar, 0); // the cache remained empty if the char wasn't found in this table - if (4 > mGlyphCache.Length()) return PR_FALSE; + if (4 >= mGlyphCache.Length()) return PR_FALSE; // the lists of glyphs of a composite char are space-separated return (kSpaceCh == mGlyphCache.CharAt(4)); } @@ -327,7 +327,7 @@ nsGlyphTable::Has(nsMathMLChar* aChar) // shortcut to sync the cache with this char... mCharCache = 0; mGlyphCache.Truncate(); ElementAt(aChar, 0); // the cache remained empty if the char wasn't found in this table - if (4 > mGlyphCache.Length()) return PR_FALSE; + if (4 >= mGlyphCache.Length()) return PR_FALSE; // see if this char is in the table as a single or as a composite char nsGlyphCode ch = mGlyphCache.CharAt(4); return ((aChar->mData[0] == ch) || (kSpaceCh == ch)); @@ -407,7 +407,7 @@ public: NS_INIT_ISUPPORTS(); } - ~nsGlyphTableList() + virtual ~nsGlyphTableList() { MOZ_COUNT_DTOR(nsGlyphTableList); } @@ -515,6 +515,7 @@ nsGlyphTableList::AddGlyphTable(nsIPresContext* aPresContext, deviceContext->GetLocalFontName(fontName, localName, aliased); if (aliased || (NS_OK == deviceContext->CheckFontExistence(localName))) { // allocate a table to be deleted at shutdown + // (see bug 35824 for coments about the aliased localName) nsGlyphTable* glyphTable = new nsGlyphTable(aFontName); if (!glyphTable) return NS_ERROR_OUT_OF_MEMORY; mTableList.AppendElement(glyphTable); @@ -938,7 +939,7 @@ ComputeSizeFromParts(nsGlyphCode* aGlyphs, nsGlyphCode firstGlyph = aGlyphs[0]; nscoord firstSize = aSizes[0]; nsGlyphCode middleGlyph = aGlyphs[1]; nscoord middleSize = aSizes[1]; nsGlyphCode lastGlyph = aGlyphs[2]; nscoord lastSize = aSizes[2]; - nsGlyphCode glueGlyph = aGlyphs[3]; nscoord glueSize = aSizes[3]; + nsGlyphCode glueGlyph = aGlyphs[3]; //nscoord glueSize = aSizes[3]; float firstFlex = 1.0f, middleFlex = 1.0f, lastFlex = 1.0f; // refine the flexibility depending on whether some parts can be left out @@ -1025,9 +1026,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext, PRUint32(mData.Length()), mBoundingMetrics); if (NS_FAILED(rv)) { -#ifdef NS_DEBUG - printf("GetBoundingMetrics failed\n"); -#endif + NS_WARNING("GetBoundingMetrics failed"); // ensure that the char later behaves like a normal char mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; // XXX to reset in dynamic updates return rv; @@ -1044,7 +1043,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext, } // see if this is a particular largeop or largeopOnly request - PRBool largeop = (NS_STRETCH_LARGEOP & aStretchHint); + PRBool largeop = (PRBool)(NS_STRETCH_LARGEOP & aStretchHint); PRBool largeopOnly = (NS_STRETCH_LARGEOP == aStretchHint); // (==, not mask!) //////////////////////////////////////////////////////////////////////////////////// @@ -1202,15 +1201,14 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext, glyphTable->ChildCountOf(this), str, NS_SUCCEEDED(rv)? "OK" : "Rejected"); #endif - if (NS_SUCCEEDED(rv)) { - // all went well, painting will be delegated from now on to children - mGlyph = 0; // this will tell paint to build by parts - mGlyphTable = glyphTable; - mBoundingMetrics = compositeSize; - aDesiredStretchSize = compositeSize; - return NS_OK; // get out ... - } - continue; // to next table + if (NS_FAILED(rv)) continue; // to next table + + // all went well, painting will be delegated from now on to children + mGlyph = 0; // this will tell paint to build by parts + mGlyphTable = glyphTable; + mBoundingMetrics = compositeSize; + aDesiredStretchSize = compositeSize; + return NS_OK; // get out ... } // See if the parts of this table fit in the desired space /////////////////////// @@ -1237,10 +1235,8 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext, else { rv = glyphTable->GetBoundingMetrics(aRenderingContext, ch, bm); if (NS_FAILED(rv)) { -#ifdef NS_DEBUG - printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); -#endif // stop if we failed to compute the bounding metrics of a part. + NS_WARNING("GetBoundingMetrics failed"); break; } } @@ -1279,7 +1275,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext, if (rbearing < bm.rightBearing) rbearing = bm.rightBearing; } bestbm.width = width; - bestbm.ascent = bmdata[0].ascent; // XXX Yes top, so that it works with TeX sqrt! + bestbm.ascent = bmdata[0].ascent; // Yes top, so that it works with TeX sqrt! bestbm.descent = computedSize - bestbm.ascent; bestbm.leftBearing = lbearing; bestbm.rightBearing = rbearing; @@ -1375,7 +1371,6 @@ nsMathMLChar::ComposeChildren(nsIPresContext* aPresContext, child->mStyleContext = mStyleContext; child->mGlyphTable = aGlyphTable; // the child is associated to this table // there goes the Stretch() ... - // XXX maybe wrap some if's inside Stretch() to skip irrelevant things to child chars nsBoundingMetrics childSize; nsresult rv = child->Stretch(aPresContext, aRenderingContext, mDirection, splitSize, childSize, aStretchHint); @@ -1415,13 +1410,14 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext, nsIFrame* aForFrame) { nsresult rv = NS_OK; + nsCOMPtr parentContext; + parentContext = getter_AddRefs(mStyleContext->GetParent()); nsIStyleContext* styleContext = mStyleContext; - nsIStyleContext* parentContext = nsnull; if (NS_STRETCH_DIRECTION_UNSUPPORTED == mDirection) { // normal drawing if there is nothing special about this char - // Set default context to the parent context to be released at the end... - styleContext = parentContext = mStyleContext->GetParent(); + // Set default context to the parent context + styleContext = parentContext; } nsStyleDisplay display; @@ -1435,9 +1431,9 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext, // Paint our background and border PRIntn skipSides = 0; //aForFrame->GetSkipSides(); nsStyleBorder border; - mStyleContext->GetStyle(eStyleStruct_Border, border); + styleContext->GetStyle(eStyleStruct_Border, border); nsStyleOutline outline; - mStyleContext->GetStyle(eStyleStruct_Outline, outline); + styleContext->GetStyle(eStyleStruct_Outline, outline); nsRect rect(mRect); //0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, @@ -1512,7 +1508,6 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext, } } } - NS_IF_RELEASE(parentContext); return rv; } @@ -1558,9 +1553,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext, else { rv = aGlyphTable->GetBoundingMetrics(aRenderingContext, ch, bm); if (NS_FAILED(rv)) { -#ifdef NS_DEBUG - printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); -#endif + NS_WARNING("GetBoundingMetrics failed"); return rv; } } @@ -1734,9 +1727,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext, else { rv = aGlyphTable->GetBoundingMetrics(aRenderingContext, ch, bm); if (NS_FAILED(rv)) { -#ifdef NS_DEBUG - printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); -#endif + NS_WARNING("GetBoundingMetrics failed"); return rv; } if (dy < aRect.y - aFontAscent + bm.ascent) { diff --git a/mozilla/layout/mathml/base/src/nsMathMLChar.h b/mozilla/layout/mathml/base/src/nsMathMLChar.h index 02e27b221f6..1320a1e5728 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLChar.h +++ b/mozilla/layout/mathml/base/src/nsMathMLChar.h @@ -24,7 +24,7 @@ #define nsMathMLChar_h___ #include "nsMathMLOperators.h" -#include "nsIMathMLFrame.h" +#include "nsMathMLFrame.h" typedef PRUnichar nsGlyphCode; class nsGlyphTable; diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp index 46cb6b5d7a9..2b1b33abccd 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -38,6 +38,7 @@ #include "nsIFontMetrics.h" #include "nsStyleUtil.h" +#include "nsIDOMText.h" #include "nsITextContent.h" #include "nsMathMLAtoms.h" @@ -49,119 +50,46 @@ // nsMathMLContainerFrame implementation // -// TODO: Proper management of ignorable whitespace -// and handling of non-math related frames. -// * Should math markups only enclose other math markups? -// Why bother... we can leave them in, as hinted in the newsgroup. -// -// * Space doesn't count. Handling space is more complicated than it seems. -// We have to clean inside and outside: -// a + b -// ^ ^ ^ ^ ^ ^ ^ ^ -// *Outside* currently handled using IsOnlyWhitespace(). -// For whitespace only frames, their rect is set zero. -// -// *Inside* not currently handled... so the user must do a -// What to do?! -// - Add a nsTextFrame::CompressWhitespace() *if* it is MathML content?! -// - via CSS property? Support for "none/compress"? (white-space: normal | pre | nowrap) - - // nsISupports // ============================================================================= -NS_INTERFACE_MAP_BEGIN(nsMathMLContainerFrame) - NS_INTERFACE_MAP_ENTRY(nsIMathMLFrame) -#ifdef NS_DEBUG - NS_INTERFACE_MAP_ENTRY(nsIFrameDebug) -#endif - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMathMLFrame) -NS_INTERFACE_MAP_END_INHERITING(nsHTMLContainerFrame) +NS_IMPL_ADDREF_INHERITED(nsMathMLContainerFrame, nsMathMLFrame) +NS_IMPL_RELEASE_INHERITED(nsMathMLContainerFrame, nsMathMLFrame) +NS_IMPL_QUERY_INTERFACE_INHERITED1(nsMathMLContainerFrame, nsHTMLContainerFrame, nsMathMLFrame) -NS_IMETHODIMP_(nsrefcnt) -nsMathMLContainerFrame::AddRef(void) -{ - return NS_OK; -} - -NS_IMETHODIMP_(nsrefcnt) -nsMathMLContainerFrame::Release(void) -{ - return NS_OK; -} - -/* /////////////// - * MathML specific - Whitespace management ... - * WHITESPACE: don't forget that whitespace doesn't count in MathML! - * empty frames shouldn't be created in MathML, oh well that's another story. - * ============================================================================= - */ - -PRBool -nsMathMLContainerFrame::IsOnlyWhitespace(nsIFrame* aFrame) -{ - NS_PRECONDITION(aFrame, "null arg"); - - // quick return if we have encountered this frame before - nsFrameState state; - aFrame->GetFrameState(&state); - if (NS_FRAME_IS_UNFLOWABLE & state) - return PR_TRUE; - - // by empty frame we mean a leaf frame whose text content is empty... - PRBool rv = PR_FALSE; - nsCOMPtr aContent; - aFrame->GetContent(getter_AddRefs(aContent)); - if (!aContent) return PR_TRUE; - PRInt32 numKids; - aContent->ChildCount(numKids); - if (0 == numKids) { - nsCOMPtr tc(do_QueryInterface(aContent)); - if (tc.get()) tc->IsOnlyWhitespace(&rv); - } - if (rv) { - // mark the frame as unflowable - aFrame->SetFrameState(NS_FRAME_IS_UNFLOWABLE | state); - } - return rv; -} +// ============================================================================= // helper to get an attribute from the content or the surrounding hierarchy nsresult nsMathMLContainerFrame::GetAttribute(nsIContent* aContent, - nsIFrame* aMathMLmstyleFrame, + nsIFrame* aMathMLmstyleFrame, nsIAtom* aAttributeAtom, nsString& aValue) { nsresult rv = NS_CONTENT_ATTR_NOT_THERE; // see if we can get the attribute from the content - if (aContent) - { + if (aContent) { rv = aContent->GetAttribute(kNameSpaceID_None, aAttributeAtom, aValue); } - if (NS_CONTENT_ATTR_NOT_THERE == rv) - { + if (NS_CONTENT_ATTR_NOT_THERE == rv) { // see if we can get the attribute from the mstyle frame - if (aMathMLmstyleFrame) - { + if (aMathMLmstyleFrame) { nsCOMPtr mstyleContent; - aMathMLmstyleFrame->GetContent(getter_AddRefs(mstyleContent)); + aMathMLmstyleFrame->GetContent(getter_AddRefs(mstyleContent)); nsIFrame* mstyleParent; - aMathMLmstyleFrame->GetParent(&mstyleParent); + aMathMLmstyleFrame->GetParent(&mstyleParent); nsPresentationData mstyleParentData; mstyleParentData.mstyle = nsnull; - - if (mstyleParent) - { - nsIMathMLFrame* aMathMLFrame = nsnull; - rv = mstyleParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && nsnull != aMathMLFrame) - { - aMathMLFrame->GetPresentationData(mstyleParentData); + + if (mstyleParent) { + nsIMathMLFrame* mathMLFrame; + rv = mstyleParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetPresentationData(mstyleParentData); } } @@ -173,7 +101,7 @@ nsMathMLContainerFrame::GetAttribute(nsIContent* aContent, } void -nsMathMLContainerFrame::GetRuleThickness(nsIRenderingContext& aRenderingContext, +nsMathMLContainerFrame::GetRuleThickness(nsIRenderingContext& aRenderingContext, nsIFontMetrics* aFontMetrics, nscoord& aRuleThickness) { @@ -206,7 +134,7 @@ nsMathMLContainerFrame::GetRuleThickness(nsIRenderingContext& aRenderingContext, } void -nsMathMLContainerFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, +nsMathMLContainerFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, nsIFontMetrics* aFontMetrics, nscoord& aAxisHeight) { @@ -224,7 +152,7 @@ nsMathMLContainerFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, // fall-back to the other version GetAxisHeight(aFontMetrics, aAxisHeight); } - + #if 0 nscoord oldAxis; GetAxisHeight(aFontMetrics, oldAxis); @@ -232,7 +160,7 @@ nsMathMLContainerFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, PRUnichar plus = '+'; rv = aRenderingContext.GetBoundingMetrics(&plus, PRUint32(1), bm); nscoord plusAxis = bm.ascent - (bm.ascent + bm.descent)/2;; - + printf("xheight:%4d Axis:%4d oldAxis:%4d plusAxis:%4d\n", xHeight, aAxisHeight, oldAxis, plusAxis); #endif @@ -242,10 +170,10 @@ nsMathMLContainerFrame::GetAxisHeight(nsIRenderingContext& aRenderingContext, // Utilities for parsing and retrieving numeric values // All returned values are in twips. -/* +/* The REC says: An explicit plus sign ('+') is not allowed as part of a numeric value - except when it is specifically listed in the syntax (as a quoted '+' or "+"), + except when it is specifically listed in the syntax (as a quoted '+' or "+"), Units allowed ID Description @@ -314,20 +242,20 @@ printf("String:%s, Number:%s, Unit:%s\n", s1, s2, s3); nsCSSUnit cssUnit; if (0 == unit.Length()) { cssUnit = eCSSUnit_Number; // no explicit unit, this is a number that will act as a multiplier - } + } else if (unit.EqualsWithConversion("%")) { floatValue = floatValue / 100.0f; aCSSValue.SetPercentValue(floatValue); return PR_TRUE; - } - else if (unit.EqualsWithConversion("em")) cssUnit = eCSSUnit_EM; - else if (unit.EqualsWithConversion("ex")) cssUnit = eCSSUnit_XHeight; - else if (unit.EqualsWithConversion("px")) cssUnit = eCSSUnit_Pixel; - else if (unit.EqualsWithConversion("in")) cssUnit = eCSSUnit_Inch; + } + else if (unit.EqualsWithConversion("em")) cssUnit = eCSSUnit_EM; + else if (unit.EqualsWithConversion("ex")) cssUnit = eCSSUnit_XHeight; + else if (unit.EqualsWithConversion("px")) cssUnit = eCSSUnit_Pixel; + else if (unit.EqualsWithConversion("in")) cssUnit = eCSSUnit_Inch; else if (unit.EqualsWithConversion("cm")) cssUnit = eCSSUnit_Centimeter; else if (unit.EqualsWithConversion("mm")) cssUnit = eCSSUnit_Millimeter; - else if (unit.EqualsWithConversion("pt")) cssUnit = eCSSUnit_Point; - else if (unit.EqualsWithConversion("pc")) cssUnit = eCSSUnit_Pica; + else if (unit.EqualsWithConversion("pt")) cssUnit = eCSSUnit_Point; + else if (unit.EqualsWithConversion("pc")) cssUnit = eCSSUnit_Pica; else // unexpected unit return PR_FALSE; @@ -336,7 +264,7 @@ printf("String:%s, Number:%s, Unit:%s\n", s1, s2, s3); } // Adapted from nsCSSStyleRule.cpp -nscoord +nscoord nsMathMLContainerFrame::CalcLength(nsIPresContext* aPresContext, nsIStyleContext* aStyleContext, const nsCSSValue& aCSSValue) @@ -384,55 +312,44 @@ nsMathMLContainerFrame::ParseNamedSpaceValue(nsIFrame* aMathMLmstyleFrame, // See if it is one of the 'namedspace' (ranging 1/18em...7/18em) PRInt32 i = 0; nsIAtom* namedspaceAtom; - if (aString.EqualsWithConversion("veryverythinmathspace")) - { + if (aString.EqualsWithConversion("veryverythinmathspace")) { i = 1; namedspaceAtom = nsMathMLAtoms::veryverythinmathspace_; } - else if (aString.EqualsWithConversion("verythinmathspace")) - { - i = 2; + else if (aString.EqualsWithConversion("verythinmathspace")) { + i = 2; namedspaceAtom = nsMathMLAtoms::verythinmathspace_; } - else if (aString.EqualsWithConversion("thinmathspace")) - { + else if (aString.EqualsWithConversion("thinmathspace")) { i = 3; namedspaceAtom = nsMathMLAtoms::thinmathspace_; } - else if (aString.EqualsWithConversion("mediummathspace")) - { + else if (aString.EqualsWithConversion("mediummathspace")) { i = 4; namedspaceAtom = nsMathMLAtoms::mediummathspace_; } - else if (aString.EqualsWithConversion("thickmathspace")) - { + else if (aString.EqualsWithConversion("thickmathspace")) { i = 5; namedspaceAtom = nsMathMLAtoms::thickmathspace_; } - else if (aString.EqualsWithConversion("verythickmathspace")) - { + else if (aString.EqualsWithConversion("verythickmathspace")) { i = 6; namedspaceAtom = nsMathMLAtoms::verythickmathspace_; } - else if (aString.EqualsWithConversion("veryverythickmathspace")) - { + else if (aString.EqualsWithConversion("veryverythickmathspace")) { i = 7; namedspaceAtom = nsMathMLAtoms::veryverythickmathspace_; } - if (0 != i) - { - if (aMathMLmstyleFrame) - { + if (0 != i) { + if (aMathMLmstyleFrame) { // see if there is a that has overriden the default value // GetAttribute() will recurse all the way up into the hierarchy nsAutoString value; if (NS_CONTENT_ATTR_HAS_VALUE == - GetAttribute(nsnull, aMathMLmstyleFrame, namedspaceAtom, value)) - { + GetAttribute(nsnull, aMathMLmstyleFrame, namedspaceAtom, value)) { if (ParseNumericValue(value, aCSSValue) && - aCSSValue.IsLengthUnit()) - { + aCSSValue.IsLengthUnit()) { return PR_TRUE; } } @@ -469,11 +386,11 @@ nsMathMLContainerFrame::ReflowError(nsIPresContext* aPresContext, // bounding metrics nsAutoString errorMsg(PRUnichar(0xFFFD)); - rv = aRenderingContext.GetBoundingMetrics(errorMsg.GetUnicode(), + rv = aRenderingContext.GetBoundingMetrics(errorMsg.GetUnicode(), PRUint32(errorMsg.Length()), mBoundingMetrics); if (NS_FAILED(rv)) { - printf("GetBoundingMetrics failed\n"); + NS_WARNING("GetBoundingMetrics failed"); aDesiredSize.width = aDesiredSize.height = 0; aDesiredSize.ascent = aDesiredSize.descent = 0; return NS_OK; @@ -487,7 +404,7 @@ nsMathMLContainerFrame::ReflowError(nsIPresContext* aPresContext, aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; - if (nsnull != aDesiredSize.maxElementSize) { + if (aDesiredSize.maxElementSize) { aDesiredSize.maxElementSize->width = aDesiredSize.width; aDesiredSize.maxElementSize->height = aDesiredSize.height; } @@ -516,69 +433,19 @@ nsMathMLContainerFrame::PaintError(nsIPresContext* aPresContext, aRenderingContext.SetFont(font.mFont); nsAutoString errorMsg(PRUnichar(0xFFFD)); - aRenderingContext.DrawString(errorMsg.GetUnicode(), - PRUint32(errorMsg.Length()), + aRenderingContext.DrawString(errorMsg.GetUnicode(), + PRUint32(errorMsg.Length()), mRect.x, mRect.y); } return NS_OK; } -// ------------------------- - -void -nsMathMLContainerFrame::ReflowEmptyChild(nsIPresContext* aPresContext, - nsIFrame* aFrame) -{ -// nsHTMLReflowMetrics emptySize(nsnull); -// nsHTMLReflowState emptyReflowState(aPresContext, aReflowState, aFrame, nsSize(0,0)); -// nsresult rv = ReflowChild(aFrame, aPresContext, emptySize, emptyReflowState, aStatus); - - // 0-size the frame - aFrame->SetRect(aPresContext, nsRect(0,0,0,0)); - - // 0-size the view, if any - nsIView* view = nsnull; - aFrame->GetView(aPresContext, &view); - if (view) { - nsCOMPtr vm; - view->GetViewManager(*getter_AddRefs(vm)); - vm->ResizeView(view, 0,0); - } -} /* ///////////// - * nsIMathMLFrame - support methods for precise positioning + * nsIMathMLFrame - support methods for precise positioning * ============================================================================= */ -NS_IMETHODIMP -nsMathMLContainerFrame::GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) -{ - aBoundingMetrics = mBoundingMetrics; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) -{ - mBoundingMetrics = aBoundingMetrics; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::GetReference(nsPoint& aReference) -{ - aReference = mReference; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::SetReference(const nsPoint& aReference) -{ - mReference = aReference; - return NS_OK; -} - // helper method to facilitate getting the reflow and bounding metrics void nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFrame, @@ -587,37 +454,28 @@ nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFra { NS_PRECONDITION(aFrame, "null arg"); - // IMPORTANT: This function is only meant to be called in Place() methods + // IMPORTANT: This function is only meant to be called in Place() methods // where it is assumed that the frame's rect is still acting as place holder // for the frame's ascent and descent information - - nsRect aRect; - aFrame->GetRect(aRect); - aReflowMetrics.descent = aRect.x; - aReflowMetrics.ascent = aRect.y; - aReflowMetrics.width = aRect.width; - aReflowMetrics.height = aRect.height; - + + nsRect rect; + aFrame->GetRect(rect); + aReflowMetrics.descent = rect.x; + aReflowMetrics.ascent = rect.y; + aReflowMetrics.width = rect.width; + aReflowMetrics.height = rect.height; + aBoundingMetrics.Clear(); - nsIMathMLFrame* aMathMLFrame = nsnull; - nsresult rv = aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetBoundingMetrics(aBoundingMetrics); -#if 0 - nsFrame::ListTag(stdout, aFrame); - printf(" subItalicCorrection:%d supItalicCorrection:%d\n", - aBoundingMetrics.subItalicCorrection, aBoundingMetrics.supItalicCorrection); -#endif + nsIMathMLFrame* mathMLFrame; + nsresult rv = aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetBoundingMetrics(aBoundingMetrics); } else { // aFrame is not a MathML frame, just return the reflow metrics aBoundingMetrics.descent = aReflowMetrics.descent; aBoundingMetrics.ascent = aReflowMetrics.ascent; aBoundingMetrics.width = aReflowMetrics.width; -#if 0 - printf("GetBoundingMetrics() failed for: "); /* getchar(); */ - nsFrame::ListTag(stdout, aFrame); - printf("\n"); -#endif + aBoundingMetrics.rightBearing = aReflowMetrics.width; } } @@ -637,14 +495,13 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) { if (NS_MATHML_STRETCH_WAS_DONE(mEmbellishData.flags)) { - printf("WARNING *** it is wrong to fire stretch more than once on a frame...\n"); -// NS_ASSERTION(PR_FALSE,"Stretch() was fired more than once on a frame!"); + NS_WARNING("it is wrong to fire stretch more than once on a frame"); return NS_OK; } mEmbellishData.flags |= NS_MATHML_STRETCH_DONE; if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) { - printf("WARNING *** it is wrong to fire stretch on a erroneous frame...\n"); + NS_WARNING("it is wrong to fire stretch on a erroneous frame"); return NS_OK; } @@ -654,26 +511,19 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, NS_ASSERTION(childFrame, "Something is wrong somewhere"); if (childFrame) { - nsIMathMLFrame* aMathMLFrame = nsnull; - rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Something is wrong somewhere"); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { + nsIMathMLFrame* mathMLFrame; + rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + NS_ASSERTION(NS_SUCCEEDED(rv) && mathMLFrame, "Something is wrong somewhere"); + if (NS_SUCCEEDED(rv) && mathMLFrame) { - // And the trick is that the child's rect.x is still holding the descent, + // And the trick is that the child's rect.x is still holding the descent, // and rect.y is still holding the ascent ... - nsRect rect; - childFrame->GetRect(rect); - nsHTMLReflowMetrics childSize(aDesiredStretchSize); - aMathMLFrame->GetBoundingMetrics(childSize.mBoundingMetrics); - childSize.descent = rect.x; - childSize.ascent = rect.y; - childSize.height = rect.height; - childSize.width = rect.width; - + GetReflowAndBoundingMetricsFor(childFrame, childSize, childSize.mBoundingMetrics); + nsBoundingMetrics containerSize = aContainerSize; - if (aStretchDirection != NS_STRETCH_DIRECTION_DEFAULT && + if (aStretchDirection != NS_STRETCH_DIRECTION_DEFAULT && aStretchDirection != mEmbellishData.direction) { // change the direction and confine the stretch to us // XXX tune this @@ -681,12 +531,12 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, } // do the stretching... - aMathMLFrame->Stretch(aPresContext, aRenderingContext, - mEmbellishData.direction, containerSize, childSize); - + mathMLFrame->Stretch(aPresContext, aRenderingContext, + mEmbellishData.direction, containerSize, childSize); + // store the updated metrics childFrame->SetRect(aPresContext, - nsRect(childSize.descent, childSize.ascent, + nsRect(childSize.descent, childSize.ascent, childSize.width, childSize.height)); // We now have one child that may have changed, re-position all our children @@ -703,8 +553,8 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, nscoord em = NSToCoordRound(float(font.mFont.size)); nsEmbellishData coreData; - mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - aMathMLFrame->GetEmbellishData(coreData); + mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + mathMLFrame->GetEmbellishData(coreData); // cache these values mEmbellishData.leftSpace = coreData.leftSpace; @@ -717,9 +567,9 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext, aDesiredStretchSize.mBoundingMetrics.width += NSToCoordRound((coreData.leftSpace + coreData.rightSpace) * em); - nscoord dx = nscoord( coreData.leftSpace * em ); - if (0 == dx) return NS_OK; - + nscoord dx = nscoord( coreData.leftSpace * em ); + if (!dx) return NS_OK; + aDesiredStretchSize.mBoundingMetrics.leftBearing += dx; aDesiredStretchSize.mBoundingMetrics.rightBearing += dx; @@ -748,7 +598,7 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, // reflow. If the stretch is not fired, the rect.x, and rect.y will remain // with inappropriate data causing children to be improperly positioned. // This helper method checks to see if our parent will fire a stretch command - // targeted at us. If not, we go ahead and fire an involutive stretch on + // targeted at us. If not, we go ahead and fire an involutive stretch on // ourselves. This will clear all the rect.x and rect.y, and return our // desired size. @@ -761,18 +611,18 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, Place(aPresContext, aRenderingContext, placeOrigin, aDesiredSize); if (!placeOrigin) { - // This means the rect.x and rect.y of our children were not set!! + // This means the rect.x and rect.y of our children were not set!! // Don't go without checking to see if our parent will later fire a Stretch() command // targeted at us. The Stretch() will cause the rect.x and rect.y to clear... PRBool parentWillFireStretch = PR_FALSE; nsEmbellishData parentData; - nsIMathMLFrame* aMathMLFrame = nsnull; - nsresult rv = mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(parentData); + nsIMathMLFrame* mathMLFrame; + nsresult rv = mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(parentData); if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(parentData.flags) || - NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(parentData.flags) || - (NS_MATHML_IS_EMBELLISH_OPERATOR(parentData.flags) + NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(parentData.flags) || + (NS_MATHML_IS_EMBELLISH_OPERATOR(parentData.flags) && parentData.firstChild == this)) { parentWillFireStretch = PR_TRUE; @@ -784,7 +634,7 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, // BEGIN of GETTING THE STRETCH SIZE // What is the size that we should use to stretch our stretchy children ???? -// 1) With this code, vertical stretching works. But horizontal stretching +// 1) With this code, vertical stretching works. But horizontal stretching // does not work when the firstChild happens to be the core embellished mo... // nsRect rect; // nsIFrame* childFrame = mEmbellishData.firstChild; @@ -802,45 +652,44 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext, // 3) With this code, we should get appropriate size when it is done !! // GetDesiredSize(aDirection, aPresContext, aRenderingContext, curSize); - // XXX It is not clear if a direction should be imposed. - // With the default direction, the MathMLChar will attempt to stretch + // XXX It is not clear if a direction should be imposed. + // With the default direction, the MathMLChar will attempt to stretch // in its preferred direction. - Stretch(aPresContext, aRenderingContext, NS_STRETCH_DIRECTION_DEFAULT, + Stretch(aPresContext, aRenderingContext, NS_STRETCH_DIRECTION_DEFAULT, curSize, aDesiredSize); } } - if (nsnull != aDesiredSize.maxElementSize) { + if (aDesiredSize.maxElementSize) { aDesiredSize.maxElementSize->width = aDesiredSize.width; aDesiredSize.maxElementSize->height = aDesiredSize.height; } // Also return our bounding metrics aDesiredSize.mBoundingMetrics = mBoundingMetrics; + + // see if we should fix the spacing + FixInterFrameSpacing(aPresContext, aDesiredSize); + return NS_OK; } // This is the method used to set the frame as an embellished container. -// It checks if the first (non-empty) child is embellished. Hence, calls -// must be bottom-up. The method must only be called from within frames who are -// entitled to be potential embellished operators as per the MathML REC. +// It checks if the first (non-empty) child is embellished. Hence, calls +// must be bottom-up. The method must only be called from within frames who are +// entitled to be potential embellished operators as per the MathML REC. NS_IMETHODIMP nsMathMLContainerFrame::EmbellishOperator() { - // Get the first non-empty child nsIFrame* firstChild = mFrames.FirstChild(); - while (firstChild) { - if (!IsOnlyWhitespace(firstChild)) break; - firstChild->GetNextSibling(&firstChild); - } if (firstChild && IsEmbellishOperator(firstChild)) { // Cache the first child mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR; mEmbellishData.firstChild = firstChild; // Cache also the inner-most embellished frame at the core of the hierarchy - nsIMathMLFrame* aMathMLFrame = nsnull; - firstChild->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); + nsIMathMLFrame* mathMLFrame; + firstChild->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); nsEmbellishData embellishData; - aMathMLFrame->GetEmbellishData(embellishData); + mathMLFrame->GetEmbellishData(embellishData); mEmbellishData.core = embellishData.core; mEmbellishData.direction = embellishData.direction; } @@ -853,136 +702,57 @@ nsMathMLContainerFrame::EmbellishOperator() return NS_OK; } -NS_IMETHODIMP -nsMathMLContainerFrame::GetEmbellishData(nsEmbellishData& aEmbellishData) -{ - aEmbellishData = mEmbellishData; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::SetEmbellishData(const nsEmbellishData& aEmbellishData) -{ - mEmbellishData = aEmbellishData; - return NS_OK; -} - PRBool nsMathMLContainerFrame::IsEmbellishOperator(nsIFrame* aFrame) { NS_PRECONDITION(aFrame, "null arg"); if (!aFrame) return PR_FALSE; - nsIMathMLFrame* aMathMLFrame = nsnull; - nsresult rv = aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_FAILED(rv) || !aMathMLFrame) return PR_FALSE; - nsEmbellishData aEmbellishData; - aMathMLFrame->GetEmbellishData(aEmbellishData); - return NS_MATHML_IS_EMBELLISH_OPERATOR(aEmbellishData.flags); + nsIMathMLFrame* mathMLFrame; + nsresult rv = aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_FAILED(rv) || !mathMLFrame) return PR_FALSE; + nsEmbellishData embellishData; + mathMLFrame->GetEmbellishData(embellishData); + return NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags); } /* ///////////// * nsIMathMLFrame - support methods for scripting elements (nested frames - * within msub, msup, msubsup, munder, mover, munderover, mmultiscripts, + * within msub, msup, msubsup, munder, mover, munderover, mmultiscripts, * mfrac, mroot, mtable). * ============================================================================= */ NS_IMETHODIMP -nsMathMLContainerFrame::GetPresentationData(nsPresentationData& aPresentationData) -{ - aPresentationData = mPresentationData; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::SetPresentationData(const nsPresentationData& aPresentationData) -{ - mPresentationData = aPresentationData; - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) -{ - mPresentationData.scriptLevel += aScriptLevelIncrement; - // update flags that are relevant to this call - if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { - // updating the displaystyle flag is allowed - if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { - mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; - } - else { - mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE; - } - } - if (NS_MATHML_IS_COMPRESSED(aFlagsToUpdate)) { - // updating the compression flag is allowed - if (NS_MATHML_IS_COMPRESSED(aFlagsValues)) { - // 'compressed' means 'prime' style in App. G, TeXbook - mPresentationData.flags |= NS_MATHML_COMPRESSED; - } - // no else. the flag is sticky. it retains its value once it is set - } - return NS_OK; -} - -NS_IMETHODIMP -nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) +nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) { PRInt32 index = 0; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if ((index >= aFirstIndex) && - ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { - nsIMathMLFrame* mathMLFrame = nsnull; - nsresult rv = childFrame->QueryInterface( - NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); - if (NS_SUCCEEDED(rv) && mathMLFrame) { - // update - mathMLFrame->UpdatePresentationData( - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - // propagate down the subtrees - mathMLFrame->UpdatePresentationDataFromChildAt(0, -1, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - } + if ((index >= aFirstIndex) && + ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { + nsIMathMLFrame* mathMLFrame; + nsresult rv = childFrame->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + // update + mathMLFrame->UpdatePresentationData( + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + // propagate down the subtrees + mathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); } - index++; } + index++; childFrame->GetNextSibling(&childFrame); } return NS_OK; } -PRInt32 -nsMathMLContainerFrame::FindSmallestFontSizeFor(nsIPresContext* aPresContext, - nsIFrame* aFrame) -{ - nsStyleFont aFont; - nsCOMPtr aStyleContext; - aFrame->GetStyleContext(getter_AddRefs(aStyleContext)); - aStyleContext->GetStyle(eStyleStruct_Font, aFont); - PRInt32 fontSize = aFont.mFont.size; - - PRInt32 childSize; - nsIFrame* childFrame; - aFrame->FirstChild(aPresContext, nsnull, &childFrame); - while (nsnull != childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - childSize = FindSmallestFontSizeFor(aPresContext, childFrame); - if (fontSize > childSize) fontSize = childSize; - } - childFrame->GetNextSibling(&childFrame); - } - return fontSize; -} - // Helper to give a style context suitable for doing the stretching of // a MathMLChar. Frame classes that use this should ensure that the // extra leaf style contexts given to the MathMLChars are acessible to @@ -1009,200 +779,95 @@ nsMathMLContainerFrame::ResolveMathMLCharStyle(nsIPresContext* aPresContext, return isStretchy; } -// helper method to alter the style context -// This method is used for switching the font to a subscript/superscript font in -// mfrac, msub, msup, msubsup, munder, mover, munderover, mmultiscripts - -// XXX change the code to ensure that the size decreases in a top-down manner. -// the coide should always insert top-scriptstyle frames, and inner frames that -// cause the size to decrease pass the smallest limit should be removed -nsresult -nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresContext) +NS_IMETHODIMP +nsMathMLContainerFrame::ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel) { - nsresult rv = NS_OK; - nsIFrame* nextFrame = mFrames.FirstChild(); - while (nsnull != nextFrame && NS_SUCCEEDED(rv)) { - nsIFrame* childFrame = nextFrame; - rv = nextFrame->GetNextSibling(&nextFrame); - if (!IsOnlyWhitespace(childFrame) && NS_SUCCEEDED(rv)) { + PRInt32 gap = mPresentationData.scriptLevel - aParentScriptLevel; + if (gap) { + // By default scriptminsize=8pt and scriptsizemultiplier=0.71 + nscoord scriptminsize = NSIntPointsToTwips(NS_MATHML_SCRIPTMINSIZE); + float scriptsizemultiplier = NS_MATHML_SCRIPTSIZEMULTIPLIER; +#if 0 + // XXX Bug 44201 + // user-supplied scriptminsize and scriptsizemultiplier that are + // restricted to particular elements are not supported because our + // css rules are fixed in mathml.css and are applicable to all elements. - // see if the child frame implements the nsIMathMLFrame interface - nsIMathMLFrame* aMathMLFrame = nsnull; - rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (nsnull != aMathMLFrame && NS_SUCCEEDED(rv)) { - - // get the scriptlevel of the child - 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 = childData.scriptLevel - mPresentationData.scriptLevel; - if (0 != gap) { - // We are about to change the font-size... We first see if we - // are in the scope of a that tells us what to do. - // This is one of the most obscure part to implement in the spec... - /* - The REC says: - - Whenever the scriptlevel is changed, either automatically or by being - explicitly incremented, decremented, or set, the current font size is - multiplied by the value of scriptsizemultiplier to the power of the - change in scriptlevel. For example, if scriptlevel is increased by 2, - the font size is multiplied by scriptsizemultiplier twice in succession; - if scriptlevel is explicitly set to 2 when it had been 3, the font size - is divided by scriptsizemultiplier. - - The default value of scriptsizemultiplier is less than one (in fact, it - is approximately the square root of 1/2), resulting in a smaller font size - with increasing scriptlevel. To prevent scripts from becoming unreadably - small, the font size is never allowed to go below the value of - scriptminsize as a result of a change to scriptlevel, though it can be - set to a lower value using the fontsize attribute on or on - token elements. If a change to scriptlevel would cause the font size to - become lower than scriptminsize using the above formula, the font size - is instead set equal to scriptminsize within the subexpression for which - scriptlevel was changed. - - In the syntax for scriptminsize, v-unit represents a unit of vertical - length. The most common unit for specifying font sizes in typesetting - is pt (points). - */ - - // default scriptsizemultiplier = 0.71 - // default scriptminsize = 8pt - - // here we only consider scriptminsize, and use the default - // smaller-font-size algorithm of the style system - PRInt32 scriptminsize = NSIntPointsToTwips(8); - - // see if there is a scriptminsize attribute on a that wraps us - nsAutoString value; - if (NS_CONTENT_ATTR_HAS_VALUE == - GetAttribute(nsnull, mPresentationData.mstyle, - nsMathMLAtoms::scriptminsize_, value)) - { - nsCSSValue cssValue; - if (ParseNumericValue(value, cssValue)) { - nsCSSUnit unit = cssValue.GetUnit(); - if (eCSSUnit_Number == unit) - scriptminsize = nscoord(float(scriptminsize) * cssValue.GetFloatValue()); - else if (eCSSUnit_Percent == unit) - scriptminsize = nscoord(float(scriptminsize) * cssValue.GetPercentValue()); - else if (eCSSUnit_Null != unit) - scriptminsize = CalcLength(aPresContext, mStyleContext, cssValue); - } -#ifdef NS_DEBUG - else { - char str[50]; - value.ToCString(str, 50); - printf("Invalid attribute scriptminsize=%s\n", str); - } + // see if there is a scriptminsize attribute on a that wraps us + if (NS_CONTENT_ATTR_HAS_VALUE == + GetAttribute(nsnull, mPresentationData.mstyle, + nsMathMLAtoms::scriptminsize_, fontsize)) { + nsCSSValue cssValue; + if (ParseNumericValue(fontsize, cssValue)) { + nsCSSUnit unit = cssValue.GetUnit(); + if (eCSSUnit_Number == unit) + scriptminsize = nscoord(float(scriptminsize) * cssValue.GetFloatValue()); + else if (eCSSUnit_Percent == unit) + scriptminsize = nscoord(float(scriptminsize) * cssValue.GetPercentValue()); + else if (eCSSUnit_Null != unit) + scriptminsize = CalcLength(aPresContext, mStyleContext, cssValue); + } + } #endif - } - // get Nav's magic font scaler - PRInt32 scaler; - aPresContext->GetFontScaler(&scaler); - float scaleFactor = nsStyleUtil::GetScalingFactor(scaler); - const nsFont& defaultFont = aPresContext->GetDefaultFontDeprecated(); + // get the incremental factor + nsAutoString fontsize; + if (0 > gap) { // the size is going to be increased + if (gap < NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT) + gap = NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT; + gap = -gap; + scriptsizemultiplier = 1.0f / scriptsizemultiplier; + fontsize.AssignWithConversion("-"); + } + else { // the size is going to be decreased + if (gap > NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT) + gap = NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT; + fontsize.AssignWithConversion("+"); + } + fontsize.AppendInt(gap, 10); + // we want to make sure that the size will stay readable + nsStyleFont font; + aParentContext->GetStyle(eStyleStruct_Font, font); + nscoord newFontSize = font.mFont.size; + while (0 < gap--) { + newFontSize = (nscoord)((float)(newFontSize) * scriptsizemultiplier); + } + if (newFontSize <= scriptminsize) { + fontsize.AssignWithConversion("scriptminsize"); + } - nsCOMPtr childContent; - childFrame->GetContent(getter_AddRefs(childContent)); - - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - - nsIFrame* firstFrame = nsnull; - nsIFrame* lastFrame = this; - nsIStyleContext* lastStyleContext = mStyleContext; - nsCOMPtr newStyleContext; - - // XXX seems not to decrease when the initail font-size is large (100pt) - nsIAtom* fontAtom = (0 < gap) ? - nsMathMLAtoms::fontsize_smaller : - nsMathMLAtoms::fontsize_larger; - - PRBool isSmaller = PR_TRUE; - if (0 > gap) { isSmaller = PR_FALSE; gap = -gap; } // absolute value - - PRInt32 smallestFontIndex, smallestFontSize = 0; - if (isSmaller) { - // find the smallest font-size in this subtree - smallestFontSize = FindSmallestFontSizeFor(aPresContext, childFrame); - } - - while (0 < gap--) { - - if (isSmaller) { - // look ahead for the next smallest font size that will be in the subtree - smallestFontIndex = nsStyleUtil::FindNextSmallerFontSize(smallestFontSize, (PRInt32)defaultFont.size, scaleFactor, aPresContext); - smallestFontSize = nsStyleUtil::CalcFontPointSize(smallestFontIndex, (PRInt32)defaultFont.size, scaleFactor, aPresContext); -//((nsFrame*)childFrame)->ListTag(stdout); -//printf(" About to move to fontsize:%dpt(%dtwips)\n", -//NSTwipsToFloorIntPoints(smallestFontSize), smallestFontSize); - if (smallestFontSize < scriptminsize) { - // don't bother doing any work -//printf("..... stopping ......\n"); -// XXX there should be a mechanism so that we never try this subtree again - break; - } - } - - aPresContext->ResolvePseudoStyleContextFor(childContent, fontAtom, lastStyleContext, - PR_FALSE, getter_AddRefs(newStyleContext)); - if (newStyleContext && newStyleContext.get() != lastStyleContext) { - // create a new wrapper frame and append it as sole child of the last created frame - nsIFrame* newFrame = nsnull; - NS_NewMathMLWrapperFrame(shell, &newFrame); - NS_ASSERTION(newFrame, "Failed to create new frame"); - if (!newFrame) break; - newFrame->Init(aPresContext, childContent, lastFrame, newStyleContext, nsnull); - - if (nsnull == firstFrame) { - firstFrame = newFrame; - } - if (this != lastFrame) { - lastFrame->SetInitialChildList(aPresContext, nsnull, newFrame); - } - lastStyleContext = newStyleContext; - lastFrame = newFrame; - } - else { - break; - } - } - if (nsnull != firstFrame) { // at least one new frame was created - mFrames.ReplaceFrame(this, childFrame, firstFrame); - childFrame->SetParent(lastFrame); - childFrame->SetNextSibling(nsnull); - aPresContext->ReParentStyleContext(childFrame, lastStyleContext); - lastFrame->SetInitialChildList(aPresContext, nsnull, childFrame); - - // if the child was an embellished operator, - // make the whole list embellished as well - nsEmbellishData embellishData; - aMathMLFrame->GetEmbellishData(embellishData); - if (0 != embellishData.flags && nsnull != embellishData.firstChild) { - do { // walk the hierarchy in a bottom-up manner - rv = lastFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!"); - if (NS_FAILED(rv) || !aMathMLFrame) break; - embellishData.firstChild = childFrame; - aMathMLFrame->SetEmbellishData(embellishData); - childFrame = lastFrame; - lastFrame->GetParent(&lastFrame); - } while (lastFrame != this); - } - } - } + // set the -moz-math-font-size attribute without notifying that we want a reflow + mContent->SetAttribute(kNameSpaceID_None, nsMathMLAtoms::fontsize, + fontsize, PR_FALSE); + // then, re-resolve the style contexts in our subtree + nsCOMPtr newStyleContext; + aPresContext->ResolveStyleContextFor(mContent, aParentContext, + PR_FALSE, getter_AddRefs(newStyleContext)); + if (newStyleContext && newStyleContext.get() != mStyleContext) { + SetStyleContext(aPresContext, newStyleContext); + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + aPresContext->ReParentStyleContext(childFrame, newStyleContext); + childFrame->GetNextSibling(&childFrame); } } } - return rv; + + // let children with different scriptsizes handle that themselves + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + nsIMathMLFrame* mathMLFrame; + nsresult res = childFrame->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + mathMLFrame->ReResolveScriptStyle(aPresContext, mStyleContext, + mPresentationData.scriptLevel); + } + childFrame->GetNextSibling(&childFrame); + } + return NS_OK; } @@ -1211,7 +876,6 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte * ============================================================================= */ -#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) NS_IMETHODIMP nsMathMLContainerFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -1229,6 +893,7 @@ nsMathMLContainerFrame::Paint(nsIPresContext* aPresContext, rv = nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) // for visual debug // ---------------- // if you want to see your bounding box, make sure to properly fill @@ -1248,9 +913,40 @@ nsMathMLContainerFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawRect(x,y,w,h); } +#endif return rv; } -#endif + +static void +CompressWhitespace(nsIContent* aContent) +{ + nsCOMPtr tag; + aContent->GetTag(*getter_AddRefs(tag)); + if (tag.get() == nsMathMLAtoms::mo_ || + tag.get() == nsMathMLAtoms::mi_ || + tag.get() == nsMathMLAtoms::mn_ || + tag.get() == nsMathMLAtoms::ms_ || + tag.get() == nsMathMLAtoms::mtext_) { + PRInt32 numKids; + aContent->ChildCount(numKids); + for (PRInt32 kid = 0; kid < numKids; kid++) { + nsCOMPtr kidContent; + aContent->ChildAt(kid, *getter_AddRefs(kidContent)); + if (kidContent.get()) { + nsCOMPtr kidText(do_QueryInterface(kidContent)); + if (kidText.get()) { + nsCOMPtr tc(do_QueryInterface(kidContent)); + if (tc) { + nsAutoString text; + tc->CopyText(text); + text.CompressWhitespace(); + tc->SetText(text, PR_FALSE); // not meant to be used if notify is needed + } + } + } + } + } +} NS_IMETHODIMP nsMathMLContainerFrame::Init(nsIPresContext* aPresContext, @@ -1259,30 +955,24 @@ nsMathMLContainerFrame::Init(nsIPresContext* aPresContext, nsIStyleContext* aContext, nsIFrame* aPrevInFlow) { + // leading and trailing whitespace doesn't count -- bug 15402 + // brute force removal for people who do a instead of a + // XXX the best fix is to skip these in nsTextFrame + CompressWhitespace(aContent); + + // let the base class do its Init() nsresult rv; - // first, let the base class do its Init() rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); - - mBoundingMetrics.Clear(); - mReference.x = mReference.y = 0; // now, if our parent implements the nsIMathMLFrame interface, we inherit // its scriptlevel and displaystyle. If the parent later wishes to increment // with other values, it will do so in its SetInitialChildList() method. - - mPresentationData.flags = 0; - mPresentationData.scriptLevel = 0; - mPresentationData.mstyle = nsnull; - mEmbellishData.flags = 0; - mEmbellishData.firstChild = nsnull; - - nsIMathMLFrame* aMathMLFrame = nsnull; - nsresult res = aParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(res) && nsnull != aMathMLFrame) { + nsIMathMLFrame* mathMLFrame; + nsresult res = aParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { nsPresentationData parentData; - aMathMLFrame->GetPresentationData(parentData); - + mathMLFrame->GetPresentationData(parentData); mPresentationData.mstyle = parentData.mstyle; mPresentationData.scriptLevel = parentData.scriptLevel; if (NS_MATHML_IS_DISPLAYSTYLE(parentData.flags)) @@ -1332,38 +1022,56 @@ nsMathMLContainerFrame::SetInitialChildList(nsIPresContext* aPresContext, while (next) { nsIFrame* child = next; next->GetNextSibling(&next); - if (!IsOnlyWhitespace(child)) { - nsInlineFrame* inlineFrame = nsnull; - nsresult res = child->QueryInterface(nsInlineFrame::kInlineFrameCID, (void**)&inlineFrame); - if (NS_SUCCEEDED(res) && inlineFrame) { - // create a new anonymous block frame to wrap this child... - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - nsIFrame* anonymous; - rv = NS_NewBlockFrame(shell, &anonymous); - if (NS_FAILED(rv)) - return rv; - nsCOMPtr newStyleContext; - aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozAnonymousBlock, - mStyleContext, PR_FALSE, - getter_AddRefs(newStyleContext)); - rv = anonymous->Init(aPresContext, mContent, this, newStyleContext, nsnull); - if (NS_FAILED(rv)) { - anonymous->Destroy(aPresContext); - return rv; - } - mFrames.ReplaceFrame(this, child, anonymous); - child->SetParent(anonymous); - child->SetNextSibling(nsnull); - aPresContext->ReParentStyleContext(child, newStyleContext); - anonymous->SetInitialChildList(aPresContext, nsnull, child); + nsInlineFrame* inlineFrame = nsnull; + nsresult res = child->QueryInterface(nsInlineFrame::kInlineFrameCID, (void**)&inlineFrame); + if (NS_SUCCEEDED(res) && inlineFrame) { + // create a new anonymous block frame to wrap this child... + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + nsIFrame* anonymous; + rv = NS_NewBlockFrame(shell, &anonymous); + if (NS_FAILED(rv)) + return rv; + nsCOMPtr newStyleContext; + aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozAnonymousBlock, + mStyleContext, PR_FALSE, + getter_AddRefs(newStyleContext)); + rv = anonymous->Init(aPresContext, mContent, this, newStyleContext, nsnull); + if (NS_FAILED(rv)) { + anonymous->Destroy(aPresContext); + return rv; } + mFrames.ReplaceFrame(this, child, anonymous); + child->SetParent(anonymous); + child->SetNextSibling(nsnull); + aPresContext->ReParentStyleContext(child, newStyleContext); + anonymous->SetInitialChildList(aPresContext, nsnull, child); } } return rv; } +NS_IMETHODIMP +nsMathMLContainerFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + nsresult rv = nsHTMLContainerFrame::AttributeChanged(aPresContext, aChild, + aNameSpaceID, aAttribute, aHint); + if (NS_FAILED(rv)) return rv; + nsCOMPtr shell; + nsCOMPtr reflowCmd; + aPresContext->GetShell(getter_AddRefs(shell)); + rv = NS_NewHTMLReflowCommand(getter_AddRefs(reflowCmd), this, + nsIReflowCommand::ContentChanged, + nsnull, aAttribute); + if (NS_SUCCEEDED(rv) && shell) shell->AppendReflowCommand(reflowCmd); + return rv; +} + // helper function to reflow token elements // note that mBoundingMetrics is computed here nsresult @@ -1401,48 +1109,44 @@ printf("\n"); aDesiredSize.ascent = aDesiredSize.descent = 0; aDesiredSize.mBoundingMetrics.Clear(); - // ask our children to compute their bounding metrics + // ask our children to compute their bounding metrics nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize, aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS); nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight); - PRInt32 count = 0; + PRInt32 count = 0; nsIFrame* childFrame; aFrame->FirstChild(aPresContext, nsnull, &childFrame); while (childFrame) { - if (IsOnlyWhitespace(childFrame)) { - ReflowEmptyChild(aPresContext, childFrame); - } - else { - nsHTMLReflowState childReflowState(aPresContext, aReflowState, - childFrame, availSize); - rv = NS_STATIC_CAST(nsMathMLContainerFrame*, - aFrame)->ReflowChild(childFrame, - aPresContext, childDesiredSize, - childReflowState, aStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); - if (NS_FAILED(rv)) return rv; + nsHTMLReflowState childReflowState(aPresContext, aReflowState, + childFrame, availSize); + rv = NS_STATIC_CAST(nsMathMLContainerFrame*, + aFrame)->ReflowChild(childFrame, + aPresContext, childDesiredSize, + childReflowState, aStatus); + //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); + if (NS_FAILED(rv)) return rv; - // origins are used as placeholders to store the child's ascent and descent. - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent, childDesiredSize.ascent, - childDesiredSize.width, childDesiredSize.height)); - // compute and cache the bounding metrics - if (0 == count) - aDesiredSize.mBoundingMetrics = childDesiredSize.mBoundingMetrics; - else - aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics; + // origins are used as placeholders to store the child's ascent and descent. + childFrame->SetRect(aPresContext, + nsRect(childDesiredSize.descent, childDesiredSize.ascent, + childDesiredSize.width, childDesiredSize.height)); + // compute and cache the bounding metrics + if (0 == count) + aDesiredSize.mBoundingMetrics = childDesiredSize.mBoundingMetrics; + else + aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics; - count++; - } - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child"); + count++; + childFrame->GetNextSibling(&childFrame); } + // cache the frame's mBoundingMetrics NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->SetBoundingMetrics(aDesiredSize.mBoundingMetrics); + // place and size children - NS_STATIC_CAST(nsMathMLContainerFrame*, - aFrame)->FinalizeReflow(aPresContext, *aReflowState.rendContext, + NS_STATIC_CAST(nsMathMLContainerFrame*, + aFrame)->FinalizeReflow(aPresContext, *aReflowState.rendContext, aDesiredSize); return NS_OK; } @@ -1455,22 +1159,20 @@ nsresult nsMathMLContainerFrame::PlaceTokenFor(nsIFrame* aFrame, nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, - PRBool aPlaceOrigin, + PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { aDesiredSize.width = aDesiredSize.height = 0; aDesiredSize.ascent = aDesiredSize.descent = 0; - + nsRect rect; nsIFrame* childFrame; aFrame->FirstChild(aPresContext, nsnull, &childFrame); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - childFrame->GetRect(rect); - aDesiredSize.width += rect.width; - if (aDesiredSize.descent < rect.x) aDesiredSize.descent = rect.x; - if (aDesiredSize.ascent < rect.y) aDesiredSize.ascent = rect.y; - } + childFrame->GetRect(rect); + aDesiredSize.width += rect.width; + if (aDesiredSize.descent < rect.x) aDesiredSize.descent = rect.x; + if (aDesiredSize.ascent < rect.y) aDesiredSize.ascent = rect.y; childFrame->GetNextSibling(&childFrame); } aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; @@ -1488,15 +1190,17 @@ nsMathMLContainerFrame::PlaceTokenFor(nsIFrame* aFrame, // place and size the child dy = aDesiredSize.ascent - rect.y; - NS_STATIC_CAST(nsMathMLContainerFrame*, - aFrame)->FinishReflowChild(childFrame, aPresContext, + NS_STATIC_CAST(nsMathMLContainerFrame*, + aFrame)->FinishReflowChild(childFrame, aPresContext, childSize, dx, dy, 0); dx += rect.width; childFrame->GetNextSibling(&childFrame); } } + NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->SetReference(nsPoint(0, aDesiredSize.ascent)); + return NS_OK; } @@ -1505,16 +1209,16 @@ NS_IMETHODIMP nsMathMLContainerFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild) { // The inline container frame does not handle the reflow - // request. It passes it up to its parent container. + // request. It passes it up to its parent container. // If you don't already have dirty children, if (!(mState & NS_FRAME_HAS_DIRTY_CHILDREN)) { if (mParent) { - // Record that you are dirty and have dirty children + // Record that you are dirty and have dirty children mState |= NS_FRAME_IS_DIRTY; - mState |= NS_FRAME_HAS_DIRTY_CHILDREN; + mState |= NS_FRAME_HAS_DIRTY_CHILDREN; - // Pass the reflow request up to the parent + // Pass the reflow request up to the parent mParent->ReflowDirtyChild(aPresShell, (nsIFrame*) this); } else { @@ -1565,36 +1269,28 @@ printf("\n"); nsReflowStatus childStatus; nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight); - nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize, + nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize, aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS); nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - ////////////// - // WHITESPACE: don't forget that whitespace doesn't count in MathML! - if (IsOnlyWhitespace(childFrame)) { - ReflowEmptyChild(aPresContext, childFrame); - } - else { - nsHTMLReflowState childReflowState(aPresContext, aReflowState, - childFrame, availSize); - rv = ReflowChild(childFrame, aPresContext, childDesiredSize, - childReflowState, childStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); - if (NS_FAILED(rv)) return rv; + nsHTMLReflowState childReflowState(aPresContext, aReflowState, + childFrame, availSize); + rv = ReflowChild(childFrame, aPresContext, childDesiredSize, + childReflowState, childStatus); + //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + if (NS_FAILED(rv)) return rv; - // At this stage, the origin points of the children have no use, so we will use the - // origins as placeholders to store the child's ascent and descent. Later on, - // we should set the origins so as to overwrite what we are storing there now. - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent, childDesiredSize.ascent, - childDesiredSize.width, childDesiredSize.height)); - } - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child"); + // At this stage, the origin points of the children have no use, so we will use the + // origins as placeholders to store the child's ascent and descent. Later on, + // we should set the origins so as to overwrite what we are storing there now. + childFrame->SetRect(aPresContext, + nsRect(childDesiredSize.descent, childDesiredSize.ascent, + childDesiredSize.width, childDesiredSize.height)); + childFrame->GetNextSibling(&childFrame); } ///////////// - // If we are a container which is entitled to stretch its children, then we + // If we are a container which is entitled to stretch its children, then we // ask our stretchy children to stretch themselves if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) || @@ -1608,7 +1304,7 @@ printf("\n"); nsBoundingMetrics containerSize = mBoundingMetrics; // get the strech direction - nsStretchDirection stretchDir = + nsStretchDirection stretchDir = NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) ? NS_STRETCH_DIRECTION_VERTICAL : NS_STRETCH_DIRECTION_HORIZONTAL; @@ -1622,21 +1318,16 @@ printf("\n"); // Its stretch will be handled separatedly when we receive // the stretch command fired by our parent frame. } - else if (!IsOnlyWhitespace(childFrame)) { - nsIMathMLFrame* aMathMLFrame = nsnull; - rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { + else { + nsIMathMLFrame* mathMLFrame; + rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { // retrieve the metrics that was stored at the previous pass - nsRect rect; - childFrame->GetRect(rect); - aMathMLFrame->GetBoundingMetrics(childDesiredSize.mBoundingMetrics); - childDesiredSize.descent = rect.x; - childDesiredSize.ascent = rect.y; - childDesiredSize.height = rect.height; - childDesiredSize.width = rect.width; + GetReflowAndBoundingMetricsFor(childFrame, + childDesiredSize, childDesiredSize.mBoundingMetrics); - aMathMLFrame->Stretch(aPresContext, *aReflowState.rendContext, - stretchDir, containerSize, childDesiredSize); + mathMLFrame->Stretch(aPresContext, *aReflowState.rendContext, + stretchDir, containerSize, childDesiredSize); // store the updated metrics childFrame->SetRect(aPresContext, nsRect(childDesiredSize.descent, childDesiredSize.ascent, @@ -1676,7 +1367,7 @@ nsMathMLContainerFrame::GetFrameType(nsIAtom** aType) const tag.get() == nsMathMLAtoms::mtext_) { *aType = nsMathMLAtoms::ordinaryMathMLFrame; } - else { + else { // everything else is a schematta element (mapped to 'Inner' in TeX) *aType = nsMathMLAtoms::schemataMathMLFrame; } @@ -1700,15 +1391,16 @@ static PRInt32 interFrameSpacingTable[4][4] = // upper half of the byte is set if the // spacing is not to be used for scriptlevel > 0 /* Ord Op Punc Inner */ - /*Ord */ {0x00, 0x00, 0x00, 0x11}, + /*Ord */ {0x01, 0x00, 0x00, 0x01}, /*Op */ {0x00, 0x00, 0x00, 0x00}, /*Punc */ {0x11, 0x00, 0x11, 0x11}, - /*Inner*/ {0x11, 0x00, 0x11, 0x11} + /*Inner*/ {0x01, 0x00, 0x11, 0x01} }; +// XXX more tuning of the result as in TeX, maybe depending on fence:true, etc static nscoord -GetInterFrameSpacing(PRInt32 aScriptLevel, - nsIAtom* aFirstFrameType, +GetInterFrameSpacing(PRInt32 aScriptLevel, + nsIAtom* aFirstFrameType, nsIAtom* aSecondFrameType) { nsMathMLFrameTypeEnum firstType = eMathMLFrameType_UNKNOWN; @@ -1727,14 +1419,14 @@ GetInterFrameSpacing(PRInt32 aScriptLevel, secondType = eMathMLFrameType_Ordinary; else if (aSecondFrameType == nsMathMLAtoms::operatorMathMLFrame) secondType = eMathMLFrameType_Operator; - else if (aSecondFrameType == nsMathMLAtoms::operatorMathMLFrame) + else if (aSecondFrameType == nsMathMLAtoms::schemataMathMLFrame) secondType = eMathMLFrameType_Inner; - + // return 0 if there is a frame that we know nothing about - if (firstType == eMathMLFrameType_UNKNOWN || + if (firstType == eMathMLFrameType_UNKNOWN || secondType == eMathMLFrameType_UNKNOWN) { return 0; - } + } PRInt32 space = interFrameSpacingTable[firstType][secondType]; if (aScriptLevel > 0 && (space & 0xF0)) { @@ -1752,8 +1444,6 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { - nsresult rv = NS_OK; - // these are needed in case this frame is empty (i.e., we don't enter the loop) aDesiredSize.width = aDesiredSize.height = 0; aDesiredSize.ascent = aDesiredSize.descent = 0; @@ -1767,41 +1457,46 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext, PRInt32 count = 0; nsHTMLReflowMetrics childSize (nsnull); nsBoundingMetrics bmChild; - nscoord italicCorrection = 0; + nscoord leftCorrection = 0, italicCorrection = 0; nsCOMPtr prevFrameType; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - nsCOMPtr childFrameType; - childFrame->GetFrameType(getter_AddRefs(childFrameType)); - GetReflowAndBoundingMetricsFor(childFrame, childSize, bmChild); - if (0 == count) { - aDesiredSize.ascent = childSize.ascent; - aDesiredSize.descent = childSize.descent; - mBoundingMetrics = bmChild; - } - else { - if (aDesiredSize.descent < childSize.descent) - aDesiredSize.descent = childSize.descent; - if (aDesiredSize.ascent < childSize.ascent) - aDesiredSize.ascent = childSize.ascent; - // add inter frame spacing - nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel, - prevFrameType, childFrameType); - mBoundingMetrics.width += space * thinSpace; - // add the child size - mBoundingMetrics += bmChild; - } - count++; - prevFrameType = childFrameType; - // add the italic correction at the end (including the last child). - // this gives a nice gap between math and non-math frames, and still - // gives the same math inter-spacing in case this frame connects to - // another math frame - GetItalicCorrection(bmChild, italicCorrection); - mBoundingMetrics.width += italicCorrection; + nsCOMPtr childFrameType; + childFrame->GetFrameType(getter_AddRefs(childFrameType)); + GetReflowAndBoundingMetricsFor(childFrame, childSize, bmChild); + GetItalicCorrection(bmChild, leftCorrection, italicCorrection); + if (0 == count) { + aDesiredSize.ascent = childSize.ascent; + aDesiredSize.descent = childSize.descent; + mBoundingMetrics = bmChild; + // update to include the left correction + mBoundingMetrics.leftBearing += leftCorrection; } + else { + if (aDesiredSize.descent < childSize.descent) + aDesiredSize.descent = childSize.descent; + if (aDesiredSize.ascent < childSize.ascent) + aDesiredSize.ascent = childSize.ascent; + // add inter frame spacing + nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel, + prevFrameType, childFrameType); + mBoundingMetrics.width += space * thinSpace; + // add the child size + mBoundingMetrics += bmChild; + } + count++; + prevFrameType = childFrameType; + // add left correction -- this fixes the problem of the italic 'f' + // e.g., q f I + mBoundingMetrics.width += leftCorrection; + mBoundingMetrics.rightBearing += leftCorrection; + // add the italic correction at the end (including the last child). + // this gives a nice gap between math and non-math frames, and still + // gives the same math inter-spacing in case this frame connects to + // another math frame + mBoundingMetrics.width += italicCorrection; + childFrame->GetNextSibling(&childFrame); } aDesiredSize.width = mBoundingMetrics.width; @@ -1820,26 +1515,24 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext, italicCorrection = 0; childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - nsCOMPtr childFrameType; - childFrame->GetFrameType(getter_AddRefs(childFrameType)); - GetReflowAndBoundingMetricsFor(childFrame, childSize, bmChild); - dy = aDesiredSize.ascent - childSize.ascent; - if (0 < count) { - // add inter frame spacing - nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel, - prevFrameType, childFrameType); - dx += space * thinSpace; - } - count++; - prevFrameType = childFrameType; - FinishReflowChild(childFrame, aPresContext, childSize, dx, dy, 0); - // add child size - dx += bmChild.width; - // add italic correction - GetItalicCorrection(bmChild, italicCorrection); - dx += italicCorrection; + nsCOMPtr childFrameType; + childFrame->GetFrameType(getter_AddRefs(childFrameType)); + GetReflowAndBoundingMetricsFor(childFrame, childSize, bmChild); + dy = aDesiredSize.ascent - childSize.ascent; + if (0 < count) { + // add inter frame spacing + nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel, + prevFrameType, childFrameType); + dx += space * thinSpace; } + count++; + prevFrameType = childFrameType; + GetItalicCorrection(bmChild, leftCorrection, italicCorrection); + // add left correction + dx += leftCorrection; + FinishReflowChild(childFrame, aPresContext, childSize, dx, dy, 0); + // add child size + italic correction + dx += bmChild.width + italicCorrection; childFrame->GetNextSibling(&childFrame); } } @@ -1847,164 +1540,101 @@ nsMathMLContainerFrame::Place(nsIPresContext* aPresContext, return NS_OK; } +// helper to fix the inter-spacing when is the only parent +// e.g., it fixes f q f I +nsresult +nsMathMLContainerFrame::FixInterFrameSpacing(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize) +{ + nsCOMPtr parentTag; + nsCOMPtr parentContent; + mParent->GetContent(getter_AddRefs(parentContent)); + parentContent->GetTag(*getter_AddRefs(parentTag)); + if (parentTag.get() == nsMathMLAtoms::math) { + nscoord gap = 0; + nscoord leftCorrection, italicCorrection; + if (mNextSibling) { + nsIMathMLFrame* mathMLFrame; + nsresult res = mNextSibling->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + // get thinspace + nsStyleFont font; + nsCOMPtr parentContext; + mParent->GetStyleContext(getter_AddRefs(parentContext)); + parentContext->GetStyle(eStyleStruct_Font, font); + nscoord thinSpace = NSToCoordRound(float(font.mFont.size)*float(3) / float(18)); + // add inter frame spacing to our width + nsCOMPtr frameType; + GetFrameType(getter_AddRefs(frameType)); + nsCOMPtr nextFrameType; + mNextSibling->GetFrameType(getter_AddRefs(nextFrameType)); + nscoord space = GetInterFrameSpacing(mPresentationData.scriptLevel, + frameType, nextFrameType); + gap += space * thinSpace; + // look ahead and also add the left italic correction of the next frame + nsBoundingMetrics bmNext; + mathMLFrame->GetBoundingMetrics(bmNext); + GetItalicCorrection(bmNext, leftCorrection, italicCorrection); + gap += leftCorrection; + } + } + // add our own italic correction + GetItalicCorrection(mBoundingMetrics, leftCorrection, italicCorrection); + gap += italicCorrection; + // see if we should shift our own children to account for the left correction + // only shift if we are the first child of - the look-ahead fixes the rest + if (leftCorrection) { + nsIFrame* childFrame; + mParent->FirstChild(aPresContext, nsnull, &childFrame); + if (this == childFrame) { + gap += leftCorrection; + childFrame = mFrames.FirstChild(); + while (childFrame) { + nsPoint origin; + childFrame->GetOrigin(origin); + childFrame->MoveTo(aPresContext, origin.x + leftCorrection, origin.y); + childFrame->GetNextSibling(&childFrame); + } + mBoundingMetrics.leftBearing += leftCorrection; + mBoundingMetrics.rightBearing += leftCorrection; + mBoundingMetrics.width += leftCorrection; + } + } + aDesiredSize.width += gap; + } + return NS_OK; +} + + //========================== -// *BEWARE* of the wrapper frame! -// This is the frame that is inserted to alter the style context of -// scripting elements. What this means is that looking for your parent -// or your siblings with (possible several) wrapper frames around you -// can make you wonder what is going on. For example, the direct parent -// of the subscript within is not , but instead the wrapper -// frame that was insterted to alter the style context of the subscript! -// You will seldom need to find out who is exactly your parent. You should -// first rethink your code to see if you can avoid finding who is your parent. -// Be careful, there are wrapper frames all over the place, and probably -// one or many are wrapping you if you are in a position where the -// scriptlevel is non zero. - nsresult -NS_NewMathMLWrapperFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsMathMLWrapperFrame* it = new (aPresShell) nsMathMLWrapperFrame; + nsMathMLmathBlockFrame* it = new (aPresShell) nsMathMLmathBlockFrame; if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - *aNewFrame = it; + *aNewFrame = it; return NS_OK; } -nsMathMLWrapperFrame::nsMathMLWrapperFrame() +nsresult +NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { -} - -nsMathMLWrapperFrame::~nsMathMLWrapperFrame() -{ -} - -NS_IMETHODIMP -nsMathMLWrapperFrame::Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus) -{ - nsresult rv = NS_OK; - aStatus = NS_FRAME_COMPLETE; - aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0; - - // See if this is an incremental reflow - if (aReflowState.reason == eReflowReason_Incremental) { - nsIFrame* targetFrame; - aReflowState.reflowCommand->GetTarget(targetFrame); -#ifdef MATHML_NOISY_INCREMENTAL_REFLOW -printf("nsMathMLWrapperFrame::Reflow:IncrementalReflow received by: "); -nsFrame::ListTag(stdout, this); -printf("for target: "); -nsFrame::ListTag(stdout, targetFrame); -printf("\n"); -#endif - if (this == targetFrame) { - } - else { - // Remove the next frame from the reflow path - nsIFrame* nextFrame; - aReflowState.reflowCommand->GetNext(nextFrame); - } + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; } - - nsIFrame* childFrame = mFrames.FirstChild(); - if (childFrame) { - nsReflowStatus childStatus; - nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize, - aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS); - nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight); - nsHTMLReflowState childReflowState(aPresContext, aReflowState, childFrame, availSize); - rv = ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowState, childStatus); - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent,childDesiredSize.ascent, - childDesiredSize.width,childDesiredSize.height)); - aDesiredSize = childDesiredSize; - aStatus = childStatus; - - mBoundingMetrics = childDesiredSize.mBoundingMetrics; - - mReference.x = 0; - mReference.y = aDesiredSize.ascent; - - FinalizeReflow(aPresContext, *aReflowState.rendContext, aDesiredSize); - } - return rv; -} - -NS_IMETHODIMP -nsMathMLWrapperFrame::Place(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - PRBool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize) -{ - aDesiredSize.width = aDesiredSize.height = 0; - aDesiredSize.ascent = aDesiredSize.descent = 0; - aDesiredSize.mBoundingMetrics.Clear(); - - nsIFrame* childFrame = mFrames.FirstChild(); - if (childFrame) { - - // get a possibly updated bounding metrics if the child is - // a stretchy MathML frame that has just been stretched, otherwise - // keep the bounding metrics that was computed in Reflow() - nsIMathMLFrame* aMathMLFrame = nsnull; - nsresult rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetBoundingMetrics(mBoundingMetrics); - aMathMLFrame->GetReference(mReference); // XXX doesn't set the correct value (due to lspace) fix me! - } - - nsRect rect; - childFrame->GetRect(rect); - aDesiredSize.descent = rect.x; - aDesiredSize.ascent = rect.y; - aDesiredSize.width = rect.width; - aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; - aDesiredSize.mBoundingMetrics = mBoundingMetrics; - - if (aPlaceOrigin) { - nsHTMLReflowMetrics childSize(nsnull); - childSize.width = rect.width; - childSize.height = rect.height; - FinishReflowChild(childFrame, aPresContext, childSize, 0, 0, 0); - } + nsMathMLmathInlineFrame* it = new (aPresShell) nsMathMLmathInlineFrame; + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; } + *aNewFrame = it; return NS_OK; } - -#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) -NS_IMETHODIMP -nsMathMLWrapperFrame::Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer) -{ - nsresult rv = NS_OK; - - rv = nsHTMLContainerFrame::Paint(aPresContext, - aRenderingContext, - aDirtyRect, - aWhichLayer); - - if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) - { - aRenderingContext.SetColor(NS_RGB(255,0,0)); - - nscoord x = mReference.x + mBoundingMetrics.leftBearing; - nscoord y = mReference.y - mBoundingMetrics.ascent; - nscoord w = mBoundingMetrics.rightBearing - mBoundingMetrics.leftBearing; - nscoord h = mBoundingMetrics.ascent + mBoundingMetrics.descent; - - aRenderingContext.DrawRect(x,y,w,h); - } - return rv; -} -#endif diff --git a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h index efeb7fba0ec..52167dbab2d 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLContainerFrame.h @@ -32,7 +32,7 @@ #include "nsMathMLAtoms.h" #include "nsMathMLOperators.h" #include "nsMathMLChar.h" -#include "nsIMathMLFrame.h" +#include "nsMathMLFrame.h" #include "nsMathMLParts.h" #include "nsCSSValue.h" @@ -44,44 +44,26 @@ * The Reflow() method relies upon Place() to position children. * By overloading Place() in derived classes, it is therefore possible * to position children in various customized ways. - * - * This frame is a *math-aware frame* in the sense that given the markup - * base arguments, the method InsertScriptLevelStyleContext() - * can be used to render the 'base' in normal-font, and the 'arguments' - * in small-font. This is a common functionality to tags like msub, msup, - * msubsup, mover, munder, munderover, mmultiscripts. All are derived - * from this base class. They use SetInitialChildList() to trigger - * InsertScriptLevelStyleContext() for the very first time as soon as all - * their children are known. However, each of these tags has its own - * Reflow() and/or Place() methods to lay its children as appropriate, - * thus overriding the default behavior in this base class. - * - * Other tags like mi that do not have 'arguments' can be derived from - * this base class as well. The class caters for empty arguments. - * Notice that mi implements its own SetInitialChildList() method - * to switch to a normal-font (rather than italics) if its text content - * is not a single character (as per the MathML REC). - * */ -class nsMathMLContainerFrame : public nsHTMLContainerFrame, public nsIMathMLFrame { +// Parameters to handle the change of font-size induced by changing the +// scriptlevel. These are hard-coded values that match with the rules in +// mathml.css. Note that mScriptLevel can exceed these bounds, but the +// scaling effect on the font-size will be bounded. The following bounds can +// be expanded provided the new corresponding rules are added in mathml.css. +#define NS_MATHML_CSS_POSITIVE_SCRIPTLEVEL_LIMIT +5 +#define NS_MATHML_CSS_NEGATIVE_SCRIPTLEVEL_LIMIT -5 +#define NS_MATHML_SCRIPTSIZEMULTIPLIER 0.71f +#define NS_MATHML_SCRIPTMINSIZE 8 + +class nsMathMLContainerFrame : public nsHTMLContainerFrame, + public nsMathMLFrame { public: - // nsIMathMLFrame methods -- see documentation in nsIMathMLFrame.h + NS_DECL_ISUPPORTS_INHERITED - NS_DECL_ISUPPORTS - - NS_IMETHOD - GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics); - - NS_IMETHOD - SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics); - - NS_IMETHOD - GetReference(nsPoint& aReference); - - NS_IMETHOD - SetReference(const nsPoint& aReference); + // -------------------------------------------------------------------------- + // Overloaded nsMathMLFrame methods -- see documentation in nsIMathMLFrame.h NS_IMETHOD Stretch(nsIPresContext* aPresContext, @@ -89,12 +71,7 @@ public: nsStretchDirection aStretchDirection, nsBoundingMetrics& aContainerSize, nsHTMLReflowMetrics& aDesiredStretchSize); -#if 0 - NS_IMETHOD - GetDesiredStretchSize(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsBoundingMetrics& aDesiredStretchSize); -#endif + NS_IMETHOD Place(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -105,30 +82,20 @@ public: EmbellishOperator(); NS_IMETHOD - GetEmbellishData(nsEmbellishData& aEmbellishData); + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); NS_IMETHOD - SetEmbellishData(const nsEmbellishData& aEmbellishData); + ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel); - NS_IMETHOD - GetPresentationData(nsPresentationData& aPresentationData); - - NS_IMETHOD - SetPresentationData(const nsPresentationData& aPresentationData); - - NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate); - - NS_IMETHOD - UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate); - - // nsHTMLContainerFrame methods + // -------------------------------------------------------------------------- + // Overloaded nsHTMLContainerFrame methods -- see documentation in nsIFrame.h NS_IMETHOD GetFrameType(nsIAtom** aType) const; @@ -164,13 +131,21 @@ public: return nsHTMLContainerFrame::DidReflow(aPresContext, aStatus); } -#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) + NS_IMETHOD + AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aHint); + NS_IMETHOD Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); -#endif + + // -------------------------------------------------------------------------- + // Additional methods // error handlers to report than an error (typically invalid markup) // was encountered during reflow. By default the user will see the @@ -216,6 +191,17 @@ public: 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus); } + // helper to add the inter-spacing when is the immediate parent. + // Since we don't (yet) handle the root element ourselves, we need to + // take special care of the inter-frame spacing on elements for which + // is the direct xml parent. This function will be repeatedly called from + // left to right on the childframes of , and by so doing it will + // emulate the spacing that would have been done by a container. + // e.g., it fixes f q f I + virtual nsresult + FixInterFrameSpacing(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize); + // helper method to complete the post-reflow hook and ensure that embellished // operators don't terminate their Reflow without receiving a Stretch command. virtual nsresult @@ -223,12 +209,6 @@ public: nsIRenderingContext& aRenderingContext, nsHTMLReflowMetrics& aDesiredSize); - // helper method to alter the style contexts of subscript/superscript elements - // XXX this is pretty much a hack until the content model caters for MathML and - // the style system has some provisions for MathML - virtual nsresult - InsertScriptLevelStyleContext(nsIPresContext* aPresContext); - // helper to give a style context suitable for doing the stretching to the // MathMLChar. Frame classes that use this should make the extra style contexts // accessible to the Style System via Get/Set AdditionalStyleContext. @@ -239,24 +219,10 @@ public: nsIStyleContext* aParenStyleContext, nsMathMLChar* aMathMLChar); - // helper to find the smallest font-size on a tree so that we don't insert - // scriptlevel fonts that lead to unreadable results on deeper nodes below us. - // XXX expensive recursive function, need something better, with cache - static PRInt32 - FindSmallestFontSizeFor(nsIPresContext* aPresContext, - nsIFrame* aFrame); - // helper to check if a frame is an embellished container static PRBool IsEmbellishOperator(nsIFrame* aFrame); - // helper methods for processing empty MathML frames (with whitespace only) - static void - ReflowEmptyChild(nsIPresContext* aPresContext, - nsIFrame* aFrame); - static PRBool - IsOnlyWhitespace(nsIFrame* aFrame); - // helper method to facilitate getting the reflow and bounding metrics // IMPORTANT: This function is only meant to be called in Place() methods // where it is assumed that the frame's rect is still acting as place holder @@ -304,6 +270,21 @@ public: } } + static void + GetItalicCorrection(nsBoundingMetrics& aBoundingMetrics, + nscoord& aLeftItalicCorrection, + nscoord& aRightItalicCorrection) + { + aRightItalicCorrection = aBoundingMetrics.rightBearing - aBoundingMetrics.width; + if (0 > aRightItalicCorrection) { + aRightItalicCorrection = 0; + } + aLeftItalicCorrection = -aBoundingMetrics.leftBearing; + if (0 > aLeftItalicCorrection) { + aLeftItalicCorrection = 0; + } + } + // helper methods for getting sup/subdrop's from a child static void GetSubDropFromChild (nsIPresContext* aPresContext, @@ -480,53 +461,78 @@ public: nscoord& aAxisHeight); protected: - - // information about the presentation policy of the frame - nsPresentationData mPresentationData; - - // 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; - virtual PRIntn GetSkipSides() const { return 0; } }; -// XXX hack until the content model caters for MathML and the style system -// has some provisions for MathML -class nsMathMLWrapperFrame : public nsMathMLContainerFrame { + +// -------------------------------------------------------------------------- +// Currently, to benefit from line-breaking inside the element, is +// simply mapping to nsBlockFrame or nsInlineFrame. +// A separate implemention needs to provide: +// 1) line-breaking +// 2) proper inter-frame spacing +// 3) firing of Stretch() (in which case FinalizeReflow() would have to be cleaned) +// Issues: If/when mathml becomes a pluggable component, the separation will be needed. +class nsMathMLmathBlockFrame : public nsBlockFrame { public: - friend nsresult NS_NewMathMLWrapperFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + friend nsresult NS_NewMathMLmathBlockFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); NS_IMETHOD - Reflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aDesiredSize, - const nsHTMLReflowState& aReflowState, - nsReflowStatus& aStatus); + SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) + { + nsresult rv; - NS_IMETHOD - Place(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - PRBool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize); + rv = nsBlockFrame::SetInitialChildList(aPresContext, aListName, aChildList); -#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) - NS_IMETHOD - Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer); -#endif + // re-resolve our subtree to set any mathml-expected scriptsizes + nsIFrame* childFrame = aChildList; // mFrames is not used by nsBlockFrame + while (childFrame) { + nsIMathMLFrame* mathMLFrame; + nsresult res = childFrame->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + mathMLFrame->ReResolveScriptStyle(aPresContext, mStyleContext, 0); + } + childFrame->GetNextSibling(&childFrame); + } + return rv; + } protected: - nsMathMLWrapperFrame(); - virtual ~nsMathMLWrapperFrame(); - - virtual PRIntn GetSkipSides() const { return 0; } + nsMathMLmathBlockFrame() {} + virtual ~nsMathMLmathBlockFrame() {} }; +class nsMathMLmathInlineFrame : public nsInlineFrame { +public: + friend nsresult NS_NewMathMLmathInlineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + + NS_IMETHOD + SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) + { + nsresult rv; + rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList); + + // re-resolve our subtree to set any mathml-expected scriptsizes + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + nsIMathMLFrame* mathMLFrame; + nsresult res = childFrame->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + mathMLFrame->ReResolveScriptStyle(aPresContext, mStyleContext, 0); + } + childFrame->GetNextSibling(&childFrame); + } + return rv; + } + +protected: + nsMathMLmathInlineFrame() {} + virtual ~nsMathMLmathInlineFrame() {} +}; #endif /* nsMathMLContainerFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLParts.h b/mozilla/layout/mathml/base/src/nsMathMLParts.h index c0fb6d036ad..86077aba580 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLParts.h +++ b/mozilla/layout/mathml/base/src/nsMathMLParts.h @@ -50,4 +50,12 @@ extern nsresult NS_NewMathMLmsqrtFrame( nsIPresShell* aPresShell, nsIFrame** aNe extern nsresult NS_NewMathMLmrootFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); extern nsresult NS_NewMathMLmactionFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +extern nsresult NS_NewMathMLmathBlockFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +extern nsresult NS_NewMathMLmathInlineFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +inline nsresult NS_NewMathMLmathFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsBlock) +{ + return (aIsBlock) + ? NS_NewMathMLmathBlockFrame(aPresShell, aNewFrame) + : NS_NewMathMLmathInlineFrame(aPresShell, aNewFrame); +} #endif /* nsMathMLParts_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp index 6fa96aa350f..20fcfc71819 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp @@ -60,21 +60,9 @@ #define NS_MATHML_ACTION_TYPE_TOOLTIP 3 // unsupported #define NS_MATHML_ACTION_TYPE_RESTYLE 4 -NS_INTERFACE_MAP_BEGIN(nsMathMLmactionFrame) - NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) -NS_INTERFACE_MAP_END_INHERITING(nsMathMLContainerFrame) - -NS_IMETHODIMP_(nsrefcnt) -nsMathMLmactionFrame::AddRef(void) -{ - return NS_OK; -} - -NS_IMETHODIMP_(nsrefcnt) -nsMathMLmactionFrame::Release(void) -{ - return NS_OK; -} +NS_IMPL_ADDREF_INHERITED(nsMathMLmactionFrame, nsMathMLContainerFrame) +NS_IMPL_RELEASE_INHERITED(nsMathMLmactionFrame, nsMathMLContainerFrame) +NS_IMPL_QUERY_INTERFACE_INHERITED1(nsMathMLmactionFrame, nsMathMLContainerFrame, nsIDOMMouseListener) nsresult NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) @@ -219,12 +207,11 @@ nsMathMLmactionFrame::GetSelectedFrame() PRInt32 count = 0; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if (!mSelectedFrame) - mSelectedFrame = childFrame; // default is first child - if (++count == selection) - mSelectedFrame = childFrame; - } + if (!mSelectedFrame) + mSelectedFrame = childFrame; // default is first child + if (++count == selection) + mSelectedFrame = childFrame; + childFrame->GetNextSibling(&childFrame); } // cater for invalid user-supplied selection @@ -241,11 +228,11 @@ nsMathMLmactionFrame::GetSelectedFrame() mEmbellishData.core = nsnull; mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED; if (mSelectedFrame) { - nsIMathMLFrame* aMathMLFrame = nsnull; - rv = mSelectedFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { + nsIMathMLFrame* mathMLFrame = nsnull; + rv = mSelectedFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { nsEmbellishData embellishData; - aMathMLFrame->GetEmbellishData(embellishData); + mathMLFrame->GetEmbellishData(embellishData); if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.firstChild) { mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR; mEmbellishData.firstChild = mSelectedFrame; // yes! diff --git a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.h index 7e56b01956d..035f3a267f2 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmactionFrame.h @@ -42,7 +42,7 @@ class nsMathMLmactionFrame : public nsMathMLContainerFrame, public: friend nsresult NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS_INHERITED NS_IMETHOD Init(nsIPresContext* aPresContext, diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp index 831fa1d5b3a..5ba46f60bcd 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp @@ -184,11 +184,8 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsIPresContext* aPresContext) PRInt32 sepCount = -1; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - sepCount++; - } - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child"); + sepCount++; + childFrame->GetNextSibling(&childFrame); } if (0 < sepCount) { mSeparatorsChar = new nsMathMLChar[sepCount]; @@ -261,28 +258,21 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mFlags | NS_REFLOW_CALC_BOUNDING_METRICS); nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - ////////////// - // WHITESPACE: don't forget that whitespace doesn't count in MathML! - if (IsOnlyWhitespace(childFrame)) { - ReflowEmptyChild(aPresContext, childFrame); - } - else { - nsHTMLReflowState childReflowState(aPresContext, aReflowState, - childFrame, availSize); - rv = ReflowChild(childFrame, aPresContext, childDesiredSize, - childReflowState, childStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); - if (NS_FAILED(rv)) return rv; + nsHTMLReflowState childReflowState(aPresContext, aReflowState, + childFrame, availSize); + rv = ReflowChild(childFrame, aPresContext, childDesiredSize, + childReflowState, childStatus); + //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + if (NS_FAILED(rv)) return rv; - // At this stage, the origin points of the children have no use, so we will use the - // origins as placeholders to store the child's ascent and descent. Later on, - // we should set the origins so as to overwrite what we are storing there now. - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent, childDesiredSize.ascent, - childDesiredSize.width, childDesiredSize.height)); - } - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child"); + // At this stage, the origin points of the children have no use, so we will use the + // origins as placeholders to store the child's ascent and descent. Later on, + // we should set the origins so as to overwrite what we are storing there now. + childFrame->SetRect(aPresContext, + nsRect(childDesiredSize.descent, childDesiredSize.ascent, + childDesiredSize.width, childDesiredSize.height)); + + childFrame->GetNextSibling(&childFrame); } // get our bounding metrics using a tentative Place() @@ -300,30 +290,28 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - nsIMathMLFrame* aMathMLFrame; - rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - // retrieve the metrics that was stored at the previous pass - childFrame->GetRect(rect); - aMathMLFrame->GetBoundingMetrics(childDesiredSize.mBoundingMetrics); - childDesiredSize.descent = rect.x; - childDesiredSize.ascent = rect.y; - childDesiredSize.height = rect.height; - childDesiredSize.width = rect.width; + nsIMathMLFrame* mathMLFrame; + rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + // retrieve the metrics that was stored at the previous pass + childFrame->GetRect(rect); + mathMLFrame->GetBoundingMetrics(childDesiredSize.mBoundingMetrics); + childDesiredSize.descent = rect.x; + childDesiredSize.ascent = rect.y; + childDesiredSize.height = rect.height; + childDesiredSize.width = rect.width; - aMathMLFrame->Stretch(aPresContext, *aReflowState.rendContext, - stretchDir, containerSize, childDesiredSize); - // store the updated metrics - childFrame->SetRect(aPresContext, - nsRect(childDesiredSize.descent, childDesiredSize.ascent, - childDesiredSize.width, childDesiredSize.height)); + mathMLFrame->Stretch(aPresContext, *aReflowState.rendContext, + stretchDir, containerSize, childDesiredSize); + // store the updated metrics + childFrame->SetRect(aPresContext, + nsRect(childDesiredSize.descent, childDesiredSize.ascent, + childDesiredSize.width, childDesiredSize.height)); - if (aDesiredSize.descent < childDesiredSize.descent) - aDesiredSize.descent = childDesiredSize.descent; - if (aDesiredSize.ascent < childDesiredSize.ascent) - aDesiredSize.ascent = childDesiredSize.ascent; - } + if (aDesiredSize.descent < childDesiredSize.descent) + aDesiredSize.descent = childDesiredSize.descent; + if (aDesiredSize.ascent < childDesiredSize.ascent) + aDesiredSize.ascent = childDesiredSize.ascent; } childFrame->GetNextSibling(&childFrame); } @@ -390,26 +378,25 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext, childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - nsHTMLReflowMetrics childSize(nsnull); - GetReflowAndBoundingMetricsFor(childFrame, childSize, bm); - if (firstTime) { - firstTime = PR_FALSE; - mBoundingMetrics = bm; - } - else - mBoundingMetrics += bm; - - FinishReflowChild(childFrame, aPresContext, childSize, - dx, aDesiredSize.ascent - childSize.ascent, 0); - dx += childSize.width; - - if (i < mSeparatorsCount) { - PlaceChar(&mSeparatorsChar[i], fontAscent, aDesiredSize.ascent, bm, dx); - mBoundingMetrics += bm; - } - i++; + nsHTMLReflowMetrics childSize(nsnull); + GetReflowAndBoundingMetricsFor(childFrame, childSize, bm); + if (firstTime) { + firstTime = PR_FALSE; + mBoundingMetrics = bm; } + else + mBoundingMetrics += bm; + + FinishReflowChild(childFrame, aPresContext, childSize, + dx, aDesiredSize.ascent - childSize.ascent, 0); + dx += childSize.width; + + if (i < mSeparatorsCount) { + PlaceChar(&mSeparatorsChar[i], fontAscent, aDesiredSize.ascent, bm, dx); + mBoundingMetrics += bm; + } + i++; + childFrame->GetNextSibling(&childFrame); } @@ -453,20 +440,20 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize) { if (aMathMLChar && 0 < aMathMLChar->Length()) { - nsOperatorFlags aFlags; - float aLeftSpace = 0.0f; - float aRightSpace = 0.0f; + nsOperatorFlags flags = 0; + float leftSpace = 0.0f; + float rightSpace = 0.0f; - nsAutoString aData; - aMathMLChar->GetData(aData); - aMathMLChar->SetData(aPresContext, aData); // XXX hack to reset, bug 45010 - PRBool found = nsMathMLOperators::LookupOperator(aData, aForm, - &aFlags, &aLeftSpace, &aRightSpace); + nsAutoString data; + aMathMLChar->GetData(data); + aMathMLChar->SetData(aPresContext, data); // XXX hack to reset, bug 45010 + PRBool found = nsMathMLOperators::LookupOperator(data, aForm, + &flags, &leftSpace, &rightSpace); // If we don't want extra space when we are a script if (found && aScriptLevel > 0) { - aLeftSpace /= 2.0f; - aRightSpace /= 2.0f; + leftSpace /= 2.0f; + rightSpace /= 2.0f; } // stretch the char to the appropriate height if it is not big enough. @@ -488,8 +475,8 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, if (NS_FAILED(res) && charSize.width == 0) { // gracefully handle cases where stretching the char failed (i.e., GetBoundingMetrics failed) // we need to get the width - aRenderingContext.GetWidth(aData, charSize.width); - // XXX the bounding metrics of the MathMLChar is not updated, but PlaceChar() + aRenderingContext.GetWidth(data, charSize.width); + // Note: the bounding metrics of the MathMLChar is not updated, but PlaceChar() // will do the right thing by leaving the necessary room to paint the char. } } @@ -500,11 +487,11 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext, aDesiredSize.descent = charSize.descent; // account the spacing - charSize.width += NSToCoordRound((aLeftSpace + aRightSpace) * em); + charSize.width += NSToCoordRound((leftSpace + rightSpace) * em); // x-origin is used to store lspace ... // y-origin is used to stored the ascent ... - aMathMLChar->SetRect(nsRect(NSToCoordRound(aLeftSpace * em), + aMathMLChar->SetRect(nsRect(NSToCoordRound(leftSpace * em), charSize.ascent, charSize.width, charSize.ascent + charSize.descent)); } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp index d5ada7a8978..ee5a85435df 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.cpp @@ -143,18 +143,11 @@ nsMathMLmfracFrame::CalcLineThickness(nsIPresContext* aPresContext, else if (eCSSUnit_Null != unit) lineThickness = CalcLength(aPresContext, aStyleContext, cssValue); } -#if 0 - else { - char str[50]; - aThicknessAttribute.ToCString(str, 50); - printf("Invalid attribute linethickness=%s\n", str); - } -#endif } } // use minimum if the lineThickness is a non-zero value less than minimun - if (0 != lineThickness && lineThickness < minimumThickness) + if (lineThickness && lineThickness < minimumThickness) lineThickness = minimumThickness; return lineThickness; @@ -214,27 +207,24 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext, nsIFrame* frameDen = nsnull; nsIFrame* childFrame = mFrames.FirstChild(); - while (nsnull != childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if (0 == count) { - // numerator - frameNum = childFrame; - GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum); - } - else if (1 == count) { - // denominator - frameDen = childFrame; - GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen); - } - count++; + while (childFrame) { + if (0 == count) { + // numerator + frameNum = childFrame; + GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum); } - rv = childFrame->GetNextSibling(&childFrame); + else if (1 == count) { + // denominator + frameDen = childFrame; + GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen); + } + count++; + + childFrame->GetNextSibling(&childFrame); } -#ifdef NS_DEBUG - if (2 != count) printf("mfrac: invalid markup\n"); -#endif - if ((2 != count) || !frameNum || !frameDen) { + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, aRenderingContext, aDesiredSize); } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h index 0f43bbeb1e1..b5762259f18 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmfracFrame.h @@ -104,14 +104,12 @@ public: // while the denominator is compressed PRInt32 increment = NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) ? 0 : 1; - UpdatePresentationDataFromChildAt(0, -1, increment, + UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - UpdatePresentationDataFromChildAt(1, 1, 0, + UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 0, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); - // switch the style of the numerator and denominator if necessary - InsertScriptLevelStyleContext(aPresContext); // check whether or not this is an embellished operator EmbellishOperator(); return rv; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmiFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmiFrame.cpp index 7495dd9261f..d12d60ecd72 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmiFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmiFrame.cpp @@ -76,12 +76,14 @@ nsMathMLmiFrame::Init(nsIPresContext* aPresContext, { nsresult rv = NS_OK; rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + +#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) + mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS; +#endif return rv; } // if our content is not a single character, we turn the font to normal -// XXX TrimWhitespace / CompressWhitespace? - NS_IMETHODIMP nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, @@ -95,10 +97,10 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext, // Get the length of the text content that we enclose // our content can include comment-nodes, attribute-nodes, text-nodes... // we use the DOM to make sure that we are only looking at text-nodes... - PRInt32 aLength = 0; + PRInt32 length = 0; PRInt32 numKids; mContent->ChildCount(numKids); - //nsAutoString aData; + //nsAutoString data; for (PRInt32 kid=0; kid kidContent; mContent->ChildAt(kid, *getter_AddRefs(kidContent)); @@ -107,57 +109,44 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext, if (kidText.get()) { PRUint32 kidLength; kidText->GetLength(&kidLength); - aLength += kidLength; + length += kidLength; //nsAutoString kidData; //kidText->GetData(kidData); - //aData += kidData; + //data += kidData; } } } nsIFrame* firstChild = mFrames.FirstChild(); - if (firstChild && 1 < aLength) { - + if (firstChild && 1 < length) { // 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; + nsAutoString fontstyle; if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::fontstyle_, fontStyle)) + nsMathMLAtoms::fontstyle_, fontstyle)) { - if (fontStyle.EqualsWithConversion("italic")) + if (fontstyle.EqualsWithConversion("italic")) return rv; } - // Get a pseudo style context for the appropriate style font - nsIAtom* fontAtom = nsMathMLAtoms::fontstyle_normal; + // set the -moz-math-font-style attribute without notifying that we want a reflow + fontstyle.AssignWithConversion("normal"); + mContent->SetAttribute(kNameSpaceID_None, nsMathMLAtoms::fontstyle, + fontstyle, PR_FALSE); + // then, re-resolve the style contexts in our subtree + nsCOMPtr parentStyleContext; + parentStyleContext = getter_AddRefs(mStyleContext->GetParent()); nsCOMPtr 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. + aPresContext->ResolveStyleContextFor(mContent, parentStyleContext, + PR_FALSE, getter_AddRefs(newStyleContext)); if (newStyleContext && newStyleContext.get() != mStyleContext) { - - nsCOMPtr shell; - aPresContext->GetShell(getter_AddRefs(shell)); - - nsIFrame* newFrame = nsnull; - NS_NewMathMLWrapperFrame(shell, &newFrame); - NS_ASSERTION(newFrame, "Failed to create new frame"); - if (newFrame) { - newFrame->Init(aPresContext, mContent, this, newStyleContext, nsnull); - // our children become children of the new frame - nsIFrame* childFrame = firstChild; - while (childFrame) { - childFrame->SetParent(newFrame); - aPresContext->ReParentStyleContext(childFrame, newStyleContext); - childFrame->GetNextSibling(&childFrame); - } - newFrame->SetInitialChildList(aPresContext, nsnull, firstChild); - // the new frame becomes our sole child - mFrames.SetFrames(newFrame); + SetStyleContext(aPresContext, newStyleContext); + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + aPresContext->ReParentStyleContext(childFrame, newStyleContext); + childFrame->GetNextSibling(&childFrame); } } } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmiFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmiFrame.h index c172df79e52..2a49ac9d078 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmiFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmiFrame.h @@ -41,6 +41,10 @@ public: nsIStyleContext* aContext, nsIFrame* aPrevInFlow); + /* mi implements its own SetInitialChildList() method + * to switch to a normal-font (rather than italics) if its text + * content is not a single character (as per the MathML REC). + */ NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, diff --git a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp index 7b8f5f573a6..8ebdc23c150 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.cpp @@ -3,19 +3,19 @@ * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ - * + * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. - * + * * The Original Code is Mozilla MathML Project. - * - * The Initial Developer of the Original Code is The University Of + * + * The Initial Developer of the Original Code is The University Of * Queensland. Portions created by The University Of Queensland are * Copyright (C) 1999 The University Of Queensland. All Rights Reserved. - * - * Contributor(s): + * + * Contributor(s): * Roger B. Sidje * David J. Fiddes * Shyjan Mahamud (added TeX rendering rules) @@ -116,10 +116,10 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, //////////////////////////////////// // Get the children's desired sizes - nscoord minShiftFromXHeight, aSubDrop, aSupDrop; + nscoord minShiftFromXHeight, subDrop, supDrop; //////////////////////////////////////// - // Initialize super/sub shifts that + // Initialize super/sub shifts that // depend only on the current font //////////////////////////////////////// @@ -142,82 +142,80 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, nscoord xHeight; fm->GetXHeight (xHeight); - nscoord aRuleSize; - GetRuleThickness (aRenderingContext, fm, aRuleSize); + nscoord ruleSize; + GetRuleThickness (aRenderingContext, fm, ruleSize); ///////////////////////////////////// // first the shift for the subscript - // aSubScriptShift{1,2} - // = minimum amount to shift the subscript down + // subScriptShift{1,2} + // = minimum amount to shift the subscript down // = sub{1,2} in TeXbook - // aSubScriptShift1 = subscriptshift attribute * x-height - nscoord aSubScriptShift1, aSubScriptShift2; + // subScriptShift1 = subscriptshift attribute * x-height + nscoord subScriptShift1, subScriptShift2; - // Get aSubScriptShift{1,2} default from font - GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2); + // Get subScriptShift{1,2} default from font + GetSubScriptShifts (fm, subScriptShift1, subScriptShift2); if (0 < mSubScriptShift) { // the user has set the subscriptshift attribute - float aFactor = ((float) aSubScriptShift2) / aSubScriptShift1; - aSubScriptShift1 = PR_MAX(aSubScriptShift1, mSubScriptShift); - aSubScriptShift2 = NSToCoordRound(aFactor * aSubScriptShift1); + float scaler = ((float) subScriptShift2) / subScriptShift1; + subScriptShift1 = PR_MAX(subScriptShift1, mSubScriptShift); + subScriptShift2 = NSToCoordRound(scaler * subScriptShift1); } // the font dependent shift - nscoord aSubScriptShift = PR_MAX(aSubScriptShift1,aSubScriptShift2); + nscoord subScriptShift = PR_MAX(subScriptShift1,subScriptShift2); ///////////////////////////////////// // next the shift for the superscript - // aSupScriptShift{1,2,3} + // supScriptShift{1,2,3} // = minimum amount to shift the supscript up // = sup{1,2,3} in TeX - // aSupScriptShift1 = superscriptshift attribute * x-height + // supScriptShift1 = superscriptshift attribute * x-height // Note that there are THREE values for supscript shifts depending // on the current style - nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3; - // Set aSupScriptShift{1,2,3} default from font - GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3); + nscoord supScriptShift1, supScriptShift2, supScriptShift3; + // Set supScriptShift{1,2,3} default from font + GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3); if (0 < mSupScriptShift) { // the user has set the superscriptshift attribute - float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1; - float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1; - aSupScriptShift1 = PR_MAX(aSupScriptShift1, mSupScriptShift); - aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1); - aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1); + float scaler2 = ((float) supScriptShift2) / supScriptShift1; + float scaler3 = ((float) supScriptShift3) / supScriptShift1; + supScriptShift1 = PR_MAX(supScriptShift1, mSupScriptShift); + supScriptShift2 = NSToCoordRound(scaler2 * supScriptShift1); + supScriptShift3 = NSToCoordRound(scaler3 * supScriptShift1); } // get sup script shift depending on current script level and display style // Rule 18c, App. G, TeXbook - nscoord aSupScriptShift; - if ( mPresentationData.scriptLevel == 0 && + nscoord supScriptShift; + if ( mPresentationData.scriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) && !NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) { // Style D in TeXbook - aSupScriptShift = aSupScriptShift1; + supScriptShift = supScriptShift1; } else if (NS_MATHML_IS_COMPRESSED(mPresentationData.flags)) { // Style C' in TeXbook = D',T',S',SS' - aSupScriptShift = aSupScriptShift3; + supScriptShift = supScriptShift3; } else { // everything else = T,S,SS - aSupScriptShift = aSupScriptShift2; + supScriptShift = supScriptShift2; } //////////////////////////////////// // Get the children's sizes //////////////////////////////////// - + nscoord width = 0, prescriptsWidth = 0, rightBearing = 0; - nsIFrame* mprescriptsFrame = nsnull; // frame of , if there. + nsIFrame* mprescriptsFrame = nsnull; // frame of , if there. PRBool isSubScript = PR_FALSE; - PRBool isSubScriptPresent = PR_TRUE; - PRBool isSupScriptPresent = PR_TRUE; - nscoord minSubScriptShift = 0, minSupScriptShift = 0; - nscoord trySubScriptShift = aSubScriptShift; - nscoord trySupScriptShift = aSupScriptShift; - nscoord maxSubScriptShift = aSubScriptShift; - nscoord maxSupScriptShift = aSupScriptShift; + nscoord minSubScriptShift = 0, minSupScriptShift = 0; + nscoord trySubScriptShift = subScriptShift; + nscoord trySupScriptShift = supScriptShift; + nscoord maxSubScriptShift = subScriptShift; + nscoord maxSupScriptShift = supScriptShift; PRInt32 count = 0; nsHTMLReflowMetrics baseSize (nsnull); nsHTMLReflowMetrics subScriptSize (nsnull); @@ -237,152 +235,121 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, aDesiredSize.ascent = aDesiredSize.descent = -10000000; aDesiredSize.width = aDesiredSize.height = 0; - nsIFrame* aChildFrame = mFrames.FirstChild(); - while (nsnull != aChildFrame) - { - if (!IsOnlyWhitespace (aChildFrame)) { - nsCOMPtr childContent; - nsCOMPtr childTag; - aChildFrame->GetContent(getter_AddRefs(childContent)); - childContent->GetTag(*getter_AddRefs(childTag)); + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + nsCOMPtr childContent; + nsCOMPtr childTag; + childFrame->GetContent(getter_AddRefs(childContent)); + childContent->GetTag(*getter_AddRefs(childTag)); - if (childTag.get() == nsMathMLAtoms::mprescripts_) { - mprescriptsFrame = aChildFrame; - firstPrescriptsPair = PR_TRUE; + if (childTag.get() == nsMathMLAtoms::mprescripts_) { + mprescriptsFrame = childFrame; + firstPrescriptsPair = PR_TRUE; + } + else { + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); + GetItalicCorrection(bmBase, italicCorrection); + + // we update mBoundingMetrics.{ascent,descent} with that + // of the baseFrame only after processing all the sup/sub pairs + // XXX need italic correction only *if* there are postscripts ? + mBoundingMetrics.width = bmBase.width + italicCorrection; + mBoundingMetrics.rightBearing = bmBase.rightBearing; + mBoundingMetrics.leftBearing = bmBase.leftBearing; // until overwritten } else { - - if (childTag.get() == nsMathMLAtoms::none_) { - // we need to record the presence of none tag explicitly - // for correct negotiation between sup/sub shifts later - if (isSubScript) { - isSubScriptPresent = PR_FALSE; - bmSubScript.Clear(); - bmSubScript.leftBearing = 10000000; - } - else { - isSupScriptPresent = PR_FALSE; - bmSupScript.Clear(); - bmSupScript.leftBearing = 10000000; - } - } - - if (0 == count) { - // base - baseFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - GetItalicCorrection(bmBase, italicCorrection); - - // we update mBoundingMetrics.{ascent,descent} with that - // of the baseFrame only after processing all the sup/sub pairs - // XXX need italic correction only *if* there are postscripts ? - mBoundingMetrics.width = bmBase.width + italicCorrection; - mBoundingMetrics.rightBearing = bmBase.rightBearing; - mBoundingMetrics.leftBearing = bmBase.leftBearing; // until overwritten + // super/subscript block + if (isSubScript) { + // subscript + subScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); + // get the subdrop from the subscript font + GetSubDropFromChild (aPresContext, subScriptFrame, subDrop); + // parameter v, Rule 18a, App. G, TeXbook + minSubScriptShift = bmBase.descent + subDrop; + trySubScriptShift = PR_MAX(minSubScriptShift,subScriptShift); + mBoundingMetrics.descent = + PR_MAX(mBoundingMetrics.descent,bmSubScript.descent); + aDesiredSize.descent = + PR_MAX(aDesiredSize.descent,subScriptSize.descent); + width = bmSubScript.width + mScriptSpace; + rightBearing = bmSubScript.rightBearing + mScriptSpace; } else { - // super/subscript block - if (isSubScript) { - if (isSubScriptPresent) { - // subscript - subScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); - // get the subdrop from the subscript font - GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop); - // parameter v, Rule 18a, App. G, TeXbook - minSubScriptShift = bmBase.descent + aSubDrop; - trySubScriptShift = PR_MAX(minSubScriptShift,aSubScriptShift); - mBoundingMetrics.descent = - PR_MAX(mBoundingMetrics.descent,bmSubScript.descent); - aDesiredSize.descent = - PR_MAX(aDesiredSize.descent,subScriptSize.descent); - width = bmSubScript.width + mScriptSpace; - rightBearing = bmSubScript.rightBearing + mScriptSpace; - } + // supscript + supScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); + // get the supdrop from the supscript font + GetSupDropFromChild (aPresContext, supScriptFrame, supDrop); + // parameter u, Rule 18a, App. G, TeXbook + minSupScriptShift = bmBase.ascent - supDrop; + // get min supscript shift limit from x-height + // = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook + minShiftFromXHeight = NSToCoordRound + ((bmSupScript.descent + (1.0f/4.0f) * xHeight)); + trySupScriptShift = + PR_MAX(minSupScriptShift,PR_MAX(minShiftFromXHeight,supScriptShift)); + mBoundingMetrics.ascent = + 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); + + if (!mprescriptsFrame) { // we are still looping over base & postscripts + mBoundingMetrics.rightBearing = mBoundingMetrics.width + rightBearing; + mBoundingMetrics.width += width; } else { - if (isSupScriptPresent) { - // supscript - supScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); - // get the supdrop from the supscript font - GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop); - // parameter u, Rule 18a, App. G, TeXbook - minSupScriptShift = bmBase.ascent - aSupDrop; - // get min supscript shift limit from x-height - // = d(x) + 1/4 * sigma_5, Rule 18c, App. G, TeXbook - minShiftFromXHeight = NSToCoordRound - ((bmSupScript.descent + (1.0f/4.0f) * xHeight)); - trySupScriptShift = - PR_MAX(minSupScriptShift,PR_MAX(minShiftFromXHeight,aSupScriptShift)); - mBoundingMetrics.ascent = - PR_MAX(mBoundingMetrics.ascent,bmSupScript.ascent); - aDesiredSize.ascent = - PR_MAX(aDesiredSize.ascent,supScriptSize.ascent); - width = PR_MAX(width, bmSupScript.width + mScriptSpace); - rightBearing = PR_MAX(rightBearing, bmSupScript.rightBearing + mScriptSpace); + prescriptsWidth += width; + if (firstPrescriptsPair) { + firstPrescriptsPair = PR_FALSE; + mBoundingMetrics.leftBearing = + PR_MIN(bmSubScript.leftBearing, bmSupScript.leftBearing); } - - if (!isSubScriptPresent && !isSupScriptPresent) { - // report an error, encourage people to get their markups in order - return ReflowError(aPresContext, aRenderingContext, aDesiredSize); - } - - if (!mprescriptsFrame) { // we are still looping over base & postscripts - mBoundingMetrics.rightBearing = mBoundingMetrics.width + rightBearing; - mBoundingMetrics.width += width; - } - else { - prescriptsWidth += width; - if (firstPrescriptsPair) { - firstPrescriptsPair = PR_FALSE; - mBoundingMetrics.leftBearing = - PR_MIN(bmSubScript.leftBearing, bmSupScript.leftBearing); - } - } - width = rightBearing = 0; - - if (isSubScriptPresent && isSupScriptPresent) { - // negotiate between the various shifts so that - // there is enough gap between the sup and subscripts - // Rule 18e, App. G, TeXbook - nscoord gap = - (trySupScriptShift - bmSupScript.descent) - - (bmSubScript.ascent - trySubScriptShift); - if (gap < 4.0f * aRuleSize) { - // adjust trySubScriptShift to get a gap of (4.0 * aRuleSize) - trySubScriptShift += NSToCoordRound ((4.0f * aRuleSize) - gap); - } - - // next we want to ensure that the bottom of the superscript - // will be > (4/5) * x-height above baseline - gap = NSToCoordRound ((4.0f/5.0f) * xHeight - - (trySupScriptShift - bmSupScript.descent)); - if (gap > 0.0f) { - trySupScriptShift += gap; - trySubScriptShift -= gap; - } - } - maxSubScriptShift = PR_MAX(maxSubScriptShift, trySubScriptShift); - maxSupScriptShift = PR_MAX(maxSupScriptShift, trySupScriptShift); - - trySubScriptShift = aSubScriptShift; - trySupScriptShift = aSupScriptShift; - isSubScriptPresent = PR_TRUE; - isSupScriptPresent = PR_TRUE; } + width = rightBearing = 0; + + // negotiate between the various shifts so that + // there is enough gap between the sup and subscripts + // Rule 18e, App. G, TeXbook + nscoord gap = + (trySupScriptShift - bmSupScript.descent) - + (bmSubScript.ascent - trySubScriptShift); + if (gap < 4.0f * ruleSize) { + // adjust trySubScriptShift to get a gap of (4.0 * ruleSize) + trySubScriptShift += NSToCoordRound ((4.0f * ruleSize) - gap); + } + + // next we want to ensure that the bottom of the superscript + // will be > (4/5) * x-height above baseline + gap = NSToCoordRound ((4.0f/5.0f) * xHeight - + (trySupScriptShift - bmSupScript.descent)); + if (gap > 0.0f) { + trySupScriptShift += gap; + trySubScriptShift -= gap; + } + + maxSubScriptShift = PR_MAX(maxSubScriptShift, trySubScriptShift); + maxSupScriptShift = PR_MAX(maxSupScriptShift, trySupScriptShift); + + trySubScriptShift = subScriptShift; + trySupScriptShift = supScriptShift; } - - isSubScript = !isSubScript; - count++; } + + isSubScript = !isSubScript; } - - aChildFrame->GetNextSibling(&aChildFrame); + count++; + childFrame->GetNextSibling(&childFrame); } // note: width=0 if all sup-sub pairs match correctly if ((0 != width) || !baseFrame || !subScriptFrame || !supScriptFrame) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, aRenderingContext, aDesiredSize); } @@ -391,15 +358,15 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, mBoundingMetrics.width += prescriptsWidth; // we left out the base during our bounding box updates, so ... - mBoundingMetrics.ascent = + mBoundingMetrics.ascent = PR_MAX(mBoundingMetrics.ascent+maxSupScriptShift,bmBase.ascent); - mBoundingMetrics.descent = + mBoundingMetrics.descent = PR_MAX(mBoundingMetrics.descent+maxSubScriptShift,bmBase.descent); // get the reflow metrics ... - aDesiredSize.ascent = + aDesiredSize.ascent = PR_MAX(aDesiredSize.ascent+maxSupScriptShift,baseSize.ascent); - aDesiredSize.descent = + aDesiredSize.descent = PR_MAX(aDesiredSize.descent+maxSubScriptShift,baseSize.descent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; @@ -409,7 +376,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, mReference.y = aDesiredSize.ascent; ////////////////// - // Place Children + // Place Children // Place prescripts, followed by base, and then postscripts. // The list of frames is in the order: {base} {postscripts} {prescripts} @@ -420,54 +387,49 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext, nsRect aRect; count = 0; - aChildFrame = mprescriptsFrame; + childFrame = mprescriptsFrame; do { - if (nsnull == aChildFrame) { // end of prescripts, + if (!childFrame) { // end of prescripts, // place the base ... - aChildFrame = baseFrame; + childFrame = baseFrame; dy = aDesiredSize.ascent - baseSize.ascent; FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0); dx += bmBase.width + mScriptSpace + italicCorrection; } - else if (mprescriptsFrame != aChildFrame) { + else if (mprescriptsFrame != childFrame) { // process each sup/sub pair - if (!IsOnlyWhitespace (aChildFrame)) { - if (0 == count) { - subScriptFrame = aChildFrame; - count++; - } - else if (1 == count) { - supScriptFrame = aChildFrame; - count = 0; - - // get the ascent/descent of sup/subscripts stored in their rects - // rect.x = descent, rect.y = ascent - GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); - GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); + if (0 == count) { + subScriptFrame = childFrame; + count = 1; + } + else if (1 == count) { + supScriptFrame = childFrame; + count = 0; - // center w.r.t. largest width - width = PR_MAX(subScriptSize.width, supScriptSize.width); + // get the ascent/descent of sup/subscripts stored in their rects + // rect.x = descent, rect.y = ascent + GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); + GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); - dy = aDesiredSize.ascent - - subScriptSize.ascent + - maxSubScriptShift; - FinishReflowChild (subScriptFrame, aPresContext, subScriptSize, - dx + (width-subScriptSize.width)/2, dy, 0); + // center w.r.t. largest width + width = PR_MAX(subScriptSize.width, supScriptSize.width); - dy = aDesiredSize.ascent - - supScriptSize.ascent - - maxSupScriptShift; - FinishReflowChild (supScriptFrame, aPresContext, supScriptSize, - dx + (width-supScriptSize.width)/2, dy, 0); + dy = aDesiredSize.ascent - subScriptSize.ascent + + maxSubScriptShift; + FinishReflowChild (subScriptFrame, aPresContext, subScriptSize, + dx + (width-subScriptSize.width)/2, dy, 0); - dx += mScriptSpace + width; - } + dy = aDesiredSize.ascent - supScriptSize.ascent - + maxSupScriptShift; + FinishReflowChild (supScriptFrame, aPresContext, supScriptSize, + dx + (width-supScriptSize.width)/2, dy, 0); + + dx += mScriptSpace + width; } } - - aChildFrame->GetNextSibling(&aChildFrame); - } while (mprescriptsFrame != aChildFrame); + childFrame->GetNextSibling(&childFrame); + } while (mprescriptsFrame != childFrame); } - + return rv; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.h index e36796558fc..26c15505849 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmmultiscriptsFrame.h @@ -60,10 +60,8 @@ public: // displaystyle to "false", within each of its arguments except base, but // leaves both attributes unchanged within base. // XXX Need to update the compression flags in the sub/sup pairs as per TeX - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - // switch the style of the postscripts and prescripts - InsertScriptLevelStyleContext(aPresContext); // check whether or not this is an embellished operator EmbellishOperator(); return rv; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp index 163df99b5ec..ed8e6ab8f8e 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoFrame.cpp @@ -119,7 +119,6 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer) { nsresult rv = NS_OK; - if (NS_MATHML_OPERATOR_GET_FORM(mFlags) || NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) { rv = mMathMLChar.Paint(aPresContext, aRenderingContext, @@ -207,87 +206,83 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext, // fill our mEmbellishData member variable nsIFrame* firstChild = mFrames.FirstChild(); - while (firstChild) { - if (!IsOnlyWhitespace(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 , , or , 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: , , or 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 == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::accent_, value)) + if (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 , , or , 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: , , or 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 == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::accent_, value)) + { + accentAttribute = PR_TRUE; + if (value.EqualsWithConversion("true")) { - accentAttribute = PR_TRUE; - if (value.EqualsWithConversion("true")) - { - mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; - } + mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; } - - // see if the movablelimits attribute is there - if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::movablelimits_, value)) - { - movablelimitsAttribute = PR_TRUE; - if (value.EqualsWithConversion("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" - // XXX should we check if the form attribute is there? - nsAutoString aData; - mMathMLChar.GetData(aData); - 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); - } + + // see if the movablelimits attribute is there + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::movablelimits_, value)) + { + movablelimitsAttribute = PR_TRUE; + if (value.EqualsWithConversion("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" + // XXX should we check if the form attribute is there? + nsAutoString aData; + mMathMLChar.GetData(aData); + 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; + } + } + } return rv; } @@ -305,23 +300,23 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) // find our form nsAutoString value; - nsOperatorFlags aForm = NS_MATHML_OPERATOR_FORM_INFIX; + nsOperatorFlags form = NS_MATHML_OPERATOR_FORM_INFIX; - nsIMathMLFrame* aMathMLFrame = nsnull; + nsIMathMLFrame* mathMLFrame = nsnull; nsEmbellishData embellishData; if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::form_, value)) { if (value.EqualsWithConversion("prefix")) - aForm = NS_MATHML_OPERATOR_FORM_PREFIX; + form = NS_MATHML_OPERATOR_FORM_PREFIX; else if (value.EqualsWithConversion("postfix")) - aForm = NS_MATHML_OPERATOR_FORM_POSTFIX; + form = NS_MATHML_OPERATOR_FORM_POSTFIX; // see if we have an embellished ancestor, and check that we are really // the 'core' of the ancestor, not just a sibling of the core - rv = mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); if (embellishData.core == this) { // flag if we have an embellished ancestor mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR; @@ -331,13 +326,13 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) else { // Get our outermost embellished container and its parent nsIFrame* embellishAncestor; - nsIFrame* aParent = this; + nsIFrame* parent = this; do { - embellishAncestor = aParent; - embellishAncestor->GetParent(&aParent); - rv = aParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + embellishAncestor = parent; + embellishAncestor->GetParent(&parent); + rv = parent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); } else { embellishData.core = nsnull; @@ -351,47 +346,30 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) // Find the position of our outermost embellished container w.r.t // its siblings (frames are singly-linked together). - ////////////// - // 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*] [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; nsIFrame* prev = nsnull; nsIFrame* next = nsnull; - nsIFrame* aFrame; + nsIFrame* frame; - aParent->FirstChild(aPresContext, nsnull, &aFrame); - while (aFrame) { - if (aFrame == embellishAncestor) { // we start looking for next - state++; - } - else if (!IsOnlyWhitespace(aFrame)) { - if (0 == state) { // we are still looking for prev - prev = aFrame; - } - else if (1 == state) { // we got next - next = aFrame; - break; // we can exit the while loop - } - } - aFrame->GetNextSibling(&aFrame); + embellishAncestor->GetNextSibling(&next); + parent->FirstChild(aPresContext, nsnull, &frame); + while (frame) { + if (frame == embellishAncestor) break; + prev = frame; + frame->GetNextSibling(&frame); } // set our form flag depending on the position if (!prev && next) - aForm = NS_MATHML_OPERATOR_FORM_PREFIX; + form = NS_MATHML_OPERATOR_FORM_PREFIX; else if (prev && !next) - aForm = NS_MATHML_OPERATOR_FORM_POSTFIX; + form = NS_MATHML_OPERATOR_FORM_POSTFIX; } // Lookup the operator dictionary - nsAutoString aData; - mMathMLChar.GetData(aData); -//NS_ASSERTION(aData[0] != '+', "Breaking..."); - mMathMLChar.SetData(aPresContext, aData); // XXX hack to reset, bug 45010 - PRBool found = nsMathMLOperators::LookupOperator(aData, aForm, + nsAutoString data; + mMathMLChar.GetData(data); + mMathMLChar.SetData(aPresContext, data); // XXX hack to reset, bug 45010 + PRBool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &mLeftSpace, &mRightSpace); // If we don't want too much extra space when we are a script @@ -461,8 +439,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) if (ParseNumericValue(value, cssValue) || ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) { - if ((eCSSUnit_Number == cssValue.GetUnit()) && - (0.0f == cssValue.GetFloatValue())) + if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue()) mLeftSpace = 0.0f; else if (cssValue.IsLengthUnit()) mLeftSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em; @@ -479,8 +456,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) if (ParseNumericValue(value, cssValue) || ParseNamedSpaceValue(mPresentationData.mstyle, value, cssValue)) { - if ((eCSSUnit_Number == cssValue.GetUnit()) && - (0.0f == cssValue.GetFloatValue())) + if ((eCSSUnit_Number == cssValue.GetUnit()) && !cssValue.GetFloatValue()) mRightSpace = 0.0f; else if (cssValue.IsLengthUnit()) mRightSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em; @@ -565,8 +541,8 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext) // See if this is an operator that should be centered to cater for // fonts that are not math-aware - if (1 == aData.Length()) { - PRUnichar ch = aData[0]; + if (1 == data.Length()) { + PRUnichar ch = data[0]; if ((ch == '+') || (ch == '=') || (ch == '*') || (ch == 0x00D7)) { // × mFlags |= NS_MATHML_OPERATOR_CENTERED; @@ -585,7 +561,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredStretchSize) { if (NS_MATHML_STRETCH_WAS_DONE(mEmbellishData.flags)) { - printf("WARNING *** it is wrong to fire stretch more than once on a frame...\n"); + NS_WARNING("it is wrong to fire stretch more than once on a frame"); return NS_OK; } mEmbellishData.flags |= NS_MATHML_STRETCH_DONE; @@ -598,10 +574,9 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, nsCOMPtr fm; aRenderingContext.SetFont(font.mFont); aRenderingContext.GetFontMetrics(*getter_AddRefs(fm)); - nscoord fontAscent, fontDescent, axisHeight, height; + nscoord leading, axisHeight, height; GetAxisHeight(aRenderingContext, fm, axisHeight); - fm->GetMaxAscent(fontAscent); - fm->GetMaxDescent(fontDescent); + fm->GetLeading(leading); // Operators that exist in the dictionary, or those that are to be centered // to cater for fonts that are not math-aware, are handled by the MathMLChar @@ -758,21 +733,21 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, mBoundingMetrics.ascent = height - mBoundingMetrics.descent; } - // Prepare the metrics to return - aDesiredStretchSize.ascent = PR_MAX(fontAscent, mBoundingMetrics.ascent); /* + delta1*/ - aDesiredStretchSize.descent = PR_MAX(fontDescent, mBoundingMetrics.descent); /* + delta2*/ - aDesiredStretchSize.width = mBoundingMetrics.width; - aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent; - aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics; - - nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent; if ((mMathMLChar.GetStretchDirection() == NS_STRETCH_DIRECTION_UNSUPPORTED) && !NS_MATHML_OPERATOR_IS_CENTERED(mFlags)) { // reset - dy = aDesiredStretchSize.ascent - charSize.ascent; - aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics = charSize; + mBoundingMetrics = charSize; } + else { + // leave a leading at the top and the bottom of the stretched char + aDesiredStretchSize.ascent = mBoundingMetrics.ascent + leading; + aDesiredStretchSize.descent = mBoundingMetrics.descent + leading; + } + aDesiredStretchSize.height = aDesiredStretchSize.ascent + aDesiredStretchSize.descent; + aDesiredStretchSize.width = mBoundingMetrics.width; + aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics; + nscoord dy = aDesiredStretchSize.ascent - mBoundingMetrics.ascent; mMathMLChar.SetRect( nsRect(0, dy, charSize.width, charSize.ascent + charSize.descent)); @@ -804,7 +779,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext, mBoundingMetrics.width = aDesiredStretchSize.width; nscoord dx = nscoord(mLeftSpace * em); - if (0 == dx) return NS_OK; + if (!dx) return NS_OK; // adjust the offsets mBoundingMetrics.leftBearing += dx; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp index 061c68a37d3..3a8745a3c43 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmoverFrame.cpp @@ -120,16 +120,14 @@ XXX The winner is the outermost in conflicting settings like these: nsIFrame* overscriptFrame = nsnull; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - count++; - if (1 == count) baseFrame = childFrame; - if (2 == count) { overscriptFrame = childFrame; break; } - } + if (0 == count) baseFrame = childFrame; + if (1 == count) { overscriptFrame = childFrame; break; } + count++; childFrame->GetNextSibling(&childFrame); } nsIMathMLFrame* overscriptMathMLFrame = nsnull; - nsIMathMLFrame* aMathMLFrame = nsnull; + nsIMathMLFrame* mathMLFrame = nsnull; nsEmbellishData embellishData; nsAutoString value; @@ -148,9 +146,9 @@ XXX The winner is the outermost in conflicting settings like these: } } else { // no attribute, get the value from the core - rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) { mPresentationData.flags |= NS_MATHML_MOVABLELIMITS; } @@ -165,9 +163,9 @@ XXX The winner is the outermost in conflicting settings like these: overscriptMathMLFrame->GetEmbellishData(embellishData); // core of the overscriptFrame if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) { - rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->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, @@ -175,7 +173,7 @@ XXX The winner is the outermost in conflicting settings like these: { if (value.EqualsWithConversion("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; else if (value.EqualsWithConversion("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; - aMathMLFrame->SetEmbellishData(embellishData); + mathMLFrame->SetEmbellishData(embellishData); } // sync the presentation data: record whether we have an accent @@ -205,14 +203,11 @@ XXX The winner is the outermost in conflicting settings like these: overscriptMathMLFrame->UpdatePresentationData(increment, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); - overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, -1, increment, + overscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); } - // switch the style of the overscript - InsertScriptLevelStyleContext(aPresContext); - return rv; } @@ -264,26 +259,22 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if (0 == count) { - // base - baseFrame = childFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // over - overFrame = childFrame; - GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); - } - count++; - } + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); + } + else if (1 == count) { + // over + overFrame = childFrame; + GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); + } + count++; childFrame->GetNextSibling(&childFrame); } - if ((2 != count) || !baseFrame || !overFrame) { -#ifdef NS_DEBUG - printf("mover: invalid markup\n"); -#endif + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, aRenderingContext, aDesiredSize); } @@ -320,7 +311,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, delta2 = bigOpSpacing5; // XXX This is not a TeX rule... - // delta1 (as computed abvove) can become really big when bmOver.descent is + // delta1 (as computed above) can become really big when bmOver.descent is // negative, e.g., if the content is &OverBar. In such case, we use the height if (bmOver.descent < 0) delta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent))); @@ -364,19 +355,32 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, delta2 = ruleThickness; } // empty over? - if (0 == (bmOver.ascent + bmOver.descent)) delta1 = 0; + if (!(bmOver.ascent + bmOver.descent)) delta1 = 0; mBoundingMetrics.ascent = bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent; mBoundingMetrics.descent = bmBase.descent; + + nscoord dxBase, dxOver = 0; + nscoord dyBase, dyOver; + + // Ad-hoc - This is to override fonts which have ready-made _accent_ + // glyphs with negative lbearing and rbearing. We want to position + // the overscript ourselves + nscoord overWidth = bmOver.width; + if (!overWidth && (bmOver.rightBearing - bmOver.leftBearing > 0)) { + overWidth = bmOver.rightBearing - bmOver.leftBearing; + dxOver = -bmOver.leftBearing; + } + if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) { - mBoundingMetrics.width = PR_MAX(bmBase.width, bmOver.width); + mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth); } else { mBoundingMetrics.width = - PR_MAX(bmBase.width/2,(bmOver.width + correction/2)/2) + - PR_MAX(bmBase.width/2,(bmOver.width - correction/2)/2); + PR_MAX(bmBase.width/2,(overWidth + correction/2)/2) + + PR_MAX(bmBase.width/2,(overWidth - correction/2)/2); } aDesiredSize.descent = baseSize.descent; @@ -385,18 +389,15 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, overSize.ascent + bmOver.descent + delta1 + bmBase.ascent); aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.width = mBoundingMetrics.width; - - nscoord dxBase, dyBase; - nscoord dxOver, dyOver; dxBase = (mBoundingMetrics.width - bmBase.width) / 2; dyBase = aDesiredSize.ascent - baseSize.ascent; if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) { - dxOver = correction + (mBoundingMetrics.width - bmOver.width)/2; + dxOver += correction + (mBoundingMetrics.width - overWidth)/2; } else { - dxOver = correction/2 + (mBoundingMetrics.width - bmOver.width)/2; + dxOver += correction/2 + (mBoundingMetrics.width - overWidth)/2; } dyOver = aDesiredSize.ascent - @@ -419,34 +420,3 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext, } return NS_OK; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp index 13ee1aa9376..5c6718aa6a7 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp @@ -208,8 +208,7 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString, aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED; if (i == stringLength) { // no explicit pseudo-unit ... - if (eCSSUnit_Number == aCSSValue.GetUnit() && - 0.0f != aCSSValue.GetFloatValue()) { + if ((eCSSUnit_Number == aCSSValue.GetUnit()) && aCSSValue.GetFloatValue()) { // ... and no explicit CSS unit either // In this case, the MathML REC suggests taking ems for @@ -375,7 +374,7 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext, nscoord height = mBoundingMetrics.ascent; nscoord depth = mBoundingMetrics.descent; nscoord width = mBoundingMetrics.width; - nscoord lspace = 0; // it is unclear from the REC what is the default here + nscoord lspace = 0; // XXX it is unclear from the REC what is the default here PRInt32 pseudoUnit; @@ -409,7 +408,7 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext, // do the padding now that we have everything - if (lspace != 0) { // there was padding on the left + if (lspace) { // there was padding on the left mBoundingMetrics.leftBearing = 0; } @@ -430,7 +429,7 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent; aDesiredSize.mBoundingMetrics = mBoundingMetrics; - if (0 != dx || 0 != dy) { + if (dx || dy) { nsRect rect; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { diff --git a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp index 8a1e582cd1c..9ab27b686ca 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.cpp @@ -186,38 +186,31 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics baseSize(nsnull); nsHTMLReflowMetrics indexSize(nsnull); nsIFrame* childFrame = mFrames.FirstChild(); - while (childFrame) - { - if (!IsOnlyWhitespace(childFrame)) { - nsHTMLReflowState childReflowState(aPresContext, aReflowState, - childFrame, availSize); - rv = ReflowChild(childFrame, aPresContext, - childDesiredSize, childReflowState, childStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); - if (NS_FAILED(rv)) { - return rv; - } - if (0 == count) { - // base - baseFrame = childFrame; - baseSize = childDesiredSize; - bmBase = childDesiredSize.mBoundingMetrics; - } - else if (1 == count) { - // index - indexFrame = childFrame; - indexSize = childDesiredSize; - bmIndex = childDesiredSize.mBoundingMetrics; - } - count++; + while (childFrame) { + nsHTMLReflowState childReflowState(aPresContext, aReflowState, + childFrame, availSize); + rv = ReflowChild(childFrame, aPresContext, + childDesiredSize, childReflowState, childStatus); + //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + if (NS_FAILED(rv)) return rv; + if (0 == count) { + // base + baseFrame = childFrame; + baseSize = childDesiredSize; + bmBase = childDesiredSize.mBoundingMetrics; } + else if (1 == count) { + // index + indexFrame = childFrame; + indexSize = childDesiredSize; + bmIndex = childDesiredSize.mBoundingMetrics; + } + count++; childFrame->GetNextSibling(&childFrame); } - if ((2 != count) || !baseFrame || !indexFrame) { -#ifdef NS_DEBUG - printf("mroot: invalid markup\n"); -#endif + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, renderingContext, aDesiredSize); } @@ -232,6 +225,7 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext, nscoord ruleThickness, leading; GetRuleThickness(renderingContext, fm, ruleThickness); + fm->GetLeading(leading); // Rule 11, App. G, TeXbook // psi = clearance between rule and content @@ -267,9 +261,6 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext, if (ruleThickness < onePixel) { ruleThickness = onePixel; } - // get the leading to be left at the top of the resulting frame - float em = float(font.mFont.size); - leading = nscoord(0.2f * em); // adjust clearance psi to absorb any excess difference if any // in height between radical and content diff --git a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.h index 156475385ae..89571060922 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmrootFrame.h @@ -60,13 +60,11 @@ public: // The element increments scriptlevel by 2, and sets displaystyle to // "false", within index, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says \sqrt is compressed - UpdatePresentationDataFromChildAt(1, 1, 2, + UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 2, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); - UpdatePresentationDataFromChildAt(0, 0, 0, + UpdatePresentationDataFromChildAt(aPresContext, 0, 0, 0, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); - // switch the style of the index - InsertScriptLevelStyleContext(aPresContext); return rv; } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp index f4a2f9d1ea6..b8bc0b544d5 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.cpp @@ -173,10 +173,8 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics baseSize(aDesiredSize); rv = nsMathMLContainerFrame::Reflow(aPresContext, baseSize, aReflowState, aStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); - if (NS_FAILED(rv)) { - return rv; - } + //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); + if (NS_FAILED(rv)) return rv; bmBase = baseSize.mBoundingMetrics; @@ -192,7 +190,8 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext, nscoord ruleThickness, leading; GetRuleThickness(renderingContext, fm, ruleThickness); - + fm->GetLeading(leading); + // Rule 11, App. G, TeXbook // psi = clearance between rule and content nscoord phi = 0, psi = 0; @@ -229,9 +228,6 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext, if (ruleThickness < onePixel) { ruleThickness = onePixel; } - // get the leading to be left at the top of the resulting frame - float em = float(font.mFont.size); - leading = nscoord(0.2f * em); // adjust clearance psi to absorb any excess difference if any // in height between radical and content @@ -273,11 +269,9 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext, dx = radicalSize.width; dy = aDesiredSize.ascent - baseSize.ascent; nsIFrame* childFrame = mFrames.FirstChild(); - while (nsnull != childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - childFrame->GetOrigin(origin); - childFrame->MoveTo(aPresContext, origin.x + dx, origin.y + dy); - } + while (childFrame) { + childFrame->GetOrigin(origin); + childFrame->MoveTo(aPresContext, origin.x + dx, origin.y + dy); childFrame->GetNextSibling(&childFrame); } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.h index a48b4e9f42f..37f2d23b95e 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmsqrtFrame.h @@ -96,7 +96,7 @@ public: // The element leaves both attributes [displaystyle and scriptlevel] // unchanged within all its arguments. // 2. The TeXBook (Ch 17. p.141) says that \sqrt is cramped - UpdatePresentationDataFromChildAt(0, -1, 0, + UpdatePresentationDataFromChildAt(aPresContext, 0, -1, 0, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); return rv; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp index fe80629ddf6..4015d3f1ee3 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.cpp @@ -80,8 +80,6 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext, mPresentationData.mstyle = this; - mInnerScriptLevelIncrement = 0; - // see if the displaystyle attribute is there nsAutoString value; if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, @@ -99,16 +97,15 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext, // see if the scriptlevel attribute is there if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None, nsMathMLAtoms::scriptlevel_, value)) { - PRInt32 aErrorCode, aUserValue; - aUserValue = value.ToInteger(&aErrorCode); - if (NS_SUCCEEDED(aErrorCode)) { + PRInt32 errorCode, userValue; + userValue = value.ToInteger(&errorCode); + if (!errorCode) { if (value[0] != '+' && value[0] != '-') { // record that it is an explicit value mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL; - mPresentationData.scriptLevel = aUserValue; + mPresentationData.scriptLevel = userValue; } else { -// mScriptLevel += aUserValue; // incremental value... - mInnerScriptLevelIncrement = aUserValue; + mPresentationData.scriptLevel += userValue; // incremental value... } } } @@ -160,11 +157,12 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, } NS_IMETHODIMP -nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) +nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) { // mstyle is special... // Since UpdatePresentationDataFromChildAt() can be called by a parent frame, @@ -199,6 +197,6 @@ nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, // let the base class worry about the update return nsMathMLContainerFrame::UpdatePresentationDataFromChildAt( - aFirstIndex, aLastIndex, aScriptLevelIncrement, + aPresContext, aFirstIndex, aLastIndex, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h index 0f77787bc5d..b3fed12862a 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmstyleFrame.h @@ -47,11 +47,12 @@ public: PRUint32 aFlagsToUpdate); NS_IMETHOD - UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate); + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, @@ -60,11 +61,10 @@ public: { nsresult rv; rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList); - // This call is peculiar to and will quickly return if nothing to update - UpdatePresentationDataFromChildAt(0, -1, mInnerScriptLevelIncrement, + // This call is peculiar to and will quickly return if there is nothing to update + UpdatePresentationDataFromChildAt(aPresContext, 0, -1, 0, NS_MATHML_DISPLAYSTYLE & mPresentationData.flags, NS_MATHML_DISPLAYSTYLE); - InsertScriptLevelStyleContext(aPresContext); return rv; } @@ -73,8 +73,6 @@ protected: virtual ~nsMathMLmstyleFrame(); virtual PRIntn GetSkipSides() const { return 0; } - - PRInt32 mInnerScriptLevelIncrement; }; #endif /* nsMathMLmstyleFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp index 13284d38d37..c94dc2a93b0 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.cpp @@ -77,19 +77,6 @@ nsMathMLmsubFrame::Init(nsIPresContext* aPresContext, nsresult rv = nsMathMLContainerFrame::Init (aPresContext, aContent, aParent, aContext, aPrevInFlow); - mSubScriptShift = 0; - mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX - - // check if the subscriptshift attribute is there - nsAutoString value; - if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::subscriptshift_, value)) { - nsCSSValue cssValue; - if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { - mSubScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); - } - } - #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS; #endif @@ -102,13 +89,27 @@ nsMathMLmsubFrame::Place (nsIPresContext* aPresContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { + // extra spacing between base and sup/subscript + nscoord scriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX + + // check if the subscriptshift attribute is there + nscoord subScriptShift = 0; + nsAutoString value; + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::subscriptshift_, value)) { + nsCSSValue cssValue; + if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { + subScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); + } + } + return nsMathMLmsubFrame::PlaceSubScript(aPresContext, aRenderingContext, aPlaceOrigin, aDesiredSize, this, - mSubScriptShift, - mScriptSpace); + subScriptShift, + scriptSpace); } // exported routine that both munder and msub share. @@ -148,38 +149,30 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext, nsBoundingMetrics bmBase, bmSubScript; - nsIFrame* aChildFrame = nsnull; - rv = aFrame->FirstChild (aPresContext, nsnull, &aChildFrame); - if (!NS_SUCCEEDED(rv) || (nsnull == aChildFrame)) { - return rv; - } - while (nsnull != aChildFrame) - { - if (!IsOnlyWhitespace(aChildFrame)) { - if (0 == count) { - // base - baseFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // subscript - subScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); - // get the subdrop from the subscript font - nscoord aSubDrop; - GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop); - // parameter v, Rule 18a, App. G, TeXbook - minSubScriptShift = bmBase.descent + aSubDrop; - } - count++; + nsIFrame* childFrame = nsnull; + aFrame->FirstChild(aPresContext, nsnull, &childFrame); + while (childFrame) { + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); } - aChildFrame->GetNextSibling(&aChildFrame); + else if (1 == count) { + // subscript + subScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); + // get the subdrop from the subscript font + nscoord subDrop; + GetSubDropFromChild (aPresContext, subScriptFrame, subDrop); + // parameter v, Rule 18a, App. G, TeXbook + minSubScriptShift = bmBase.descent + subDrop; + } + count++; + childFrame->GetNextSibling(&childFrame); } -#ifdef NS_DEBUG - if (2 != count) printf("msub: invalid markup\n"); -#endif - if ((2 != count) || !baseFrame || !subScriptFrame) { + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->ReflowError(aPresContext, aRenderingContext, @@ -197,29 +190,29 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext, // const nsStyleFont* aFont = // (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font); - const nsStyleFont* aFont; - baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)aFont); + const nsStyleFont* font; + baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font); - aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm)); + aPresContext->GetMetricsFor (font->mFont, getter_AddRefs(fm)); fm->GetXHeight (xHeight); nscoord minShiftFromXHeight = (nscoord) (bmSubScript.ascent - (4.0f/5.0f) * xHeight); - // aSubScriptShift + // subScriptShift // = minimum amount to shift the subscript down set by user or from the font // = sub1 in TeX // = subscriptshift attribute * x-height - nscoord aSubScriptShift, dummy; - // get aSubScriptShift default from font - GetSubScriptShifts (fm, aSubScriptShift, dummy); + nscoord subScriptShift, dummy; + // get subScriptShift default from font + GetSubScriptShifts (fm, subScriptShift, dummy); - aSubScriptShift = - PR_MAX(aSubScriptShift, aUserSubScriptShift); + subScriptShift = + PR_MAX(subScriptShift, aUserSubScriptShift); // get actual subscriptshift to be used // Rule 18b, App. G, TeXbook nscoord actualSubScriptShift = - PR_MAX(minSubScriptShift,PR_MAX(aSubScriptShift,minShiftFromXHeight)); + PR_MAX(minSubScriptShift,PR_MAX(subScriptShift,minShiftFromXHeight)); // get bounding box for base + subscript nsBoundingMetrics boundingMetrics; boundingMetrics.ascent = diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.h index 59963cf238b..bfda5095e23 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubFrame.h @@ -68,11 +68,9 @@ public: // The element increments scriptlevel by 1, and sets displaystyle to // "false", within subscript, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the subscript is compressed - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); - // switch the style of the subscript - InsertScriptLevelStyleContext(aPresContext); // check whether or not this is an embellished operator EmbellishOperator(); return rv; @@ -83,11 +81,6 @@ public: virtual ~nsMathMLmsubFrame(); 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; }; #endif /* nsMathMLmsubFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp index 3bb32519f36..1c3302e25f8 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.cpp @@ -77,28 +77,6 @@ nsMathMLmsubsupFrame::Init(nsIPresContext* aPresContext, nsresult rv = nsMathMLContainerFrame::Init (aPresContext, aContent, aParent, aContext, aPrevInFlow); - mSubScriptShift = 0; - mSupScriptShift = 0; - mScriptSpace = 0; - - // check if the subscriptshift attribute is there - nsAutoString value; - if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::subscriptshift_, value)) { - nsCSSValue cssValue; - if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { - mSubScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); - } - } - // check if the superscriptshift attribute is there - if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::superscriptshift_, value)) { - nsCSSValue cssValue; - if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { - mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); - } - } - #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS; #endif @@ -112,13 +90,37 @@ nsMathMLmsubsupFrame::Place (nsIPresContext* aPresContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { + // extra spacing between base and sup/subscript + nscoord scriptSpace = 0; + + // check if the subscriptshift attribute is there + nsAutoString value; + nscoord subScriptShift = 0; + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::subscriptshift_, value)) { + nsCSSValue cssValue; + if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { + subScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); + } + } + // check if the superscriptshift attribute is there + nscoord supScriptShift = 0; + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::superscriptshift_, value)) { + nsCSSValue cssValue; + if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { + supScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); + } + } + return nsMathMLmsubsupFrame::PlaceSubSupScript (aPresContext, aRenderingContext, aPlaceOrigin, aDesiredSize, this, - mSubScriptShift, - mScriptSpace); + subScriptShift, + supScriptShift, + scriptSpace); } // exported routine that both munderover and msubsup share. @@ -163,47 +165,40 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, nsBoundingMetrics bmBase, bmSubScript, bmSupScript; - nsIFrame* aChildFrame = nsnull; - rv = aFrame->FirstChild (aPresContext, nsnull, &aChildFrame); - if (!NS_SUCCEEDED(rv) || (nsnull == aChildFrame)) { - return rv; - } - while (nsnull != aChildFrame) { - if (!IsOnlyWhitespace(aChildFrame)) { - if (0 == count) { - // base - baseFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // subscript - subScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); - // get the subdrop from the subscript font - nscoord aSubDrop; - GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop); - // parameter v, Rule 18a, App. G, TeXbook - minSubScriptShift = bmBase.descent + aSubDrop; - } - else if (2 == count) { - // superscript - supScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); - // get the supdrop from the supscript font - nscoord aSupDrop; - GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop); - // parameter u, Rule 18a, App. G, TeXbook - minSupScriptShift = bmBase.ascent - aSupDrop; - } - count++; + nsIFrame* childFrame = nsnull; + aFrame->FirstChild (aPresContext, nsnull, &childFrame); + while (childFrame) { + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); } - aChildFrame->GetNextSibling(&aChildFrame); + else if (1 == count) { + // subscript + subScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript); + // get the subdrop from the subscript font + nscoord aSubDrop; + GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop); + // parameter v, Rule 18a, App. G, TeXbook + minSubScriptShift = bmBase.descent + aSubDrop; + } + else if (2 == count) { + // superscript + supScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); + // get the supdrop from the supscript font + nscoord aSupDrop; + GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop); + // parameter u, Rule 18a, App. G, TeXbook + minSupScriptShift = bmBase.ascent - aSupDrop; + } + count++; + childFrame->GetNextSibling(&childFrame); } -#ifdef NS_DEBUG - if (3 != count) printf("msubsup: invalid markup\n"); -#endif - if ((3 != count) || !baseFrame || !subScriptFrame || !supScriptFrame) { + if (3 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->ReflowError(aPresContext, aRenderingContext, @@ -219,11 +214,11 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, // slightly different from nsMathMLmsubFrame.cpp ////////////////////////////////////////////////// - // aSubScriptShift{1,2} + // subScriptShift{1,2} // = minimum amount to shift the subscript down // = sub{1,2} in TeXbook - // aSubScriptShift1 = subscriptshift attribute * x-height - nscoord aSubScriptShift1, aSubScriptShift2; + // subScriptShift1 = subscriptshift attribute * x-height + nscoord subScriptShift1, subScriptShift2; // const nsStyleFont* aFont = // (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font); @@ -238,23 +233,23 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, nscoord xHeight; fm->GetXHeight (xHeight); - nscoord aRuleSize; - GetRuleThickness (aRenderingContext, fm, aRuleSize); + nscoord ruleSize; + GetRuleThickness (aRenderingContext, fm, ruleSize); - // Get aSubScriptShift{1,2} default from font - GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2); + // Get subScriptShift{1,2} default from font + GetSubScriptShifts (fm, subScriptShift1, subScriptShift2); if (0 < aUserSubScriptShift) { // the user has set the subscriptshift attribute - float aFactor = ((float) aSubScriptShift2) / aSubScriptShift1; - aSubScriptShift1 = PR_MAX(aSubScriptShift1, aUserSubScriptShift); - aSubScriptShift2 = NSToCoordRound(aFactor * aSubScriptShift1); + float scaler = ((float) subScriptShift2) / subScriptShift1; + subScriptShift1 = PR_MAX(subScriptShift1, aUserSubScriptShift); + subScriptShift2 = NSToCoordRound(scaler * subScriptShift1); } // get a tentative value for subscriptshift // Rule 18d, App. G, TeXbook - nscoord aSubScriptShift = - PR_MAX(minSubScriptShift,PR_MAX(aSubScriptShift1,aSubScriptShift2)); + nscoord subScriptShift = + PR_MAX(minSubScriptShift,PR_MAX(subScriptShift1,subScriptShift2)); ////////////////////////////////////////////////// // Get supscript shift @@ -266,70 +261,70 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, nscoord minShiftFromXHeight = (nscoord) (bmSupScript.descent + (1.0f/4.0f) * xHeight); - // aSupScriptShift{1,2,3} + // supScriptShift{1,2,3} // = minimum amount to shift the supscript up // = sup{1,2,3} in TeX - // aSupScriptShift1 = superscriptshift attribute * x-height + // supScriptShift1 = superscriptshift attribute * x-height // Note that there are THREE values for supscript shifts depending // on the current style - nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3; - // Set aSupScriptShift{1,2,3} default from font - GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3); + nscoord supScriptShift1, supScriptShift2, supScriptShift3; + // Set supScriptShift{1,2,3} default from font + GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3); if (0 < aUserSupScriptShift) { // the user has set the superscriptshift attribute - float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1; - float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1; - aSupScriptShift1 = PR_MAX(aSupScriptShift1, aUserSupScriptShift); - aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1); - aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1); + float scaler2 = ((float) supScriptShift2) / supScriptShift1; + float scaler3 = ((float) supScriptShift3) / supScriptShift1; + supScriptShift1 = PR_MAX(supScriptShift1, aUserSupScriptShift); + supScriptShift2 = NSToCoordRound(scaler2 * supScriptShift1); + supScriptShift3 = NSToCoordRound(scaler3 * supScriptShift1); } // get sup script shift depending on current script level and display style // Rule 18c, App. G, TeXbook - nscoord aSupScriptShift; + nscoord supScriptShift; nsPresentationData presentationData; mathMLFrame->GetPresentationData(presentationData); if ( presentationData.scriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) && !NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style D in TeXbook - aSupScriptShift = aSupScriptShift1; + supScriptShift = supScriptShift1; } else if (NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style C' in TeXbook = D',T',S',SS' - aSupScriptShift = aSupScriptShift3; + supScriptShift = supScriptShift3; } else { // everything else = T,S,SS - aSupScriptShift = aSupScriptShift2; + supScriptShift = supScriptShift2; } // get tentative value for superscriptshift // Rule 18c, App. G, TeXbook - aSupScriptShift = - PR_MAX(minSupScriptShift,PR_MAX(aSupScriptShift,minShiftFromXHeight)); + supScriptShift = + PR_MAX(minSupScriptShift,PR_MAX(supScriptShift,minShiftFromXHeight)); ////////////////////////////////////////////////// - // Negotiate between aSupScriptShift and aSubScriptShift + // Negotiate between supScriptShift and subScriptShift // so that there will be enough gap between them // Rule 18e, App. G, TeXbook ////////////////////////////////////////////////// nscoord gap = - (aSupScriptShift - bmSupScript.descent) - - (bmSubScript.ascent - aSubScriptShift); - if (gap < 4.0f * aRuleSize) { - // adjust aSubScriptShift to get a gap of (4.0 * aRuleSize) - aSubScriptShift += NSToCoordRound ((4.0f * aRuleSize) - gap); + (supScriptShift - bmSupScript.descent) - + (bmSubScript.ascent - subScriptShift); + if (gap < 4.0f * ruleSize) { + // adjust subScriptShift to get a gap of (4.0 * ruleSize) + subScriptShift += NSToCoordRound ((4.0f * ruleSize) - gap); } // next we want to ensure that the bottom of the superscript // will be > (4/5) * x-height above baseline gap = NSToCoordRound ((4.0f/5.0f) * xHeight - - (aSupScriptShift - bmSupScript.descent)); - if (gap > 0.0f) { - aSupScriptShift += gap; - aSubScriptShift -= gap; + (supScriptShift - bmSupScript.descent)); + if (gap > 0) { + supScriptShift += gap; + subScriptShift -= gap; } ////////////////////////////////////////////////// @@ -339,9 +334,9 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, // get bounding box for base + subscript + superscript nsBoundingMetrics boundingMetrics; boundingMetrics.ascent = - PR_MAX(bmBase.ascent, (bmSupScript.ascent + aSupScriptShift)); + PR_MAX(bmBase.ascent, (bmSupScript.ascent + supScriptShift)); boundingMetrics.descent = - PR_MAX(bmBase.descent, (bmSubScript.descent + aSubScriptShift)); + PR_MAX(bmBase.descent, (bmSubScript.descent + subScriptShift)); // add aScriptSpace to both super/subscript // add italicCorrection only to superscript @@ -357,12 +352,12 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, // reflow metrics aDesiredSize.ascent = PR_MAX(baseSize.ascent, - PR_MAX(subScriptSize.ascent - aSubScriptShift, - supScriptSize.ascent + aSupScriptShift)); + PR_MAX(subScriptSize.ascent - subScriptShift, + supScriptSize.ascent + supScriptShift)); aDesiredSize.descent = PR_MAX(baseSize.descent, - PR_MAX(subScriptSize.descent + aSubScriptShift, - supScriptSize.descent - aSupScriptShift)); + 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); @@ -377,11 +372,11 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext, FinishReflowChild(baseFrame, aPresContext, baseSize, dx, dy, 0); // ... and subscript dx = bmBase.width + aScriptSpace; - dy = aDesiredSize.ascent - (subScriptSize.ascent - aSubScriptShift); + dy = aDesiredSize.ascent - (subScriptSize.ascent - subScriptShift); FinishReflowChild(subScriptFrame, aPresContext, subScriptSize, dx, dy, 0); // ... and the superscript dx = bmBase.width + aScriptSpace + italicCorrection; - dy = aDesiredSize.ascent - (supScriptSize.ascent + aSupScriptShift); + dy = aDesiredSize.ascent - (supScriptSize.ascent + supScriptShift); FinishReflowChild(supScriptFrame, aPresContext, supScriptSize, dx, dy, 0); } diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.h index 03ffa8eef38..cbbe1f10295 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmsubsupFrame.h @@ -71,14 +71,12 @@ public: // unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the superscript inherits the compression // while the subscript is compressed - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - UpdatePresentationDataFromChildAt(1, 1, 0, + UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 0, NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED); - // switch the style of the subscript and superscript - InsertScriptLevelStyleContext(aPresContext); // check whether or not this is an embellished operator EmbellishOperator(); return rv; @@ -89,12 +87,6 @@ protected: virtual ~nsMathMLmsubsupFrame(); 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; }; #endif /* nsMathMLmsubsupFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp index f664f8a1fbf..d3d271262a0 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.cpp @@ -76,19 +76,6 @@ nsMathMLmsupFrame::Init(nsIPresContext* aPresContext, nsresult rv = nsMathMLContainerFrame::Init (aPresContext, aContent, aParent, aContext, aPrevInFlow); - mSupScriptShift = 0; - mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX - - // check if the superscriptshift attribute is there - nsAutoString value; - if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, - nsMathMLAtoms::superscriptshift_, value)) { - nsCSSValue cssValue; - if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { - mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); - } - } - #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX) mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS; #endif @@ -101,13 +88,27 @@ nsMathMLmsupFrame::Place (nsIPresContext* aPresContext, PRBool aPlaceOrigin, nsHTMLReflowMetrics& aDesiredSize) { + // extra spacing between base and sup/subscript + nscoord scriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX + + // check if the superscriptshift attribute is there + nsAutoString value; + nscoord supScriptShift = 0; + if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle, + nsMathMLAtoms::superscriptshift_, value)) { + nsCSSValue cssValue; + if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) { + supScriptShift = CalcLength(aPresContext, mStyleContext, cssValue); + } + } + return nsMathMLmsupFrame::PlaceSuperScript (aPresContext, aRenderingContext, aPlaceOrigin, aDesiredSize, this, - mSupScriptShift, - mScriptSpace); + supScriptShift, + scriptSpace); } // exported routine that both mover and msup share. @@ -148,34 +149,30 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext, nsBoundingMetrics bmBase, bmSupScript; - nsIFrame* aChildFrame = nsnull; - aFrame->FirstChild(aPresContext, nsnull, &aChildFrame); - while (nsnull != aChildFrame) { - if (!IsOnlyWhitespace(aChildFrame)) { - if (0 == count) { - // base - baseFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // superscript - supScriptFrame = aChildFrame; - GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); - // get the supdrop from the supscript font - nscoord aSupDrop; - GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop); - // parameter u, Rule 18a, App. G, TeXbook - minSupScriptShift = bmBase.ascent - aSupDrop; - } - count++; + nsIFrame* childFrame = nsnull; + aFrame->FirstChild(aPresContext, nsnull, &childFrame); + while (childFrame) { + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); } - aChildFrame->GetNextSibling(&aChildFrame); + else if (1 == count) { + // superscript + supScriptFrame = childFrame; + GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript); + // get the supdrop from the supscript font + nscoord supDrop; + GetSupDropFromChild (aPresContext, supScriptFrame, supDrop); + // parameter u, Rule 18a, App. G, TeXbook + minSupScriptShift = bmBase.ascent - supDrop; + } + count++; + childFrame->GetNextSibling(&childFrame); } -#ifdef NS_DEBUG - if (2 != count) printf("msup: invalid markup\n"); -#endif - if ((2 != count) || !baseFrame || !supScriptFrame) { + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return NS_STATIC_CAST(nsMathMLContainerFrame*, aFrame)->ReflowError(aPresContext, aRenderingContext, @@ -193,60 +190,60 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext, // const nsStyleFont* aFont = // (const nsStyleFont*) aStyleContext->GetStyleData (eStyleStruct_Font); - const nsStyleFont *aFont; - baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)aFont); + const nsStyleFont *font; + baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font); - aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm)); + aPresContext->GetMetricsFor (font->mFont, getter_AddRefs(fm)); fm->GetXHeight (xHeight); nscoord minShiftFromXHeight = (nscoord) (bmSupScript.descent + (1.0f/4.0f) * xHeight); nscoord italicCorrection; GetItalicCorrection(bmBase, italicCorrection); - // aSupScriptShift{1,2,3} + // supScriptShift{1,2,3} // = minimum amount to shift the supscript up // = sup{1,2,3} in TeX - // aSupScriptShift1 = superscriptshift attribute * x-height + // supScriptShift1 = superscriptshift attribute * x-height // Note that there are THREE values for supscript shifts depending // on the current style - nscoord aSupScriptShift1, aSupScriptShift2, aSupScriptShift3; - // Set aSupScriptShift{1,2,3} default from font - GetSupScriptShifts (fm, aSupScriptShift1, aSupScriptShift2, aSupScriptShift3); + nscoord supScriptShift1, supScriptShift2, supScriptShift3; + // Set supScriptShift{1,2,3} default from font + GetSupScriptShifts (fm, supScriptShift1, supScriptShift2, supScriptShift3); if (0 < aUserSupScriptShift) { // the user has set the superscriptshift attribute - float aFactor2 = ((float) aSupScriptShift2) / aSupScriptShift1; - float aFactor3 = ((float) aSupScriptShift3) / aSupScriptShift1; - aSupScriptShift1 = - PR_MAX(aSupScriptShift1, aUserSupScriptShift); - aSupScriptShift2 = NSToCoordRound(aFactor2 * aSupScriptShift1); - aSupScriptShift3 = NSToCoordRound(aFactor3 * aSupScriptShift1); + float scaler2 = ((float) supScriptShift2) / supScriptShift1; + float scaler3 = ((float) supScriptShift3) / supScriptShift1; + supScriptShift1 = + PR_MAX(supScriptShift1, aUserSupScriptShift); + supScriptShift2 = NSToCoordRound(scaler2 * supScriptShift1); + supScriptShift3 = NSToCoordRound(scaler3 * supScriptShift1); } // get sup script shift depending on current script level and display style // Rule 18c, App. G, TeXbook - nscoord aSupScriptShift; + nscoord supScriptShift; nsPresentationData presentationData; mathMLFrame->GetPresentationData (presentationData); if ( presentationData.scriptLevel == 0 && NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) && !NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style D in TeXbook - aSupScriptShift = aSupScriptShift1; + supScriptShift = supScriptShift1; } else if (NS_MATHML_IS_COMPRESSED(presentationData.flags)) { // Style C' in TeXbook = D',T',S',SS' - aSupScriptShift = aSupScriptShift3; + supScriptShift = supScriptShift3; } else { // everything else = T,S,SS - aSupScriptShift = aSupScriptShift2; + supScriptShift = supScriptShift2; } // get actual supscriptshift to be used // Rule 18c, App. G, TeXbook nscoord actualSupScriptShift = - PR_MAX(minSupScriptShift,PR_MAX(aSupScriptShift,minShiftFromXHeight)); + PR_MAX(minSupScriptShift,PR_MAX(supScriptShift,minShiftFromXHeight)); // bounding box nsBoundingMetrics boundingMetrics; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.h index 6815897add5..f8446a61523 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmsupFrame.h @@ -69,11 +69,9 @@ public: // "false", within superscript, but leaves both attributes unchanged within base. // 2. The TeXbook (Ch 17. p.141) says the superscript *inherits* the compression, // so we don't set the compression flag. Our parent will propagate its own. - UpdatePresentationDataFromChildAt(1, -1, 1, + UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); - // switch the style of the superscript - InsertScriptLevelStyleContext(aPresContext); // check whether or not this is an embellished operator EmbellishOperator(); return rv; @@ -84,11 +82,6 @@ protected: virtual ~nsMathMLmsupFrame(); virtual PRIntn GetSkipSides() const { return 0; } - -private: - nscoord mScriptSpace; // scriptspace from TeX for extra spacing after sup/subscript - // = 0.5pt in plain TeX - nscoord mSupScriptShift; }; #endif /* nsMathMLmsupFrame_h___ */ diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp index 3f68e652a49..b861041ab93 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.cpp @@ -257,6 +257,10 @@ MapAlignAttributesInto(nsIPresContext* aPresContext, // -------- // implementation of nsMathMLmtableOuterFrame +NS_IMPL_ADDREF_INHERITED(nsMathMLmtableOuterFrame, nsMathMLFrame) +NS_IMPL_RELEASE_INHERITED(nsMathMLmtableOuterFrame, nsMathMLFrame) +NS_IMPL_QUERY_INTERFACE_INHERITED1(nsMathMLmtableOuterFrame, nsTableOuterFrame, nsMathMLFrame) + nsresult NS_NewMathMLmtableOuterFrame (nsIPresShell* aPresShell, nsIFrame** aNewFrame) { @@ -282,22 +286,6 @@ nsMathMLmtableOuterFrame::~nsMathMLmtableOuterFrame() { } -NS_INTERFACE_MAP_BEGIN(nsMathMLmtableOuterFrame) - NS_INTERFACE_MAP_ENTRY(nsIMathMLFrame) -NS_INTERFACE_MAP_END_INHERITING(nsTableOuterFrame) - -NS_IMETHODIMP_(nsrefcnt) -nsMathMLmtableOuterFrame::AddRef(void) -{ - return NS_OK; -} - -NS_IMETHODIMP_(nsrefcnt) -nsMathMLmtableOuterFrame::Release(void) -{ - return NS_OK; -} - NS_IMETHODIMP nsMathMLmtableOuterFrame::Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -307,15 +295,142 @@ nsMathMLmtableOuterFrame::Init(nsIPresContext* aPresContext, { nsresult rv = nsTableOuterFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + // now, if our parent implements the nsIMathMLFrame interface, we inherit + // its scriptlevel and displaystyle. If the parent later wishes to increment + // with other values, it will do so in its SetInitialChildList() method. + + // XXX the REC says that by default, displaystyle=false in + + nsIMathMLFrame* mathMLFrame = nsnull; + nsresult res = aParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + nsPresentationData parentData; + mathMLFrame->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; + } + else { + // see if our parent has 'display: block' + // XXX should we restrict this to the top level parent ? + const nsStyleDisplay* display; + aParent->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); + if (display->mDisplay == NS_STYLE_DISPLAY_BLOCK) { + mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; + } + } + + // see if the displaystyle attribute is there and let it override what we inherited + nsAutoString value; + if (NS_CONTENT_ATTR_HAS_VALUE == + nsMathMLContainerFrame::GetAttribute(mContent, nsnull, + nsMathMLAtoms::displaystyle_, value)) { + if (value.EqualsWithConversion("true")) { + mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; + } + else if (value.EqualsWithConversion("false")) { + mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE; + } + } + return rv; } +// helper to let the update of presentation data pass through +// a subtree that may contain non-math container frames +void +UpdatePresentationDataFor(nsIPresContext* aPresContext, + nsIFrame* aFrame, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + nsIMathMLFrame* mathMLFrame = nsnull; + nsresult rv = aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + // update + mathMLFrame->UpdatePresentationData( + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + } + // propagate down the subtrees + nsIFrame* childFrame; + aFrame->FirstChild(aPresContext, nsnull, &childFrame); + while (childFrame) { + UpdatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + childFrame->GetNextSibling(&childFrame); + } +} + +// helper to let the scriptstyle re-resolution pass through +// a subtree that may contain non-math container frames +void +ReResolveScriptStyleFor(nsIPresContext* aPresContext, + nsIFrame* aFrame, + PRInt32 aScriptLevel) +{ + nsIFrame* childFrame = nsnull; + nsCOMPtr styleContext; + aFrame->GetStyleContext(getter_AddRefs(styleContext)); + aFrame->FirstChild(aPresContext, nsnull, &childFrame); + while (childFrame) { + nsIMathMLFrame* mathMLFrame; + nsresult res = childFrame->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + mathMLFrame->ReResolveScriptStyle(aPresContext, styleContext, aScriptLevel); + } + else { + ReResolveScriptStyleFor(aPresContext, childFrame, aScriptLevel); + } + childFrame->GetNextSibling(&childFrame); + } +} + +NS_IMETHODIMP +nsMathMLmtableOuterFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + PRInt32 index = 0; + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + if ((index >= aFirstIndex) && + ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { + UpdatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + } + index++; + childFrame->GetNextSibling(&childFrame); + } + return NS_OK; +} + +NS_IMETHODIMP +nsMathMLmtableOuterFrame::ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel) +{ + // pass aParentScriptLevel -- it is as if we were not there... + ReResolveScriptStyleFor(aPresContext, this, aParentScriptLevel); + return NS_OK; +} + + NS_IMETHODIMP nsMathMLmtableOuterFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { +//NS_ASSERTION(eReflowReason_Incremental != aReflowState.reason, "Break"); // we want to return a table that is centered according to the align attribute nsresult rv = nsTableOuterFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); @@ -375,11 +490,16 @@ nsMathMLmtableOuterFrame::Reflow(nsIPresContext* aPresContext, // XXX Temporary hack! We are going to reflow again because // the table frame code is skipping the Pass 2 reflow when, // at the Pass 1 reflow, the available size is unconstrained. - // Skipping the Pass2 messes the alignments... + // Skipping the Pass2 messes the MathML alignments... + nsFrameState state; + nsIFrame* innerTableFrame = mFrames.FirstChild(); + innerTableFrame->GetFrameState(&state); + innerTableFrame->SetFrameState(state | NS_FRAME_IS_DIRTY); + mState |= NS_FRAME_HAS_DIRTY_CHILDREN; nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); -// ReflowDirtyChild(presShell, mFrames.FirstChild()); - mParent->ReflowDirtyChild(presShell, this); + nsFrame::CreateAndPostReflowCommand(presShell, this, + nsIReflowCommand::ReflowDirty, nsnull, nsnull, nsnull); } return rv; @@ -389,6 +509,10 @@ nsMathMLmtableOuterFrame::Reflow(nsIPresContext* aPresContext, // -------- // implementation of nsMathMLmtdFrame +NS_IMPL_ADDREF_INHERITED(nsMathMLmtdFrame, nsMathMLFrame) +NS_IMPL_RELEASE_INHERITED(nsMathMLmtdFrame, nsMathMLFrame) +NS_IMPL_QUERY_INTERFACE_INHERITED1(nsMathMLmtdFrame, nsBlockFrame, nsMathMLFrame) + nsresult NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { @@ -412,6 +536,54 @@ nsMathMLmtdFrame::~nsMathMLmtdFrame() { } +NS_IMETHODIMP +nsMathMLmtdFrame::Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + nsresult rv; + rv = nsBlockFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + + // record that children that are ignorable whitespace should be excluded + mState |= NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE; + + // now, get our outermost parent that implements the nsIMathMLFrame interface, + // we will inherit its scriptlevel and displaystyle. If that parent later wishes + // to increment with other values, it will do so in its SetInitialChildList() method. + nsIFrame* parent = aParent; + while (parent) { + nsIMathMLFrame* mathMLFrame = nsnull; + nsresult res = parent->QueryInterface( + NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(res) && mathMLFrame) { + nsPresentationData parentData; + mathMLFrame->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; + break; + } + parent->GetParent(&parent); + } + + return rv; +} + +NS_IMETHODIMP +nsMathMLmtdFrame::ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel) +{ + // pass aParentScriptLevel -- it is as if we were not there... + ReResolveScriptStyleFor(aPresContext, this, aParentScriptLevel); + return NS_OK; +} + NS_IMETHODIMP nsMathMLmtdFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h index b36819f7cfa..9d349057099 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h +++ b/mozilla/layout/mathml/base/src/nsMathMLmtableFrame.h @@ -30,113 +30,27 @@ // class nsMathMLmtableOuterFrame : public nsTableOuterFrame, - public nsIMathMLFrame + public nsMathMLFrame { public: friend nsresult NS_NewMathMLmtableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS_INHERITED - // nsIMathMLFrame methods -- see documentation in nsIMathMLFrame.h + // Overloaded nsIMathMLFrame methods NS_IMETHOD - GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) - { - aBoundingMetrics = mBoundingMetrics; - return NS_OK; - } + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); NS_IMETHOD - SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) - { - mBoundingMetrics = aBoundingMetrics; - return NS_OK; - } - - NS_IMETHOD - GetReference(nsPoint& aReference) - { - aReference = mReference; - return NS_OK; - } - - NS_IMETHOD - SetReference(const nsPoint& aReference) - { - mReference = aReference; - return NS_OK; - } - - NS_IMETHOD - Stretch(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - nsStretchDirection aStretchDirection, - nsBoundingMetrics& aContainerSize, - nsHTMLReflowMetrics& aDesiredStretchSize) - { - return NS_OK; - } - - NS_IMETHOD - Place(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - PRBool aPlaceOrigin, - nsHTMLReflowMetrics& aDesiredSize) - { - return NS_OK; - } - - NS_IMETHOD - EmbellishOperator() - { - return NS_OK; - } - - NS_IMETHOD - GetEmbellishData(nsEmbellishData& aEmbellishData) - { - aEmbellishData = mEmbellishData; - return NS_OK; - } - - NS_IMETHOD - SetEmbellishData(const nsEmbellishData& aEmbellishData) - { - mEmbellishData = aEmbellishData; - return NS_OK; - } - - NS_IMETHOD - GetPresentationData(nsPresentationData& aPresentationData) - { - aPresentationData = mPresentationData; - return NS_OK; - } - - NS_IMETHOD - SetPresentationData(const nsPresentationData& aPresentationData) - { - mPresentationData = aPresentationData; - return NS_OK; - } - - NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) - { - return NS_OK; - } - - NS_IMETHOD - UpdatePresentationDataFromChildAt(PRInt32 aFirstIndex, - PRInt32 aLastIndex, - PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) - { - return NS_OK; - } + ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel); // overloaded nsTableOuterFrame methods @@ -156,27 +70,30 @@ public: protected: nsMathMLmtableOuterFrame(); virtual ~nsMathMLmtableOuterFrame(); - - // information about the presentation policy of the frame - nsPresentationData mPresentationData; - - // 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; }; // class nsMathMLmtableOuterFrame // -------------- -class nsMathMLmtdFrame : public nsBlockFrame { +class nsMathMLmtdFrame : public nsBlockFrame, + public nsMathMLFrame { public: friend nsresult NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + NS_DECL_ISUPPORTS_INHERITED + + NS_IMETHOD + ReResolveScriptStyle(nsIPresContext* aPresContext, + nsIStyleContext* aParentContext, + PRInt32 aParentScriptLevel); + + NS_IMETHOD + Init(nsIPresContext* aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow); + NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp index 8d50cda63bd..1c139f5fe0a 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderFrame.cpp @@ -119,16 +119,14 @@ XXX The winner is the outermost setting in conflicting settings like these: nsIFrame* underscriptFrame = nsnull; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - count++; - if (1 == count) baseFrame = childFrame; - if (2 == count) { underscriptFrame = childFrame; break; } - } + if (0 == count) baseFrame = childFrame; + if (1 == count) { underscriptFrame = childFrame; break; } + count++; childFrame->GetNextSibling(&childFrame); } nsIMathMLFrame* underscriptMathMLFrame = nsnull; - nsIMathMLFrame* aMathMLFrame = nsnull; + nsIMathMLFrame* mathMLFrame = nsnull; nsEmbellishData embellishData; nsAutoString value; @@ -147,9 +145,9 @@ XXX The winner is the outermost setting in conflicting settings like these: } } else { // no attribute, get the value from the core - rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) { mPresentationData.flags |= NS_MATHML_MOVABLELIMITS; } @@ -164,9 +162,9 @@ XXX The winner is the outermost setting in conflicting settings like these: underscriptMathMLFrame->GetEmbellishData(embellishData); // core of the underscriptFrame if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) { - rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->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, @@ -174,7 +172,7 @@ XXX The winner is the outermost setting in conflicting settings like these: { if (value.EqualsWithConversion("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; else if (value.EqualsWithConversion("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; - aMathMLFrame->SetEmbellishData(embellishData); + mathMLFrame->SetEmbellishData(embellishData); } // sync the presentation data: record whether we have an accentunder @@ -199,14 +197,11 @@ XXX The winner is the outermost setting in conflicting settings like these: underscriptMathMLFrame->UpdatePresentationData(increment, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); - underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, -1, increment, + underscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); } - // switch the style of the underscript - InsertScriptLevelStyleContext(aPresContext); - return rv; } @@ -238,7 +233,7 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, nsresult rv = NS_OK; if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) && - !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { + !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { // place like subscript return nsMathMLmsubFrame::PlaceSubScript(aPresContext, aRenderingContext, @@ -259,27 +254,22 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if (0 == count) { - // base - baseFrame = childFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // under - underFrame = childFrame; - GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); - } - count++; + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); } - rv = childFrame->GetNextSibling(&childFrame); - NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child"); + else if (1 == count) { + // under + underFrame = childFrame; + GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); + } + count++; + childFrame->GetNextSibling(&childFrame); } - if ((2 != count) || !baseFrame || !underFrame) { -#ifdef NS_DEBUG - printf("munder: invalid markup"); -#endif + if (2 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, aRenderingContext, aDesiredSize); } @@ -324,7 +314,7 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, delta2 = ruleThickness; } // empty under? - if (0 == (bmUnder.ascent + bmUnder.descent)) delta1 = 0; + if (!(bmUnder.ascent + bmUnder.descent)) delta1 = 0; mBoundingMetrics.ascent = bmBase.ascent; mBoundingMetrics.descent = @@ -357,7 +347,6 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext, if (aPlaceOrigin) { nscoord dy = 0; // place base - dy = 0; FinishReflowChild(baseFrame, aPresContext, baseSize, dxBase, dy, 0); // place underscript dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent - underSize.ascent; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp index e0ffafdd111..efa427383fb 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp @@ -116,18 +116,16 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, 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; } - } + if (0 == count) baseFrame = childFrame; + if (1 == count) underscriptFrame = childFrame; + if (2 == count) { overscriptFrame = childFrame; break; } + count++; childFrame->GetNextSibling(&childFrame); } nsIMathMLFrame* underscriptMathMLFrame = nsnull; nsIMathMLFrame* overscriptMathMLFrame = nsnull; - nsIMathMLFrame* aMathMLFrame = nsnull; + nsIMathMLFrame* mathMLFrame; nsEmbellishData embellishData; nsAutoString value; @@ -147,9 +145,9 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, } } else { // no attribute, get the value from the core - rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = mEmbellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->GetEmbellishData(embellishData); if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) { mPresentationData.flags |= NS_MATHML_MOVABLELIMITS; } @@ -164,9 +162,9 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, underscriptMathMLFrame->GetEmbellishData(embellishData); // core of the underscriptFrame if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) { - rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->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, @@ -174,7 +172,7 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, { if (value.EqualsWithConversion("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; else if (value.EqualsWithConversion("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; - aMathMLFrame->SetEmbellishData(embellishData); + mathMLFrame->SetEmbellishData(embellishData); } // sync the presentation data: record whether we have an accentunder @@ -192,9 +190,9 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, overscriptMathMLFrame->GetEmbellishData(embellishData); // core of the overscriptFrame if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.core) { - rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame); - if (NS_SUCCEEDED(rv) && aMathMLFrame) { - aMathMLFrame->GetEmbellishData(embellishData); + rv = embellishData.core->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (NS_SUCCEEDED(rv) && mathMLFrame) { + mathMLFrame->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, @@ -202,7 +200,7 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, { if (value.EqualsWithConversion("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT; else if (value.EqualsWithConversion("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; - aMathMLFrame->SetEmbellishData(embellishData); + mathMLFrame->SetEmbellishData(embellishData); } // sync the presentation data: record whether we have an accent @@ -237,7 +235,7 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, overscriptMathMLFrame->UpdatePresentationData(increment, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); - overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, -1, increment, + overscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE | compress, NS_MATHML_DISPLAYSTYLE | compress); } @@ -251,14 +249,11 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, underscriptMathMLFrame->UpdatePresentationData(increment, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); - underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, -1, increment, + underscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED, NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED); } - // switch the style of the underscript and the overscript - InsertScriptLevelStyleContext(aPresContext); - return rv; } @@ -291,7 +286,7 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, nsresult rv = NS_OK; if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) && - !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { + !NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { // place like sub-superscript pair return nsMathMLmsubsupFrame::PlaceSubSupScript(aPresContext, aRenderingContext, @@ -314,31 +309,27 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { - if (!IsOnlyWhitespace(childFrame)) { - if (0 == count) { - // base - baseFrame = childFrame; - GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); - } - else if (1 == count) { - // under - underFrame = childFrame; - GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); - } - else if (2 == count) { - // over - overFrame = childFrame; - GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); - } - count++; + if (0 == count) { + // base + baseFrame = childFrame; + GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase); } + else if (1 == count) { + // under + underFrame = childFrame; + GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder); + } + else if (2 == count) { + // over + overFrame = childFrame; + GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver); + } + count++; childFrame->GetNextSibling(&childFrame); } - if ((3 != count) || !baseFrame || !underFrame || !overFrame) { -#ifdef NS_DEBUG - printf("munderover: invalid markup\n"); -#endif + if (3 != count) { // report an error, encourage people to get their markups in order + NS_WARNING("invalid markup"); return ReflowError(aPresContext, aRenderingContext, aDesiredSize); } @@ -384,7 +375,7 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, underDelta2 = ruleThickness; } // empty under? - if (0 == (bmUnder.ascent + bmUnder.descent)) underDelta1 = 0; + if (!(bmUnder.ascent + bmUnder.descent)) underDelta1 = 0; nscoord correction = 0; nscoord overDelta1 = 0; // gap between base and overscript @@ -417,7 +408,7 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext, overDelta2 = ruleThickness; } // empty over? - if (0 == (bmOver.ascent + bmOver.descent)) overDelta1 = 0; + if (!(bmOver.ascent + bmOver.descent)) overDelta1 = 0; mBoundingMetrics.ascent = bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent;