Remove nsMathMLmnFrame

This commit is contained in:
rbs@maths.uq.edu.au
2000-03-28 09:38:24 +00:00
parent 05938718c7
commit 17542e0bd7
46 changed files with 4033 additions and 2436 deletions
+2 -2
View File
@@ -50,8 +50,8 @@ CPPSRCS = nsMathMLChar.cpp \
nsMathMLmsubsupFrame.cpp \
nsMathMLmmultiscriptsFrame.cpp \
nsMathMLmiFrame.cpp \
nsMathMLmnFrame.cpp \
nsMathMLmtdFrame.cpp \
nsMathMLmtextFrame.cpp \
nsMathMLmtableFrame.cpp \
nsMathMLmoFrame.cpp \
nsMathMLmunderFrame.cpp \
nsMathMLmoverFrame.cpp \
+4 -4
View File
@@ -36,11 +36,11 @@ CPPSRCS= nsMathMLChar.cpp \
nsMathMLmfracFrame.cpp \
nsMathMLmsubFrame.cpp \
nsMathMLmiFrame.cpp \
nsMathMLmnFrame.cpp \
nsMathMLmtextFrame.cpp \
nsMathMLmsubsupFrame.cpp \
nsMathMLmmultiscriptsFrame.cpp \
nsMathMLmsupFrame.cpp \
nsMathMLmtdFrame.cpp \
nsMathMLmtableFrame.cpp \
nsMathMLmoFrame.cpp \
nsMathMLmunderFrame.cpp \
nsMathMLmoverFrame.cpp \
@@ -62,11 +62,11 @@ CPP_OBJS= .\$(OBJDIR)\nsMathMLChar.obj \
.\$(OBJDIR)\nsMathMLmfracFrame.obj \
.\$(OBJDIR)\nsMathMLmsubFrame.obj \
.\$(OBJDIR)\nsMathMLmiFrame.obj \
.\$(OBJDIR)\nsMathMLmnFrame.obj \
.\$(OBJDIR)\nsMathMLmtextFrame.obj \
.\$(OBJDIR)\nsMathMLmsubsupFrame.obj \
.\$(OBJDIR)\nsMathMLmmultiscriptsFrame.obj \
.\$(OBJDIR)\nsMathMLmsupFrame.obj \
.\$(OBJDIR)\nsMathMLmtdFrame.obj \
.\$(OBJDIR)\nsMathMLmtableFrame.obj \
.\$(OBJDIR)\nsMathMLmoFrame.obj \
.\$(OBJDIR)\nsMathMLmunderFrame.obj \
.\$(OBJDIR)\nsMathMLmoverFrame.obj \
+49 -85
View File
@@ -18,7 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
*/
#define SHOW_BOUNDING_BOX 1
#ifndef nsIMathMLFrame_h___
#define nsIMathMLFrame_h___
@@ -81,14 +81,14 @@ public:
* the stretched frame. Only member data of the struct that are
* relevant to the direction are used (the rest is ignored).
* @param aDesiredStretchSize [in/out] On input the current size
* size of the frame, on output the size after stretching.
* of the frame, on output the size after stretching.
*/
NS_IMETHOD
Stretch(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize,
nsStretchMetrics& aDesiredStretchSize) = 0;
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredStretchSize) = 0;
#if 0
NS_IMETHOD
@@ -187,20 +187,23 @@ public:
SetPresentationData(const nsPresentationData& aPresentationData) = 0;
/* UpdatePresentationData :
* Increments the scriptlevel of the frame, and set its displaystyle.
* Increments the scriptlevel of the frame, and
* sets its displaystyle and compression flags.
* Note that <mstyle> is the only tag which allows to set
* <mstyle displaystyle="true|false" scriptlevel="[+|-]number">
* to reset or increment the scriptlevel in a manual way.
* Therefore <mstyle> has its peculiar version of this method.
* Therefore <mstyle> has its own peculiar version of this method.
*/
NS_IMETHOD
UpdatePresentationData(PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle) = 0;
PRBool aDisplayStyle,
PRBool aCompressed) = 0;
/* UpdatePresentationDataFromChildAt :
* Increments the scriplevel and set the display level on the whole tree.
* For child frames at: aIndex, aIndex+1, aIndex+2, etc, this method set
* their mDisplayStyle to aDisplayStyle and increment their mScriptLevel
* Increments the scriplevel and
* sets the displaystyle and compression flags on the whole tree.
* For child frames at: aIndex, aIndex+1, aIndex+2, etc, this method sets
* their displaystyle and compressed flags, and increment their mScriptLevel
* with aScriptLevelIncrement. The increment is propagated down to the
* subtrees of each of these child frames. Note that <mstyle> is the only
* tag which allows <mstyle displaystyle="true|false" scriptlevel="[+|-]number">
@@ -210,57 +213,8 @@ public:
NS_IMETHOD
UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle) = 0;
};
/* Structure used for stretching a frame. */
struct nsStretchMetrics {
// nscoord leading;
nscoord descent, ascent;
nscoord width, height;
float leftSpace, rightSpace;
nsStretchMetrics(nscoord aDescent = 0,
nscoord aAscent = 0,
nscoord aWidth = 0,
nscoord aHeight = 0,
float aLeftSpace = 0.0f,
float aRightSpace = 0.0f) {
width = aWidth;
height = aHeight;
ascent = aAscent;
descent = aDescent;
leftSpace = aLeftSpace;
rightSpace = aRightSpace;
}
nsStretchMetrics(const nsStretchMetrics& aStretchMetrics) {
width = aStretchMetrics.width;
height = aStretchMetrics.height;
ascent = aStretchMetrics.ascent;
descent = aStretchMetrics.descent;
leftSpace = aStretchMetrics.leftSpace;
rightSpace = aStretchMetrics.rightSpace;
}
nsStretchMetrics(const nsHTMLReflowMetrics& aReflowMetrics) {
width = aReflowMetrics.width;
height = aReflowMetrics.height;
ascent = aReflowMetrics.ascent;
descent = aReflowMetrics.descent;
leftSpace = 0.0f;
rightSpace = 0.0f;
}
PRBool
operator == (const nsStretchMetrics& aStretchMetrics) {
return (width == aStretchMetrics.width &&
height == aStretchMetrics.height &&
ascent == aStretchMetrics.ascent &&
descent == aStretchMetrics.descent &&
leftSpace == aStretchMetrics.leftSpace &&
rightSpace == aStretchMetrics.rightSpace);
}
PRBool aDisplayStyle,
PRBool aCompressed) = 0;
};
// struct used by a frame to modulate its presentation
@@ -283,7 +237,7 @@ struct nsEmbellishData {
nsIFrame* firstChild; // handy pointer on our embellished child
nsIFrame* core; // pointer on the mo frame at the core of the embellished hierarchy
nsStretchDirection direction;
nscoord leftSpace, rightSpace;
float leftSpace, rightSpace;
nsEmbellishData()
{
@@ -291,7 +245,7 @@ struct nsEmbellishData {
firstChild = nsnull;
core = nsnull;
direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
leftSpace = rightSpace = 0;
leftSpace = rightSpace = 0.0f;
}
};
@@ -328,16 +282,21 @@ struct nsEmbellishData {
// an accentunder frame
#define NS_MATHML_ACCENTUNDER 0x00000020
// This bit is set if the frame is <mover>, <munder> or <munderover>
// This bit is set if the frame is an <mover>, <munder> or <munderover>
// whose base frame is a <mo> frame (or an embellished container with
// a core <mo>) for which the movablelimits attribute is set to true
#define NS_MATHML_MOVABLELIMITS 0x00000040
// This bit is set when the frame cannot be formatted due to an
// error (e.g., invalid markup such as a <msup> without an overscript).
// When set, a visual feedback will be provided to the user.
#define NS_MATHML_ERROR 0x80000000
// This bit is used for visual debug. When set, the bounding box
// of your frame is painted. You should therefore ensure that you
// have properly filled your mReference and mBoundingMetrics in
// of your frame is painted. This visual debug enable to ensure that
// you have properly filled your mReference and mBoundingMetrics in
// Place().
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x80000000
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x40000000
// Macros that retrieve those bits
#define NS_MATHML_IS_DISPLAYSTYLE(_flags) \
@@ -361,6 +320,9 @@ struct nsEmbellishData {
#define NS_MATHML_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_MOVABLELIMITS == ((_flags) & NS_MATHML_MOVABLELIMITS))
#define NS_MATHML_HAS_ERROR(_flags) \
(NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
#define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
(NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
@@ -369,28 +331,30 @@ struct nsEmbellishData {
// in their relevant situation as they become available
// This bit is set if the frame is an embellished operator.
#define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
#define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
// This bit is set if the frame is an embellished container that
// will fire a stretch command on its first (non-empty) child.
#define NS_MATHML_STRETCH_FIRST_CHILD NS_MATHML_EMBELLISH_OPERATOR
// This bit is set if the frame will fire a vertical stretch
// command on all its (non-empty) children.
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
// vertical stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000002
// This bit is set if the frame will fire a stretch command on all
// its (non-empty) children.
// Tags like <mrow> (or an inferred mrow), munderover, etc,
// will fire a stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN 0x00000002
// This bit is set if the frame will fire a horizontal stretch
// command on all its (non-empty) children.
// Tags like munder, mover, munderover, will fire a
// horizontal stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000004
// This bit is set if the frame is an <mo> frame that should behave
// like an accent
#define NS_MATHML_EMBELLISH_ACCENT 0x00000004
// like an accent XXX since it is <mo> specific, use NS_MATHML_EMBELLISH_MO_ACCENT instead?
#define NS_MATHML_EMBELLISH_ACCENT 0x00000008
// This bit is set if the frame is an <mo> frame with the movablelimits
// attribute set to true
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000008
// attribute set to true XXX since it is <mo> specific, use NS_MATHML_EMBELLISH_MO_MOVABLELIMITS instead?
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000010
// a bit used for debug
#define NS_MATHML_STRETCH_DONE 0x80000000
#define NS_MATHML_STRETCH_DONE 0x80000000
// Macros that retrieve those bits
@@ -398,11 +362,11 @@ struct nsEmbellishData {
#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
(NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
#define NS_MATHML_WILL_STRETCH_FIRST_CHILD(_flags) \
(NS_MATHML_STRETCH_FIRST_CHILD == ((_flags) & NS_MATHML_STRETCH_FIRST_CHILD))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
File diff suppressed because it is too large Load Diff
+53 -31
View File
@@ -17,6 +17,7 @@
*
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLChar_h___
@@ -25,52 +26,63 @@
#include "nsMathMLOperators.h"
#include "nsIMathMLFrame.h"
// enum of chars that we know something about
typedef PRUnichar nsGlyphCode;
class nsGlyphTable;
// List of enums of all known chars
enum nsMathMLCharEnum {
eMathMLChar_DONT_STRETCH = -1,
#define MATHML_CHAR(_name, _value, _direction) eMathMLChar_##_name,
#include "nsMathMLCharList.h"
#undef MATHML_CHAR
#define WANT_CHAR_ENUM
#include "nsMathMLCharList.h"
#undef WANT_CHAR_ENUM
eMathMLChar_COUNT
};
// Hints for Stretch() to indicate criteria for stretching
#define NS_STRETCH_SMALLER -1 // don't stretch more than requested size
#define NS_STRETCH_NORMAL 0 // try to stretch to requested size - DEFAULT
#define NS_STRETCH_LARGER 1 // try to stretch more than requested size
// class used to handle stretchy symbols (accent and boundary symbol)
// class used to handle stretchy symbols (accent, delimiter and boundary symbols)
class nsMathMLChar
{
public:
// constructor and destructor
nsMathMLChar()
{
mStyleContext = nsnull;
}
virtual ~nsMathMLChar()
~nsMathMLChar() // not a virtual destructor: this class is not intended to be subclassed
{
}
NS_IMETHOD
nsresult
Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext);
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
nsIFrame* aForFrame);
// This is the method called to ask the char to stretch itself.
// aDesiredStretchSize is an IN/OUT parameter.
// On input - it contains our current size.
// On input - it contains our current size, or zero if current size is unknown
// On output - the same size or the new size that the char wants.
NS_IMETHOD
nsresult
Stretch(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize,
nsStretchMetrics& aDesiredStretchSize);
nsBoundingMetrics& aContainerSize,
nsBoundingMetrics& aDesiredStretchSize,
PRInt32 aStretchHint = NS_STRETCH_NORMAL);
// If you call SetData(), it will lookup the enum of the data
// and set mEnum for you. If the data is an arbitrary string for
// which no enum is defined, mEnum is set to eMathMLChar_DONT_STRETCH
// and the data is interpreted as a normal string.
void
SetData(nsString& aData);
SetData(nsIPresContext* aPresContext,
nsString& aData);
void
GetData(nsString& aData) {
@@ -80,10 +92,11 @@ public:
// If you call SetEnum(), it will lookup the actual value of the data and
// set it for you. All the enums listed above have their corresponding data.
void
SetEnum(nsMathMLCharEnum aEnum);
SetEnum(nsIPresContext* aPresContext,
nsMathMLCharEnum aEnum);
nsMathMLCharEnum
Enum() {
GetEnum() {
return mEnum;
}
@@ -114,43 +127,52 @@ public:
mRect = aRect;
}
// Metrics that _exactly_ enclose the char. The char *must* have *already*
// being stretched before you can call the GetBoundingMetrics() method.
// IMPORTANT: since chars have their own style contexts, and may be rendered
// with glyphs that are not in the parent font, just calling the default
// aRenderingContext.GetBoundingMetrics(aChar) can give incorrect results.
void
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
aBoundingMetrics = mBoundingMetrics;
}
// Hooks to access the extra leaf style contexts given to the MathMLChars.
// They provide an interface to make them acessible to the Style System via
// the Get/Set AdditionalStyleContext() APIs. Owners of MathMLChars
// should honor these APIs.
nsresult
GetStyleContext(nsIStyleContext** aStyleContext) const;
nsresult
SetStyleContext(nsIStyleContext* aStyleContext);
private:
nsString mData;
PRUnichar mGlyph;
nsRect mRect;
nsStretchDirection mDirection;
nsMathMLCharEnum mEnum;
nsStretchDirection mDirection;
nsRect mRect;
nsBoundingMetrics mBoundingMetrics;
nsIStyleContext* mStyleContext;
nsGlyphTable* mGlyphTable;
nsGlyphCode mGlyph;
// helper methods
static void
DrawGlyph(nsIRenderingContext& aRenderingContext,
PRUnichar aChar,
nscoord aX,
nscoord aY,
nsRect& aClipRect);
static nsresult
PaintVertically(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aFontAscent,
nsIStyleContext* aStyleContext,
nscoord fontAscent,
nscoord fontDescent,
nsGlyphTable* aGlyphTable,
nsMathMLCharEnum aCharEnum,
nsRect aRect);
static nsresult
PaintHorizontally(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nscoord aFontAscent,
nsIStyleContext* aStyleContext,
nscoord fontAscent,
nscoord fontDescent,
nsGlyphTable* aGlyphTable,
nsMathMLCharEnum aCharEnum,
nsRect aRect);
};
+279 -124
View File
@@ -17,6 +17,7 @@
*
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
/******
@@ -29,153 +30,307 @@
All entries must be enclosed in the macro MATHML_CHAR which will have cruel
and unusual things done to them.
To add support for a particular stretchy char, you should move its
MATHML_CHAR entry out of the #ifdef list and append it in the active list.
How it works
============
* Stretchy chars that come from the same font are grouped together.
For example, stretchy chars that can be build with the Symbol font are enclosed in:
#if defined(WANT_SYMBOL_DATA)
...
#endif
* To add support for a <b>new stretchy char within a font</b>, you should
add its MATHML_CHAR entry in the appropriate list. Each relevant row looks like:
The first argument of MATHML_CHAR will be converted in an enum of
the form, e.g., eMathMLChar_LeftParenthesis, which will be used in
the code. Therefore the ORDER OF THE ACTIVE LIST IS SIGNIFICANT.
(The order in which chars are gradually appended in the active list is
not-significant, but once added in the active list, they should remain
in their positions. If you want to shuffle the active list, you should
also make sure to adjust the related data structures in nsMathMLChar.cpp)
MATHML_CHAR(index, enum, top _ middle _ bottom _ glue, size0 _ ... _ size{N-1})
o The second argument of MATHML_CHAR will be converted in an 'enum' of the form,
e.g., eMathMLChar_LeftParenthesis, which will be used in the code.
o The first argument 'index' represents the previous index augmented with:
1 + number of glyphs listed in the previous row. In general therefore,
the k+1st index after the k-th index must satisfy the relationship:
index[k+1] = index[k] + 5 + N.
where:
5 represents the 4 partial glyphs: top (or left), middle, bottom (or right), glue,
*plus* the null separator that is inserted after the list of glyphs!
N represents the total number of bigger sizes: size0, ..., size{N-1}.
* To add support for a <b>new font</b>, you should create the list of stretchy chars
that can be rendered with that font, and then declare an instance of nsGlyphTable
associated to that font in nsMathMLChar.cpp. Then update the font-family list
of :-moz-math-font-style-stretchy in mathml.css to instruct the Style System to
pass your font in your preferred order.
* There can be two types of data: either with Unicode points, or with direct
glyph indices within the fonts. XXX The second variant is not yet supported.
******/
#if defined(WANT_CHAR_ENUM)
#define MATHML_CHAR(_enum, _unicode, _direction) eMathMLChar_##_enum,
#elif defined(WANT_CHAR_INFO)
#define MATHML_CHAR(_enum, _unicode, _direction) {_unicode, _direction, nsnull},
#elif defined(WANT_CHAR_DATA)
#define MATHML_CHAR(_index, _enum, _parts, _sizes) {eMathMLChar_##_enum, _index},
#elif defined(WANT_GLYPH_DATA)
#define MATHML_CHAR(_index, _enum, _parts, _sizes) _parts, _sizes, 0x0000,
#endif
#if defined(WANT_CHAR_ENUM) || defined(WANT_CHAR_INFO)
// short names for a short while...
#define STRETCH_UNSUPPORTED NS_STRETCH_DIRECTION_UNSUPPORTED
#define STRETCH_HORIZONTAL NS_STRETCH_DIRECTION_HORIZONTAL
#define STRETCH_VERTICAL NS_STRETCH_DIRECTION_VERTICAL
/* active list - these are chars that we know something about */
// List of all strecthy chars from the MathML's Operator Dictionary ------------------
// -----------------------------------------------------------------------------------
MATHML_CHAR(LeftParenthesis, '(' , STRETCH_VERTICAL)
MATHML_CHAR(RightParenthesis, ')' , STRETCH_VERTICAL)
MATHML_CHAR(Integral, 0x222B, STRETCH_VERTICAL)
MATHML_CHAR(LeftSquareBracket, '[' , STRETCH_VERTICAL)
MATHML_CHAR(RightSquareBracket, ']' , STRETCH_VERTICAL)
MATHML_CHAR(LeftCurlyBracket, '{' , STRETCH_VERTICAL)
MATHML_CHAR(RightCurlyBracket, '}' , STRETCH_VERTICAL)
MATHML_CHAR(VerticalBar, 0x007C, STRETCH_VERTICAL) // '|'
MATHML_CHAR(Integral, 0x222B, STRETCH_VERTICAL)
MATHML_CHAR(DownArrow, 0x2193, STRETCH_VERTICAL)
MATHML_CHAR(UpArrow, 0x2191, STRETCH_VERTICAL)
MATHML_CHAR(LeftArrow, 0x2190, STRETCH_HORIZONTAL)
MATHML_CHAR(RightArrow, 0x2192, STRETCH_HORIZONTAL)
MATHML_CHAR(OverBar, 0x00AF, STRETCH_HORIZONTAL)
MATHML_CHAR(VerticalBar, '|' , STRETCH_VERTICAL)
MATHML_CHAR(Sqrt, 0x221A, STRETCH_UNSUPPORTED)
MATHML_CHAR(Sqrt, 0x221A, STRETCH_VERTICAL)
MATHML_CHAR(LeftAngleBracket, 0x3008, STRETCH_VERTICAL)
MATHML_CHAR(LeftBracketingBar, 0xF603, STRETCH_VERTICAL)
MATHML_CHAR(LeftCeiling, 0x2308, STRETCH_VERTICAL)
MATHML_CHAR(LeftDoubleBracket, 0x301A, STRETCH_VERTICAL)
MATHML_CHAR(LeftDoubleBracketingBar, 0xF605, STRETCH_VERTICAL)
MATHML_CHAR(LeftFloor, 0x230A, STRETCH_VERTICAL)
MATHML_CHAR(RightAngleBracket, 0x3009, STRETCH_VERTICAL)
MATHML_CHAR(RightBracketingBar, 0xF604, STRETCH_VERTICAL)
MATHML_CHAR(RightCeiling, 0x2309, STRETCH_VERTICAL)
MATHML_CHAR(RightDoubleBracket, 0x301B, STRETCH_VERTICAL)
MATHML_CHAR(RightDoubleBracketingBar, 0xF606, STRETCH_VERTICAL)
MATHML_CHAR(RightFloor, 0x230B, STRETCH_VERTICAL)
MATHML_CHAR(HorizontalLine, 0xE859, STRETCH_HORIZONTAL)
MATHML_CHAR(VerticalLine, 0xE85A, STRETCH_VERTICAL)
MATHML_CHAR(VerticalSeparator, 0xE85C, STRETCH_VERTICAL)
MATHML_CHAR(Implies, 0x21D2, STRETCH_HORIZONTAL)
MATHML_CHAR(And, 0x2227, STRETCH_HORIZONTAL)
MATHML_CHAR(Or, 0x2228, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleLeftArrow, 0x21D0, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleLeftRightArrow, 0x21D4, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleRightArrow, 0x21D2, STRETCH_HORIZONTAL)
MATHML_CHAR(DownLeftRightVector, 0xF50B, STRETCH_VERTICAL)
MATHML_CHAR(DownLeftTeeVector, 0xF50E, STRETCH_VERTICAL)
MATHML_CHAR(DownLeftVector, 0x21BD, STRETCH_VERTICAL)
MATHML_CHAR(DownLeftVectorBar, 0xF50C, STRETCH_VERTICAL)
MATHML_CHAR(DownRightTeeVector, 0xF50F, STRETCH_VERTICAL)
MATHML_CHAR(DownRightVector, 0x21C1, STRETCH_VERTICAL)
MATHML_CHAR(DownRightVectorBar, 0xF50D, STRETCH_VERTICAL)
MATHML_CHAR(LeftArrowBar, 0x21E4, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftArrowRightArrow, 0x21C6, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftRightArrow, 0x2194, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftRightVector, 0xF505, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftTeeArrow, 0x21A4, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftTeeVector, 0xF509, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftVector, 0x21BC, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftVectorBar, 0xF507, STRETCH_HORIZONTAL)
MATHML_CHAR(LowerLeftArrow, 0x2199, STRETCH_HORIZONTAL)
MATHML_CHAR(LowerRightArrow, 0x2198, STRETCH_HORIZONTAL)
MATHML_CHAR(RightArrowBar, 0x21E5, STRETCH_HORIZONTAL)
MATHML_CHAR(RightArrowLeftArrow, 0x21C4, STRETCH_HORIZONTAL)
MATHML_CHAR(RightTeeArrow, 0x21A6, STRETCH_HORIZONTAL)
MATHML_CHAR(RightTeeVector, 0xF50A, STRETCH_HORIZONTAL)
MATHML_CHAR(RightVector, 0x21C0, STRETCH_HORIZONTAL)
MATHML_CHAR(RightVectorBar, 0xF508, STRETCH_HORIZONTAL)
MATHML_CHAR(UpperLeftArrow, 0x2196, STRETCH_VERTICAL)
MATHML_CHAR(UpperRightArrow, 0x2197, STRETCH_VERTICAL)
MATHML_CHAR(Equilibrium, 0x21CC, STRETCH_HORIZONTAL)
MATHML_CHAR(ReverseEquilibrium, 0x21CB, STRETCH_HORIZONTAL)
MATHML_CHAR(SquareUnion, 0x2294, STRETCH_VERTICAL)
MATHML_CHAR(Union, 0x22C3, STRETCH_VERTICAL)
MATHML_CHAR(UnionPlus, 0x228E, STRETCH_VERTICAL)
MATHML_CHAR(Intersection, 0x22C2, STRETCH_VERTICAL)
MATHML_CHAR(SquareIntersection, 0x2293, STRETCH_VERTICAL)
MATHML_CHAR(Vee, 0x22C1, STRETCH_VERTICAL)
MATHML_CHAR(Sum, 0x2211, STRETCH_VERTICAL)
MATHML_CHAR(ClockwiseContourIntegral, 0x2232, STRETCH_VERTICAL)
MATHML_CHAR(ContourIntegral, 0x222E, STRETCH_VERTICAL)
MATHML_CHAR(CounterClockwiseContourIntegral, 0x2233, STRETCH_VERTICAL)
MATHML_CHAR(DoubleContourIntegral, 0x222F, STRETCH_VERTICAL)
MATHML_CHAR(Wedge, 0x22C0, STRETCH_VERTICAL)
MATHML_CHAR(Coproduct, 0x2210, STRETCH_VERTICAL)
MATHML_CHAR(Product, 0x220F, STRETCH_VERTICAL)
MATHML_CHAR(Backslash, 0x2216, STRETCH_VERTICAL)
MATHML_CHAR(Slash, '/' , STRETCH_VERTICAL)
MATHML_CHAR(DoubleDownArrow, 0x21D3, STRETCH_VERTICAL)
MATHML_CHAR(DoubleLongLeftArrow, 0xE200, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleLongLeftRightArrow, 0xE202, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleLongRightArrow, 0xE204, STRETCH_HORIZONTAL)
MATHML_CHAR(DoubleUpArrow, 0x21D1, STRETCH_VERTICAL)
MATHML_CHAR(DoubleUpDownArrow, 0x21D5, STRETCH_VERTICAL)
MATHML_CHAR(DownArrowBar, 0xF504, STRETCH_VERTICAL)
MATHML_CHAR(DownArrowUpArrow, 0xE216, STRETCH_VERTICAL)
MATHML_CHAR(DownTeeArrow, 0x21A7, STRETCH_VERTICAL)
MATHML_CHAR(LeftDownTeeVector, 0xF519, STRETCH_VERTICAL)
MATHML_CHAR(LeftDownVector, 0x21C3, STRETCH_VERTICAL)
MATHML_CHAR(LeftDownVectorBar, 0xF517, STRETCH_VERTICAL)
MATHML_CHAR(LeftUpDownVector, 0xF515, STRETCH_VERTICAL)
MATHML_CHAR(LeftUpTeeVector, 0xF518, STRETCH_VERTICAL)
MATHML_CHAR(LeftUpVector, 0x21BF, STRETCH_VERTICAL)
MATHML_CHAR(LeftUpVectorBar, 0xF516, STRETCH_VERTICAL)
MATHML_CHAR(LongLeftArrow, 0xE201, STRETCH_HORIZONTAL)
MATHML_CHAR(LongLeftRightArrow, 0xE203, STRETCH_HORIZONTAL)
MATHML_CHAR(LongRightArrow, 0xE205, STRETCH_HORIZONTAL)
MATHML_CHAR(ReverseUpEquilibrium, 0xE217, STRETCH_VERTICAL)
MATHML_CHAR(RightDownTeeVector, 0xF514, STRETCH_VERTICAL)
MATHML_CHAR(RightDownVector, 0x21C2, STRETCH_VERTICAL)
MATHML_CHAR(RightDownVectorBar, 0xF512, STRETCH_VERTICAL)
MATHML_CHAR(RightUpDownVector, 0xF510, STRETCH_VERTICAL)
MATHML_CHAR(RightUpTeeVector, 0xF513, STRETCH_VERTICAL)
MATHML_CHAR(RightUpVector, 0x21BE, STRETCH_VERTICAL)
MATHML_CHAR(RightUpVectorBar, 0xF511, STRETCH_VERTICAL)
MATHML_CHAR(UpArrowBar, 0xF503, STRETCH_VERTICAL)
MATHML_CHAR(UpArrowDownArrow, 0x21C5, STRETCH_VERTICAL)
MATHML_CHAR(UpDownArrow, 0x2195, STRETCH_VERTICAL)
MATHML_CHAR(UpEquilibrium, 0xE218, STRETCH_VERTICAL)
MATHML_CHAR(UpTeeArrow, 0x21A5, STRETCH_VERTICAL)
MATHML_CHAR(DiacriticalTilde, 0x02DC, STRETCH_HORIZONTAL)
MATHML_CHAR(Hacek, 0x02C7, STRETCH_HORIZONTAL)
MATHML_CHAR(Hat, 0x0302, STRETCH_HORIZONTAL)
MATHML_CHAR(OverCurlyBracket, 0xF612, STRETCH_HORIZONTAL)
MATHML_CHAR(OverBracket, 0xF614, STRETCH_HORIZONTAL)
MATHML_CHAR(OverParenthesis, 0xF610, STRETCH_HORIZONTAL)
MATHML_CHAR(UnderBar, 0x0332, STRETCH_HORIZONTAL)
MATHML_CHAR(UnderCurlyBracket, 0xF613, STRETCH_HORIZONTAL)
MATHML_CHAR(UnderBracket, 0xF615, STRETCH_HORIZONTAL)
MATHML_CHAR(UnderParenthesis, 0xF611, STRETCH_HORIZONTAL)
MATHML_CHAR(CircleDot, 0x2299, STRETCH_VERTICAL)
MATHML_CHAR(CirclePlus, 0x2295, STRETCH_VERTICAL)
MATHML_CHAR(CircleMultiply, 0x2297, STRETCH_VERTICAL)
MATHML_CHAR(Tilde, 0x223C, STRETCH_HORIZONTAL)
//UnionMultiply (UnionPlus?), 0x228E, STRETCH_VERTICAL,
// Oversight? \parallel (&DoubleVerticalBar, 0x2225) is not stretchy in
// the REC operator dictionary...
// Extra stretchy operators that are not in the MathML REC Operator Dictionary
// -----------------------------------------------------------------------------------
// XXX For these extra to work, they must also be added in nsMathMLOperators
MATHML_CHAR(RightArrowAccent, 0x20D7, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftArrowAccent, 0x20D6, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftRightArrowAccent, 0x20E1, STRETCH_HORIZONTAL)
MATHML_CHAR(RightHarpoonAccent, 0x20D1, STRETCH_HORIZONTAL)
MATHML_CHAR(LeftHarpoonAccent, 0x20D0, STRETCH_HORIZONTAL)
#if 0
MATHML_CHAR(LeftAngleBracket, 0x3008, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftBracketingBar, 0xF603, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftCeiling, 0x2308, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftDoubleBracket, 0x301A, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftDoubleBracketingBar, 0xF605, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftFloor, 0x230A, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightAngleBracket, 0x3009, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightBracketingBar, 0xF604, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightCeiling, 0x2309, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightDoubleBracket, 0x301B, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightDoubleBracketingBar, 0xF606, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightFloor, 0x230B, STRETCH_UNSUPPORTED)
MATHML_CHAR(HorizontalLine, 0xE859, STRETCH_UNSUPPORTED)
MATHML_CHAR(VerticalLine, 0xE85A, STRETCH_UNSUPPORTED)
MATHML_CHAR(VerticalSeparator, 0xE85C, STRETCH_UNSUPPORTED)
MATHML_CHAR(Implies, 0x21D2, STRETCH_UNSUPPORTED)
MATHML_CHAR(Or, 0xE375, STRETCH_UNSUPPORTED)
MATHML_CHAR(And, 0xE374, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleLeftArrow, 0x21D0, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleLeftRightArrow, 0x21D4, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleRightArrow, 0x21D2, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownLeftRightVector, 0xF50B, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownLeftTeeVector, 0xF50E, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownLeftVector, 0x21BD, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownLeftVectorBar, 0xF50C, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownRightTeeVector, 0xF50F, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownRightVector, 0x21C1, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownRightVectorBar, 0xF50D, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftArrowBar, 0x21E4, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftArrowRightArrow, 0x21C6, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftRightArrow, 0x2194, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftRightVector, 0xF505, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftTeeArrow, 0x21A4, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftTeeVector, 0xF509, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftVector, 0x21BC, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftVectorBar, 0xF507, STRETCH_UNSUPPORTED)
MATHML_CHAR(LowerLeftArrow, 0x2199, STRETCH_UNSUPPORTED)
MATHML_CHAR(LowerRightArrow, 0x2198, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightArrowBar, 0x21E5, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightArrowLeftArrow, 0x21C4, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightTeeArrow, 0x21A6, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightTeeVector, 0xF50A, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightVector, 0x21C0, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightVectorBar, 0xF508, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpperLeftArrow, 0x2196, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpperRightArrow, 0x2197, STRETCH_UNSUPPORTED)
MATHML_CHAR(Equilibrium, 0x21CC, STRETCH_UNSUPPORTED)
MATHML_CHAR(ReverseEquilibrium, 0x21CB, STRETCH_UNSUPPORTED)
MATHML_CHAR(SquareUnion, 0x2294, STRETCH_UNSUPPORTED)
MATHML_CHAR(Union, 0x22C3, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnionPlus, 0x228E, STRETCH_UNSUPPORTED)
MATHML_CHAR(Intersection, 0x22C2, STRETCH_UNSUPPORTED)
MATHML_CHAR(SquareIntersection, 0x2293, STRETCH_UNSUPPORTED)
MATHML_CHAR(Vee, 0x22C1, STRETCH_UNSUPPORTED)
MATHML_CHAR(Sum, 0x2211, STRETCH_UNSUPPORTED)
MATHML_CHAR(Union, 0x22C3, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnionPlus, 0x228E, STRETCH_UNSUPPORTED)
MATHML_CHAR(ClockwiseContourIntegral, 0x2232, STRETCH_UNSUPPORTED)
MATHML_CHAR(ContourIntegral, 0x222E, STRETCH_UNSUPPORTED)
MATHML_CHAR(CounterClockwiseContourIntegral, 0x2233, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleContourIntegral, 0x222F, STRETCH_UNSUPPORTED)
MATHML_CHAR(Wedge, 0x22C0, STRETCH_UNSUPPORTED)
MATHML_CHAR(Coproduct, 0x2210, STRETCH_UNSUPPORTED)
MATHML_CHAR(Product, 0x220F, STRETCH_UNSUPPORTED)
MATHML_CHAR(Intersection, 0x22C2, STRETCH_UNSUPPORTED)
MATHML_CHAR(Backslash, 0x2216, STRETCH_UNSUPPORTED)
MATHML_CHAR(Divide, '/' , STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleDownArrow, 0x21D3, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleLongLeftArrow, 0xE200, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleLongLeftRightArrow, 0xE202, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleLongRightArrow, 0xE204, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleUpArrow, 0x21D1, STRETCH_UNSUPPORTED)
MATHML_CHAR(DoubleUpDownArrow, 0x21D5, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownArrowBar, 0xF504, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownArrowUpArrow, 0xE216, STRETCH_UNSUPPORTED)
MATHML_CHAR(DownTeeArrow, 0x21A7, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftDownTeeVector, 0xF519, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftDownVector, 0x21C3, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftDownVectorBar, 0xF517, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftUpDownVector, 0xF515, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftUpTeeVector, 0xF518, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftUpVector, 0x21BF, STRETCH_UNSUPPORTED)
MATHML_CHAR(LeftUpVectorBar, 0xF516, STRETCH_UNSUPPORTED)
MATHML_CHAR(LongLeftArrow, 0xE201, STRETCH_UNSUPPORTED)
MATHML_CHAR(LongLeftRightArrow, 0xE203, STRETCH_UNSUPPORTED)
MATHML_CHAR(LongRightArrow, 0xE205, STRETCH_UNSUPPORTED)
MATHML_CHAR(ReverseUpEquilibrium, 0xE217, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightDownTeeVector, 0xF514, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightDownVector, 0x21C2, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightDownVectorBar, 0xF512, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightUpDownVector, 0xF510, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightUpTeeVector, 0xF513, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightUpVector, 0x21BE, STRETCH_UNSUPPORTED)
MATHML_CHAR(RightUpVectorBar, 0xF511, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpArrowBar, 0xF503, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpArrowDownArrow, 0x21C5, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpDownArrow, 0x2195, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpEquilibrium, 0xE218, STRETCH_UNSUPPORTED)
MATHML_CHAR(UpTeeArrow, 0x21A5, STRETCH_UNSUPPORTED)
MATHML_CHAR(DiacriticalTilde, 0x02DC, STRETCH_UNSUPPORTED)
MATHML_CHAR(Hacek, 0x02C7, STRETCH_UNSUPPORTED)
MATHML_CHAR(Hat, 0x0302, STRETCH_UNSUPPORTED)
MATHML_CHAR(OverBrace, 0xF612, STRETCH_UNSUPPORTED)
MATHML_CHAR(OverBracket, 0xF614, STRETCH_UNSUPPORTED)
MATHML_CHAR(OverParenthesis, 0xF610, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnderBar, 0x0332, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnderBrace, 0xF613, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnderBracket, 0xF615, STRETCH_UNSUPPORTED)
MATHML_CHAR(UnderParenthesis, 0xF611, STRETCH_UNSUPPORTED)
#endif
#undef STRETCH_UNSUPPORTED
#undef STRETCH_HORIZONTAL
#undef STRETCH_VERTICAL
#elif defined(WANT_CHAR_DATA) || defined(WANT_GLYPH_DATA)
#define _ , // dirty trick to make the macro handle a variable number of glyphs...
// Data for strecthy chars that are supported by the Symbol font ---------------------
// -----------------------------------------------------------------------------------
#if defined(WANT_SYMBOL_DATA)//[top/left][middle][bot/right][glue] [size0 ... size{N-1}]
MATHML_CHAR( 0, LeftParenthesis, 0xF8EB _ 0x0000 _ 0xF8ED _ 0xF8EC, 0x0028)
MATHML_CHAR( 6, RightParenthesis, 0xF8F6 _ 0x0000 _ 0xF8F8 _ 0xF8F7, 0x0029)
MATHML_CHAR(12, Integral, 0x2320 _ 0x0000 _ 0x2321 _ 0xF8F5, 0x222B)
MATHML_CHAR(18, LeftSquareBracket, 0xF8EE _ 0xF8EF _ 0xF8F0 _ 0xF8EF, 0x005B)
MATHML_CHAR(24, RightSquareBracket, 0xF8F9 _ 0xF8FA _ 0xF8FB _ 0xF8FA, 0x005D)
MATHML_CHAR(30, LeftCurlyBracket, 0xF8F1 _ 0xF8F2 _ 0xF8F3 _ 0xF8F4, 0x007B)
MATHML_CHAR(36, RightCurlyBracket, 0xF8FC _ 0xF8FD _ 0xF8FE _ 0xF8F4, 0x007D)
MATHML_CHAR(42, UpArrow, 0x2191 _ 0x0000 _ 0x0000 _ 0xF8E6, 0x2191)
MATHML_CHAR(48, DownArrow, 0x0000 _ 0x0000 _ 0x2193 _ 0xF8E6, 0x2193)
MATHML_CHAR(54, UpDownArrow, 0x2191 _ 0x0000 _ 0x2193 _ 0xF8E6, 0x2195)
MATHML_CHAR(60, LeftArrow, 0x2190 _ 0x0000 _ 0x0000 _ 0xF8E7, 0x2190)
MATHML_CHAR(66, RightArrow, 0x0000 _ 0x0000 _ 0x2192 _ 0xF8E7, 0x2192)
MATHML_CHAR(72, LeftRightArrow, 0x2190 _ 0x0000 _ 0x2192 _ 0xF8E7, 0x2194)
MATHML_CHAR(78, OverBar, 0x0000 _ 0x0000 _ 0x0000 _ 0x00AF, 0x00AF)
MATHML_CHAR(84, VerticalBar, 0x0000 _ 0x0000 _ 0x0000 _ 0x007C, 0x007C)
#endif // defined(WANT_SYMBOL_DATA)
// Data for strecthy chars that are supported by the MT Extra font -------------------
// -----------------------------------------------------------------------------------
#if defined(WANT_MTEXTRA_DATA)//[top/left][middle][bot/right][glue] [size0 ... size{N-1}]
MATHML_CHAR( 0, UnderCurlyBracket, 0xEC00 _ 0xEC01 _ 0xEC02 _ 0xEC03, 0xF613)
MATHML_CHAR( 6, OverCurlyBracket, 0xEC04 _ 0xEC05 _ 0xEC06 _ 0xEC03, 0xF612)
MATHML_CHAR(12, LeftArrowAccent, 0x20D6 _ 0x0000 _ 0x0000 _ 0xEB00, 0x20D6)
MATHML_CHAR(18, RightArrowAccent, 0x0000 _ 0x0000 _ 0x20D7 _ 0xEB00, 0x20D7)
MATHML_CHAR(24, LeftRightArrowAccent,0x20D6 _ 0x0000 _ 0x20D7 _ 0xEB00, 0x20E1)
MATHML_CHAR(30, LeftHarpoonAccent, 0x20D0 _ 0x0000 _ 0x0000 _ 0xEB00, 0x20D0)
MATHML_CHAR(36, RightHarpoonAccent, 0x0000 _ 0x0000 _ 0x20D1 _ 0xEB00, 0x20D1)
#endif // defined(WANT_MTEXTRA_DATA)
// Data for strecthy chars that are supported by TeX's CMSY font ---------------------
// -----------------------------------------------------------------------------------
#if defined(WANT_CMSY_DATA) //[top/left][middle][bot/right][glue] [size0 ... size{N-1}]
MATHML_CHAR( 0, DoubleLeftArrow, 0x21D0 _ 0x0000 _ 0x0000 _ '=', 0x21D0)
MATHML_CHAR( 6, DoubleRightArrow, 0x0000 _ 0x0000 _ 0x21D2 _ '=', 0x21D2)
MATHML_CHAR(12, DoubleLeftRightArrow,0x21D0 _ 0x0000 _ 0x21D2 _ '=', 0x21D4)
MATHML_CHAR(18, DoubleLongLeftArrow, 0x21D0 _ 0x0000 _ 0x0000 _ '=', 0xE200)
MATHML_CHAR(24, DoubleLongRightArrow,0x0000 _ 0x0000 _ 0x21D2 _ '=', 0xE204)
MATHML_CHAR(30, DoubleLongLeftRightArrow, 0x21D0 _ 0x0000 _ 0x21D2 _ '=', 0xE202)
#endif // defined(WANT_CMSY_DATA)
// Data for strecthy chars that are supported by TeX's CMEX font ---------------------
// -----------------------------------------------------------------------------------
#if defined(WANT_CMEX_DATA) // [top/left][middle][bot/right][glue] [size0 ... size{N-1}]
MATHML_CHAR( 0, LeftParenthesis, 0xE030 _ 0x0000 _ 0xE040 _ 0xE042, 0x0028 _ 0xE072 _ 0xE089 _ 0xE08B _ 0xE099)
MATHML_CHAR( 10, RightParenthesis, 0xE031 _ 0x0000 _ 0xE041 _ 0xE043, 0x0029 _ 0xE073 _ 0xE08A _ 0xE08C _ 0xE021)
MATHML_CHAR( 20, LeftSquareBracket, 0xE032 _ 0x0000 _ 0xE034 _ 0xE036, 0x005B _ 0xE074 _ 0xE08D _ 0xE05B _ 0xE022)
MATHML_CHAR( 30, RightSquareBracket, 0xE033 _ 0x0000 _ 0xE035 _ 0xE037, 0x005D _ 0xE075 _ 0xE08E _ 0xE05C _ 0xE023)
MATHML_CHAR( 40, LeftFloor, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x230A _ 0xE076 _ 0xE08F _ 0xE05D _ 0xE024)
MATHML_CHAR( 50, RightFloor, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x230B _ 0xE077 _ 0xE090 _ 0xE05E _ 0xE025)
MATHML_CHAR( 60, LeftCeiling, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2308 _ 0xE078 _ 0xE091 _ 0xE05F _ 0xE026)
MATHML_CHAR( 70, RightCeiling, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2309 _ 0xE079 _ 0xE092 _ 0xE060 _ 0xE027)
MATHML_CHAR( 80, LeftCurlyBracket, 0xE038 _ 0xE03C _ 0xE03A _ 0xE03E, 0x007B _ 0xE07A _ 0xE093 _ 0xE061 _ 0xE028)
MATHML_CHAR( 90, RightCurlyBracket, 0xE039 _ 0xE03D _ 0xE03B _ 0xE03E, 0x007D _ 0xE07B _ 0xE094 _ 0xE062 _ 0xE029)
MATHML_CHAR(100, LeftAngleBracket, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x3008 _ 0xE07C _ 0xE095 _ 0xE044 _ 0xE02A)
MATHML_CHAR(110, RightAngleBracket, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x3009 _ 0xE07D _ 0xE096 _ 0xE045 _ 0xE02B)
MATHML_CHAR(120, SquareUnion, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2294 _ 0xE046)
MATHML_CHAR(127, ContourIntegral, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x222E _ 0xE047)
MATHML_CHAR(134, CircleDot, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2299 _ 0xE048)
MATHML_CHAR(141, CirclePlus, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2249 _ 0xE04A)
MATHML_CHAR(148, CircleMultiply, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2297 _ 0xE04B)
MATHML_CHAR(155, Sum, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2211 _ 0xE04C)
MATHML_CHAR(162, Product, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x220F _ 0xE04D)
MATHML_CHAR(169, Slash, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, '/' _ 0xE02E _ 0xE097 _ 0xE080 _ 0xE02C)
MATHML_CHAR(179, Integral, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x222B _ 0xE04E)
MATHML_CHAR(186, Union, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x22C3 _ 0xE04F)
MATHML_CHAR(193, Intersection, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x22C2 _ 0xE050)
MATHML_CHAR(200, UnionPlus, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x228E _ 0xE051)
MATHML_CHAR(207, And, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2227 _ 0xE052)
MATHML_CHAR(214, Or, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2228 _ 0xE053)
MATHML_CHAR(221, Coproduct, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x2210 _ 0xE054)
MATHML_CHAR(228, Hat, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x0302 _ 0xE055 _ 0xE056 _ 0xE057)
MATHML_CHAR(237, Tilde, 0x0000 _ 0x0000 _ 0x0000 _ 0x0000, 0x223C _ 0xE058 _ 0xE059 _ 0xE05A)
MATHML_CHAR(246, Sqrt, 0xE069 _ 0x0000 _ 0xE067 _ 0xE068, 0x221A _ 0xE063 _ 0xE064 _ 0xE065 _ 0xE066)
MATHML_CHAR(256, UpArrow, 0xE06B _ 0x0000 _ 0x0000 _ 0xE03F, 0x2191)
MATHML_CHAR(262, DownArrow, 0x0000 _ 0x0000 _ 0xE06C _ 0xE03F, 0x2193)
MATHML_CHAR(268, UpDownArrow, 0xE06B _ 0x0000 _ 0xE06C _ 0xE03F, 0x2195)
MATHML_CHAR(274, DoubleUpArrow, 0xE071 _ 0x0000 _ 0x0000 _ 0xE06A, 0x21D1)
MATHML_CHAR(280, DoubleDownArrow, 0x0000 _ 0x0000 _ 0xE09A _ 0xE06A, 0x21D3)
MATHML_CHAR(286, DoubleUpDownArrow, 0xE071 _ 0x0000 _ 0xE09A _ 0xE06A, 0x21D5)
#endif // defined(WANT_CMEX_DATA)
#undef _
#endif // defined(WANT_CHAR_DATA) || defined(WANT_GLYPH_DATA)
#undef MATHML_CHAR
File diff suppressed because it is too large Load Diff
+86 -82
View File
@@ -68,10 +68,8 @@ class nsMathMLContainerFrame : public nsHTMLContainerFrame, public nsIMathMLFram
public:
// nsIMathMLFrame methods -- see documentation in nsIMathMLFrame.h
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_DECL_ISUPPORTS
NS_IMETHOD
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics);
@@ -89,8 +87,8 @@ public:
Stretch(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize,
nsStretchMetrics& aDesiredStretchSize);
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredStretchSize);
#if 0
NS_IMETHOD
GetDesiredStretchSize(nsIPresContext* aPresContext,
@@ -120,12 +118,14 @@ public:
NS_IMETHOD
UpdatePresentationData(PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle);
PRBool aDisplayStyle,
PRBool aCompressed);
NS_IMETHOD
UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle);
PRBool aDisplayStyle,
PRBool aCompressed);
// nsHTMLContainerFrame methods
@@ -164,6 +164,20 @@ public:
nsFramePaintLayer aWhichLayer);
#endif
// error handlers to report than an error (typically invalid markup)
// was encountered during reflow. By default the user will see the
// Unicode REPLACEMENT CHAR U+FFFD at the spot where the error was
// encountered.
virtual nsresult
ReflowError(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsHTMLReflowMetrics& aDesiredSize);
virtual nsresult
PaintError(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// helper function to reflow token elements
static nsresult
ReflowTokenFor(nsIFrame* aFrame,
@@ -194,45 +208,28 @@ public:
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
}
// helper function to reflow all children before placing them.
// With MathML, we have to reflow all children and use their desired size
// information in order to figure out how to lay them.
// aDirection = 0 means children will later be laid horizontally
// aDirection = 1 means children will later be laid vertically
NS_IMETHOD
ReflowChildren(PRInt32 aDirection,
nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// helper function to fire a Stretch command on all children,
// Note that if the container is embellished, the stretch is not fired
// on its embellished child. It is the responsibility of the parent
// of the embellished container to fire a stretch that is then passed
// onto the embellished child.
// If an embellished container doesn't have a parent that will fire
// a stretch, it will do it itself (see FinalizeReflow).
NS_IMETHOD
StretchChildren(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize);
// helper method to complete the post-reflow hook and ensure that embellished
// operators don't terminate their Reflow without receiving a Stretch command.
NS_IMETHOD
FinalizeReflow(PRInt32 aDirection,
nsIPresContext* aPresContext,
virtual nsresult
FinalizeReflow(nsIPresContext* aPresContext,
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
NS_IMETHOD
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
static void
ResolveMathMLCharStyle(nsIPresContext* aPresContext,
nsIContent* aContent,
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
@@ -245,12 +242,11 @@ public:
IsEmbellishOperator(nsIFrame* aFrame);
// helper methods for processing empty MathML frames (with whitespace only)
static PRBool
IsOnlyWhitespace(nsIFrame* aFrame);
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
@@ -263,8 +259,9 @@ public:
// helper to check if a content has an attribute. If content is nsnull or if
// the attribute is not there, check if the attribute is on the mstyle frame.
// @return NS_CONTENT_ATTR_HAS_VALUE --if attribute is there
// NS_CONTENT_ATTR_NOT_THERE --if attribute is not there
// @return NS_CONTENT_ATTR_HAS_VALUE --if attribute has non-empty value, attr="value"
// NS_CONTENT_ATTR_NO_VALUE --if attribute has empty value, attr=""
// NS_CONTENT_ATTR_NOT_THERE --if attribute is not there
static nsresult
GetAttribute(nsIContent* aContent,
nsIFrame* aMathMLmstyleFrame,
@@ -309,6 +306,16 @@ public:
GetSupDrop (fm, aSupDrop);
}
static void
GetSkewCorrectionFromChild (nsIPresContext* aPresContext,
nsIFrame* aChild,
nscoord& aSkewCorrection)
{
// default is 0
// individual classes should over-ride this method if necessary
aSkewCorrection = 0;
}
// 2 levels of subscript shifts
static void
GetSubScriptShifts (nsIFontMetrics *fm,
@@ -354,8 +361,8 @@ public:
static void
GetSubShifts (nsIFontMetrics *fm,
nscoord& aSubShift1,
nscoord& aSubShift2)
nscoord& aSubShift1,
nscoord& aSubShift2)
{
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
@@ -365,9 +372,9 @@ public:
static void
GetSupShifts (nsIFontMetrics *fm,
nscoord& aSupShift1,
nscoord& aSupShift2,
nscoord& aSupShift3)
nscoord& aSupShift1,
nscoord& aSupShift2,
nscoord& aSupShift3)
{
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
@@ -377,10 +384,10 @@ public:
}
static void
GetNumShifts (nsIFontMetrics *fm,
nscoord& numShift1,
nscoord& numShift2,
nscoord& numShift3)
GetNumeratorShifts (nsIFontMetrics *fm,
nscoord& numShift1,
nscoord& numShift2,
nscoord& numShift3)
{
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
@@ -390,9 +397,9 @@ public:
}
static void
GetDenShifts (nsIFontMetrics *fm,
nscoord& denShift1,
nscoord& denShift2)
GetDenominatorShifts (nsIFontMetrics *fm,
nscoord& denShift1,
nscoord& denShift2)
{
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
@@ -402,7 +409,7 @@ public:
static void
GetAxisHeight (nsIFontMetrics *fm,
nscoord& axisHeight)
nscoord& axisHeight)
{
fm->GetXHeight (axisHeight);
axisHeight = NSToCoordRound (250.000f/430.556f * axisHeight);
@@ -410,11 +417,11 @@ public:
static void
GetBigOpSpacings (nsIFontMetrics *fm,
nscoord& bigOpSpacing1,
nscoord& bigOpSpacing2,
nscoord& bigOpSpacing3,
nscoord& bigOpSpacing4,
nscoord& bigOpSpacing5)
nscoord& bigOpSpacing1,
nscoord& bigOpSpacing2,
nscoord& bigOpSpacing3,
nscoord& bigOpSpacing4,
nscoord& bigOpSpacing5)
{
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
@@ -425,34 +432,23 @@ public:
bigOpSpacing5 = NSToCoordRound (100.000f/430.556f * xHeight);
}
#if 0
NS_IMETHOD
GetItalicCorrection (nscoord& italicCorrection)
{
italicCorrection = mItalicCorrection;
return NS_OK;
}
NS_IMETHOD
SetItalicCorrection (nscoord italicCorrection)
{
mItalicCorrection = italicCorrection;
return NS_OK;
}
#endif
NS_IMETHOD
GetRuleThickness (nsIFontMetrics *fm, nscoord& ruleThickness)
static void
GetRuleThickness(nsIFontMetrics* fm,
nscoord& ruleThickness)
{
nscoord xHeight;
fm->GetXHeight (xHeight);
ruleThickness = NSToCoordRound (40.000f/430.556f * xHeight);
return NS_OK;
}
// the rule thickness is not accurately obtained using the x-height.
// Here is a slow GetRuleThickness() which obtains the rule
// thickness by actually measuring the overbar char U+00AF
static void
GetRuleThickness(nsIRenderingContext& aRenderingContext,
nsIFontMetrics* aFontMetrics,
nscoord& aRuleThickness);
protected:
// information about the presentation policy of the frame
@@ -488,6 +484,14 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
NS_IMETHOD
Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
#endif
protected:
nsMathMLWrapperFrame();
virtual ~nsMathMLWrapperFrame();
+2 -1
View File
@@ -28,7 +28,7 @@
// Factory methods for creating MathML objects
extern nsresult NS_NewMathMLmrowFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmiFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmnFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmtextFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmoFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmphantomFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmpaddedFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
@@ -44,6 +44,7 @@ extern nsresult NS_NewMathMLmoverFrame ( nsIPresShell* aPresShell, nsIFrame** aN
extern nsresult NS_NewMathMLmunderoverFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmmultiscriptsFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmstyleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmtableOuterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmtdFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmsqrtFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
extern nsresult NS_NewMathMLmrootFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
+10 -43
View File
@@ -233,7 +233,7 @@ nsMathMLmactionFrame::GetSelectedFrame()
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
if (mSelectedFrame) {
nsIMathMLFrame* aMathMLFrame = nsnull;
rv = mSelectedFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
rv = mSelectedFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
nsEmbellishData embellishData;
aMathMLFrame->GetEmbellishData(embellishData);
@@ -270,10 +270,10 @@ nsMathMLmactionFrame::SetInitialChildList(nsIPresContext* aPresContext,
// Return the selected frame ...
NS_IMETHODIMP
nsMathMLmactionFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsMathMLmactionFrame::GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame)
nsIFrame** aFrame)
{
nsIFrame* childFrame = GetSelectedFrame();
if (childFrame)
@@ -292,7 +292,7 @@ nsMathMLmactionFrame::Paint(nsIPresContext* aPresContext,
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
if (disp->mVisible && mRect.width && mRect.height) {
if (disp->IsVisible() && mRect.width && mRect.height) {
// Paint our background and border
PRIntn skipSides = GetSkipSides();
const nsStyleColor* color = (const nsStyleColor*)
@@ -317,42 +317,6 @@ nsMathMLmactionFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
}
// Only reflow the selected child ...
NS_IMETHODIMP
nsMathMLmactionFrame::ReflowChildren(PRInt32 aDirection,
nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
aStatus = NS_FRAME_COMPLETE;
nsIFrame* childFrame = GetSelectedFrame();
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
if (childFrame) {
// ask the child to compute its bounding metrics
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, 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));
aDesiredSize.width = childDesiredSize.width;
aDesiredSize.ascent = childDesiredSize.ascent;
aDesiredSize.descent = childDesiredSize.descent;
aDesiredSize.height = childDesiredSize.height;
}
return NS_OK;
}
// Only place the selected child ...
NS_IMETHODIMP
nsMathMLmactionFrame::Place(nsIPresContext* aPresContext,
@@ -360,7 +324,9 @@ nsMathMLmactionFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
aDesiredSize.width = aDesiredSize.height = 0;
aDesiredSize.ascent = aDesiredSize.descent = 0;
mBoundingMetrics.Clear();
nsIFrame* childFrame = GetSelectedFrame();
if (childFrame) {
GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics);
@@ -368,8 +334,9 @@ nsMathMLmactionFrame::Place(nsIPresContext* aPresContext,
FinishReflowChild(childFrame, aPresContext, aDesiredSize, 0, 0, 0);
}
mReference.x = 0;
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
mReference.y = aDesiredSize.ascent;
}
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
return NS_OK;
}
+3 -10
View File
@@ -57,10 +57,10 @@ public:
nsIFrame* aChildList);
NS_IMETHOD
GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint,
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
nsIFrame** aFrame);
NS_IMETHOD
Paint(nsIPresContext* aPresContext,
@@ -68,13 +68,6 @@ public:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD
ReflowChildren(PRInt32 aDirection,
nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
+318 -170
View File
@@ -77,11 +77,16 @@ nsMathMLmfencedFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mOpenChar = nsnull;
mCloseChar = nsnull;
mSeparatorsChar = nsnull;
mSeparatorsCount = 0;
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -97,7 +102,7 @@ nsMathMLmfencedFrame::SetInitialChildList(nsIPresContext* aPresContext,
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
if (NS_FAILED(rv)) return rv;
rv = ReCreateFencesAndSeparators();
rv = ReCreateFencesAndSeparators(aPresContext);
return rv;
}
@@ -116,7 +121,7 @@ nsMathMLmfencedFrame::RemoveFencesAndSeparators()
}
nsresult
nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
nsMathMLmfencedFrame::ReCreateFencesAndSeparators(nsIPresContext* aPresContext)
{
nsresult rv;
@@ -126,42 +131,56 @@ nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
//////////////
// see if the opening fence is there ...
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::open_, value)) {
rv = GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::open_, value);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
value.Trim(" ");
data = value;
}
else data = '('; // default as per the MathML REC
else if (NS_CONTENT_ATTR_NOT_THERE == rv)
data = '('; // default as per the MathML REC
else
data = "";
if (0 < data.Length()) {
mOpenChar = new nsMathMLChar;
if (!mOpenChar) return NS_ERROR_OUT_OF_MEMORY;
mOpenChar->SetData(data);
mOpenChar->SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar);
}
//////////////
// see if the closing fence is there ...
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::close_, value)) {
rv = GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::close_, value);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
value.Trim(" ");
data = value;
}
else data = ')'; // default as per the MathML REC
else if (NS_CONTENT_ATTR_NOT_THERE == rv)
data = ')'; // default as per the MathML REC
else
data = "";
if (0 < data.Length()) {
mCloseChar = new nsMathMLChar;
if (!mCloseChar) return NS_ERROR_OUT_OF_MEMORY;
mCloseChar->SetData(data);
mCloseChar->SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar);
}
//////////////
// see if separators are there ...
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::separators_, value)) {
rv = GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::separators_, value);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
value.Trim(" ");
data = value;
}
else data = ','; // default as per the MathML REC
else if (NS_CONTENT_ATTR_NOT_THERE == rv)
data = ','; // default as per the MathML REC
else
data = "";
mSeparatorsCount = data.Length();
if (0 < mSeparatorsCount) {
@@ -180,7 +199,8 @@ nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
nsAutoString sepChar;
for (PRInt32 i = 0; i < sepCount; i++) {
sepChar = (i < mSeparatorsCount) ? data[i] : data[mSeparatorsCount-1];
mSeparatorsChar[i].SetData(sepChar);
mSeparatorsChar[i].SetData(aPresContext, sepChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i]);
}
}
mSeparatorsCount = sepCount;
@@ -202,11 +222,14 @@ nsMathMLmfencedFrame::Paint(nsIPresContext* aPresContext,
aDirtyRect, aWhichLayer);
////////////
// paint fences and separators
if (NS_SUCCEEDED(rv) && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
if (mOpenChar) mOpenChar->Paint(aPresContext, aRenderingContext, mStyleContext);
if (mCloseChar) mCloseChar->Paint(aPresContext, aRenderingContext, mStyleContext);
if (NS_SUCCEEDED(rv)) {
if (mOpenChar) mOpenChar->Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
if (mCloseChar) mCloseChar->Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
for (PRInt32 i = 0; i < mSeparatorsCount; i++) {
mSeparatorsChar[i].Paint(aPresContext, aRenderingContext, mStyleContext);
mSeparatorsChar[i].Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
}
}
return rv;
@@ -218,172 +241,225 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
nsresult rv;
aDesiredSize.width = aDesiredSize.height = 0;
aDesiredSize.ascent = aDesiredSize.descent = 0;
/////////////
// Reflow children
// Asking each child to cache its bounding metrics
nsReflowStatus childStatus;
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
//////////////////
// Reflow Children
nsRect rect;
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
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);
ReflowEmptyChild(aPresContext, childFrame);
}
else {
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
childFrame, availSize);
rv = ReflowChild(childFrame, aPresContext,
childDesiredSize, childReflowState, childStatus);
rv = ReflowChild(childFrame, aPresContext, childDesiredSize,
childReflowState, childStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
if (NS_FAILED(rv)) {
return rv;
}
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. Before return, we should set the origins so as to overwrite
// what we are storing there now.
// 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));
aDesiredSize.width += childDesiredSize.width;
if (aDesiredSize.ascent < childDesiredSize.ascent) {
aDesiredSize.ascent = childDesiredSize.ascent;
}
if (aDesiredSize.descent < childDesiredSize.descent) {
aDesiredSize.descent = childDesiredSize.descent;
}
}
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
// get our bounding metrics using a tentative Place()
Place(aPresContext, *aReflowState.rendContext, PR_FALSE, aDesiredSize);
// What size should we use to stretch our stretchy children
// XXX tune this
nsBoundingMetrics containerSize = mBoundingMetrics;
/////////////
// Ask stretchy children to stretch themselves
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
nsStretchMetrics parentSize(aDesiredSize);
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
childFrame = mFrames.FirstChild();
while (childFrame) {
// retrieve the metrics that was stored at the previous pass
childFrame->GetRect(rect);
nsStretchMetrics childSize(rect.x, rect.y, rect.width, rect.height);
//////////
// Stretch ...
// Only directed at frames that implement the nsIMathMLFrame interface
nsIMathMLFrame* aMathMLFrame;
rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
aMathMLFrame->Stretch(aPresContext, renderingContext,
stretchDir, parentSize, childSize);
// store the updated metrics
childFrame->SetRect(aPresContext,
nsRect(childSize.descent, childSize.ascent,
childSize.width, childSize.height));
}
aDesiredSize.width += childSize.width;
if (aDesiredSize.ascent < childSize.ascent) {
aDesiredSize.ascent = childSize.ascent;
}
if (aDesiredSize.descent < childSize.descent) {
aDesiredSize.descent = childSize.descent;
}
childFrame->GetNextSibling(&childFrame);
}
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
//////////////////////////////////////////
// Prepare the opening fence, separators, and closing fence, and
// adjust the x-origin of children.
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
renderingContext.SetFont(font.mFont);
// grab some metrics that will help to adjust the placements
nsCOMPtr<nsIFontMetrics> fm;
nscoord fontAscent, fontDescent, em;
renderingContext.GetFontMetrics(*getter_AddRefs(fm));
fm->GetMaxAscent(fontAscent);
fm->GetMaxDescent(fontDescent);
em = NSToCoordRound(float(font.mFont.size));
parentSize = nsStretchMetrics(aDesiredSize);
nscoord dx = 0; // running x-origin of children ...
/////////////////
// opening fence ...
ReflowChar(aPresContext, renderingContext, mStyleContext, mOpenChar, NS_MATHML_OPERATOR_FORM_PREFIX,
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
/////////////////
// separators ...
PRInt32 i = 0;
nsRect rect;
childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
childFrame->GetRect(rect);
childFrame->MoveTo(aPresContext, dx, rect.y);
dx += rect.width;
if (i < mSeparatorsCount) {
ReflowChar(aPresContext, renderingContext, mStyleContext, &mSeparatorsChar[i], NS_MATHML_OPERATOR_FORM_INFIX,
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
i++;
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;
aMathMLFrame->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;
}
}
childFrame->GetNextSibling(&childFrame);
}
//////////////////////////////////////////
// Prepare the opening fence, separators, and closing fence, and
// adjust the origin of children.
PRInt32 i;
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
nscoord axisHeight, em;
GetAxisHeight(fm, axisHeight);
em = NSToCoordRound(float(font.mFont.size));
nscoord fontAscent, fontDescent;
fm->GetMaxAscent(fontAscent);
fm->GetMaxDescent(fontDescent);
// we need to center around the axis
nscoord delta = PR_MAX(containerSize.ascent - axisHeight,
containerSize.descent + axisHeight);
containerSize.ascent = delta + axisHeight;
containerSize.descent = delta - axisHeight;
/////////////////
// opening fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, mOpenChar,
NS_MATHML_OPERATOR_FORM_PREFIX, mPresentationData.scriptLevel,
fontAscent, fontDescent, axisHeight, em,
containerSize, aDesiredSize);
/////////////////
// separators ...
for (i = 0; i < mSeparatorsCount; i++) {
ReflowChar(aPresContext, *aReflowState.rendContext, &mSeparatorsChar[i],
NS_MATHML_OPERATOR_FORM_INFIX, mPresentationData.scriptLevel,
fontAscent, fontDescent, axisHeight, em,
containerSize, aDesiredSize);
}
/////////////////
// closing fence ...
ReflowChar(aPresContext, renderingContext, mStyleContext, mCloseChar, NS_MATHML_OPERATOR_FORM_POSTFIX,
mPresentationData.scriptLevel, fontAscent, fontDescent, em, parentSize, aDesiredSize, dx);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
ReflowChar(aPresContext, *aReflowState.rendContext, mCloseChar,
NS_MATHML_OPERATOR_FORM_POSTFIX, mPresentationData.scriptLevel,
fontAscent, fontDescent, axisHeight, em,
containerSize, aDesiredSize);
//////////////////
// Adjust the y-origin of each child.
// Adjust the origins of each child.
// and update our bounding metrics
i = 0;
nscoord dy, dx = 0;
nsBoundingMetrics bm;
PRBool firstTime = PR_TRUE;
mBoundingMetrics.Clear();
if (mOpenChar) {
mOpenChar->GetBoundingMetrics(bm);
mOpenChar->GetRect(rect);
dy = aDesiredSize.ascent - rect.y;
if (mOpenChar->GetEnum() == eMathMLChar_DONT_STRETCH)
dy += (fontAscent - bm.ascent);
mOpenChar->SetRect(nsRect(dx + rect.x, dy,
bm.width, rect.height));
dx += rect.width;
bm.descent = (bm.ascent + bm.descent) - rect.y;
bm.ascent = rect.y;
mBoundingMetrics = bm;
firstTime = PR_FALSE;
}
childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
childFrame->GetRect(rect);
// childFrame->MoveTo(aPresContext, rect.x, aDesiredSize.ascent - rect.y);
nsHTMLReflowMetrics childSize(nsnull);
childSize.width = rect.width;
childSize.height = rect.height;
FinishReflowChild(childFrame, aPresContext, childSize, rect.x, aDesiredSize.ascent - rect.y, 0);
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) {
mSeparatorsChar[i].GetBoundingMetrics(bm);
mSeparatorsChar[i].GetRect(rect);
dy = aDesiredSize.ascent - rect.y;
if (mSeparatorsChar[i].GetEnum() == eMathMLChar_DONT_STRETCH)
dy += (fontAscent - bm.ascent);
mSeparatorsChar[i].SetRect(nsRect(dx + rect.x, dy,
bm.width, rect.height));
dx += rect.width;
bm.descent = (bm.ascent + bm.descent) - rect.y;
bm.ascent = rect.y;
bm.leftBearing += rect.x;
bm.rightBearing += rect.x;
bm.width = rect.width;
mBoundingMetrics += bm;
}
i++;
}
childFrame->GetNextSibling(&childFrame);
}
if (mOpenChar) {
mOpenChar->GetRect(rect);
mOpenChar->SetRect(nsRect(rect.x, aDesiredSize.ascent - rect.y, rect.width, rect.height));
}
if (mCloseChar) {
mCloseChar->GetBoundingMetrics(bm);
mCloseChar->GetRect(rect);
mCloseChar->SetRect(nsRect(rect.x, aDesiredSize.ascent - rect.y, rect.width, rect.height));
}
for (i = 0; i < mSeparatorsCount; i++) {
mSeparatorsChar[i].GetRect(rect);
mSeparatorsChar[i].SetRect(nsRect(rect.x, aDesiredSize.ascent - rect.y, rect.width, rect.height));
dy = aDesiredSize.ascent - rect.y;
if (mCloseChar->GetEnum() == eMathMLChar_DONT_STRETCH)
dy += (fontAscent - bm.ascent);
mCloseChar->SetRect(nsRect(dx + rect.x, dy,
bm.width, rect.height));
bm.descent = (bm.ascent + bm.descent) - rect.y;
bm.ascent = rect.y;
bm.leftBearing += rect.x;
bm.rightBearing += rect.x;
bm.width = rect.width;
if (firstTime)
mBoundingMetrics = bm;
else
mBoundingMetrics += bm;
}
aDesiredSize.width = mBoundingMetrics.width;
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
if (aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
@@ -392,61 +468,133 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
nsresult
nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
nsMathMLChar* aMathMLChar,
nsOperatorFlags aForm,
PRInt32 aScriptLevel,
nscoord fontAscent,
nscoord fontDescent,
nscoord axisHeight,
nscoord em,
nsStretchMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize,
nscoord& aX)
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize)
{
if (aMathMLChar && 0 < aMathMLChar->Length()) {
nsStretchMetrics aCharSize(fontDescent, fontAscent, 0, fontDescent + fontAscent);
aRenderingContext.GetWidth(aMathMLChar->GetUnicode(),
PRUint32(aMathMLChar->Length()),
aCharSize.width);
// stretch the char to the appropriate height if it is not big enough.
nsBoundingMetrics charSize;
charSize.Clear(); // this will tell stretch that we don't know the default size
aMathMLChar->Stretch(aPresContext, aRenderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
aContainerSize, charSize);
if (eMathMLChar_DONT_STRETCH != aMathMLChar->GetEnum())
{
// has changed... so center the char around the axis
nscoord height = charSize.ascent + charSize.descent;
charSize.ascent = height/2 + axisHeight;
charSize.descent = height - charSize.ascent;
}
else {
charSize.ascent = fontAscent;
charSize.descent = fontDescent;
}
if (aDesiredSize.ascent < charSize.ascent)
aDesiredSize.ascent = charSize.ascent;
if (aDesiredSize.descent < charSize.descent)
aDesiredSize.descent = charSize.descent;
nsOperatorFlags aFlags;
float aLeftSpace = 0.0f;
float aRightSpace = 0.0f;
nsAutoString aData;
aMathMLChar->GetData(aData);
PRBool found = nsMathMLOperators::LookupOperator(aData, aForm,
&aFlags, &aLeftSpace, &aRightSpace);
if (found) {
// If we don't want extra space when we are a script
if (aScriptLevel > 0) {
aLeftSpace /= 2.0f;
aRightSpace /= 2.0f;
}
if (NS_MATHML_OPERATOR_IS_STRETCHY(aFlags)) {
// Stretch the operator to the appropriate height if it is not big enough.
aMathMLChar->Stretch(aPresContext, aRenderingContext, aStyleContext,
NS_STRETCH_DIRECTION_VERTICAL,
aContainerSize, aCharSize);
}
&aFlags, &aLeftSpace, &aRightSpace);
// If we don't want extra space when we are a script
if (found && aScriptLevel > 0) {
aLeftSpace /= 2.0f;
aRightSpace /= 2.0f;
}
else { // call an involutive Stretch() to properly initialize and prepare the char
aMathMLChar->Stretch(aPresContext, aRenderingContext, aStyleContext,
NS_STRETCH_DIRECTION_VERTICAL,
aCharSize, aCharSize);
}
if (aDesiredSize.ascent < aCharSize.ascent)
aDesiredSize.ascent = aCharSize.ascent;
if (aDesiredSize.descent < aCharSize.descent)
aDesiredSize.descent = aCharSize.descent;
// y-origin is used to store the ascent ...
aMathMLChar->SetRect(nsRect(aX + nscoord( aLeftSpace * em ),
aCharSize.ascent, aCharSize.width, aCharSize.height));
// account the spacing
aCharSize.width += nscoord( (aLeftSpace + aRightSpace) * em );
charSize.width += NSToCoordRound((aLeftSpace + aRightSpace) * em);
aDesiredSize.width += aCharSize.width;
aX += aCharSize.width;
// x-origin is used to store lspace ...
// y-origin is used to stored the ascent ...
aMathMLChar->SetRect(nsRect(NSToCoordRound(aLeftSpace * em),
charSize.ascent, charSize.width,
charSize.ascent + charSize.descent));
}
return NS_OK;
}
// ----------------------
// the Style System will use these to pass the proper style context to our MathMLChar
NS_IMETHODIMP
nsMathMLmfencedFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
{
NS_PRECONDITION(aStyleContext, "null OUT ptr");
PRInt32 openIndex = -1;
PRInt32 closeIndex = -1;
PRInt32 lastIndex = mSeparatorsCount-1;
if (mOpenChar) {
lastIndex++;
openIndex = lastIndex;
}
if (mCloseChar) {
lastIndex++;
closeIndex = lastIndex;
}
if (aIndex < 0 || aIndex > lastIndex) {
return NS_ERROR_INVALID_ARG;
}
*aStyleContext = nsnull;
if (aIndex < mSeparatorsCount) {
mSeparatorsChar[aIndex].GetStyleContext(aStyleContext);
}
else if (aIndex == openIndex) {
mOpenChar->GetStyleContext(aStyleContext);
}
else if (aIndex == closeIndex) {
mCloseChar->GetStyleContext(aStyleContext);
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmfencedFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
{
PRInt32 openIndex = -1;
PRInt32 closeIndex = -1;
PRInt32 lastIndex = mSeparatorsCount-1;
if (mOpenChar) {
lastIndex++;
openIndex = lastIndex;
}
if (mCloseChar) {
lastIndex++;
closeIndex = lastIndex;
}
if (aIndex < 0 || aIndex > lastIndex) {
return NS_ERROR_INVALID_ARG;
}
if (aIndex < mSeparatorsCount) {
mSeparatorsChar[aIndex].SetStyleContext(aStyleContext);
}
else if (aIndex == openIndex) {
mOpenChar->SetStyleContext(aStyleContext);
}
else if (aIndex == closeIndex) {
mCloseChar->SetStyleContext(aStyleContext);
}
return NS_OK;
}
+12 -6
View File
@@ -33,7 +33,14 @@
class nsMathMLmfencedFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
NS_IMETHOD
GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -73,16 +80,15 @@ protected:
static nsresult
ReflowChar(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIStyleContext* aStyleContext,
nsMathMLChar* aMathMLChar,
nsOperatorFlags aForm,
PRInt32 aScriptLevel,
nscoord fontAscent,
nscoord fontDescent,
nscoord axisHeight,
nscoord em,
nsStretchMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize,
nscoord& aX);
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredSize);
// clean up
void
@@ -90,7 +96,7 @@ protected:
// add fences and separators when all child frames are known
nsresult
ReCreateFencesAndSeparators();
ReCreateFencesAndSeparators(nsIPresContext* aPresContext);
};
#endif /* nsMathMLmfencedFrame_h___ */
+282 -125
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
@@ -43,6 +44,17 @@
// <mfrac> -- form a fraction from two subexpressions - implementation
//
// various fraction line thicknesses (multiplicative values of the default rule thickness)
#define THIN_FRACTION_LINE 0.5f
#define THIN_FRACTION_LINE_MINIMUM_PIXELS 1 // minimum of 1 pixel
#define MEDIUM_FRACTION_LINE 1.5f
#define MEDIUM_FRACTION_LINE_MINIMUM_PIXELS 2 // minimum of 2 pixels
#define THICK_FRACTION_LINE 2.0f
#define THICK_FRACTION_LINE_MINIMUM_PIXELS 4 // minimum of 4 pixels
nsresult
NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@@ -58,7 +70,8 @@ NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
nsMathMLmfracFrame::nsMathMLmfracFrame()
nsMathMLmfracFrame::nsMathMLmfracFrame() :
mLineRect()
{
}
@@ -80,52 +93,71 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
return rv;
}
nsAutoString value;
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nscoord
nsMathMLmfracFrame::CalcLineThickness(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsString& aThicknessAttribute,
nscoord onePixel,
nscoord aDefaultRuleThickness)
{
nscoord defaultThickness = aDefaultRuleThickness;
nscoord lineThickness = aDefaultRuleThickness;
nscoord minimumThickness = onePixel;
nscoord defaultThickness = onePixel * DEFAULT_FRACTION_LINE_THICKNESS;
mLineThickness = defaultThickness;
// see if the linethickness attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE ==
GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::linethickness_, value))
{
if (value == "thin")
mLineThickness = onePixel * THIN_FRACTION_LINE_THICKNESS;
else if (value == "medium")
mLineThickness = onePixel * MEDIUM_FRACTION_LINE_THICKNESS;
else if (value == "thick")
mLineThickness = onePixel * THICK_FRACTION_LINE_THICKNESS;
if (0 < aThicknessAttribute.Length()) {
if (aThicknessAttribute.Equals("thin")) {
lineThickness = NSToCoordFloor(defaultThickness * THIN_FRACTION_LINE);
minimumThickness = onePixel * THIN_FRACTION_LINE_MINIMUM_PIXELS;
// should visually decrease by at least one pixel, if default is not a pixel
if (defaultThickness > onePixel && lineThickness > defaultThickness - onePixel)
lineThickness = defaultThickness - onePixel;
}
else if (aThicknessAttribute.Equals("medium")) {
lineThickness = NSToCoordRound(defaultThickness * MEDIUM_FRACTION_LINE);
minimumThickness = onePixel * MEDIUM_FRACTION_LINE_MINIMUM_PIXELS;
// should visually increase by at least one pixel
if (lineThickness < defaultThickness + onePixel)
lineThickness = defaultThickness + onePixel;
}
else if (aThicknessAttribute.Equals("thick")) {
lineThickness = NSToCoordCeil(defaultThickness * THICK_FRACTION_LINE);
minimumThickness = onePixel * THICK_FRACTION_LINE_MINIMUM_PIXELS;
// should visually increase by at least two pixels
if (lineThickness < defaultThickness + 2*onePixel)
lineThickness = defaultThickness + 2*onePixel;
}
else { // see if it is a plain number, or a percentage, or a h/v-unit like 1ex, 2px, 1em
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue)) {
if (ParseNumericValue(aThicknessAttribute, cssValue)) {
nsCSSUnit unit = cssValue.GetUnit();
if (eCSSUnit_Number == unit)
mLineThickness = nscoord(float(defaultThickness) * cssValue.GetFloatValue());
lineThickness = nscoord(float(defaultThickness) * cssValue.GetFloatValue());
else if (eCSSUnit_Percent == unit)
mLineThickness = nscoord(float(defaultThickness) * cssValue.GetPercentValue());
lineThickness = nscoord(float(defaultThickness) * cssValue.GetPercentValue());
else if (eCSSUnit_Null != unit)
mLineThickness = CalcLength(aPresContext, mStyleContext, cssValue);
lineThickness = CalcLength(aPresContext, aStyleContext, cssValue);
}
#ifdef NS_DEBUG
#if 0
else {
char str[50];
value.ToCString(str, 50);
aThicknessAttribute.ToCString(str, 50);
printf("Invalid attribute linethickness=%s\n", str);
}
#endif
}
}
mLineOrigin.x = 0;
mLineOrigin.y = 0;
// use minimum if the lineThickness is a non-zero value less than minimun
if (0 != lineThickness && lineThickness < minimumThickness)
lineThickness = minimumThickness;
return rv;
return lineThickness;
}
NS_IMETHODIMP
@@ -134,21 +166,11 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
nsresult rv = NS_OK;
/////////////
// paint the numerator and denominator
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) {
return rv;
}
////////////
// paint the fraction line
if (NS_SUCCEEDED(rv) && 0 < mLineThickness) {
if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) &&
!NS_MATHML_HAS_ERROR(mPresentationData.flags) &&
!mLineRect.IsEmpty()) {
/*
// line looking like <hr noshade>
const nsStyleColor* color;
@@ -158,115 +180,250 @@ nsMathMLmfracFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.SetColor(colors[0]);
*/
// solid line with the current text color
const nsStyleColor* color =
(const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetColor(color->mColor);
nsStyleColor color;
mStyleContext->GetStyle(eStyleStruct_Color, color);
aRenderingContext.SetColor(color.mColor);
// draw the line
aRenderingContext.FillRect(mLineOrigin.x, mLineOrigin.y, mRect.width, mLineThickness);
// draw the line, there is 1 pixel padding at either end
aRenderingContext.FillRect(mLineRect.x, mLineRect.y,
mLineRect.width, mLineRect.height);
}
return rv;
/////////////
// paint the numerator and denominator
return nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
}
// over-ride the default method to update presentation parameters
// Rule 15a, App. G, TeXbook
NS_IMETHODIMP
nsMathMLmfracFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle,
PRBool aCompressed)
{
PRBool displayStyle = NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags);
PRBool compressed = NS_MATHML_IS_COMPRESSED(mPresentationData.flags);
nsIFrame* childFrame = mFrames.FirstChild();
while (nsnull != childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
nsIMathMLFrame* aMathMLFrame = nsnull;
nsresult rv = childFrame->QueryInterface
(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame);
if (NS_SUCCEEDED(rv) && nsnull != aMathMLFrame) {
if (0 == aIndex++) {
// update numerator
if (displayStyle) {
// switch to text with current compression
aMathMLFrame->UpdatePresentationData(0, PR_FALSE, compressed);
}
else {
// apply the default rule
aMathMLFrame->UpdatePresentationData
(aScriptLevelIncrement, aDisplayStyle, aCompressed);
}
}
else {
// update denominator
if (displayStyle) {
// switch to text with compression
aMathMLFrame->UpdatePresentationData(0, PR_FALSE, PR_TRUE);
}
else {
// apply the default rule
aMathMLFrame->UpdatePresentationData
(aScriptLevelIncrement, aDisplayStyle, aCompressed);
}
}
// propagate down the subtrees
aMathMLFrame->UpdatePresentationDataFromChildAt
(0, aScriptLevelIncrement, aDisplayStyle, aCompressed);
}
}
childFrame->GetNextSibling(&childFrame);
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsMathMLmfracFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nsresult rv = NS_OK;
nsReflowStatus childStatus;
// 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);
//////////////////
// Reflow Children
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmNum, bmDen;
nsHTMLReflowMetrics sizeNum (nsnull);
nsHTMLReflowMetrics sizeDen (nsnull);
nsIFrame* frameNum = nsnull;
nsIFrame* frameDen = nsnull;
nscoord count = 0;
nsRect rect[2];
nsIFrame* child[2];
nsIFrame* childFrame = mFrames.FirstChild();
while (nsnull != childFrame)
{
//////////////
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
if (IsOnlyWhitespace(childFrame)) {
ReflowEmptyChild(aPresContext, childFrame);
}
else if (2 > count) {
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;
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);
}
child[count] = childFrame;
rect[count].width = childDesiredSize.width;
rect[count].height = childDesiredSize.height;
count++;
}
// else { invalid markup... }
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
#ifdef NS_DEBUG
if (2 != count) printf("mfrac: invalid markup");
#endif
if ((2 != count) || !frameNum || !frameDen) {
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
//////////////////
// Get shifts
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
aRenderingContext.SetFont(font.mFont);
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
nscoord defaultRuleThickness;
GetRuleThickness(aRenderingContext, fm, defaultRuleThickness);
// see if the linethickness attribute is there
nsAutoString value;
GetAttribute(mContent, mPresentationData.mstyle, nsMathMLAtoms::linethickness_, value);
mLineRect.height = CalcLineThickness(aPresContext, mStyleContext,
value, onePixel, defaultRuleThickness);
nscoord numShift = 0;
nscoord denShift = 0;
// Rule 15b, App. G, TeXbook
nscoord numShift1, numShift2, numShift3;
nscoord denShift1, denShift2;
GetNumeratorShifts(fm, numShift1, numShift2, numShift3);
GetDenominatorShifts(fm, denShift1, denShift2);
if (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// C > T
numShift = numShift1;
denShift = denShift1;
}
else {
numShift = (0 < mLineRect.height) ? numShift2 : numShift3;
denShift = denShift2;
}
nscoord minClearance = 0;
nscoord actualClearance = 0;
nscoord axisHeight = 0;
nscoord actualRuleThickness = (0 < mLineRect.height) ? mLineRect.height : 0;
if (0 == actualRuleThickness) {
// Rule 15c, App. G, TeXbook
// min clearance between numerator and denominator
minClearance = (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ?
7 * defaultRuleThickness : 3 * defaultRuleThickness;
actualClearance =
(numShift - bmNum.descent) - (bmDen.ascent - denShift);
// actualClearance should be >= minClearance
if (actualClearance < minClearance) {
nscoord halfGap = (minClearance - actualClearance)/2;
numShift += halfGap;
denShift += halfGap;
}
}
else {
// Rule 15d, App. G, TeXbook
GetAxisHeight (fm, axisHeight);
// min clearance between numerator or denominator and middle of bar
// TeX has a different interpretation of the thickeness.
// Try $a \above10pt b$ to see. Here is what TeX does:
// minClearance = (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ?
// 3 * actualRuleThickness : actualRuleThickness;
// we don't follow TeX here, we use a modified version of Rule 15c in which
// one defaultRuleThickness is replaced by one actualRuleThickness
minClearance = actualRuleThickness +
(NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) ?
6 * defaultRuleThickness : 2 * defaultRuleThickness;
// adjust numShift to maintain minClearance if needed
actualClearance =
(numShift - bmNum.descent) - (axisHeight + actualRuleThickness/2);
if (actualClearance < minClearance) {
numShift += (minClearance - actualClearance);
}
// adjust denShift to maintain minClearance if needed
actualClearance =
(axisHeight - actualRuleThickness/2) - (bmDen.ascent - denShift);
if (actualClearance < minClearance) {
denShift += (minClearance - actualClearance);
}
}
//////////////////
// Place Children
// Get the <strike> line and center the fraction bar with the <strike> line.
nscoord strikeOffset, strikeThickness;
nsCOMPtr<nsIFontMetrics> fm;
const nsStyleFont* aFont =
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
aPresContext->GetMetricsFor(aFont->mFont, getter_AddRefs(fm));
fm->GetStrikeout(strikeOffset, strikeThickness);
// there is 1 pixel padding at either end of the fraction
nscoord width = 2*onePixel + PR_MAX(bmNum.width, bmDen.width);
nscoord dxNum = (width - sizeNum.width)/2;
nscoord dxDen = (width - sizeDen.width)/2;
// Take care of mLineThickness
float p2t;
nscoord halfThickspace;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
mBoundingMetrics.rightBearing =
PR_MAX(dxNum + bmNum.rightBearing, dxDen + bmDen.rightBearing);
if (mBoundingMetrics.rightBearing < width - onePixel)
mBoundingMetrics.rightBearing = width - onePixel;
mBoundingMetrics.leftBearing =
PR_MIN(dxNum + bmNum.leftBearing, dxDen + bmDen.leftBearing);
if (mBoundingMetrics.leftBearing > onePixel)
mBoundingMetrics.leftBearing = onePixel;
mBoundingMetrics.ascent = bmNum.ascent + numShift;
mBoundingMetrics.descent = bmDen.descent + denShift;
mBoundingMetrics.width = width;
// distance from the middle of the axis
halfThickspace = (mLineThickness > onePixel)? mLineThickness/2 : 0;
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
aDesiredSize.ascent = rect[0].height + strikeOffset + halfThickspace;
aDesiredSize.descent = rect[1].height - strikeOffset + halfThickspace;
aDesiredSize.ascent = sizeNum.ascent + numShift;
aDesiredSize.descent = sizeDen.descent + denShift;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
rect[0].x = (aDesiredSize.width - rect[0].width) / 2; // center w.r.t largest width
rect[1].x = (aDesiredSize.width - rect[1].width) / 2;
rect[0].y = 0;
rect[1].y = aDesiredSize.height - rect[1].height;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
// child[0]->SetRect(aPresContext, rect[0]);
// child[1]->SetRect(aPresContext, rect[1]);
nsHTMLReflowMetrics childSize(nsnull);
for (PRInt32 i=0; i<count; i++) {
childSize.width = rect[i].width;
childSize.height = rect[i].height;
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
if (aPlaceOrigin) {
nscoord dy;
// place numerator
dy = 0;
FinishReflowChild(frameNum, aPresContext, sizeNum, dxNum, dy, 0);
// place denominator
dy = aDesiredSize.height - sizeDen.height;
FinishReflowChild(frameDen, aPresContext, sizeDen, dxDen, dy, 0);
// place the fraction bar - dy is top of bar
dy = aDesiredSize.ascent - (axisHeight + actualRuleThickness/2);
mLineRect.SetRect(onePixel, dy, width - 2*onePixel, actualRuleThickness);
}
SetLineOrigin(nsPoint(0,rect[0].height)); // position the fraction bar
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
// XXX Fix me!
mBoundingMetrics.ascent = aDesiredSize.ascent;
mBoundingMetrics.descent = aDesiredSize.descent;
mBoundingMetrics.width = aDesiredSize.width;
return NS_OK;
}
+23 -20
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmfracFrame_h___
@@ -66,14 +67,6 @@ environment, but can be set explicitly only on the <mstyle>
element.
*/
// default fraction line thickness in pixels
#define DEFAULT_FRACTION_LINE_THICKNESS 1
#define THIN_FRACTION_LINE_THICKNESS 1
#define MEDIUM_FRACTION_LINE_THICKNESS 2
#define THICK_FRACTION_LINE_THICKNESS 4
class nsMathMLmfracFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
@@ -85,11 +78,18 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
#if 0
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
#endif
NS_IMETHOD
Paint(nsIPresContext* aPresContext,
@@ -97,6 +97,12 @@ public:
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD
UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle,
PRBool aCompressed);
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
@@ -104,20 +110,18 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(0, 1, PR_FALSE);
UpdatePresentationDataFromChildAt(0, 1, PR_FALSE, PR_TRUE);
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
void
SetLineThickness(const nscoord aLineThickness) {
mLineThickness = aLineThickness;
}
void
SetLineOrigin(const nsPoint& aOrigin) {
mLineOrigin = aOrigin;
}
// helper to translate the thickness attribute into a usable form
static nscoord
CalcLineThickness(nsIPresContext* aPresContext,
nsIStyleContext* aStyleContext,
nsString& aThicknessAttribute,
nscoord onePixel,
nscoord aDefaultRuleThickness);
protected:
nsMathMLmfracFrame();
@@ -125,8 +129,7 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
nsPoint mLineOrigin;
nscoord mLineThickness;
nsRect mLineRect;
};
#endif /* nsMathMLmfracFrame_h___ */
+2 -2
View File
@@ -131,13 +131,13 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == mstyleContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::fontstyle_, fontStyle))
{
if (fontStyle == "italic")
if (fontStyle.Equals("italic"))
return rv;
}
}
// Get a pseudo style context for the appropriate style font
fontStyle = ":-moz-math-font-style-normal";
fontStyle.Assign(":-moz-math-font-style-normal");
nsCOMPtr<nsIAtom> fontAtom(getter_AddRefs(NS_NewAtom(fontStyle)));
nsCOMPtr<nsIStyleContext> newStyleContext;
aPresContext->ResolvePseudoStyleContextFor(mContent, fontAtom, mStyleContext,
@@ -124,16 +124,26 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
////////////////////////////////////////
// get x-height (an ex)
#if 0
nscoord xHeight = 0;
nsCOMPtr<nsIFontMetrics> fm;
const nsStyleFont* aFont =
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
fm->GetXHeight (xHeight);
#endif
nscoord aRuleSize = 0;
// XXX need to do update this ...
GetRuleThickness (fm, aRuleSize);
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
aRenderingContext.SetFont(font.mFont);
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
nscoord xHeight;
fm->GetXHeight (xHeight);
nscoord aRuleSize;
GetRuleThickness (aRenderingContext, fm, aRuleSize);
/////////////////////////////////////
// first the shift for the subscript
@@ -212,9 +222,9 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics subScriptSize (nsnull);
nsHTMLReflowMetrics supScriptSize (nsnull);
nsIFrame* baseFrame;
nsIFrame* subScriptFrame;
nsIFrame* supScriptFrame;
nsIFrame* baseFrame = nsnull;
nsIFrame* subScriptFrame = nsnull;
nsIFrame* supScriptFrame = nsnull;
PRBool firstPrescriptsPair = PR_FALSE;
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
@@ -311,7 +321,10 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
rightBearing = PR_MAX(rightBearing, bmSupScript.rightBearing + mScriptSpace);
}
NS_ASSERTION((isSubScriptPresent || isSupScriptPresent),"mmultiscripts : both sup/subscripts are absent");
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;
@@ -366,6 +379,11 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
rv = aChildFrame->GetNextSibling(&aChildFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
// 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
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
// we left out the width of prescripts, so ...
mBoundingMetrics.rightBearing += prescriptsWidth;
@@ -386,7 +404,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
aDesiredSize.width = mBoundingMetrics.width;
mReference.x = 0;
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
mReference.y = aDesiredSize.ascent;
//////////////////
// Place Children
@@ -405,7 +423,6 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
if (nsnull == aChildFrame) { // end of prescripts,
// place the base ...
aChildFrame = baseFrame;
// dy = mBoundingMetrics.ascent - bmBase.ascent;
dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild (baseFrame, aPresContext, baseSize, dx, dy, 0);
dx += baseSize.width + bmBase.supItalicCorrection;
@@ -433,14 +450,7 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
supScriptSize.width = aRect.width;
supScriptSize.height = aRect.height;
// XXX should we really center the boxes
// XXX i'm leaving it as left-justified
// XXX which is consistent with what's done for <msubsup>
// reverting to center. It looks much nicer and adds a bit
// of variety to the engine. At least we have two functions
// doing two different things.
// center w.r.t. largest width
width = PR_MAX(subScriptSize.width, supScriptSize.width);
dy = aDesiredSize.ascent -
@@ -55,7 +55,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE, PR_FALSE);
// switch the style of the postscripts and prescripts
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
@@ -1,99 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* 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 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):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#include "nsCOMPtr.h"
#include "nsHTMLParts.h"
#include "nsIHTMLContent.h"
#include "nsFrame.h"
#include "nsLineLayout.h"
#include "nsHTMLIIDs.h"
#include "nsIPresContext.h"
#include "nsHTMLAtoms.h"
#include "nsUnitConversion.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsStyleChangeList.h"
#include "nsINameSpaceManager.h"
#include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#include "nsStyleUtil.h"
#include "nsMathMLmnFrame.h"
//
// <mn> -- number - implementation
//
nsresult
NS_NewMathMLmnFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsMathMLmnFrame* it = new (aPresShell) nsMathMLmnFrame;
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
return NS_OK;
}
nsMathMLmnFrame::nsMathMLmnFrame()
{
}
nsMathMLmnFrame::~nsMathMLmnFrame()
{
}
NS_IMETHODIMP
nsMathMLmnFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = NS_OK;
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
return rv;
}
NS_IMETHODIMP
nsMathMLmnFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
return ReflowTokenFor(this, aPresContext, aDesiredSize,
aReflowState, aStatus);
}
NS_IMETHODIMP
nsMathMLmnFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
return PlaceTokenFor(this, aPresContext, aRenderingContext,
aPlaceOrigin, aDesiredSize);
}
+241 -157
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
@@ -84,6 +85,10 @@
// the baseline) are identifiers displayed in a non-slanted font (i.e., under
// the suggested rules, when both operands are multi-character identifiers).
// additional style context to be used by our MathMLChar.
#define NS_MATHML_CHAR_STYLE_CONTEXT_INDEX 0
nsresult
NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@@ -115,19 +120,20 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
{
nsresult rv = NS_OK;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
rv = mMathMLChar.Paint(aPresContext,
aRenderingContext,
mStyleContext);
if (NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
rv = mMathMLChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
aRenderingContext.SetColor(NS_RGB(0,0,255));
aRenderingContext.SetColor(NS_RGB(0,255,255));
nscoord x = mReference.x + mBoundingMetrics.leftBearing;
nscoord y = mReference.y;
nscoord y = mReference.y - mBoundingMetrics.ascent;
//nsRect rect;
//mMathMLChar.GetRect(rect);
//y = rect.y;
nscoord w = mBoundingMetrics.rightBearing - mBoundingMetrics.leftBearing;
nscoord h = mBoundingMetrics.ascent + mBoundingMetrics.descent;
aRenderingContext.DrawRect(x,y,w,h);
@@ -135,10 +141,8 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
#endif
}
else { // let the base class worry about the painting
rv = nsMathMLContainerFrame::Paint(aPresContext,
aRenderingContext,
aDirtyRect,
aWhichLayer);
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
}
return rv;
}
@@ -160,20 +164,6 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
mMinSize = float(NS_UNCONSTRAINEDSIZE);
mMaxSize = float(NS_UNCONSTRAINEDSIZE);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
NS_IMETHODIMP
nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// get the text that we enclose. // XXX aData.CompressWhitespace() ?
nsAutoString aData;
// PRInt32 aLength = 0;
@@ -197,7 +187,22 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
}
}
// cache the operator
mMathMLChar.SetData(aData);
mMathMLChar.SetData(aPresContext, aData);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mMathMLChar);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
NS_IMETHODIMP
nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// fill our mEmbellishData member variable
nsIFrame* firstChild = mFrames.FirstChild();
@@ -216,7 +221,7 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
// 2) do we have movablelimits="true"
// they need the extra information to decide how to treat their scripts/limits
// (note: <mover>, <munder>, or <munderover> need not necessarily be our
// (note: <mover>, <munder>, or <munderover> need not necessarily be our
// direct parent -- case of embellished operators)
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; // default is false
@@ -227,53 +232,56 @@ nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
PRBool movablelimitsAttribute = PR_FALSE;
// see if the accent attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::accent_, value))
{
accentAttribute = PR_TRUE;
if (value == "true")
if (value.Equals("true"))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
}
}
// see if the movablelimits attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::movablelimits_, value))
{
movablelimitsAttribute = PR_TRUE;
if (value == "true")
if (value.Equals("true"))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
}
if (!accentAttribute || !movablelimitsAttribute) {
// If we reach here, it means one or both attributes are missing
// If we reach here, it means one or both attributes are missing.
// Unfortunately, we have to lookup the dictionary to see who
// we are, i.e., two lookups, counting also the one in Stretch()!
// The lookup in Stretch() assumes that the surrounding frame tree
// is already fully constructed, which is not true at this stage.
// all accent="true" in the dictionary have form="postfix"
nsOperatorFlags aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
// 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",
// 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;
}
@@ -317,7 +325,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
aParent->GetParent(&aParent);
} while (IsEmbellishOperator(aParent));
// flag if we have an embellished ancestor
if (embellishAncestor != this)
if (embellishAncestor != this)
{
hasEmbellishAncestor = PR_TRUE;
}
@@ -376,13 +384,13 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
PRBool found = nsMathMLOperators::LookupOperator(aData, aForm,
&mFlags, &mLeftSpace, &mRightSpace);
// All operators are symmetric. But this symmetric flag is *not* stored in
// the operator dictionary and operators are treated as non-symmetric...
// Uncomment the folllowing line to change this behavior.
//mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
// All operators are symmetric. But this symmetric flag is *not* stored in
// the Operator Dictionary ... Add it now
mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
// If the operator exists in the dictionary and is stretchy, it is mutable
if (found && NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
if (found && NS_MATHML_OPERATOR_IS_STRETCHY(mFlags))
{
mFlags |= NS_MATHML_OPERATOR_MUTABLE;
}
@@ -437,12 +445,12 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
}
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::symmetric_, value)) {
if (value == ktrue) mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
nsMathMLAtoms::symmetric_, value)) {
if (value == kfalse) mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
else if (value == ktrue) mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
}
// If we are an accent without explicit lspace="." or rspace=".",
// If we are an accent without explicit lspace="." or rspace=".",
// ignore our default left/right space
// Get the value of 'em'
@@ -454,8 +462,13 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::lspace_, value)) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
mLeftSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
if (ParseNumericValue(value, cssValue))
{
if ((eCSSUnit_Number == cssValue.GetUnit()) &&
(0.0f == cssValue.GetFloatValue()))
mLeftSpace = 0.0f;
else if (cssValue.IsLengthUnit())
mLeftSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
}
}
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
@@ -466,8 +479,13 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::rspace_, value)) {
nsCSSValue cssValue;
if (ParseNumericValue(value, cssValue) && cssValue.IsLengthUnit()) {
mRightSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
if (ParseNumericValue(value, cssValue))
{
if ((eCSSUnit_Number == cssValue.GetUnit()) &&
(0.0f == cssValue.GetFloatValue()))
mRightSpace = 0.0f;
else if (cssValue.IsLengthUnit())
mRightSpace = float(CalcLength(aPresContext, mStyleContext, cssValue)) / em;
}
}
else if (NS_MATHML_EMBELLISH_IS_ACCENT(mEmbellishData.flags)) {
@@ -508,8 +526,12 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
}
}
// If the stretchy attribute has been disabled, the operator is not mutable
if (!found || !NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
// If the stretchy or largeop attributes have been disabled,
// the operator is not mutable
if (!found ||
(!NS_MATHML_OPERATOR_IS_STRETCHY(mFlags) &&
!NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)))
{
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
}
}
@@ -521,8 +543,8 @@ NS_IMETHODIMP
nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize,
nsStretchMetrics& aDesiredStretchSize)
nsBoundingMetrics& aContainerSize,
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");
@@ -530,141 +552,167 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
}
mEmbellishData.flags |= NS_MATHML_STRETCH_DONE;
// if (0 == mFlags) { // first time...
InitData(aPresContext);
// }
InitData(aPresContext);
// get the axis height;
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
nscoord fontAscent, fontDescent, axisHeight;
GetAxisHeight(fm, axisHeight);
fm->GetMaxAscent(fontAscent);
fm->GetMaxDescent(fontDescent);
/////////
// See if it is okay to stretch
// Operators that exist in the dictionary are handled by the MathMLChar
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
if (!NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
// Place our children
Place(aPresContext, aRenderingContext, PR_TRUE, aDesiredStretchSize);
}
else {
// The rendering will be handled by our MathML char
nsStretchMetrics initialSize(aDesiredStretchSize);
nsStretchMetrics container(aContainerSize);
nsBoundingMetrics charSize;
nsBoundingMetrics initialSize = aDesiredStretchSize.mBoundingMetrics;
nsBoundingMetrics container = initialSize;
// little adjustments if the operator is symmetric
// see if it is okay to stretch
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags) &&
((aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) ||
(aStretchDirection == NS_STRETCH_DIRECTION_DEFAULT &&
mMathMLChar.GetStretchDirection() == NS_STRETCH_DIRECTION_VERTICAL)))
{
container.ascent = PR_MAX(container.ascent, container.descent);
container.descent = container.ascent;
container.height = container.ascent + container.descent;
container = aContainerSize;
// get ready in case we encounter user-desired min-max
initialSize.ascent = PR_MAX(initialSize.ascent, initialSize.descent);
initialSize.descent = initialSize.ascent;
initialSize.height = initialSize.ascent + initialSize.descent;
}
// some adjustments if the operator is symmetric and vertical
// check for user-desired min-max size
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags) &&
((aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) ||
(aStretchDirection == NS_STRETCH_DIRECTION_DEFAULT &&
mMathMLChar.GetStretchDirection() == NS_STRETCH_DIRECTION_VERTICAL)))
{
// we need to center about the axis
nscoord delta = PR_MAX(container.ascent - axisHeight,
container.descent + axisHeight);
container.ascent = delta + axisHeight;
container.descent = delta - axisHeight;
if (mMaxSize != float(NS_UNCONSTRAINEDSIZE) && mMaxSize > 0.0f) {
// if we are here, there is a user defined maxsize ...
if (NS_MATHML_OPERATOR_MAXSIZE_IS_EXPLICIT(mFlags)) {
// there is an explicit value like maxsize="20pt"
// try to maintain the aspect ratio of the char
float aspect = mMaxSize / float(initialSize.ascent + initialSize.descent);
container.ascent =
PR_MIN(container.ascent, nscoord(initialSize.ascent * aspect));
container.descent =
PR_MIN(container.descent, nscoord(initialSize.descent * aspect));
// below we use a type cast instead of a conversion to avoid a VC++ bug
// see http://support.microsoft.com/support/kb/articles/Q115/7/05.ASP
container.width =
PR_MIN(container.width, (nscoord)mMaxSize);
// get ready in case we encounter user-desired min-max size
delta = PR_MAX(initialSize.ascent - axisHeight,
initialSize.descent + axisHeight);
initialSize.ascent = delta + axisHeight;
initialSize.descent = delta - axisHeight;
}
else { // multiplicative value
container.ascent =
PR_MIN(container.ascent, nscoord(initialSize.ascent * mMaxSize));
container.descent =
PR_MIN(container.descent, nscoord(initialSize.descent * mMaxSize));
container.width =
PR_MIN(container.width, nscoord(initialSize.width * mMaxSize));
// check for user-desired min-max size
if (mMaxSize != float(NS_UNCONSTRAINEDSIZE) && mMaxSize > 0.0f) {
// if we are here, there is a user defined maxsize ...
if (NS_MATHML_OPERATOR_MAXSIZE_IS_EXPLICIT(mFlags)) {
// there is an explicit value like maxsize="20pt"
// try to maintain the aspect ratio of the char
float aspect = mMaxSize / float(initialSize.ascent + initialSize.descent);
container.ascent =
PR_MIN(container.ascent, nscoord(initialSize.ascent * aspect));
container.descent =
PR_MIN(container.descent, nscoord(initialSize.descent * aspect));
// below we use a type cast instead of a conversion to avoid a VC++ bug
// see http://support.microsoft.com/support/kb/articles/Q115/7/05.ASP
container.width =
PR_MIN(container.width, (nscoord)mMaxSize);
}
else { // multiplicative value
container.ascent =
PR_MIN(container.ascent, nscoord(initialSize.ascent * mMaxSize));
container.descent =
PR_MIN(container.descent, nscoord(initialSize.descent * mMaxSize));
container.width =
PR_MIN(container.width, nscoord(initialSize.width * mMaxSize));
}
}
if (mMinSize != float(NS_UNCONSTRAINEDSIZE) && mMinSize > 0.0f) {
// if we are here, there is a user defined minsize ...
if (NS_MATHML_OPERATOR_MINSIZE_IS_EXPLICIT(mFlags)) {
// there is an explicit value like minsize="20pt"
// try to maintain the aspect ratio of the char
float aspect = mMinSize / float(initialSize.ascent + initialSize.descent);
container.ascent =
PR_MAX(container.ascent, nscoord(initialSize.ascent * aspect));
container.descent =
PR_MAX(container.descent, nscoord(initialSize.descent * aspect));
container.width =
PR_MAX(container.width, (nscoord)mMinSize);
}
else { // multiplicative value
container.ascent =
PR_MAX(container.ascent, nscoord(initialSize.ascent * mMinSize));
container.descent =
PR_MAX(container.descent, nscoord(initialSize.descent * mMinSize));
container.width =
PR_MAX(container.width, nscoord(initialSize.width * mMinSize));
}
}
}
if (mMinSize != float(NS_UNCONSTRAINEDSIZE) && mMinSize > 0.0f) {
// if we are here, there is a user defined minsize ...
if (NS_MATHML_OPERATOR_MINSIZE_IS_EXPLICIT(mFlags)) {
// there is an explicit value like minsize="20pt"
// try to maintain the aspect ratio of the char
float aspect = mMinSize / float(initialSize.ascent + initialSize.descent);
container.ascent =
PR_MAX(container.ascent, nscoord(initialSize.ascent * aspect));
container.descent =
PR_MAX(container.descent, nscoord(initialSize.descent * aspect));
container.width =
PR_MAX(container.width, (nscoord)mMinSize);
}
else { // multiplicative value
container.ascent =
PR_MAX(container.ascent, nscoord(initialSize.ascent * mMinSize));
container.descent =
PR_MAX(container.descent, nscoord(initialSize.descent * mMinSize));
container.width =
PR_MAX(container.width, nscoord(initialSize.width * mMinSize));
}
}
// things may have changed
container.height = container.ascent + container.descent;
// let the MathMLChar stretch itself...
charSize.Clear(); // this will tell stretch that we don't know the default size
mMathMLChar.Stretch(aPresContext, aRenderingContext,
mStyleContext, aStretchDirection,
container, aDesiredStretchSize);
if (initialSize == aDesiredStretchSize) { // hasn't changed !
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
}
}
/////////
// Place our children and adjust our children's offsets to leave the spacing.
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
// The rendering will be handled by our MathML char
mMathMLChar.SetRect(nsRect(0, 0, aDesiredStretchSize.width,
aDesiredStretchSize.height));
// update our bounding metrics... it becomes that of our MathML char
aStretchDirection, container, charSize);
// update our bounding metrics... it becomes that of our MathML char
mMathMLChar.GetBoundingMetrics(mBoundingMetrics);
}
else {
nsHTMLReflowMetrics aReflowMetrics(nsnull);
Place(aPresContext, aRenderingContext, PR_TRUE, aReflowMetrics);
// Prepare the metrics to be returned
aDesiredStretchSize.width = aReflowMetrics.width;
aDesiredStretchSize.height = aReflowMetrics.height;
aDesiredStretchSize.ascent = aReflowMetrics.ascent;
aDesiredStretchSize.descent = aReflowMetrics.descent;
// For vertical operators we want to center about the axis of the container.
if (NS_MATHML_OPERATOR_IS_SYMMETRIC(mFlags) &&
((aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) ||
(aStretchDirection == NS_STRETCH_DIRECTION_DEFAULT &&
mMathMLChar.GetStretchDirection() == NS_STRETCH_DIRECTION_VERTICAL)))
{
// the desired size returned by mMathMLChar maybe different
// from the size of the container.
// the mMathMLChar.mRect.y calculation is subtle, watch out!!!
nscoord height = mBoundingMetrics.ascent + mBoundingMetrics.descent;
mBoundingMetrics.ascent = height/2 + axisHeight;
mBoundingMetrics.descent = height - mBoundingMetrics.ascent;
}
// 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.GetEnum() == eMathMLChar_DONT_STRETCH)
{
dy = (aDesiredStretchSize.ascent - charSize.ascent);
aDesiredStretchSize.mBoundingMetrics = mBoundingMetrics = charSize;
}
mMathMLChar.SetRect(
nsRect(0, dy, charSize.width,
charSize.ascent + charSize.descent));
mReference.x = 0;
mReference.y = aDesiredStretchSize.ascent;
}
aDesiredStretchSize.leftSpace = mLeftSpace;
aDesiredStretchSize.rightSpace = mRightSpace;
mReference.x = 0;
mReference.y = aDesiredStretchSize.ascent - mBoundingMetrics.ascent;
// Before we leave... there is a last item in the check-list:
// If our parent is not embellished, it means we are the outermost embellished
// container and so we put the spacing, otherwise we don't include the spacing,
// the outermost embellished container will take care of it.
if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
// Get the value of 'em'
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
nscoord em = NSToCoordRound(float(font.mFont.size));
// Account the spacing
aDesiredStretchSize.width += nscoord( (aDesiredStretchSize.leftSpace + aDesiredStretchSize.rightSpace) * em );
aDesiredStretchSize.width += nscoord((mLeftSpace + mRightSpace) * em);
mBoundingMetrics.width = aDesiredStretchSize.width;
nscoord dx = nscoord(mLeftSpace * em);
nscoord dx = nscoord( mLeftSpace * em );
if (0 == dx) return NS_OK;
// adjust the offsets
@@ -672,7 +720,7 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
mBoundingMetrics.rightBearing += dx;
nsRect rect;
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
if (NS_MATHML_OPERATOR_GET_FORM(mFlags)) {
mMathMLChar.GetRect(rect);
mMathMLChar.SetRect(nsRect(rect.x + dx, rect.y, rect.width, rect.height));
}
@@ -707,3 +755,39 @@ nsMathMLmoFrame::Place(nsIPresContext* aPresContext,
return PlaceTokenFor(this, aPresContext, aRenderingContext,
aPlaceOrigin, aDesiredSize);
}
// ----------------------
// the Style System will use these to pass the proper style context to our MathMLChar
NS_IMETHODIMP
nsMathMLmoFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
{
NS_PRECONDITION(aStyleContext, "null OUT ptr");
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
*aStyleContext = nsnull;
switch (aIndex) {
case NS_MATHML_CHAR_STYLE_CONTEXT_INDEX:
mMathMLChar.GetStyleContext(aStyleContext);
break;
default:
return NS_ERROR_INVALID_ARG;
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmoFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
{
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
switch (aIndex) {
case NS_MATHML_CHAR_STYLE_CONTEXT_INDEX:
mMathMLChar.SetStyleContext(aStyleContext);
break;
}
return NS_OK;
}
+18 -9
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmoFrame_h___
@@ -33,7 +34,14 @@
class nsMathMLmoFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
NS_IMETHOD
GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -70,8 +78,8 @@ public:
Stretch(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsStretchDirection aStretchDirection,
nsStretchMetrics& aContainerSize,
nsStretchMetrics& aDesiredStretchSize);
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredStretchSize);
// helper method to lookup the operator dictionary and initialize our member data
void
@@ -83,12 +91,13 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator.
nsOperatorFlags mFlags;
float mLeftSpace;
float mRightSpace;
float mMinSize;
float mMaxSize;
nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator.
nsOperatorFlags mFlags;
float mLeftSpace;
float mRightSpace;
float mMinSize;
float mMaxSize;
};
#endif /* nsMathMLmoFrame_h___ */
+144 -100
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
@@ -76,8 +77,11 @@ nsMathMLmoverFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -177,6 +181,7 @@ XXX The winner is the outermost in conflicting settings like these:
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTOVER;
}
//XXX should sync the presentation data be at this spot, after the if?
}
}
}
@@ -191,8 +196,8 @@ XXX The winner is the outermost in conflicting settings like these:
if (overscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)? 0 : 1;
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE, PR_FALSE);
}
// switch the style of the overscript
@@ -200,35 +205,6 @@ XXX The winner is the outermost in conflicting settings like these:
return rv;
}
NS_IMETHODIMP
nsMathMLmoverFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
/////////////
// Reflow children
ReflowChildren(1, aPresContext, aDesiredSize, aReflowState, aStatus);
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
/////////////
// Ask stretchy children to stretch themselves
nsStretchMetrics containerSize(aDesiredSize);
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_HORIZONTAL;
StretchChildren(aPresContext, renderingContext, stretchDir, containerSize);
/////////////
// Place children now by re-adjusting the origins to align the baselines
FinalizeReflow(1, aPresContext, renderingContext, aDesiredSize);
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
/*
The REC says:
@@ -254,84 +230,152 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nscoord count = 0;
nsRect rect[2];
nsIFrame* child[2];
nscoord width[2];
nscoord maxWidth = 0;
nsresult rv = NS_OK;
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmOver;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics overSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* overFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame) && 2 > count) {
childFrame->GetRect(rect[count]);
child[count] = childFrame;
if (aPlaceOrigin) {
width[count] = rect[count].width;
if (IsEmbellishOperator(childFrame)) {
// treated as if embellishments were not there...
nsIMathMLFrame* aMathMLFrame = nsnull;
nsresult rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&aMathMLFrame);
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
nsRect rect;
nsEmbellishData embellishData;
aMathMLFrame->GetEmbellishData(embellishData);
embellishData.core->GetRect(rect);
width[count] = rect.width + embellishData.leftSpace + embellishData.rightSpace;
}
}
maxWidth = PR_MAX(maxWidth, width[count]); // clean up and use "if" later
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++;
}
childFrame->GetNextSibling(&childFrame);
}
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
if ((2 != count) || !baseFrame || !overFrame) {
#ifdef NS_DEBUG
printf("mover: invalid markup");
#endif
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
aDesiredSize.ascent = rect[0].y;
aDesiredSize.descent = rect[0].x;
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
////////////////////
// Place Children
aDesiredSize.ascent += rect[1].height;
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
if (aPlaceOrigin) {
rect[0].x = (maxWidth - width[0]) / 2; // center w.r.t largest width
rect[1].x = (maxWidth - width[1]) / 2;
rect[1].y = 0;
rect[0].y = rect[1].height;
}
//ignore the leading (line spacing) that is attached to the text
nscoord leading;
const nsStyleFont* font =
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
aRenderingContext.SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
const nsStyleFont* aFont =
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
aPresContext->GetMetricsFor(aFont->mFont, getter_AddRefs(fm));
fm->GetLeading(leading);
aDesiredSize.height -= leading;
aDesiredSize.ascent -= leading;
rect[0].y -= leading;
//
if (aPlaceOrigin) {
// child[0]->SetRect(aPresContext, rect[0]);
// child[1]->SetRect(aPresContext, rect[1]);
nsHTMLReflowMetrics childSize(nsnull);
for (PRInt32 i=0; i<count; i++) {
childSize.width = rect[i].width;
childSize.height = rect[i].height;
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
}
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
nscoord ruleThickness;
GetRuleThickness (aRenderingContext, fm, ruleThickness);
// there are 2 different types of placement depending on
// whether we want an accented overscript or not
nscoord correction = 0;
nscoord delta1 = 0; // gap between base and overscript
nscoord delta2 = 0; // extra space above overscript
if (!NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
// Rule 13a, App. G, TeXbook
// GetItalicCorrectionFromChild (baseFrame, correction);
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
bigOpSpacing1, dummy,
bigOpSpacing3, dummy,
bigOpSpacing5);
delta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent));
delta2 = bigOpSpacing5;
// XXX This is not a TeX rule...
// delta1 (as computed abvove) 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)));
}
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
else {
// Rule 12, App. G, TeXbook
GetSkewCorrectionFromChild (aPresContext, baseFrame, correction);
#if 0
delta1 = -PR_MIN(bmBase.ascent, xHeight);
#endif
// We don't follow Rule 12 here since TeX has some implicit
// assumptions in the computation of delta1.
// Should we use Rule 9 like \overline does?
delta1 = ruleThickness;
delta2 = ruleThickness;
}
// empty over?
if (0 == (bmOver.ascent + bmOver.descent)) delta1 = 0;
mBoundingMetrics.ascent =
bmOver.ascent + bmOver.descent + delta1 + bmBase.ascent;
#if 0
// Rule 12 (cont.)
if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
// delta1 is -ve for an accent
// hence as per Rule 12, App. G, TeXbook, we should ...
mBoundingMetrics.ascent = PR_MAX(mBoundingMetrics.ascent, bmBase.ascent);
}
#endif
mBoundingMetrics.descent = bmBase.descent;
if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
mBoundingMetrics.width = PR_MAX(bmBase.width, bmOver.width);
}
else {
mBoundingMetrics.width =
PR_MAX(bmBase.width/2,(bmOver.width + correction/2)/2) +
PR_MAX(bmBase.width/2,(bmOver.width - correction/2)/2);
}
// XXX Fix me!
mBoundingMetrics.ascent = aDesiredSize.ascent;
mBoundingMetrics.descent = aDesiredSize.descent;
mBoundingMetrics.width = aDesiredSize.width;
aDesiredSize.descent = baseSize.descent;
aDesiredSize.ascent = mBoundingMetrics.ascent + delta2;
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;
}
else {
dxOver = correction/2 + (mBoundingMetrics.width - bmOver.width)/2;
}
dyOver = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
mBoundingMetrics.leftBearing =
PR_MIN(dxBase + bmBase.leftBearing, dxOver + bmOver.leftBearing);
mBoundingMetrics.rightBearing =
PR_MAX(dxBase + bmBase.rightBearing, dxOver + bmOver.rightBearing);
if (aPlaceOrigin) {
// place base
FinishReflowChild (baseFrame, aPresContext, baseSize, dxBase, dyBase, 0);
// place overscript
FinishReflowChild (overFrame, aPresContext, overSize, dxOver, dyOver, 0);
}
return NS_OK;
}
+1 -6
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmoverFrame_h___
@@ -41,12 +42,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
+48 -30
View File
@@ -89,7 +89,7 @@ nsMathMLmpaddedFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
/*
parse the attributes
@@ -139,6 +139,9 @@ nsMathMLmpaddedFrame::Init(nsIPresContext* aPresContext,
ParseAttribute(value, mLeftSpaceSign, mLeftSpace, mLeftSpacePseudoUnit);
}
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -172,11 +175,9 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
else
aSign = NS_MATHML_SIGN_UNSPECIFIED;
/*
// skip any space in-between
// skip any space after the sign
while (i < stringLength && XP_IS_SPACE(aString[i]))
i++;
*/
///////////////////////
// get the string that represents the numeric value
@@ -226,15 +227,18 @@ nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
return PR_FALSE;
}
// else the only other valid possibility here is a percentage value,
// otherwise ParseNumericValue() would have failed
aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
return PR_TRUE;
}
aString.Right(value, stringLength - i);
if (value == "width") aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
else if (value == "height") aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
else if (value == "depth") aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH;
else if (value == "lspace") aPseudoUnit = NS_MATHML_PSEUDO_UNIT_LSPACE;
if (value.Equals("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
else if (value.Equals("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
else if (value.Equals("depth")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH;
else if (value.Equals("lspace")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_LSPACE;
else // unexpected pseudo-unit
{
aCSSValue.Reset();
@@ -265,7 +269,7 @@ nsMathMLmpaddedFrame::UpdateValue(nsIPresContext* aPresContext,
PRInt32 aPseudoUnit,
nsCSSValue& aCSSValue,
nscoord aLeftSpace,
nsHTMLReflowMetrics& aReflowMetrics,
nsBoundingMetrics& aBoundingMetrics,
nscoord& aValueToUpdate)
{
nsCSSUnit unit = aCSSValue.GetUnit();
@@ -278,15 +282,15 @@ nsMathMLmpaddedFrame::UpdateValue(nsIPresContext* aPresContext,
switch(aPseudoUnit)
{
case NS_MATHML_PSEUDO_UNIT_WIDTH:
scaler = aReflowMetrics.width;
scaler = aBoundingMetrics.width;
break;
case NS_MATHML_PSEUDO_UNIT_HEIGHT:
scaler = aReflowMetrics.ascent;
scaler = aBoundingMetrics.ascent;
break;
case NS_MATHML_PSEUDO_UNIT_DEPTH:
scaler = aReflowMetrics.descent;
scaler = aBoundingMetrics.descent;
break;
case NS_MATHML_PSEUDO_UNIT_LSPACE:
@@ -295,16 +299,16 @@ nsMathMLmpaddedFrame::UpdateValue(nsIPresContext* aPresContext,
default:
// if we ever reach here, it would mean something is wrong
// somwehere with the setup and/or the caller
// somewhere with the setup and/or the caller
NS_ASSERTION(0, "Unexpected Pseudo Unit");
return;
}
}
if (eCSSUnit_Number == unit)
amount = nscoord(float(scaler) * aCSSValue.GetFloatValue());
amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
else if (eCSSUnit_Percent == unit)
amount = nscoord(float(scaler) * aCSSValue.GetPercentValue());
amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
else
amount = CalcLength(aPresContext, aStyleContext, aCSSValue);
@@ -322,7 +326,7 @@ nsMathMLmpaddedFrame::UpdateValue(nsIPresContext* aPresContext,
to 0 if it would otherwise become negative. Dimensions which are
initially 0 can be made negative
*/
if (0 <= oldValue && 0 > aValueToUpdate) aValueToUpdate = 0;
if (0 < oldValue && 0 > aValueToUpdate) aValueToUpdate = 0;
}
}
@@ -344,9 +348,9 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext,
return rv;
}
nscoord height = aDesiredSize.ascent;
nscoord depth = aDesiredSize.descent;
nscoord width = aDesiredSize.width;
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
PRInt32 pseudoUnit;
@@ -356,33 +360,51 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext,
? NS_MATHML_PSEUDO_UNIT_WIDTH : mWidthPseudoUnit;
UpdateValue(aPresContext, mStyleContext,
mWidthSign, pseudoUnit, mWidth,
lspace, aDesiredSize, width);
lspace, mBoundingMetrics, width);
// update height
pseudoUnit = (mHeightPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
? NS_MATHML_PSEUDO_UNIT_HEIGHT : mHeightPseudoUnit;
UpdateValue(aPresContext, mStyleContext,
mHeightSign, pseudoUnit, mHeight,
lspace, aDesiredSize, height);
lspace, mBoundingMetrics, height);
// update depth
pseudoUnit = (mDepthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
? NS_MATHML_PSEUDO_UNIT_DEPTH : mDepthPseudoUnit;
UpdateValue(aPresContext, mStyleContext,
mDepthSign, pseudoUnit, mDepth,
lspace, aDesiredSize, depth);
lspace, mBoundingMetrics, depth);
// update lspace -- should be *last* because lspace is overwritten!!
pseudoUnit = (mLeftSpacePseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
? NS_MATHML_PSEUDO_UNIT_LSPACE : mLeftSpacePseudoUnit;
UpdateValue(aPresContext, mStyleContext,
mLeftSpaceSign, pseudoUnit, mLeftSpace,
lspace, aDesiredSize, lspace);
lspace, mBoundingMetrics, lspace);
// do the padding now that we have everything
nscoord dy = height - aDesiredSize.ascent;
if (lspace != 0) { // there was padding on the left
mBoundingMetrics.leftBearing = 0;
}
if (width != mBoundingMetrics.width) { // there was padding on the right
mBoundingMetrics.rightBearing = lspace + width;
}
nscoord dy = height - mBoundingMetrics.ascent;
nscoord dx = lspace;
mBoundingMetrics.ascent = height;
mBoundingMetrics.descent = depth;
mBoundingMetrics.width = lspace + width;
aDesiredSize.ascent += dy;
aDesiredSize.descent += depth - mBoundingMetrics.descent;
aDesiredSize.width = mBoundingMetrics.width;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
if (0 != dx || 0 != dy) {
nsRect rect;
nsIFrame* childFrame = mFrames.FirstChild();
@@ -393,12 +415,8 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext,
}
}
aDesiredSize.ascent = height;
aDesiredSize.descent = depth;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = width;
// XXX need to tweak mBoundingMetrics/mReference as well ...
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
return NS_OK;
}
@@ -83,7 +83,7 @@ private:
PRInt32 aPseudoUnit,
nsCSSValue& aCSSValue,
nscoord aLeftSpace,
nsHTMLReflowMetrics& aReflowMetrics,
nsBoundingMetrics& aBoundingMetrics,
nscoord& aValueToUpdate);
};
@@ -66,6 +66,19 @@ nsMathMLmphantomFrame::~nsMathMLmphantomFrame()
{
}
NS_IMETHODIMP
nsMathMLmphantomFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return rv;
}
NS_METHOD
nsMathMLmphantomFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -34,6 +34,13 @@ class nsMathMLmphantomFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmphantomFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
+237 -124
View File
@@ -19,6 +19,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Vilya Harvey <vilya@nag.co.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
@@ -41,9 +42,18 @@
#include "nsMathMLmrootFrame.h"
//
// <msqrt> and <mroot> -- form a radical
// <msqrt> and <mroot> -- form a radical - implementation
//
//TODO:
// The code assumes that TeX fonts are picked! Another separate version of
// Reflow() is needed as a fall-back for cases where TeX fonts (CMSY/CMEX)
// are not installed on the system, e.g., the fall-back could explicitly
// draw the branches of the radical using th default rule thickness.
// additional style context to be used by our MathMLChar.
#define NS_SQR_CHAR_STYLE_CONTEXT_INDEX 0
nsresult
NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@@ -55,16 +65,14 @@ NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
*aNewFrame = it;
return NS_OK;
}
nsMathMLmrootFrame::nsMathMLmrootFrame() :
mSqrChar(),
mBarChar()
mBarRect()
{
mSqrChar.SetEnum(eMathMLChar_Sqrt);
mBarChar.SetEnum(eMathMLChar_OverBar);
}
nsMathMLmrootFrame::~nsMathMLmrootFrame()
@@ -73,14 +81,23 @@ nsMathMLmrootFrame::~nsMathMLmrootFrame()
NS_IMETHODIMP
nsMathMLmrootFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
nsresult rv = NS_OK;
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
// XXX Attributes?
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mSqrChar.SetEnum(aPresContext, eMathMLChar_Sqrt);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -90,18 +107,47 @@ nsMathMLmrootFrame::Paint(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
/////////////
// paint the base and the index
nsresult rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
nsresult rv = NS_OK;
if (NS_SUCCEEDED(rv) && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// paint the sqrt symbol
rv = mSqrChar.Paint(aPresContext, aRenderingContext, mStyleContext);
/////////////
// paint the sqrt symbol
if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) &&
!NS_MATHML_HAS_ERROR(mPresentationData.flags))
{
mSqrChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
// paint the overline bar
rv = mBarChar.Paint(aPresContext, aRenderingContext, mStyleContext);
nsStyleColor color;
mStyleContext->GetStyle(eStyleStruct_Color, color);
aRenderingContext.SetColor(color.mColor);
aRenderingContext.FillRect(mBarRect.x, mBarRect.y,
mBarRect.width, mBarRect.height);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
nsRect rect;
mSqrChar.GetRect(rect);
nsBoundingMetrics bm;
mSqrChar.GetBoundingMetrics(bm);
aRenderingContext.SetColor(NS_RGB(255,0,0));
nscoord x = rect.x + bm.leftBearing;
nscoord y = rect.y;
nscoord w = bm.rightBearing - bm.leftBearing;
nscoord h = bm.ascent + bm.descent;
aRenderingContext.DrawRect(x,y,w,h);
}
#endif
}
/////////////
// paint the content we are square-rooting
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
return rv;
}
@@ -112,28 +158,30 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
nsReflowStatus childStatus;
// 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);
nsReflowStatus childStatus;
aDesiredSize.width = aDesiredSize.height = 0;
aDesiredSize.ascent = aDesiredSize.descent = 0;
nsBoundingMetrics bmSqr, bmBase, bmIndex;
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
//////////////////
// Reflow Children
PRInt32 count = 0;
nsIFrame* child[2];
nsRect rect[4];
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* indexFrame = nsnull;
nsHTMLReflowMetrics baseSize(nsnull);
nsHTMLReflowMetrics indexSize(nsnull);
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame)
{
//////////////
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
if (IsOnlyWhitespace(childFrame)) {
ReflowEmptyChild(aPresContext, childFrame);
}
else if (2 > count) {
if (!IsOnlyWhitespace(childFrame)) {
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
childFrame, availSize);
rv = ReflowChild(childFrame, aPresContext,
@@ -143,134 +191,199 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
return rv;
}
if (0 == count) {
aDesiredSize.descent = childDesiredSize.descent;
aDesiredSize.ascent = childDesiredSize.ascent;
aDesiredSize.width = childDesiredSize.width;
// base
baseFrame = childFrame;
baseSize = childDesiredSize;
bmBase = childDesiredSize.mBoundingMetrics;
}
else if (1 == count) {
// index
indexFrame = childFrame;
indexSize = childDesiredSize;
bmIndex = childDesiredSize.mBoundingMetrics;
}
// 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. Before return, we should set the origins so as to overwrite
// what we are storing there now.
child[count] = childFrame;
rect[count] = nsRect(childDesiredSize.descent, childDesiredSize.ascent,
childDesiredSize.width, childDesiredSize.height);
count++;
}
// else { invalid markup... }
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
if ((2 != count) || !baseFrame || !indexFrame) {
#ifdef NS_DEBUG
printf("mroot: invalid markup");
#endif
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, renderingContext, aDesiredSize);
}
////////////
// Prepare the radical symbol and the overline bar
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
renderingContext.SetFont(font.mFont);
// grab some metrics to help adjusting the placements
nsCOMPtr<nsIFontMetrics> fm;
nscoord fontAscent, fontDescent;
renderingContext.GetFontMetrics(*getter_AddRefs(fm));
fm->GetMaxAscent(fontAscent);
fm->GetMaxDescent(fontDescent);
nsBoundingMetrics bmSqr, bmBar;
nscoord dx, dy;
nscoord ruleThickness;
GetRuleThickness(renderingContext, fm, ruleThickness);
// radical symbol
renderingContext.GetBoundingMetrics(mSqrChar.GetUnicode(), PRUint32(1), bmSqr);
nscoord widthSqr = bmSqr.width; // width of the radical symbol
// Rule 11, App. G, TeXbook
// psi = clearance between rule and content
nscoord phi = 0, psi = 0;
if (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
fm->GetXHeight(phi);
else
phi = ruleThickness;
psi = ruleThickness + phi/4;
// Stretch the radical symbol to the appropriate height if it is not big enough.
nsBoundingMetrics contSize = bmBase;
contSize.descent = bmBase.ascent + bmBase.descent + psi;
contSize.ascent = ruleThickness;
// overline bar
renderingContext.GetBoundingMetrics(mBarChar.GetUnicode(), PRUint32(1), bmBar);
nscoord heightBar = bmBar.ascent - bmBar.descent; // height of the overline bar
nsBoundingMetrics radicalSize;
radicalSize.Clear(); // this tells Stretch() that we don't know the current size
// Stretch the sqrt symbol to the appropriate height if it is not big enough.
nsStretchMetrics contSize(aDesiredSize);
nsStretchMetrics desSize(fontDescent, fontAscent, widthSqr, fontAscent + fontDescent);
mSqrChar.Stretch(aPresContext, renderingContext, mStyleContext,
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
widthSqr = desSize.width;
if (aDesiredSize.ascent < desSize.ascent) {
aDesiredSize.ascent = desSize.ascent;
}
if (aDesiredSize.descent < desSize.descent) {
aDesiredSize.descent = desSize.descent;
}
// height(radical) should be >= height(base) + psi + ruleThickness
// however, nsMathMLChar will only try to meet this condition
// with no guarantee.
mSqrChar.Stretch(aPresContext, renderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
contSize, radicalSize,
NS_STRETCH_LARGER);
// radicalSize have changed at this point, and should match with
// the bounding metrics of the char
mSqrChar.GetBoundingMetrics(bmSqr);
// According to TeX, the ascent of the returned radical should be
// the thickness of the overline
ruleThickness = bmSqr.ascent;
// adjust clearance psi to absorb any excess difference if any
// in height between radical and content
if (bmSqr.descent > (bmBase.ascent + bmBase.descent) + psi)
psi = (psi + bmSqr.descent - (bmBase.ascent + bmBase.descent))/2;
// Update the desired size for the container (like msqrt, index is not yet uncluded)
// the baseline will be that of the base.
mBoundingMetrics.ascent = bmBase.ascent + psi + ruleThickness;
mBoundingMetrics.descent =
PR_MAX(bmBase.descent, (bmSqr.descent - (bmBase.ascent + psi)));
mBoundingMetrics.width = bmSqr.width + bmBase.width;
mBoundingMetrics.leftBearing = bmSqr.leftBearing;
mBoundingMetrics.rightBearing = bmSqr.width +
PR_MAX(bmBase.width, bmBase.rightBearing); // take also care of the rule
aDesiredSize.ascent = mBoundingMetrics.ascent + ruleThickness;
aDesiredSize.descent =
PR_MAX(baseSize.descent, (mBoundingMetrics.descent + ruleThickness));
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
dx = 0;
dy = bmSqr.ascent - fontAscent;
rect[2] = nsRect(dx, dy, desSize.width, aDesiredSize.height);
dx = bmSqr.rightBearing;
/////////////
// Re-adjust the desired size to include the index.
// the index is raised by some fraction of the height
// of the radical, see \mroot macro in App. B, TexBook
nscoord raiseIndexDelta = NSToCoordRound(0.6f * (bmSqr.ascent + bmSqr.descent));
nscoord indexRaisedAscent = mBoundingMetrics.ascent // top of radical
- (bmSqr.ascent + bmSqr.descent) // to bottom of radical
+ raiseIndexDelta + bmIndex.ascent + bmIndex.descent; // to top of raised index
// Stretch the overline bar to the appropriate width if it is not big enough.
contSize = nsStretchMetrics(aDesiredSize);
desSize = nsStretchMetrics(fontDescent, fontAscent, bmBar.rightBearing-bmBar.leftBearing, fontAscent + fontDescent);
nsStretchMetrics oldSize = desSize;
mBarChar.Stretch(aPresContext, renderingContext, mStyleContext,
NS_STRETCH_DIRECTION_HORIZONTAL, contSize, desSize);
dy = bmBar.ascent - fontAscent;
if (oldSize == desSize) { // hasn't changed size! Char will be painted as a normal char
dx -= bmBar.leftBearing; // adjust so that it coincides with the sqrt char
}
rect[3] = nsRect(dx, dy, desSize.width, heightBar);
//////////////////
// Place Children now by setting the origin of each child.
nscoord thickspace = bmBar.ascent-bmBar.descent; // height of the bar
aDesiredSize.ascent += thickspace;
rect[0].y = aDesiredSize.ascent - rect[0].y; // y-origin of base
dy = thickspace + (bmSqr.ascent-bmSqr.descent)/3 - rect[1].height;
rect[1].y = dy;
if (0 > dy) {
dy = -dy;
aDesiredSize.ascent += dy;
rect[0].y += dy;
rect[1].y = 0;
rect[2].y += dy; // y-origin of bar
rect[3].y += dy; // y-origin of sqrt char
nscoord indexClearance = 0;
if (mBoundingMetrics.ascent < indexRaisedAscent) {
indexClearance =
indexRaisedAscent - mBoundingMetrics.ascent; // excess gap introduced by a tall index
mBoundingMetrics.ascent = indexRaisedAscent;
aDesiredSize.ascent = mBoundingMetrics.ascent + ruleThickness;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
}
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
rect[1].x = 0; // x-origin of index
rect[0].x = widthSqr;
aDesiredSize.width = widthSqr + rect[0].width;
if (0 < rect[1].width) {
dx = rect[1].width - (bmSqr.rightBearing - bmSqr.leftBearing)/2;
aDesiredSize.width += dx;
rect[0].x += dx; // x-origin of base
rect[2].x += dx; // x-origin of sqrt char
rect[3].x += dx; // x-origin of bar
// the index is tucked in closer to the radical
// XXX assumes that the kern does not make the content and radical collide.
nscoord xHeight = 0;
fm->GetXHeight(xHeight);
nscoord indexRadicalKern = NSToCoordRound(1.35f * xHeight);
if (indexRadicalKern < bmIndex.width)
{
mBoundingMetrics.width += (bmIndex.width - indexRadicalKern);
aDesiredSize.width = mBoundingMetrics.width;
}
// child[0]->SetRect(aPresContext, rect[0]);
// child[1]->SetRect(aPresContext, rect[1]);
nsHTMLReflowMetrics childSize(nsnull);
for (PRInt32 i=0; i<count; i++) {
childSize.width = rect[i].width;
childSize.height = rect[i].height;
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
nscoord dx = 0, dy = 0, lbearing;
// place the index
dx = (indexRadicalKern > bmIndex.width) ? indexRadicalKern - bmIndex.width : 0;
dy = aDesiredSize.ascent - (indexRaisedAscent + indexSize.ascent - bmIndex.ascent);
FinishReflowChild(indexFrame, aPresContext, indexSize, dx, dy, 0);
lbearing = dx + bmIndex.leftBearing;
// place the radical symbol
dx = (indexRadicalKern > bmIndex.width) ? 0 : bmIndex.width - indexRadicalKern;
dy = indexClearance + ruleThickness; // leave a kern=ruleThickness at the top
mSqrChar.SetRect(nsRect(dx, dy, bmSqr.width, bmSqr.ascent + bmSqr.descent));
if (lbearing < dx + bmSqr.leftBearing) {
mBoundingMetrics.leftBearing = lbearing;
mBoundingMetrics.rightBearing += dx;
}
mSqrChar.SetRect(rect[2]);
mBarChar.SetRect(rect[3]);
// place the radical bar
dx += bmSqr.width;
dy = indexClearance + ruleThickness; // leave a kern=ruleThickness at the top
mBarRect.SetRect(dx, dy, bmBase.width, ruleThickness);
// place the base
dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild(baseFrame, aPresContext, baseSize, dx, dy, 0);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
// XXX Fix me!
mBoundingMetrics.ascent = aDesiredSize.ascent;
mBoundingMetrics.descent = aDesiredSize.descent;
mBoundingMetrics.width = aDesiredSize.width;
// ----------------------
// the Style System will use these to pass the proper style context to our MathMLChar
NS_IMETHODIMP
nsMathMLmrootFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
{
NS_PRECONDITION(aStyleContext, "null OUT ptr");
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
*aStyleContext = nsnull;
switch (aIndex) {
case NS_SQR_CHAR_STYLE_CONTEXT_INDEX:
mSqrChar.GetStyleContext(aStyleContext);
break;
default:
return NS_ERROR_INVALID_ARG;
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmrootFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
{
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
switch (aIndex) {
case NS_SQR_CHAR_STYLE_CONTEXT_INDEX:
mSqrChar.SetStyleContext(aStyleContext);
break;
}
return NS_OK;
}
+12 -3
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmrootFrame_h___
@@ -33,7 +34,14 @@
class nsMathMLmrootFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
NS_IMETHOD
GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -48,7 +56,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 2, PR_FALSE);
UpdatePresentationDataFromChildAt(1, 2, PR_FALSE, PR_FALSE);
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
@@ -71,7 +79,8 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
nsMathMLChar mSqrChar, mBarChar;
nsMathMLChar mSqrChar;
nsRect mBarRect;
};
#endif /* nsMathMLmrootFrame_h___ */
+4 -2
View File
@@ -75,8 +75,10 @@ nsMathMLmrowFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
// XXX Attributes?
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
+164 -73
View File
@@ -19,6 +19,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Vilya Harvey <vilya@nag.co.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
@@ -44,6 +45,15 @@
// <msqrt> and <mroot> -- form a radical - implementation
//
//TODO:
// The code assumes that TeX fonts are picked! Another separate version of
// Reflow() is needed as a fall-back for cases where TeX fonts (CMSY/CMEX)
// are not installed on the system, e.g., the fall-back could explicitly
// draw the branches of the radical using th default rule thickness.
// additional style context to be used by our MathMLChar.
#define NS_SQR_CHAR_STYLE_CONTEXT_INDEX 0
nsresult
NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@@ -61,10 +71,8 @@ NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
nsMathMLmsqrtFrame::nsMathMLmsqrtFrame() :
mSqrChar(),
mBarChar()
mBarRect()
{
mSqrChar.SetEnum(eMathMLChar_Sqrt);
mBarChar.SetEnum(eMathMLChar_OverBar);
}
nsMathMLmsqrtFrame::~nsMathMLmsqrtFrame()
@@ -82,9 +90,14 @@ nsMathMLmsqrtFrame::Init(nsIPresContext* aPresContext,
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
// TODO: other attributes...
mSqrChar.SetEnum(aPresContext, eMathMLChar_Sqrt);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -95,19 +108,46 @@ nsMathMLmsqrtFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer)
{
nsresult rv = NS_OK;
/////////////
// paint the sqrt symbol
if ((NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) &&
!NS_MATHML_HAS_ERROR(mPresentationData.flags))
{
mSqrChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
// paint the overline bar
nsStyleColor color;
mStyleContext->GetStyle(eStyleStruct_Color, color);
aRenderingContext.SetColor(color.mColor);
aRenderingContext.FillRect(mBarRect.x, mBarRect.y,
mBarRect.width, mBarRect.height);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
nsRect rect;
mSqrChar.GetRect(rect);
nsBoundingMetrics bm;
mSqrChar.GetBoundingMetrics(bm);
aRenderingContext.SetColor(NS_RGB(255,0,0));
nscoord x = rect.x + bm.leftBearing;
nscoord y = rect.y;
nscoord w = bm.rightBearing - bm.leftBearing;
nscoord h = bm.ascent + bm.descent;
aRenderingContext.DrawRect(x,y,w,h);
}
#endif
}
/////////////
// paint the content we are square-rooting
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
if (NS_SUCCEEDED(rv) && NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// paint the sqrt symbol
rv = mSqrChar.Paint(aPresContext, aRenderingContext, mStyleContext);
// paint the overline bar
rv = mBarChar.Paint(aPresContext, aRenderingContext, mStyleContext);
}
return rv;
}
@@ -119,96 +159,111 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
{
nsresult rv = NS_OK;
nsBoundingMetrics bmSqr, bmBase;
///////////////
// Let the base class format our content like an inferred mrow
rv = nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize,
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;
}
nscoord oldAscent = aDesiredSize.ascent;
bmBase = baseSize.mBoundingMetrics;
////////////
// Prepare the radical symbol and the overline bar
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
renderingContext.SetFont(font.mFont);
// grab some metrics that will help to adjust the placements
nsCOMPtr<nsIFontMetrics> fm;
nscoord fontAscent, fontDescent;
renderingContext.GetFontMetrics(*getter_AddRefs(fm));
fm->GetMaxAscent(fontAscent);
fm->GetMaxDescent(fontDescent);
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nscoord ruleThickness;
GetRuleThickness(renderingContext, fm, ruleThickness);
nsBoundingMetrics bmSqr, bmBar;
nscoord dx, dy;
// Rule 11, App. G, TeXbook
// psi = clearance between rule and content
nscoord phi = 0, psi = 0;
if (NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
fm->GetXHeight(phi);
else
phi = ruleThickness;
psi = ruleThickness + phi/4;
// Stretch the radical symbol to the appropriate height if it is not big enough.
nsBoundingMetrics contSize = bmBase;
contSize.ascent = ruleThickness;
contSize.descent = bmBase.ascent + bmBase.descent + psi;
// radical symbol
renderingContext.GetBoundingMetrics(mSqrChar.GetUnicode(), PRUint32(1), bmSqr);
nscoord charWidth = bmSqr.width; // width of the radical symbol
nsBoundingMetrics radicalSize;
radicalSize.Clear(); // this tells Stretch() that we don't know the current size
// overline bar
renderingContext.GetBoundingMetrics(mBarChar.GetUnicode(), PRUint32(1), bmBar);
nscoord thickspace = bmBar.ascent + bmBar.descent; // height of the overline bar
// height(radical) should be >= height(base) + psi + ruleThickness
// however, nsMathMLChar will only try to meet this condition
// with no guarantee.
mSqrChar.Stretch(aPresContext, renderingContext,
NS_STRETCH_DIRECTION_VERTICAL,
contSize, radicalSize,
NS_STRETCH_LARGER);
// radicalSize have changed at this point, and should match with
// the bounding metrics of the char
mSqrChar.GetBoundingMetrics(bmSqr);
// Stretch the sqrt symbol to the appropriate height if it is not big enough.
nsStretchMetrics contSize(aDesiredSize);
nsStretchMetrics desSize(fontDescent, fontAscent, charWidth, fontAscent + fontDescent);
mSqrChar.Stretch(aPresContext, renderingContext, mStyleContext,
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
charWidth = desSize.width;
if (aDesiredSize.ascent < desSize.ascent) {
aDesiredSize.ascent = desSize.ascent;
}
if (aDesiredSize.descent < desSize.descent) {
aDesiredSize.descent = desSize.descent;
}
// According to TeX, the ascent of the returned radical should be
// the thickness of the overline
ruleThickness = bmSqr.ascent;
// adjust clearance psi to absorb any excess difference if any
// in height between radical and content
if (bmSqr.descent > (bmBase.ascent + bmBase.descent) + psi)
psi = (psi + bmSqr.descent - (bmBase.ascent + bmBase.descent))/2;
nscoord dx = 0, dy = 0;
// place the radical symbol
dy = ruleThickness; // leave a kern=ruleThickness at the top
mSqrChar.SetRect(nsRect(dx, dy, bmSqr.width, bmSqr.ascent + bmSqr.descent));
// place the radical bar
dx = bmSqr.width;
dy = ruleThickness; // leave a kern=ruleThickness at the top
mBarRect.SetRect(dx, dy, bmBase.width, ruleThickness);
// Update the desired size for the container.
// the baseline will be that of the base.
mBoundingMetrics.ascent = bmBase.ascent + psi + ruleThickness;
mBoundingMetrics.descent =
PR_MAX(bmBase.descent, (bmSqr.descent - (bmBase.ascent + psi)));
mBoundingMetrics.width = bmSqr.width + bmBase.width;
mBoundingMetrics.leftBearing = bmSqr.leftBearing;
mBoundingMetrics.rightBearing = bmSqr.width +
PR_MAX(bmBase.width, bmBase.rightBearing); // take also care of the rule
aDesiredSize.ascent = bmBase.ascent + psi + 2*ruleThickness;
aDesiredSize.descent =
PR_MAX(baseSize.descent, (mBoundingMetrics.descent + ruleThickness));
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
dx = 0;
dy = 2*onePixel + (bmSqr.ascent - fontAscent);
mSqrChar.SetRect(nsRect(dx, dy, desSize.width, aDesiredSize.height));
dx = bmSqr.rightBearing;
// Stretch the overline bar to the appropriate width if it is not big enough.
contSize = nsStretchMetrics(aDesiredSize);
desSize = nsStretchMetrics(fontDescent, fontAscent, bmBar.rightBearing-bmBar.leftBearing, fontAscent + fontDescent);
nsStretchMetrics oldSize = desSize;
mBarChar.Stretch(aPresContext, renderingContext, mStyleContext,
NS_STRETCH_DIRECTION_HORIZONTAL, contSize, desSize);
dy = 2*onePixel + (bmBar.ascent - fontAscent);
if (oldSize == desSize) { // hasn't changed size! Char will be painted as a normal char
dx -= bmBar.leftBearing; // adjust so that it coincides with the sqrt char
// XXX need also to check when a single glyph wil be used
}
mBarChar.SetRect(nsRect(dx, dy, desSize.width, 2*onePixel + thickspace));
// Update the size of the container
aDesiredSize.width += charWidth;
aDesiredSize.ascent += 2*onePixel + thickspace;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
//////////////////
// Adjust the origins to leave room for the sqrt char and the overline bar
nsRect rect;
dx = charWidth;
dy = aDesiredSize.ascent - oldAscent;
nsPoint origin;
dx = radicalSize.width;
dy = aDesiredSize.ascent - baseSize.ascent;
nsIFrame* childFrame = mFrames.FirstChild();
while (nsnull != childFrame) {
if (!IsOnlyWhitespace(childFrame)) {
childFrame->GetRect(rect);
childFrame->MoveTo(aPresContext, dx, rect.y + dy);
dx += rect.width;
childFrame->GetOrigin(origin);
childFrame->MoveTo(aPresContext, origin.x + dx, origin.y + dy);
}
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
@@ -218,7 +273,43 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
// ----------------------
// the Style System will use these to pass the proper style context to our MathMLChar
NS_IMETHODIMP
nsMathMLmsqrtFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
{
NS_PRECONDITION(aStyleContext, "null OUT ptr");
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
*aStyleContext = nsnull;
switch (aIndex) {
case NS_SQR_CHAR_STYLE_CONTEXT_INDEX:
mSqrChar.GetStyleContext(aStyleContext);
break;
default:
return NS_ERROR_INVALID_ARG;
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsqrtFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
{
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
switch (aIndex) {
case NS_SQR_CHAR_STYLE_CONTEXT_INDEX:
mSqrChar.SetStyleContext(aStyleContext);
break;
}
return NS_OK;
}
+10 -1
View File
@@ -19,6 +19,7 @@
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Vilya Harvey <vilya@nag.co.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmsqrtFrame_h___
@@ -58,6 +59,13 @@ class nsMathMLmsqrtFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
NS_IMETHOD
GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@@ -83,7 +91,8 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
nsMathMLChar mSqrChar, mBarChar;
nsMathMLChar mSqrChar;
nsRect mBarRect;
};
#endif /* nsMathMLmsqrtFrame_h___ */
+17 -6
View File
@@ -76,6 +76,8 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mPresentationData.mstyle = this;
mInnerScriptLevelIncrement = 0;
@@ -120,7 +122,8 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
NS_IMETHODIMP
nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle)
PRBool aDisplayStyle,
PRBool aCompressed)
{
// mstyle is special...
// Since UpdatePresentationData() can be called by a parent frame, the
@@ -136,6 +139,10 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement,
if (!NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
mPresentationData.scriptLevel += aScriptLevelIncrement;
}
if (aCompressed)
mPresentationData.flags |= NS_MATHML_COMPRESSED;
else
mPresentationData.flags &= ~NS_MATHML_COMPRESSED;
return NS_OK;
}
@@ -143,12 +150,14 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement,
NS_IMETHODIMP
nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle)
PRBool aDisplayStyle,
PRBool aCompressed)
{
// mstyle is special...
// Since UpdatePresentationDataFromChildAt() can be called by a parent frame,
// wee need to ensure that the attributes of mstyle take precedence
PRBool compressed = NS_MATHML_IS_COMPRESSED(mPresentationData.flags);
PRBool displayStyle = NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags);
if (NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) {
aDisplayStyle = displayStyle;
@@ -156,10 +165,12 @@ nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
if (NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) {
aScriptLevelIncrement = 0;
}
if (0 == aScriptLevelIncrement && aDisplayStyle == displayStyle)
return NS_OK;
if (0 == aScriptLevelIncrement &&
aDisplayStyle == displayStyle &&
aCompressed == compressed)
return NS_OK; // quick return, there is nothing to change
// let the base class worry about the update
return nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(aIndex,
aScriptLevelIncrement, aDisplayStyle);
aScriptLevelIncrement, aDisplayStyle, aCompressed);
}
+6 -17
View File
@@ -30,19 +30,6 @@
// <mstyle> -- style change
//
#if 0
#define NS_MATHML_MSTYLE_SCRIPTLEVEL_EXPLICIT (1)
#define NS_MATHML_MSTYLE_DISPLAYSTYLE (1<<1)
#define NS_MATHML_MSTYLE_HAS_SCRIPTLEVEL_EXPLICIT(_flags) \
(NS_MATHML_MSTYLE_SCRIPTLEVEL_EXPLICIT == ((_flags) & NS_MATHML_MSTYLE_SCRIPTLEVEL_EXPLICIT))
#define NS_MATHML_MSTYLE_HAS_DISPLAYSTYLE(_flags) \
(NS_MATHML_MSTYLE_DISPLAYSTYLE == ((_flags) & NS_MATHML_MSTYLE_DISPLAYSTYLE))
#endif
class nsMathMLmstyleFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
@@ -56,12 +43,14 @@ public:
NS_IMETHOD
UpdatePresentationData(PRInt32 aScriptLevel,
PRBool aDisplayStyle);
PRBool aDisplayStyle,
PRBool aCompressed);
NS_IMETHOD
UpdatePresentationDataFromChildAt(PRInt32 aIndex,
PRInt32 aScriptLevelIncrement,
PRBool aDisplayStyle);
PRBool aDisplayStyle,
PRBool aCompressed);
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
@@ -70,7 +59,8 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(0, mInnerScriptLevelIncrement, NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags));
UpdatePresentationDataFromChildAt(0, mInnerScriptLevelIncrement,
NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags), PR_FALSE);
InsertScriptLevelStyleContext(aPresContext);
return rv;
}
@@ -82,7 +72,6 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
PRInt32 mInnerScriptLevelIncrement;
// PRInt32 mFlags;
};
#endif /* nsMathMLmstyleFrame_h___ */
+9 -6
View File
@@ -91,7 +91,7 @@ nsMathMLmsubFrame::Init(nsIPresContext* aPresContext,
}
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
// mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -136,15 +136,18 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
// parameter v, Rule 18a, App. G, TeXbook
minSubScriptShift = bmBase.descent + aSubDrop;
}
else {
NS_ASSERTION((count < 2),"nsMathMLmsubFrame : invalid markup");
}
count++;
}
rv = aChildFrame->GetNextSibling(&aChildFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
#ifdef NS_DEBUG
if (2 != count) printf("msub: invalid markup");
#endif
if ((2 != count) || !baseFrame || !subScriptFrame) {
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
//////////////////
// Place Children
@@ -199,7 +202,7 @@ nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
aDesiredSize.width = baseSize.width + mScriptSpace + subScriptSize.width;
mReference.x = 0;
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
mReference.y = aDesiredSize.ascent;
if (aPlaceOrigin) {
nscoord dx, dy;
+1 -1
View File
@@ -55,7 +55,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE, PR_FALSE);
// switch the style of the subscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
+24 -22
View File
@@ -100,7 +100,7 @@ nsMathMLmsubsupFrame::Init(nsIPresContext* aPresContext,
}
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
// mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -120,9 +120,9 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics subScriptSize (nsnull);
nsHTMLReflowMetrics supScriptSize (nsnull);
nsIFrame* baseFrame;
nsIFrame* subScriptFrame;
nsIFrame* supScriptFrame;
nsIFrame* baseFrame = nsnull;
nsIFrame* subScriptFrame = nsnull;
nsIFrame* supScriptFrame = nsnull;
// parameter v, Rule 18a, Appendix G of the TeXbook
nscoord minSubScriptShift = 0;
// parameter u in Rule 18a, Appendix G of the TeXbook
@@ -159,15 +159,18 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
// parameter u, Rule 18a, App. G, TeXbook
minSupScriptShift = bmBase.ascent - aSupDrop;
}
else {
NS_ASSERTION((count < 2),"nsMathMLmsubFrame : invalid markup");
}
count++;
}
rv = aChildFrame->GetNextSibling(&aChildFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
#ifdef NS_DEBUG
if (3 != count) printf("msubsup: invalid markup");
#endif
if ((3 != count) || !baseFrame || !subScriptFrame || !supScriptFrame) {
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
//////////////////
// Place Children
@@ -184,18 +187,21 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
// aSubScriptShift1 = subscriptshift attribute * x-height
nscoord aSubScriptShift1, aSubScriptShift2;
// get x-height (an ex)
nscoord xHeight = 0;
nsCOMPtr<nsIFontMetrics> fm;
// 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);
aRenderingContext.SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
// get x-height (an ex)
nscoord xHeight;
fm->GetXHeight (xHeight);
nscoord aRuleSize;
GetRuleThickness (aRenderingContext, fm, aRuleSize);
// Get aSubScriptShift{1,2} default from font
GetSubScriptShifts (fm, aSubScriptShift1, aSubScriptShift2);
@@ -206,7 +212,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
aSubScriptShift1 = PR_MAX(aSubScriptShift1, mSubScriptShift);
aSubScriptShift2 = NSToCoordRound(aFactor * aSubScriptShift1);
}
// get a tentative value for subscriptshift
// Rule 18d, App. G, TeXbook
nscoord aSubScriptShift =
@@ -271,10 +277,6 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
// Rule 18e, App. G, TeXbook
//////////////////////////////////////////////////
nscoord aRuleSize;
// XXX need to do update this ...
GetRuleThickness (fm, aRuleSize);
// aRuleSize /= 2;
nscoord gap =
(aSupScriptShift - bmSupScript.descent) -
(bmSubScript.ascent - aSubScriptShift);
@@ -310,7 +312,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
PR_MAX((bmBase.supItalicCorrection + bmSupScript.width),
(bmBase.subItalicCorrection + bmSubScript.width));
// to be simplfied later
// to be simplified later
nscoord dyBase = mBoundingMetrics.ascent - bmBase.ascent;
nscoord dySubScript = mBoundingMetrics.ascent - bmSubScript.ascent + aSubScriptShift;
nscoord dySupScript = mBoundingMetrics.ascent - bmSupScript.ascent - aSupScriptShift;
@@ -327,7 +329,7 @@ nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
mReference.x = 0;
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
mReference.y = aDesiredSize.ascent;
mBoundingMetrics.leftBearing = bmBase.leftBearing;
mBoundingMetrics.rightBearing = bmBase.width + mScriptSpace +
PR_MAX((bmBase.supItalicCorrection + bmSupScript.rightBearing),
@@ -55,7 +55,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE, PR_FALSE);
// switch the style of the subscript and superscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
+11 -7
View File
@@ -90,7 +90,7 @@ nsMathMLmsupFrame::Init(nsIPresContext* aPresContext,
}
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
// mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -110,8 +110,8 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
nsRect aRect;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics supScriptSize (nsnull);
nsIFrame* baseFrame;
nsIFrame* supScriptFrame;
nsIFrame* baseFrame = nsnull;
nsIFrame* supScriptFrame = nsnull;
// parameter u in Rule 18a, Appendix G of the TeXbook
nscoord minSupScriptShift = 0;
@@ -136,14 +136,18 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
// parameter u, Rule 18a, App. G, TeXbook
minSupScriptShift = bmBase.ascent - aSupDrop;
}
else {
NS_ASSERTION((count < 2),"nsMathMLmsupFrame : invalid markup");
}
count++;
}
rv = aChildFrame->GetNextSibling(&aChildFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
#ifdef NS_DEBUG
if (2 != count) printf("msup: invalid markup");
#endif
if ((2 != count) || !baseFrame || !supScriptFrame) {
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
//////////////////
// Place Children
@@ -226,7 +230,7 @@ nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
aDesiredSize.width = baseSize.width + mScriptSpace + supScriptSize.width;
mReference.x = 0;
mReference.y = aDesiredSize.ascent - mBoundingMetrics.ascent;
mReference.y = aDesiredSize.ascent;
if (aPlaceOrigin) {
nscoord dx, dy;
+1 -1
View File
@@ -55,7 +55,7 @@ public:
{
nsresult rv;
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE, PR_FALSE);
// switch the style of the superscript
InsertScriptLevelStyleContext(aPresContext);
// check whether or not this is an embellished operator
+188 -5
View File
@@ -47,6 +47,8 @@
nsresult
NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
// return NS_NewMathMLmrowFrame(aPresShell, aNewFrame);
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
@@ -69,20 +71,201 @@ nsMathMLmtdFrame::~nsMathMLmtdFrame()
{
}
#if 0
// wrap our children in an anonymous inferred mrow
NS_IMETHODIMP
nsMathMLmtdFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
// First, let the base class do its work
nsresult rv = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList);
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsIFrame* newFrame = nsnull;
NS_NewMathMLmrowFrame(shell, &newFrame);
NS_ASSERTION(newFrame, "Failed to create new frame");
if (newFrame) {
nsCOMPtr<nsIStyleContext> newStyleContext;
aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozAnonymousBlock,
mStyleContext, PR_FALSE,
getter_AddRefs(newStyleContext));
rv = newFrame->Init(aPresContext, mContent, this, newStyleContext, nsnull);
if (NS_FAILED(rv)) {
newFrame->Destroy(aPresContext);
return rv;
}
// our children become children of the new frame
nsIFrame* firstChild = mFrames.FirstChild();
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);
}
return rv;
}
#endif
NS_IMETHODIMP
nsMathMLmtdFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
// Let the base class do the reflow
rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
nsresult rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
printf("Ending cell body with aDesiredSize: asc:%d desc:%d\n",
aDesiredSize.ascent, aDesiredSize.descent);
#if 0
// make sure that we return the desired size of our inner mrow frame
nsIFrame* childFrame = mFrames.FirstChild();
nsIMathMLFrame* aMathMLFrame = nsnull;
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
NS_ASSERTION(NS_SUCCEEDED(rv) && nsnull != aMathMLFrame, "Mystery");
if (NS_SUCCEEDED(rv) && nsnull != aMathMLFrame) {
// get our ascent and descent
nsPoint ref;
aMathMLFrame->GetReference(ref);
nsBoundingMetrics bm;
aMathMLFrame->GetBoundingMetrics(bm);
// aDesiredSize.ascent = ref.y + bm.ascent;
// aDesiredSize.descent = aDesiredSize.height - ref.y;
nsRect rect;
childFrame->GetRect(rect);
nsFrame::ListTag(stdout, childFrame);
printf("\nEnding mtd with: rect(%d,%d,%d,%d) ref(%d,%d) bm:asc=%d,desc=%d, asc:%d desc:%d\n",
rect.x,rect.y,rect.width,rect.height, ref.x, ref.y, bm.ascent,bm.descent, aDesiredSize.ascent,aDesiredSize.descent);
}
#endif
// more about <maligngroup/> and <malignmark/> later
// ...
return rv;
}
NS_IMETHODIMP
nsMathMLmtdFrame::DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus)
{
nsRect rect;
GetRect(rect);
nsFrame::ListTag(stdout, this);
printf("\nend mtd with: rect(%d,%d,%d,%d)\n",
rect.x,rect.y,rect.width,rect.height);
#if 0
nsIFrame* childFrame = mFrames.FirstChild();
childFrame->GetRect(rect);
nsFrame::ListTag(stdout, this);
printf("\nend child mtd with: rect(%d,%d,%d,%d)\n",
rect.x,rect.y,rect.width,rect.height);
#endif
// NS_ASSERTION(0, "Break in mtd::DidReflow");
return nsHTMLContainerFrame::DidReflow(aPresContext, aStatus);
}
#if 0
NS_IMETHODIMP
nsMathMLmtdFrame:Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aReflowStatus)
{
nsresult rv = NS_OK;
nsIFrame* kid = mFrames.FirstChild();
nsIFrame* nextRCFrame = nsnull;
if (aReflowState.reason == eReflowReason_Incremental) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this != target) {
aReflowState.reflowCommand->GetNext(nextRCFrame);
}
}
// Setup reflow state for our child
nsSize availSize(aReflowState.availableWidth, aReflowState.availableHeight);
const nsMargin& bp = aReflowState.mComputedBorderPadding;
nscoord lr = bp.left + bp.right;
nscoord tb = bp.top + bp.bottom;
if (NS_UNCONSTRAINEDSIZE != availSize.width) {
availSize.width -= lr;
}
if (NS_UNCONSTRAINEDSIZE != availSize.height) {
availSize.height -= tb;
}
// Reflow the child
if (!aReflowState.mLineLayout) {
printf("No line layout for mtd ....\n");
// When there is no lineLayout provided, we provide our own. The
// only time that the first-letter-frame is not reflowing in a
// line context is when its floating.
nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize);
nsLineLayout ll(aPresContext, nsnull, &aReflowState,
nsnull != aMetrics.maxElementSize);
// ll.BeginLineReflow(0, 0, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE,
// PR_FALSE, PR_TRUE);
ll.BeginLineReflow(0, 0, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE,
PR_FALSE, PR_FALSE);
// aLineLayout.BeginLineReflow(x, aState.mY,
// availWidth, availHeight,
// impactedByFloaters,
// PR_FALSE /*XXX isTopOfPage*/);
rs.mLineLayout = &ll;
// ll.SetFirstLetterStyleOK(PR_TRUE);
kid->WillReflow(aPresContext);
kid->Reflow(aPresContext, aMetrics, rs, aReflowStatus);
ll.EndLineReflow();
}
else {
printf("Line layout for mtd is %p....\n", aReflowState.mLineLayout);
// Pretend we are a span and reflow the child frame
nsLineLayout* ll = aReflowState.mLineLayout;
PRBool pushedFrame;
ll->BeginSpan(this, &aReflowState, bp.left, availSize.width);
ll->ReflowFrame(kid, &nextRCFrame, aReflowStatus, &aMetrics, pushedFrame);
nsSize size;
ll->EndSpan(this, size, aMetrics.maxElementSize);
}
// Place and size the child and update the output metrics
kid->MoveTo(aPresContext, bp.left, bp.top);
kid->SizeTo(aPresContext, aMetrics.width, aMetrics.height);
kid->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
aMetrics.width += lr;
aMetrics.height += tb;
aMetrics.ascent += bp.top;
aMetrics.descent += bp.bottom;
if (aMetrics.maxElementSize) {
aMetrics.maxElementSize->width += lr;
aMetrics.maxElementSize->height += tb;
}
return rv;
}
#endif
+12
View File
@@ -31,15 +31,27 @@
//
class nsMathMLmtdFrame : public nsAreaFrame {
//class nsMathMLmtdFrame : public nsBlockFrame {
public:
friend nsresult NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
#if 0
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
#endif
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD
DidReflow(nsIPresContext* aPresContext,
nsDidReflowStatus aStatus);
protected:
nsMathMLmtdFrame();
virtual ~nsMathMLmtdFrame();
+110 -78
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
@@ -76,8 +77,11 @@ nsMathMLmunderFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
}
@@ -190,8 +194,8 @@ XXX The winner is the outermost setting in conflicting settings like these:
if (underscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE, PR_FALSE);
}
// switch the style of the underscript
@@ -200,37 +204,6 @@ XXX The winner is the outermost setting in conflicting settings like these:
return rv;
}
NS_IMETHODIMP
nsMathMLmunderFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
/////////////
// Reflow children
ReflowChildren(1, aPresContext, aDesiredSize, aReflowState, aStatus);
/////////////
// Ask stretchy children to stretch themselves
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
nsStretchMetrics containerSize(aDesiredSize);
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_HORIZONTAL;
StretchChildren(aPresContext, renderingContext, stretchDir, containerSize);
/////////////
// Place children now by re-adjusting the origins to align the baselines
FinalizeReflow(1, aPresContext, renderingContext, aDesiredSize);
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or
@@ -256,61 +229,120 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nscoord count = 0;
nsRect rect[2];
nsIFrame* child[2];
nsresult rv = NS_OK;
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmUnder;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics underSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* underFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame) && 2 > count) {
childFrame->GetRect(rect[count]);
child[count] = 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++;
}
childFrame->GetNextSibling(&childFrame);
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
if ((2 != count) || !baseFrame || !underFrame) {
#ifdef NS_DEBUG
printf("munder: invalid markup");
#endif
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
aDesiredSize.descent = rect[0].x;
aDesiredSize.ascent = rect[0].y;
aDesiredSize.descent += rect[1].height;
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
////////////////////
// Place Children
rect[0].x = (aDesiredSize.width - rect[0].width) / 2; // center w.r.t largest width
rect[1].x = (aDesiredSize.width - rect[1].width) / 2;
rect[0].y = 0;
rect[1].y = aDesiredSize.height - rect[1].height;
//ignore the leading (line spacing) that is attached to the text
nscoord leading;
const nsStyleFont* font =
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
aRenderingContext.SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
const nsStyleFont* aFont =
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
aPresContext->GetMetricsFor(aFont->mFont, getter_AddRefs(fm));
fm->GetLeading(leading);
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
nscoord ruleThickness;
GetRuleThickness (aRenderingContext, fm, ruleThickness);
// there are 2 different types of placement depending on
// whether we want an accented under or not
nscoord italicCorrection = 0;
nscoord delta1 = 0; // gap between base and underscript
nscoord delta2 = 0; // extra space beneath underscript
if (!NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)) {
// Rule 13a, App. G, TeXbook
// GetItalicCorrectionFromChild (baseFrame, italicCorrection);
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
dummy, bigOpSpacing2,
dummy, bigOpSpacing4,
bigOpSpacing5);
delta1 = PR_MAX(bigOpSpacing2, (bigOpSpacing4 - bmUnder.ascent));
delta2 = bigOpSpacing5;
}
else {
// No corresponding rule in TeXbook - we are on our own here
// XXX tune the gap delta between base and underscript
// Should we use Rule 10 like \underline does?
delta1 = ruleThickness;
delta2 = ruleThickness;
}
// empty under?
if (0 == (bmUnder.ascent + bmUnder.descent)) delta1 = 0;
mBoundingMetrics.ascent = bmBase.ascent;
mBoundingMetrics.descent =
bmBase.descent + delta1 + bmUnder.ascent + bmUnder.descent;
mBoundingMetrics.width =
PR_MAX(bmBase.width/2,(bmUnder.width + italicCorrection/2)/2) +
PR_MAX(bmBase.width/2,(bmUnder.width - italicCorrection/2)/2);
nscoord dxBase = (mBoundingMetrics.width - bmBase.width) / 2;
nscoord dxUnder = (mBoundingMetrics.width - (bmUnder.width + italicCorrection/2)) / 2;
aDesiredSize.ascent = baseSize.ascent;
aDesiredSize.descent = mBoundingMetrics.descent + delta2;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
mBoundingMetrics.leftBearing =
PR_MIN(dxBase + bmBase.leftBearing, dxUnder + bmUnder.leftBearing);
mBoundingMetrics.rightBearing =
PR_MAX(dxBase + bmBase.rightBearing, dxUnder + bmUnder.rightBearing);
aDesiredSize.height -= leading;
aDesiredSize.descent -= leading;
rect[1].y -= leading;
//
if (aPlaceOrigin) {
// child[0]->SetRect(aPresContext, rect[0]);
// child[1]->SetRect(aPresContext, rect[1]);
nsHTMLReflowMetrics childSize(nsnull);
for (PRInt32 i=0; i<count; i++) {
childSize.width = rect[i].width;
childSize.height = rect[i].height;
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
}
}
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
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;
FinishReflowChild(underFrame, aPresContext, underSize, dxUnder, dy, 0);
}
// XXX Fix me!
mBoundingMetrics.ascent = aDesiredSize.ascent;
mBoundingMetrics.descent = aDesiredSize.descent;
mBoundingMetrics.width = aDesiredSize.width;
return NS_OK;
}
+1 -6
View File
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmunderFrame_h___
@@ -41,12 +42,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
* Pierre Phaneuf <pp@ludusdesign.com>
*/
@@ -76,7 +77,7 @@ nsMathMLmunderoverFrame::Init(nsIPresContext* aPresContext,
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
return rv;
}
@@ -137,7 +138,7 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value == "true") {
if (value.Equals("true")) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
@@ -167,8 +168,8 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
if (value.Equals("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
@@ -195,8 +196,8 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
if (value == "true") embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value == "false") embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
if (value.Equals("true")) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals("false")) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
aMathMLFrame->SetEmbellishData(embellishData);
}
@@ -221,15 +222,15 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
if (underscriptMathMLFrame) {
incrementScriptLevel = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE, PR_FALSE);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE, PR_FALSE);
}
if (overscriptMathMLFrame)
{
incrementScriptLevel = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)? 0 : 1;
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationData(incrementScriptLevel, PR_FALSE, PR_FALSE);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(0, incrementScriptLevel, PR_FALSE, PR_FALSE);
}
// switch the style of the underscript and the overscript
@@ -238,37 +239,6 @@ nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
/////////////
// Reflow children
ReflowChildren(1, aPresContext, aDesiredSize, aReflowState, aStatus);
/////////////
// Ask stretchy children to stretch themselves
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
nsStretchMetrics containerSize(aDesiredSize);
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_HORIZONTAL;
StretchChildren(aPresContext, renderingContext, stretchDir, containerSize);
/////////////
// Place children now by re-adjusting the origins to align the baselines
FinalizeReflow(1, aPresContext, renderingContext, aDesiredSize);
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
/*
The REC says:
* If the base is an operator with movablelimits="true" (or an embellished
@@ -294,65 +264,174 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nscoord count = 0;
nsRect rect[3];
nsIFrame* child[3];
aDesiredSize.width = 0;
nsresult rv = NS_OK;
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmUnder, bmOver;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics underSize (nsnull);
nsHTMLReflowMetrics overSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* overFrame = nsnull;
nsIFrame* underFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (!IsOnlyWhitespace(childFrame) && 3 > count) {
child[count] = childFrame;
childFrame->GetRect(rect[count]);
if (aDesiredSize.width < rect[count].width) aDesiredSize.width = rect[count].width;
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++;
}
childFrame->GetNextSibling(&childFrame);
rv = childFrame->GetNextSibling(&childFrame);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
}
if ((3 != count) || !baseFrame || !underFrame || !overFrame) {
#ifdef NS_DEBUG
printf("munderover: invalid markup\n");
#endif
// report an error, encourage people to get their markups in order
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
aDesiredSize.descent = rect[0].x;
aDesiredSize.ascent = rect[0].y;
aDesiredSize.ascent += rect[2].height;
aDesiredSize.descent += rect[1].height;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
rect[0].x = (aDesiredSize.width - rect[0].width) / 2; // center w.r.t largest width
rect[1].x = (aDesiredSize.width - rect[1].width) / 2;
rect[2].x = (aDesiredSize.width - rect[2].width) / 2;
rect[0].y = rect[2].height;
rect[1].y = aDesiredSize.height - rect[1].height;
rect[2].y = 0;
//ignore the leading (line spacing) that is attached to the text
nsStyleFont font;
mStyleContext->GetStyle(eStyleStruct_Font, font);
////////////////////
// Place Children
const nsStyleFont* font =
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
aRenderingContext.SetFont(font->mFont);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
nscoord leading;
fm->GetLeading(leading);
aRenderingContext.GetFontMetrics(*getter_AddRefs(fm));
aDesiredSize.height -= 2*leading;
aDesiredSize.ascent -= leading;
aDesiredSize.descent -= leading;
rect[0].y -= leading;
rect[1].y -= 2*leading;
//
nscoord xHeight = 0;
fm->GetXHeight (xHeight);
nscoord ruleThickness;
GetRuleThickness (aRenderingContext, fm, ruleThickness);
// there are 2 different types of placement depending on
// whether we want an accented under or not
nscoord italicCorrection = 0;
nscoord underDelta1 = 0; // gap between base and underscript
nscoord underDelta2 = 0; // extra space beneath underscript
if (!NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)) {
// Rule 13a, App. G, TeXbook
// GetItalicCorrectionFromChild (baseFrame, italicCorrection);
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
dummy, bigOpSpacing2,
dummy, bigOpSpacing4,
bigOpSpacing5);
underDelta1 = PR_MAX(bigOpSpacing2, (bigOpSpacing4 - bmUnder.ascent));
underDelta2 = bigOpSpacing5;
}
else {
// No corresponding rule in TeXbook - we are on our own here
// XXX tune the gap delta between base and underscript
// Should we use Rule 10 like \underline does?
underDelta1 = ruleThickness;
underDelta2 = ruleThickness;
}
// empty under?
if (0 == (bmUnder.ascent + bmUnder.descent)) underDelta1 = 0;
nscoord aCorrection = 0;
nscoord overDelta1 = 0; // gap between base and overscript
nscoord overDelta2 = 0; // extra space above overscript
if (!NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
// Rule 13a, App. G, TeXbook
// GetItalicCorrectionFromChild (baseFrame, aCorrection);
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;
GetBigOpSpacings (fm,
bigOpSpacing1, dummy,
bigOpSpacing3, dummy,
bigOpSpacing5);
overDelta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - bmOver.descent));
overDelta2 = bigOpSpacing5;
// XXX This is not a TeX rule...
// delta1 (as computed abvove) 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)
overDelta1 = PR_MAX(bigOpSpacing1, (bigOpSpacing3 - (bmOver.ascent + bmOver.descent)));
}
else {
// Rule 13, App. G, TeXbook
GetSkewCorrectionFromChild (aPresContext, baseFrame, aCorrection);
#if 0
// XXX tune these
overDelta1 = PR_MIN(bmOver.ascent,xHeight);
overDelta2 = 0;
#endif
overDelta1 = ruleThickness;
overDelta2 = ruleThickness;
}
// empty over?
if (0 == (bmOver.ascent + bmOver.descent)) overDelta1 = 0;
mBoundingMetrics.ascent =
bmBase.ascent + overDelta1 + bmOver.ascent + bmOver.descent;
mBoundingMetrics.descent =
bmBase.descent + underDelta1 + bmUnder.ascent + bmUnder.descent;
mBoundingMetrics.width =
PR_MAX(bmBase.width/2,PR_MAX((bmUnder.width + italicCorrection/2)/2,(bmOver.width - aCorrection/2)/2)) +
PR_MAX(bmBase.width/2,PR_MAX((bmUnder.width - italicCorrection/2)/2,(bmOver.width + aCorrection/2)/2));
nscoord dxBase = (mBoundingMetrics.width - bmBase.width) / 2;
nscoord dxOver = (mBoundingMetrics.width - (bmOver.width - aCorrection/2)) / 2;
nscoord dxUnder = (mBoundingMetrics.width - (bmUnder.width + italicCorrection/2)) / 2;
aDesiredSize.ascent =
mBoundingMetrics.ascent + overDelta2;
aDesiredSize.descent =
mBoundingMetrics.descent + underDelta2;
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
aDesiredSize.width = mBoundingMetrics.width;
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
mBoundingMetrics.leftBearing =
PR_MIN(dxBase + bmBase.leftBearing, dxUnder + bmUnder.leftBearing);
mBoundingMetrics.rightBearing =
PR_MAX(dxBase + bmBase.rightBearing, dxUnder + bmUnder.rightBearing);
mBoundingMetrics.leftBearing =
PR_MIN(mBoundingMetrics.leftBearing, dxOver + bmOver.leftBearing);
mBoundingMetrics.rightBearing =
PR_MAX(mBoundingMetrics.rightBearing, dxOver + bmOver.rightBearing);
aDesiredSize.mBoundingMetrics = mBoundingMetrics;
if (aPlaceOrigin) {
// child[0]->SetRect(aPresContext, rect[0]);
// child[1]->SetRect(aPresContext, rect[1]);
// child[2]->SetRect(aPresContext, rect[2]);
nsHTMLReflowMetrics childSize(nsnull);
for (PRInt32 i=0; i<count; i++) {
childSize.width = rect[i].width;
childSize.height = rect[i].height;
FinishReflowChild(child[i], aPresContext, childSize, rect[i].x, rect[i].y, 0);
}
nscoord dy;
// place overscript
dy = aDesiredSize.ascent - mBoundingMetrics.ascent + bmOver.ascent - overSize.ascent;
FinishReflowChild (overFrame, aPresContext, overSize, dxOver, dy, 0);
// place base
dy = aDesiredSize.ascent - baseSize.ascent;
FinishReflowChild (baseFrame, aPresContext, baseSize, dxBase, dy, 0);
// place underscript
dy = aDesiredSize.ascent + mBoundingMetrics.descent - bmUnder.descent - underSize.ascent;
FinishReflowChild (underFrame, aPresContext, underSize, dxUnder, dy, 0);
}
// XXX Fix me!
mBoundingMetrics.ascent = aDesiredSize.ascent;
mBoundingMetrics.descent = aDesiredSize.descent;
mBoundingMetrics.width = aDesiredSize.width;
return NS_OK;
}
@@ -18,6 +18,7 @@
* Contributor(s):
* Roger B. Sidje <rbs@maths.uq.edu.au>
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
* Shyjan Mahamud <mahamud@cs.cmu.edu>
*/
#ifndef nsMathMLmunderoverFrame_h___
@@ -41,12 +42,6 @@ public:
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,