зеркало из https://github.com/mozilla/pjs.git
[NOT PART OF THE DEFAULT BUILD]. *Changes to bring the MathML code in sync with layout (this will clear bugs 19398 and 20858). *Postfixed atoms with underscore. *Major revamps to launch the support of embellished operators.
This commit is contained in:
Родитель
26924339a8
Коммит
1231a3e001
|
@ -22,6 +22,15 @@
|
|||
#ifndef nsIMathMLFrame_h___
|
||||
#define nsIMathMLFrame_h___
|
||||
|
||||
struct nsEmbellishState;
|
||||
struct nsStretchMetrics;
|
||||
typedef PRInt32 nsStretchDirection;
|
||||
|
||||
#define NS_STRETCH_DIRECTION_UNSUPPORTED -1
|
||||
#define NS_STRETCH_DIRECTION_DEFAULT 0
|
||||
#define NS_STRETCH_DIRECTION_HORIZONTAL 1
|
||||
#define NS_STRETCH_DIRECTION_VERTICAL 2
|
||||
|
||||
// IID for the nsIMathMLFrame interface (the IID was taken from IIDS.h)
|
||||
/* a6cf9113-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IMATHMLFRAME_IID \
|
||||
|
@ -34,20 +43,133 @@ class nsIMathMLFrame : public nsISupports {
|
|||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IMATHMLFRAME_IID; return iid; }
|
||||
|
||||
/* SUPPORT FOR PRECISE POSITIONING */
|
||||
/*====================================================================*/
|
||||
|
||||
/* Metrics that _exactly_ enclose the text of the frame.
|
||||
* The frame *must* have *already* being reflowed, before you can call
|
||||
* the GetBoundingMetrics() method.
|
||||
* Note that for a frame with nested children, the bounding metrics
|
||||
* will exactly enclose its children. For example, the bounding metrics
|
||||
* of msub is the smallest rectangle that exactly encloses both the
|
||||
* base and the subscript.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics) = 0;
|
||||
/*
|
||||
NS_IMETHOD
|
||||
GetReference(nsPoint& aReference) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
SetReference(const nsPoint& aReference) = 0;
|
||||
*/
|
||||
|
||||
/* SUPPORT FOR STRETCHY ELEMENTS: <mo> */
|
||||
/*====================================================================*/
|
||||
|
||||
/* Stretch :
|
||||
* method used to ask a stretchy MathML frame to stretch
|
||||
* itself depending on its context
|
||||
* Called to ask a stretchy MathML frame to stretch itself depending
|
||||
* on its context.
|
||||
*
|
||||
* @param aStretchDirection [in] the direction where to attempt to
|
||||
* stretch.
|
||||
* @param aContainerSize [in] struct that suggests the maximumn size for
|
||||
* 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.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize) = 0;
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize) = 0;
|
||||
|
||||
#if 0
|
||||
NS_IMETHOD
|
||||
GetDesiredStretchSize(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchMetrics& aDesiredStretchSize) = 0;
|
||||
#endif
|
||||
/* Place :
|
||||
* This method is used before returning from Reflow(), or when a MathML frame
|
||||
* has just been stretched. It is called to fine-tune the positions of the elements.
|
||||
*
|
||||
* IMPORTANT: This method uses the origin of child frames (rect.x and rect.y) as
|
||||
* placeholders between calls: On invocation, child->GetRect(rect) should give a
|
||||
* rect such that rect.x holds the child's descent, rect.y holds the child's ascent,
|
||||
* (rect.width should give the width, and rect.height should give the height).
|
||||
* The Place() method will use this information to compute the desired size
|
||||
* of the frame.
|
||||
*
|
||||
* @param aPlaceOrigin [in]
|
||||
* If aPlaceOrigin is false, compute your desired size using the
|
||||
* information in your children's rectangles. However, upon return,
|
||||
* the origins of your children should keep their ascent information, i.e.,
|
||||
* a child rect.x, and rect.y should still act like placeholders for the
|
||||
* child's descent and ascent.
|
||||
*
|
||||
* If aPlaceOrigin is true, reflow is finished. You should position all
|
||||
* your children, and return your desired size. You should now convert
|
||||
* the origins of your child frames into the coordinate system
|
||||
* expected by Gecko (which is relative to the upper-left
|
||||
* corner of the parent) and use FinishReflowChild() on your children
|
||||
* to complete post-reflow operations.
|
||||
*
|
||||
* @param aDesiredSize [out] parameter where you should return your
|
||||
* desired size and your ascent/descent info. Compute your desired size
|
||||
* using the information in your children's rectangles, and include any
|
||||
* space you want for border/padding in the desired size you return.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize) = 0;
|
||||
|
||||
/* EmbellishOperator :
|
||||
* Call this method to probe and set a frame as an "embellished operator".
|
||||
* Calls must be bottom up. The method will set the frame as an
|
||||
* "embellished operator" if the frame satisfies the definition of
|
||||
* the MathML REC. Conversely, it will set the frame as
|
||||
* non-embellished if it is not an "embellished operator".
|
||||
*
|
||||
* Note that this method must only be called from tags who *can* be
|
||||
* embellished operators.
|
||||
*
|
||||
* The MathML REC precisely defines an "embellished operator" as:
|
||||
* - an <mo> element;
|
||||
* - or one of the elements <msub>, <msup>, <msubsup>, <munder>, <mover>,
|
||||
* <munderover>, <mmultiscripts>, <mfrac>, or <semantics>, whose first
|
||||
* argument exists and is an embellished operator;
|
||||
* - or one of the elements <mstyle>, <mphantom>, or <mpadded>, such that
|
||||
* an <mrow> containing the same arguments would be an embellished
|
||||
* operator;
|
||||
* - or an <maction> element whose selected subexpression exists and is an
|
||||
* embellished operator;
|
||||
* - or an <mrow> whose arguments consist (in any order) of one embellished
|
||||
* operator and zero or more spacelike elements.
|
||||
*
|
||||
* When an embellished frame receives a Stretch() command, it passes the
|
||||
* command to its first child and the stretched size is bubbled up from the
|
||||
* inner-most <mo> frame.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
EmbellishOperator() = 0;
|
||||
|
||||
/* GetEmbellishState/SetEmbellishState :
|
||||
* Get/Set the mEmbellish member data.
|
||||
*/
|
||||
|
||||
NS_IMETHOD
|
||||
GetEmbellishState(nsEmbellishState& aEmbellishState) = 0;
|
||||
|
||||
NS_IMETHOD
|
||||
SetEmbellishState(const nsEmbellishState& aEmbellishState) = 0;
|
||||
|
||||
|
||||
/* SUPPORT FOR SCRIPTING ELEMENTS: */
|
||||
|
@ -64,6 +186,7 @@ public:
|
|||
* Increments the scriptlevel of the frame, and set its displaystyle.
|
||||
* 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.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
|
@ -86,5 +209,94 @@ public:
|
|||
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);
|
||||
}
|
||||
};
|
||||
|
||||
#define NS_MATHML_EMBELLISH_OPERATOR 0x1
|
||||
|
||||
#define NS_MATHML_STRETCH_FIRST_CHILD NS_MATHML_EMBELLISH_OPERATOR
|
||||
#define NS_MATHML_STRETCH_ALL_CHILDREN 0x2
|
||||
|
||||
#define NS_MATHML_STRETCH_DONE 0x4
|
||||
|
||||
#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
|
||||
(NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
|
||||
|
||||
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
|
||||
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
|
||||
|
||||
// an embellished container will fire a stretch command to its first (non-empty) child
|
||||
#define NS_MATHML_WILL_STRETCH_FIRST_CHILD(_flags) \
|
||||
(NS_MATHML_STRETCH_FIRST_CHILD == ((_flags) & NS_MATHML_STRETCH_FIRST_CHILD))
|
||||
|
||||
// <mrow> (or an inferred mrow) will fire a stretch command to all its (non-empty) children
|
||||
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN(_flags) \
|
||||
(NS_MATHML_STRETCH_ALL_CHILDREN == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN))
|
||||
|
||||
// struct used by an embellished container to keep track of its embellished child
|
||||
struct nsEmbellishState {
|
||||
PRUint32 flags;
|
||||
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;
|
||||
|
||||
nsEmbellishState()
|
||||
{
|
||||
flags = 0;
|
||||
firstChild = nsnull;
|
||||
core = nsnull;
|
||||
direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
||||
leftSpace = rightSpace = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* nsIMathMLFrame_h___ */
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
// XXX Error-prone stuff. See how it can be automated.
|
||||
|
||||
/* Structure of the table gMathMLCharGlyph[]:
|
||||
------------------------------------------
|
||||
The table is divided into sections, each corresponding to a
|
||||
stretchy symbol. Each section itself is divided into two blocks
|
||||
that are separated with the special null code 0x0000.
|
||||
|
@ -58,8 +59,8 @@
|
|||
Another separate table, gMathMLCharIndex[], is used to store
|
||||
pointers to the beginning of each section.
|
||||
|
||||
3 steps are needed to extend the table:
|
||||
---------------------------------------
|
||||
Three steps are needed to extend the table:
|
||||
---------------------------------------=---
|
||||
1. Append your new section in gMathMLCharGlyph[].
|
||||
2. Append your new enum in nsMathMLCharEnum, and kMathMLChar
|
||||
3. Append a new pointer in gMathMLCharIndex[], so that
|
||||
|
@ -222,17 +223,29 @@ static PRUnichar gMathMLCharGlyph[] = {
|
|||
//------------
|
||||
//index = 66
|
||||
//Section for: square-root bar
|
||||
0xF8E5, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0x00AF, // RADICAL EXTENDER # radicalex (CUS) -- formerly 0xF8E5
|
||||
|
||||
0x0000, // That's all folks ...
|
||||
//Block of partial glyphs in the order top/left, middle, bottom/right, glue
|
||||
0xF8E5, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0xF8E5, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0xF8E5, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0xF8E5, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0x00AF, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0x00AF, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0x00AF, // RADICAL EXTENDER # radicalex (CUS)
|
||||
0x00AF, // RADICAL EXTENDER # radicalex (CUS)
|
||||
|
||||
//------------
|
||||
//index = 72
|
||||
//Section for: vertical bar (0x2223)
|
||||
'|',
|
||||
|
||||
0x0000, // That's all folks ...
|
||||
//Block of partial glyphs in the order top/left, middle, bottom/right, glue
|
||||
'|',
|
||||
'|',
|
||||
'|',
|
||||
'|',
|
||||
|
||||
//------------
|
||||
//index = 78
|
||||
//end of table ...
|
||||
0x0000,
|
||||
};
|
||||
|
@ -251,47 +264,84 @@ static PRInt32 gMathMLCharIndex[] = {
|
|||
54, // eMathMLChar_LeftArrow,
|
||||
60, // eMathMLChar_RightArrow,
|
||||
66, // eMathMLChar_RadicalBar,
|
||||
72, // safeguard, *must* always point at the *end* of gMathMLCharGlyph[]
|
||||
72, // eMathMLChar_Radical, -- placeholder for now
|
||||
72, // eMathMLChar_VerticalBar,
|
||||
78, // safeguard, *must* always point at the *end* of gMathMLCharGlyph[]
|
||||
};
|
||||
|
||||
// data to enable a clean architecture and extensibility
|
||||
|
||||
#define STRETCH_UNSUPPORTED NS_STRETCH_DIRECTION_UNSUPPORTED
|
||||
#define STRETCH_HORIZONTAL NS_STRETCH_DIRECTION_HORIZONTAL
|
||||
#define STRETCH_VERTICAL NS_STRETCH_DIRECTION_VERTICAL
|
||||
|
||||
static const PRInt32 kMathMLChar[] = {
|
||||
eMathMLChar_LeftParenthesis , '(',
|
||||
eMathMLChar_RightParenthesis , ')',
|
||||
eMathMLChar_Integral , 0x222B,
|
||||
eMathMLChar_LeftSquareBracket, '[',
|
||||
eMathMLChar_RightSquareBracket, ']',
|
||||
eMathMLChar_LeftCurlyBracket, '{',
|
||||
eMathMLChar_RightCurlyBracket, '}',
|
||||
eMathMLChar_DownArrow, 0x2193,
|
||||
eMathMLChar_UpArrow, 0x2191,
|
||||
eMathMLChar_LeftArrow, 0x2190,
|
||||
eMathMLChar_RightArrow, 0x2192,
|
||||
eMathMLChar_RadicalBar, 0xF8E5,
|
||||
// eMathMLChar_Radical, 0x221A,
|
||||
eMathMLChar_LeftParenthesis , '(', STRETCH_VERTICAL,
|
||||
eMathMLChar_RightParenthesis , ')', STRETCH_VERTICAL,
|
||||
eMathMLChar_Integral , 0x222B, STRETCH_VERTICAL,
|
||||
eMathMLChar_LeftSquareBracket, '[', STRETCH_VERTICAL,
|
||||
eMathMLChar_RightSquareBracket, ']', STRETCH_VERTICAL,
|
||||
eMathMLChar_LeftCurlyBracket, '{', STRETCH_VERTICAL,
|
||||
eMathMLChar_RightCurlyBracket, '}', STRETCH_VERTICAL,
|
||||
eMathMLChar_DownArrow, 0x2193, STRETCH_VERTICAL,
|
||||
eMathMLChar_UpArrow, 0x2191, STRETCH_VERTICAL,
|
||||
eMathMLChar_LeftArrow, 0x2190, STRETCH_HORIZONTAL,
|
||||
eMathMLChar_RightArrow, 0x2192, STRETCH_HORIZONTAL,
|
||||
eMathMLChar_RadicalBar, 0x00AF, STRETCH_HORIZONTAL,
|
||||
eMathMLChar_Radical, 0x221A, STRETCH_UNSUPPORTED,
|
||||
eMathMLChar_VerticalBar, '|', STRETCH_VERTICAL,
|
||||
};
|
||||
|
||||
#undef STRETCH_UNSUPPORTED
|
||||
#undef STRETCH_HORIZONTAL
|
||||
#undef STRETCH_VERTICAL
|
||||
|
||||
//---------------------------------------------
|
||||
|
||||
// Helper method that detects a new enum and cache it for you.
|
||||
// You do not have to call this method. SetData() will call it
|
||||
// for you whenever mData changes.
|
||||
// If you call SetData(), it will lookup the enum
|
||||
// of the char and set it for you.
|
||||
void
|
||||
nsMathMLChar::SetEnum() {
|
||||
nsMathMLChar::SetData(nsString& aData) {
|
||||
mData = aData;
|
||||
// some assumptions until proven otherwise!
|
||||
mEnum = eMathMLChar_DONT_STRETCH;
|
||||
mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
||||
// lookup the enum ...
|
||||
if (1 == mData.Length()) {
|
||||
PRUnichar ch = mData[0];
|
||||
PRInt32 count = sizeof(kMathMLChar) / sizeof(kMathMLChar[0]);
|
||||
for (PRInt32 i = 0; i < count; i += 2) {
|
||||
for (PRInt32 i = 0; i < count; i += 3) {
|
||||
if (ch == kMathMLChar[i+1]) {
|
||||
mEnum = nsMathMLCharEnum(kMathMLChar[i]);
|
||||
mDirection = kMathMLChar[i+2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If you call SetEnum(), it will lookup the actual value
|
||||
// of the char and set it for you.
|
||||
void
|
||||
nsMathMLChar::SetEnum(nsMathMLCharEnum aEnum) {
|
||||
mEnum = aEnum;
|
||||
// some assumptions until proven otherwise!
|
||||
mData = "";
|
||||
mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
||||
// lookup the data ...
|
||||
if (mEnum != eMathMLChar_DONT_STRETCH) {
|
||||
PRInt32 count = sizeof(kMathMLChar) / sizeof(kMathMLChar[0]);
|
||||
for (PRInt32 i = 0; i < count; i += 3) {
|
||||
if (mEnum == kMathMLChar[i]) {
|
||||
mData = PRUnichar(kMathMLChar[i+1]);
|
||||
mDirection = kMathMLChar[i+2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(mData.Length(), "Something is wrong somewhere");
|
||||
}
|
||||
|
||||
/*
|
||||
The Stretch:
|
||||
@param aContainerSize - suggested size for the stretched char
|
||||
|
@ -328,46 +378,47 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize)
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsStretchDirection aDirection = aStretchDirection;
|
||||
|
||||
if (aDirection == NS_STRETCH_DIRECTION_DEFAULT) {
|
||||
aDirection = mDirection;
|
||||
}
|
||||
|
||||
// quick return if there is nothing special about this char
|
||||
if (eMathMLChar_DONT_STRETCH == mEnum) {
|
||||
if (eMathMLChar_DONT_STRETCH == mEnum || aDirection != mDirection) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check the common situations where stretching is not actually needed
|
||||
// XXX need better criteria
|
||||
if (aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
if (aDirection == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
if (aContainerSize.height <= aDesiredStretchSize.height) {
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char behaves like a normal char
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char later behaves like a normal char
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else if (aStretchDirection == NS_STRETCH_DIRECTION_HORIZONTAL) {
|
||||
else if (aDirection == NS_STRETCH_DIRECTION_HORIZONTAL) {
|
||||
if (aContainerSize.width <= aDesiredStretchSize.width) {
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char behaves like a normal char
|
||||
mEnum = eMathMLChar_DONT_STRETCH; // ensure that the char later behaves like a normal char
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// printf("Container height:%d ascent:%d descent:%d\n contains height:%d ascent:%d descent:%d\n",
|
||||
// aContainerSize.height, aContainerSize.ascent, aContainerSize.descent,
|
||||
// aDesiredStretchSize.height, aDesiredStretchSize.ascent,
|
||||
// printf("Container height:%d width:%d ascent:%d descent:%d\n contains height:%d width:%d ascent:%d descent:%d\n",
|
||||
// aContainerSize.height, aContainerSize.width, aContainerSize.ascent, aContainerSize.descent,
|
||||
// aDesiredStretchSize.height, aDesiredStretchSize.width, aDesiredStretchSize.ascent,
|
||||
// aDesiredStretchSize.descent);
|
||||
|
||||
// XXX Note: there are other symbols that just need to slightly
|
||||
// increase their size, like \Sum
|
||||
|
||||
// Set font
|
||||
nsStyleFont font;
|
||||
nsStyleColor color;
|
||||
aStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
aStyleContext->GetStyle(eStyleStruct_Color, color);
|
||||
|
||||
// Set color and font
|
||||
aRenderingContext.SetColor(color.mColor);
|
||||
aRenderingContext.SetFont(font.mFont);
|
||||
|
||||
nscoord height = aDesiredStretchSize.height;
|
||||
|
@ -383,24 +434,25 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
PRBool sizeOK = PR_FALSE;
|
||||
PRUnichar ch = gMathMLCharGlyph[index++];
|
||||
nsBoundingMetrics bm;
|
||||
|
||||
while (ch && index <= limit) {
|
||||
// printf("Checking size of:%c index:%d\n", ch & 0x00FF, index);
|
||||
rv = aRenderingContext.GetBoundingMetrics(&ch, PRUint32(1), bm);
|
||||
if (NS_FAILED(rv)) { printf("GetBoundingMetrics failed for %04X:%c\n", ch, ch&0x00FF); /*getchar();*/ return rv; }
|
||||
h = bm.ascent - bm.descent;
|
||||
w = bm.width;
|
||||
w = bm.rightBearing - bm.leftBearing;
|
||||
|
||||
// printf("height:%d width:%d ascent:%d descent:%d\n",
|
||||
// height, bm.width, bm.ascent, bm.descent);
|
||||
|
||||
// XXX temp hack -- need better criteria
|
||||
if ((aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL && h > height) ||
|
||||
(aStretchDirection == NS_STRETCH_DIRECTION_HORIZONTAL && w > width)) {
|
||||
if ((aDirection == NS_STRETCH_DIRECTION_VERTICAL && h > height) ||
|
||||
(aDirection == NS_STRETCH_DIRECTION_HORIZONTAL && w > width)) {
|
||||
sizeOK = PR_TRUE;
|
||||
descent = -bm.descent; // flip the sign, as expected by Gecko
|
||||
ascent = bm.ascent;
|
||||
height = bm.ascent - bm.descent;
|
||||
width = bm.width;
|
||||
width = bm.rightBearing - bm.leftBearing;
|
||||
mGlyph = ch;
|
||||
break;
|
||||
}
|
||||
|
@ -413,7 +465,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
nscoord a, d;
|
||||
h = w = a = d = 0;
|
||||
float flex[3] = {0.7f, 0.3f, 0.7f}; // XXX hack!
|
||||
if (aStretchDirection == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
if (aDirection == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
// default is to fill-up the area given to us
|
||||
width = aDesiredStretchSize.width;
|
||||
height = aContainerSize.height;
|
||||
|
@ -434,7 +486,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else if (aStretchDirection == NS_STRETCH_DIRECTION_HORIZONTAL) {
|
||||
else if (aDirection == NS_STRETCH_DIRECTION_HORIZONTAL) {
|
||||
// default is to fill-up the area given to us
|
||||
width = aContainerSize.width;
|
||||
height = aDesiredStretchSize.height;
|
||||
|
@ -450,6 +502,7 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
if (i < 3) w += nscoord(flex[i]*(bm.rightBearing-bm.leftBearing)); // sum widths of the parts...
|
||||
}
|
||||
if (w <= aContainerSize.width) { // can nicely fit in the available space...
|
||||
//printf("%04X can nicely fit in the available space...\n", ch);
|
||||
// ascent = a;
|
||||
// height = a - d;
|
||||
} else { // sum of parts doesn't fit in the space... will use a single glyph
|
||||
|
@ -459,9 +512,6 @@ nsMathMLChar::Stretch(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// cache the stretch direction to be used later at the painting stage
|
||||
mDirection = aStretchDirection;
|
||||
|
||||
aDesiredStretchSize.width = width;
|
||||
aDesiredStretchSize.height = height;
|
||||
aDesiredStretchSize.ascent = ascent;
|
||||
|
@ -486,13 +536,13 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext,
|
|||
aRenderingContext.SetColor(color.mColor);
|
||||
aRenderingContext.SetFont(font.mFont);
|
||||
|
||||
// quick return if there is nothing special about this char ...
|
||||
if (eMathMLChar_DONT_STRETCH == mEnum) {
|
||||
if (eMathMLChar_DONT_STRETCH == mEnum || NS_STRETCH_DIRECTION_UNSUPPORTED == mDirection) {
|
||||
// normal drawing if there is nothing special about this char ...
|
||||
aRenderingContext.DrawString(mData.GetUnicode(), PRUint32(mData.Length()), mRect.x, mRect.y);
|
||||
return NS_OK;
|
||||
//printf("Painting %04X like a normal char\n", mData[0]);
|
||||
}
|
||||
|
||||
if (0 < mGlyph) { // wow, there is a glyph of appropriate size!
|
||||
else if (0 < mGlyph) { // wow, there is a glyph of appropriate size!
|
||||
//printf("Painting %04X with a glyph of appropriate size\n", mData[0]);
|
||||
aRenderingContext.DrawString(&mGlyph, PRUint32(1), mRect.x, mRect.y);
|
||||
}
|
||||
else { // paint by parts
|
||||
|
@ -503,10 +553,10 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext,
|
|||
fm->GetMaxAscent(fontAscent);
|
||||
fm->GetMaxDescent(fontDescent);
|
||||
// do the painting ...
|
||||
if (mDirection == NS_STRETCH_DIRECTION_VERTICAL)
|
||||
if (NS_STRETCH_DIRECTION_VERTICAL == mDirection)
|
||||
return PaintVertically(aPresContext, aRenderingContext, aStyleContext,
|
||||
fontAscent, fontDescent, mEnum, mRect);
|
||||
else if (mDirection == NS_STRETCH_DIRECTION_HORIZONTAL)
|
||||
else if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection)
|
||||
return PaintHorizontally(aPresContext, aRenderingContext, aStyleContext,
|
||||
fontAscent, fontDescent, mEnum, mRect);
|
||||
}
|
||||
|
@ -519,16 +569,16 @@ nsMathMLChar::Paint(nsIPresContext* aPresContext,
|
|||
|
||||
// draw a glyph in a clipped area so that we don't have hairy chars pending outside
|
||||
void
|
||||
nsMathMLChar::DrawChar(nsIRenderingContext& aRenderingContext,
|
||||
PRUnichar aChar,
|
||||
nscoord aX,
|
||||
nscoord aY,
|
||||
nsRect& aClipRect)
|
||||
nsMathMLChar::DrawGlyph(nsIRenderingContext& aRenderingContext,
|
||||
PRUnichar aGlyph,
|
||||
nscoord aX,
|
||||
nscoord aY,
|
||||
nsRect& aClipRect)
|
||||
{
|
||||
PRBool clipState;
|
||||
aRenderingContext.PushState();
|
||||
aRenderingContext.SetClipRect(aClipRect, nsClipCombine_kIntersect, clipState);
|
||||
aRenderingContext.DrawString(&aChar, PRUint32(1), aX, aY);
|
||||
aRenderingContext.DrawString(&aGlyph, PRUint32(1), aX, aY);
|
||||
aRenderingContext.PopState(clipState);
|
||||
}
|
||||
|
||||
|
@ -548,10 +598,10 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
|
|||
// jump past the glyphs of various size...
|
||||
PRUnichar ch = gMathMLCharGlyph[index++];
|
||||
while (ch && index <= limit) {
|
||||
ch = gMathMLCharGlyph[index++];
|
||||
ch = gMathMLCharGlyph[index++];
|
||||
}
|
||||
// return if there are no partial glyphs (an erroneous table!)
|
||||
if (!gMathMLCharGlyph[index]) return NS_OK;
|
||||
if (!gMathMLCharGlyph[index]) { printf("Erroneous gMathMLCharGlyph table!\n"); return NS_OK; }
|
||||
|
||||
nscoord dx = aRect.x;
|
||||
nscoord dy = aRect.y;
|
||||
|
@ -628,7 +678,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
|
|||
|
||||
if (!clipRect.IsEmpty()) {
|
||||
clipRect.Inflate(onePixel, onePixel);
|
||||
DrawChar(aRenderingContext, ch, dx, dy, clipRect);
|
||||
DrawGlyph(aRenderingContext, ch, dx, dy, clipRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,7 +703,7 @@ nsMathMLChar::PaintVertically(nsIPresContext* aPresContext,
|
|||
}
|
||||
count++;
|
||||
dy += stride;
|
||||
DrawChar(aRenderingContext, ch, dx, dy, clipRect);
|
||||
DrawGlyph(aRenderingContext, ch, dx, dy, clipRect);
|
||||
// NS_ASSERTION(5000 == count, "Error - gMathMLCharGlyph is incorrectly set");
|
||||
if (1000 == count) return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
@ -686,7 +736,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext,
|
|||
ch = gMathMLCharGlyph[index++];
|
||||
}
|
||||
// return if there are no partial glyphs (an erroneous table!)
|
||||
if (!gMathMLCharGlyph[index]) return NS_OK;
|
||||
if (!gMathMLCharGlyph[index]) { printf("Erroneous gMathMLCharGlyph table!\n"); return NS_OK; }
|
||||
|
||||
nscoord dx = aRect.x;
|
||||
nscoord dy = aRect.y;
|
||||
|
@ -757,7 +807,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext,
|
|||
// getchar();
|
||||
if (!clipRect.IsEmpty()) {
|
||||
clipRect.Inflate(onePixel, onePixel);
|
||||
DrawChar(aRenderingContext, ch, dx, dy, clipRect);
|
||||
DrawGlyph(aRenderingContext, ch, dx, dy, clipRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,7 +834,7 @@ nsMathMLChar::PaintHorizontally(nsIPresContext* aPresContext,
|
|||
}
|
||||
count++;
|
||||
dx += stride;
|
||||
DrawChar(aRenderingContext, ch, dx, dy, clipRect);
|
||||
DrawGlyph(aRenderingContext, ch, dx, dy, clipRect);
|
||||
// NS_ASSERTION(5000 == count, "Error - gMathMLCharGlyph is incorrectly set");
|
||||
if (1000 == count) return NS_ERROR_UNEXPECTED;
|
||||
// printf("Drawing %04X ascent:%d descent:%d at position dx:%d dy:%d\n",
|
||||
|
|
|
@ -23,13 +23,9 @@
|
|||
#define nsMathMLChar_h___
|
||||
|
||||
#include "nsMathMLOperators.h"
|
||||
#include "nsIMathMLFrame.h"
|
||||
|
||||
typedef PRUint32 nsStretchDirection;
|
||||
|
||||
#define NS_STRETCH_DIRECTION_HORIZONTAL 0
|
||||
#define NS_STRETCH_DIRECTION_VERTICAL 1
|
||||
|
||||
// chars that we know how to stretch
|
||||
// chars that we know how something about
|
||||
enum nsMathMLCharEnum {
|
||||
eMathMLChar_DONT_STRETCH = -1,
|
||||
eMathMLChar_LeftParenthesis,
|
||||
|
@ -44,57 +40,12 @@ enum nsMathMLCharEnum {
|
|||
eMathMLChar_LeftArrow,
|
||||
eMathMLChar_RightArrow,
|
||||
eMathMLChar_RadicalBar,
|
||||
eMathMLChar_Radical,
|
||||
eMathMLChar_VerticalBar,
|
||||
eMathMLChar_COUNT
|
||||
};
|
||||
|
||||
// Structure used for a char's size and alignment information.
|
||||
struct nsCharMetrics {
|
||||
// nscoord leading;
|
||||
nscoord descent, ascent;
|
||||
nscoord width, height;
|
||||
|
||||
nsCharMetrics(nscoord aDescent=0, nscoord aAscent=0,
|
||||
nscoord aWidth=0, nscoord aHeight=0) {
|
||||
width = aWidth;
|
||||
height = aHeight;
|
||||
ascent = aAscent;
|
||||
descent = aDescent;
|
||||
}
|
||||
|
||||
nsCharMetrics(const nsCharMetrics& aCharMetrics) {
|
||||
width = aCharMetrics.width;
|
||||
height = aCharMetrics.height;
|
||||
ascent = aCharMetrics.ascent;
|
||||
descent = aCharMetrics.descent;
|
||||
}
|
||||
|
||||
nsCharMetrics(const nsHTMLReflowMetrics& aReflowMetrics) {
|
||||
width = aReflowMetrics.width;
|
||||
height = aReflowMetrics.height;
|
||||
ascent = aReflowMetrics.ascent;
|
||||
descent = aReflowMetrics.descent;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
operator=(const nsCharMetrics& aCharMetrics) {
|
||||
width = aCharMetrics.width;
|
||||
height = aCharMetrics.height;
|
||||
ascent = aCharMetrics.ascent;
|
||||
descent = aCharMetrics.descent;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRBool
|
||||
operator==(const nsCharMetrics& aCharMetrics) {
|
||||
return (width == aCharMetrics.width &&
|
||||
height == aCharMetrics.height &&
|
||||
ascent == aCharMetrics.ascent &&
|
||||
descent == aCharMetrics.descent);
|
||||
}
|
||||
};
|
||||
|
||||
// class used to handle stretchy symbols (accent and boundary symbols)
|
||||
// class used to handle stretchy symbols (accent and boundary symbol)
|
||||
class nsMathMLChar
|
||||
{
|
||||
public:
|
||||
|
@ -103,49 +54,59 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
/*
|
||||
nsMathMLChar() : mData(),
|
||||
mGlyph(0)
|
||||
{
|
||||
nsStr::Initialize(mData, eTwoByte); // with MathML, we are two-byte by default
|
||||
}
|
||||
*/
|
||||
|
||||
virtual ~nsMathMLChar()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsIStyleContext* aStyleContext);
|
||||
NS_IMETHOD
|
||||
Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsIStyleContext* aStyleContext);
|
||||
|
||||
// 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 output - the same size or the new size that the char wants.
|
||||
NS_IMETHOD Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize);
|
||||
NS_IMETHOD
|
||||
Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize);
|
||||
|
||||
// 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);
|
||||
|
||||
void
|
||||
SetData(nsString& aData) {
|
||||
mData = aData;
|
||||
SetEnum();
|
||||
}
|
||||
|
||||
void
|
||||
GetData(nsString& aData) {
|
||||
aData = mData;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
nsMathMLCharEnum
|
||||
Enum() {
|
||||
return mEnum;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
Length() {
|
||||
return mData.Length();
|
||||
}
|
||||
|
||||
nsStretchDirection
|
||||
GetStretchDirection() {
|
||||
return mDirection;
|
||||
}
|
||||
|
||||
// Sometimes we only want to pass the data to another routine,
|
||||
// this function helps to avoid copying
|
||||
const PRUnichar*
|
||||
|
@ -164,22 +125,20 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
nsString mData;
|
||||
PRUnichar mGlyph;
|
||||
nsRect mRect;
|
||||
PRInt32 mDirection;
|
||||
nsMathMLCharEnum mEnum;
|
||||
nsString mData;
|
||||
PRUnichar mGlyph;
|
||||
nsRect mRect;
|
||||
nsStretchDirection mDirection;
|
||||
nsMathMLCharEnum mEnum;
|
||||
|
||||
// helper methods
|
||||
void
|
||||
SetEnum();
|
||||
|
||||
static void
|
||||
DrawChar(nsIRenderingContext& aRenderingContext,
|
||||
PRUnichar aChar,
|
||||
nscoord aX,
|
||||
nscoord aY,
|
||||
nsRect& aClipRect);
|
||||
DrawGlyph(nsIRenderingContext& aRenderingContext,
|
||||
PRUnichar aChar,
|
||||
nscoord aX,
|
||||
nscoord aY,
|
||||
nsRect& aClipRect);
|
||||
|
||||
static nsresult
|
||||
PaintVertically(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -111,8 +111,7 @@ nsMathMLContainerFrame::IsOnlyWhitespace(nsIFrame* aFrame)
|
|||
// by empty frame we mean a leaf frame whose text content is empty...
|
||||
nsCOMPtr<nsIContent> aContent;
|
||||
aFrame->GetContent(getter_AddRefs(aContent));
|
||||
if (nsnull == aContent)
|
||||
return PR_TRUE;
|
||||
if (!aContent) return PR_TRUE;
|
||||
PRInt32 numKids;
|
||||
aContent->ChildCount(numKids);
|
||||
if (0 == numKids) {
|
||||
|
@ -144,9 +143,39 @@ nsMathMLContainerFrame::ReflowEmptyChild(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
/* /////////////
|
||||
* nsIMathMLFrame - support methods for stretchy elements and scripting
|
||||
* elements (nested frames within msub, msup, msubsup, munder, mover,
|
||||
* munderover, mmultiscripts, mfrac, mroot, mtable).
|
||||
* nsIMathMLFrame - support methods for precise positioning
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
NS_IMETHOD
|
||||
GetReference(nsPoint& aReference)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
SetReference(const nsPoint& aReference);
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* /////////////
|
||||
* nsIMathMLFrame - support methods for stretchy elements
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
|
@ -154,12 +183,246 @@ NS_IMETHODIMP
|
|||
nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize)
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize)
|
||||
{
|
||||
return NS_OK; // the Stretch() is only implemented by <mo> and its nsMathMLChar
|
||||
nsresult rv = NS_OK;
|
||||
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellish.flags)) {
|
||||
|
||||
if (NS_MATHML_STRETCH_WAS_DONE(mEmbellish.flags)) {
|
||||
printf("WARNING *** it is wrong to fire stretch more than once on a frame...\n");
|
||||
// NS_ASSERTION(PR_FALSE,"Stretch() was fired more than once on a frame!");
|
||||
return NS_OK;
|
||||
}
|
||||
mEmbellish.flags |= NS_MATHML_STRETCH_DONE;
|
||||
|
||||
|
||||
// Pass the stretch to the first non-empty child ...
|
||||
|
||||
nsIFrame* childFrame = mEmbellish.firstChild;
|
||||
NS_ASSERTION(childFrame, "Something is wrong somewhere");
|
||||
|
||||
if (childFrame) {
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Something is wrong somewhere");
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsHTMLReflowMetrics aReflowMetrics(nsnull);
|
||||
|
||||
nsRect rect;
|
||||
childFrame->GetRect(rect);
|
||||
// And the trick is that rect.x is still holding the descent, and rect.y
|
||||
// is still holding the ascent ...
|
||||
nsStretchMetrics childSize(rect.x, rect.y, rect.width, rect.height);
|
||||
nsStretchMetrics container(aContainerSize);
|
||||
|
||||
if (aStretchDirection != NS_STRETCH_DIRECTION_DEFAULT && aStretchDirection != mEmbellish.direction) {
|
||||
// change the direction and confine the stretch to us
|
||||
#if 0
|
||||
GetDesiredStretchSize(aPresContext, aRenderingContext, container);
|
||||
#endif
|
||||
GetRect(rect);
|
||||
container = nsStretchMetrics(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
aMathMLFrame->Stretch(aPresContext, aRenderingContext, mEmbellish.direction,
|
||||
container, childSize);
|
||||
childFrame->SetRect(aPresContext,
|
||||
nsRect(childSize.descent, childSize.ascent,
|
||||
childSize.width, childSize.height));
|
||||
|
||||
// We now have one child that may have changed, re-position all our children
|
||||
Place(aPresContext, aRenderingContext, PR_TRUE, aReflowMetrics);
|
||||
|
||||
// Prepare the metrics to be returned
|
||||
aDesiredStretchSize = nsStretchMetrics(aReflowMetrics);
|
||||
aDesiredStretchSize.leftSpace = childSize.leftSpace;
|
||||
aDesiredStretchSize.rightSpace = childSize.rightSpace;
|
||||
|
||||
// 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 (!IsEmbellishOperator(mParent)) {
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
nscoord em = NSToCoordRound(float(font.mFont.size));
|
||||
|
||||
// cache these values
|
||||
mEmbellish.leftSpace = nscoord( em * aDesiredStretchSize.leftSpace );
|
||||
mEmbellish.rightSpace = nscoord( em * aDesiredStretchSize.rightSpace );
|
||||
|
||||
aDesiredStretchSize.width += nscoord( (aDesiredStretchSize.leftSpace + aDesiredStretchSize.rightSpace) * em );
|
||||
nscoord dx = nscoord( aDesiredStretchSize.leftSpace * em );
|
||||
if (0 == dx) return NS_OK;
|
||||
|
||||
nsPoint origin;
|
||||
childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
childFrame->GetOrigin(origin);
|
||||
childFrame->MoveTo(aPresContext, origin.x + dx, origin.y);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::FinalizeReflow(PRInt32 aDirection,
|
||||
nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
// During reflow, we use rect.x and rect.y as placeholders for the child's ascent
|
||||
// and descent in expectation of a stretch command. Hence we need to ensure that
|
||||
// a stretch command will actually be fired later on, after exiting from our
|
||||
// reflow. If the stretch is not fired, the rect.x, and rect.y will remain
|
||||
// with inappropriate data causing children to be improperly positioned.
|
||||
// This helper method checks to see if our parent will fire a stretch command
|
||||
// targeted at us. If not, we go ahead and fire an involutive stretch on
|
||||
// ourselves. This will clear all the rect.x and rect.y, and return our
|
||||
// desired size.
|
||||
|
||||
|
||||
// First, complete the post-reflow hook.
|
||||
// We use the information in our children rectangles to position them.
|
||||
// If placeOrigin==false, then Place() will not touch rect.x, and rect.y.
|
||||
// They will still be holding the ascent and descent for each child.
|
||||
PRBool placeOrigin = !NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellish.flags);
|
||||
Place(aPresContext, aRenderingContext, placeOrigin, aDesiredSize);
|
||||
|
||||
if (!placeOrigin) {
|
||||
// This means the rect.x and rect.y of our children were not set!!
|
||||
// Don't go without checking to see if our parent will later fire a Stretch() command
|
||||
// targeted at us. The Stretch() will cause the rect.x and rect.y to clear...
|
||||
PRBool parentWillFireStretch = PR_FALSE;
|
||||
nsEmbellishState parentState;
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = mParent->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
aMathMLFrame->GetEmbellishState(parentState);
|
||||
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN(parentState.flags) ||
|
||||
(NS_MATHML_WILL_STRETCH_FIRST_CHILD(parentState.flags) &&
|
||||
parentState.firstChild == this)) {
|
||||
parentWillFireStretch = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (!parentWillFireStretch) {
|
||||
// There is nobody who will fire the stretch for us, we do it ourselves!
|
||||
|
||||
// BEGIN of GETTING THE STRETCH SIZE
|
||||
// What is the size that we should use to stretch our stretchy children ????
|
||||
|
||||
// 1) With this code, vertical stretching works. But horizontal stretching
|
||||
// does not work when the firstChild happens to be the core embellished mo...
|
||||
// nsRect rect;
|
||||
// nsIFrame* childFrame = mEmbellish.firstChild;
|
||||
// NS_ASSERTION(childFrame, "Something is wrong somewhere");
|
||||
// childFrame->GetRect(rect);
|
||||
// nsStretchMetrics curSize(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
|
||||
// 2) With this code, horizontal stretching works. But vertical stretching
|
||||
// is done in some cases where frames could have simply been kept as is.
|
||||
nsStretchMetrics curSize(aDesiredSize);
|
||||
|
||||
|
||||
// 3) With this code, we should get appropriate size when it is done !!
|
||||
// GetDesiredSize(aDirection, aPresContext, aRenderingContext, curSize);
|
||||
|
||||
// XXX It is not clear if a direction should be imposed.
|
||||
// With the default direction, the MathMLChar will attempt to stretch
|
||||
// in its preferred direction.
|
||||
|
||||
nsStretchMetrics newSize(curSize);
|
||||
Stretch(aPresContext, aRenderingContext, NS_STRETCH_DIRECTION_DEFAULT,
|
||||
curSize, newSize);
|
||||
|
||||
aDesiredSize.width = newSize.width;
|
||||
aDesiredSize.height = newSize.height;
|
||||
aDesiredSize.ascent = newSize.ascent;
|
||||
aDesiredSize.descent = newSize.descent;
|
||||
}
|
||||
}
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is the method used to set the frame as an embellished container.
|
||||
// It checks if the first (non-empty) child is embellished. Hence, calls
|
||||
// must be bottom-up. The method must only be called from within frames who are
|
||||
// entitled to be potential embellished operators as per the MathML REC.
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::EmbellishOperator()
|
||||
{
|
||||
// Get the first non-empty child
|
||||
nsIFrame* firstChild = mFrames.FirstChild();
|
||||
while (firstChild) {
|
||||
if (!IsOnlyWhitespace(firstChild)) break;
|
||||
firstChild->GetNextSibling(&firstChild);
|
||||
}
|
||||
if (firstChild && IsEmbellishOperator(firstChild)) {
|
||||
// Cache the first child
|
||||
mEmbellish.flags |= NS_MATHML_EMBELLISH_OPERATOR;
|
||||
mEmbellish.firstChild = firstChild;
|
||||
// Cache also the inner-most embellished frame at the core of the hierarchy
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = firstChild->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
|
||||
nsEmbellishState embellishState;
|
||||
aMathMLFrame->GetEmbellishState(embellishState);
|
||||
mEmbellish.core = embellishState.core;
|
||||
mEmbellish.direction = embellishState.direction;
|
||||
}
|
||||
else {
|
||||
mEmbellish.flags &= ~NS_MATHML_EMBELLISH_OPERATOR;
|
||||
mEmbellish.firstChild = nsnull;
|
||||
mEmbellish.core = nsnull;
|
||||
mEmbellish.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::GetEmbellishState(nsEmbellishState& aEmbellishState)
|
||||
{
|
||||
aEmbellishState = mEmbellish;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::SetEmbellishState(const nsEmbellishState& aEmbellishState)
|
||||
{
|
||||
mEmbellish = aEmbellishState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMathMLContainerFrame::IsEmbellishOperator(nsIFrame* aFrame)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "null arg");
|
||||
if (!aFrame) return PR_FALSE;
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = aFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_FAILED(rv) || !aMathMLFrame) return PR_FALSE;
|
||||
nsEmbellishState aEmbellishState;
|
||||
aMathMLFrame->GetEmbellishState(aEmbellishState);
|
||||
return NS_MATHML_IS_EMBELLISH_OPERATOR(aEmbellishState.flags);
|
||||
}
|
||||
|
||||
/* /////////////
|
||||
* nsIMathMLFrame - support methods for scripting elements (nested frames
|
||||
* within msub, msup, msubsup, munder, mover, munderover, mmultiscripts,
|
||||
* mfrac, mroot, mtable).
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::GetPresentationData(PRInt32* aScriptLevel,
|
||||
PRBool* aDisplayStyle)
|
||||
|
@ -184,7 +447,7 @@ nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(PRInt32 aIndex,
|
|||
PRInt32 aScriptLevelIncrement,
|
||||
PRBool aDisplayStyle)
|
||||
{
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
if (0 >= aIndex--) {
|
||||
|
@ -218,7 +481,7 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
|||
if (!IsOnlyWhitespace(childFrame) && NS_SUCCEEDED(rv)) {
|
||||
|
||||
// see if the child frame implements the nsIMathMLFrame interface
|
||||
nsIMathMLFrame* aMathMLFrame;
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (nsnull != aMathMLFrame && NS_SUCCEEDED(rv)) {
|
||||
|
||||
|
@ -237,6 +500,9 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
|||
nsCOMPtr<nsIContent> childContent;
|
||||
childFrame->GetContent(getter_AddRefs(childContent));
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
|
||||
nsIFrame* firstFrame = nsnull;
|
||||
nsIFrame* lastFrame = this;
|
||||
nsIStyleContext* lastStyleContext = mStyleContext;
|
||||
|
@ -250,11 +516,11 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
|||
while (0 < gap--) {
|
||||
|
||||
aPresContext->ResolvePseudoStyleContextFor(childContent, fontAtom, lastStyleContext,
|
||||
PR_FALSE, getter_AddRefs(newStyleContext));
|
||||
PR_FALSE, getter_AddRefs(newStyleContext));
|
||||
if (newStyleContext && newStyleContext.get() != lastStyleContext) {
|
||||
// create a new frame and append it as sole child of the last created frame
|
||||
// create a new wrapper frame and append it as sole child of the last created frame
|
||||
nsIFrame* newFrame = nsnull;
|
||||
NS_NewMathMLWrapperFrame(&newFrame);
|
||||
NS_NewMathMLWrapperFrame(shell, &newFrame);
|
||||
NS_ASSERTION(newFrame, "Failed to create new frame");
|
||||
|
||||
newFrame->Init(aPresContext, childContent, lastFrame, newStyleContext, nsnull);
|
||||
|
@ -278,6 +544,22 @@ nsMathMLContainerFrame::InsertScriptLevelStyleContext(nsIPresContext* aPresConte
|
|||
childFrame->SetNextSibling(nsnull);
|
||||
aPresContext->ReParentStyleContext(childFrame, lastStyleContext);
|
||||
lastFrame->SetInitialChildList(aPresContext, nsnull, childFrame);
|
||||
|
||||
// if the child was an embellished operator,
|
||||
// make the whole list embellished as well
|
||||
nsEmbellishState embellishState;
|
||||
aMathMLFrame->GetEmbellishState(embellishState);
|
||||
if (0 != embellishState.flags && nsnull != embellishState.firstChild) {
|
||||
do { // walk the hierarchy in a bottom-up manner
|
||||
rv= lastFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
|
||||
if (NS_FAILED(rv) || !aMathMLFrame) break;
|
||||
embellishState.firstChild = childFrame;
|
||||
aMathMLFrame->SetEmbellishState(embellishState);
|
||||
childFrame = lastFrame;
|
||||
lastFrame->GetParent(&lastFrame);
|
||||
} while (lastFrame != this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,6 +591,9 @@ nsMathMLContainerFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
mScriptLevel = 0;
|
||||
mDisplayStyle = PR_TRUE;
|
||||
|
||||
mEmbellish.flags = 0;
|
||||
mEmbellish.firstChild = nsnull;
|
||||
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult res = aParent->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
|
@ -353,20 +638,21 @@ nsMathMLContainerFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
if (!IsOnlyWhitespace(child)) {
|
||||
nsInlineFrame* inlineFrame = nsnull;
|
||||
rv = child->QueryInterface(nsInlineFrame::kInlineFrameCID, (void**)&inlineFrame);
|
||||
if (inlineFrame) {
|
||||
if (NS_SUCCEEDED(rv) && inlineFrame) {
|
||||
// create a new anonymous block frame to wrap this child...
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsIFrame* anonymous;
|
||||
rv = NS_NewBlockFrame(&anonymous);
|
||||
rv = NS_NewBlockFrame(shell, &anonymous);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsCOMPtr<nsIStyleContext> newStyleContext;
|
||||
aPresContext->ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::mozAnonymousBlock,
|
||||
mStyleContext, PR_FALSE,
|
||||
getter_AddRefs(newStyleContext));
|
||||
mStyleContext, PR_FALSE,
|
||||
getter_AddRefs(newStyleContext));
|
||||
rv = anonymous->Init(aPresContext, mContent, this, newStyleContext, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
anonymous->Destroy(aPresContext);
|
||||
delete anonymous;
|
||||
return rv;
|
||||
}
|
||||
mFrames.ReplaceFrame(this, child, anonymous);
|
||||
|
@ -381,6 +667,217 @@ nsMathMLContainerFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// helper method to compute the desired size of a frame
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::GetDesiredStretchSize(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsRect rect;
|
||||
nscoord count = 0;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
childFrame->GetRect(rect);
|
||||
if (IsEmbellishOperator(childFrame)) {
|
||||
// We have encountered an embellished operator...
|
||||
// It is treated as if the embellishments were not there!
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsEmbellishState embellishState;
|
||||
aMathMLFrame->GetEmbellishState(embellishState);
|
||||
embellishState.core->GetRect(rect);
|
||||
}
|
||||
}
|
||||
if (0 == aDirection) { // for horizontal positioning of child frames like in mrow
|
||||
aDesiredSize.width += rect.width;
|
||||
if (aDesiredSize.ascent < rect.y) aDesiredSize.ascent = rect.y;
|
||||
if (aDesiredSize.descent < rect.x) aDesiredSize.descent = rect.x;
|
||||
}
|
||||
else if (1 == aDirection) { // for vertical positioning of child frames like in mfrac, munder
|
||||
if (0 == count) { // it is the ascent and descent of the 'base' that is returned by defaul
|
||||
aDesiredSize.ascent = rect.y;
|
||||
aDesiredSize.descent = rect.x;
|
||||
}
|
||||
if (aDesiredSize.width < rect.width) aDesiredSize.width = rect.width;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
// Check if embellished operators didn't have (non-empty) sibblings...
|
||||
if (0 < count && 0 == aDirection && 0 == aDesiredSize.height) {
|
||||
// Return the font ascent and font descent
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
|
||||
fm->GetMaxAscent(aDesiredSize.ascent);
|
||||
fm->GetMaxDescent(aDesiredSize.descent);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
}
|
||||
if (0 < count && 1 == aDirection && 0 == aDesiredSize.width) {
|
||||
// Return em
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
aDesiredSize.width = NSToCoordRound(float(font.mFont.size));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// helper function to reflow all children
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::ReflowChildren(PRInt32 aDirection,
|
||||
nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
NS_PRECONDITION(aDirection==0 || aDirection==1, "Unknown direction");
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
nscoord count = 0;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
//////////////
|
||||
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
|
||||
if (IsOnlyWhitespace(childFrame)) {
|
||||
ReflowEmptyChild(aPresContext, childFrame);
|
||||
}
|
||||
else {
|
||||
nsHTMLReflowState childReflowState(aPresContext, aReflowState,
|
||||
childFrame, availSize);
|
||||
rv = ReflowChild(childFrame, aPresContext, childDesiredSize,
|
||||
childReflowState, childStatus);
|
||||
NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// 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));
|
||||
|
||||
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN(mEmbellish.flags) &&
|
||||
IsEmbellishOperator(childFrame)) {
|
||||
// We have encountered an embellished operator...
|
||||
// It is treated as if the embellishments were not there!
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
|
||||
nsEmbellishState embellishState;
|
||||
aMathMLFrame->GetEmbellishState(embellishState);
|
||||
nsRect rect;
|
||||
embellishState.core->GetRect(rect);
|
||||
childDesiredSize.descent = rect.x;
|
||||
childDesiredSize.ascent = rect.y;
|
||||
childDesiredSize.width = rect.width;
|
||||
childDesiredSize.height = rect.height;
|
||||
|
||||
#if 0
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
nsStretchMetrics stretchSize;
|
||||
aMathMLFrame->GetDesiredStretchSize(aPresContext, renderingContext, stretchSize);
|
||||
childDesiredSize.descent = stretchSize.descent;
|
||||
childDesiredSize.ascent = stretchSize.ascent;
|
||||
childDesiredSize.width = stretchSize.width;
|
||||
childDesiredSize.height = stretchSize.height;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (0 == aDirection) { // for horizontal positioning of child frames like in mrow
|
||||
aDesiredSize.width += childDesiredSize.width;
|
||||
if (aDesiredSize.ascent < childDesiredSize.ascent) aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
if (aDesiredSize.descent < childDesiredSize.descent) aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
else if (1 == aDirection) { // for vertical positioning of child frames like in mfrac, munder
|
||||
if (0 == count) { // it is the ascent and descent of the 'base' that is returned by defaul
|
||||
aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
if (aDesiredSize.width < childDesiredSize.width) aDesiredSize.width = childDesiredSize.width;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
// Check if embellished operators didn't have (non-empty) sibblings...
|
||||
if (0 < count && 0 == aDirection && 0 == aDesiredSize.height) {
|
||||
// Return the font ascent and font descent
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
|
||||
fm->GetMaxAscent(aDesiredSize.ascent);
|
||||
fm->GetMaxDescent(aDesiredSize.descent);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
}
|
||||
if (0 < count && 1 == aDirection && 0 == aDesiredSize.width) {
|
||||
// Return em
|
||||
nsStyleFont font;
|
||||
mStyleContext->GetStyle(eStyleStruct_Font, font);
|
||||
aDesiredSize.width = NSToCoordRound(float(font.mFont.size));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// helper function to stretch all children
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::StretchChildren(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsStretchMetrics& aContainerSize)
|
||||
{
|
||||
nsRect rect;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if (mEmbellish.firstChild == childFrame) {
|
||||
// Skip this child... because:
|
||||
// If we are here it means we are an embellished container and
|
||||
// for now, we don't touch our embellished child frame.
|
||||
// Its stretch will be handled separatedly when we receive
|
||||
// stretch command fired by our parent frame.
|
||||
}
|
||||
else {
|
||||
nsIMathMLFrame* aMathMLFrame;
|
||||
nsresult rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
// retrieve the metrics that was stored at the ReflowChildren pass
|
||||
childFrame->GetRect(rect);
|
||||
nsStretchMetrics childSize(rect.x, rect.y, rect.width, rect.height);
|
||||
aMathMLFrame->Stretch(aPresContext, aRenderingContext,
|
||||
aStretchDirection, aContainerSize, childSize);
|
||||
// store the updated metrics
|
||||
childFrame->SetRect(aPresContext,
|
||||
nsRect(childSize.descent, childSize.ascent,
|
||||
childSize.width, childSize.height));
|
||||
}
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
@ -389,127 +886,99 @@ nsMathMLContainerFrame::Reflow(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
nsRect rect;
|
||||
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
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 {
|
||||
nsHTMLReflowState childReflowState(aPresContext, aReflowState, childFrame, availSize);
|
||||
rv = ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowState, childStatus);
|
||||
NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// At this stage, the origin points of the children have no use, so we will use the
|
||||
// origins as placeholders to store the child's ascent and descent. Before return,
|
||||
// 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;
|
||||
ReflowChildren(0, aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
||||
/////////////
|
||||
// Ask stretchy children to stretch themselves
|
||||
|
||||
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
|
||||
nsCharMetrics parentSize(aDesiredSize);
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame) {
|
||||
|
||||
// retrieve the metrics that was stored at the previous pass
|
||||
childFrame->GetRect(rect);
|
||||
nsCharMetrics childSize(rect.x, rect.y, rect.width, rect.height);
|
||||
// If we are a container which is entitled to stretch its children, then we
|
||||
// ask our stretchy children to stretch themselves
|
||||
|
||||
//////////
|
||||
// Stretch ...
|
||||
// Only directed at frames that implement the nsIMathMLFrame interface
|
||||
nsIMathMLFrame* aMathMLFrame;
|
||||
rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && nsnull != 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;
|
||||
}
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
|
||||
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN(mEmbellish.flags)) {
|
||||
nsStretchMetrics containerSize(aDesiredSize);
|
||||
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
|
||||
|
||||
StretchChildren(aPresContext, renderingContext, stretchDir, containerSize);
|
||||
}
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
/////////////
|
||||
// Place Children now by re-adjusting the origins to align the baselines
|
||||
|
||||
nsPoint offset(0,0);
|
||||
childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame) {
|
||||
childFrame->GetRect(rect);
|
||||
offset.y = aDesiredSize.ascent - rect.y;
|
||||
childFrame->MoveTo(aPresContext, offset.x,offset.y);
|
||||
offset.x += rect.width;
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
// Place children now by re-adjusting the origins to align the baselines
|
||||
FinalizeReflow(0, aPresContext, renderingContext, aDesiredSize);
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLContainerFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
nsRect rect;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
childFrame->GetRect(rect);
|
||||
|
||||
aDesiredSize.width += rect.width;
|
||||
if (aDesiredSize.descent < rect.x) aDesiredSize.descent = rect.x;
|
||||
if (aDesiredSize.ascent < rect.y) aDesiredSize.ascent = rect.y;
|
||||
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dy;
|
||||
nscoord dx = 0;
|
||||
childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
childFrame->GetRect(rect);
|
||||
|
||||
dy = aDesiredSize.ascent - rect.y;
|
||||
|
||||
nsHTMLReflowMetrics childSize(nsnull);
|
||||
childSize.width = rect.width;
|
||||
childSize.height = rect.height;
|
||||
// childSize.descent = rect.x;
|
||||
// childSize.ascent = rect.y;
|
||||
|
||||
// Place and size the child
|
||||
// childFrame->MoveTo(aPresContext, dx, dy);
|
||||
FinishReflowChild(childFrame, aPresContext, childSize, dx, dy, 0);
|
||||
|
||||
dx += rect.width;
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//==========================
|
||||
// *BEWARE* of the wrapper frame!
|
||||
// This is the frame that is inserted to alter the style context of
|
||||
// scripting elements. What this means is that looking for your parent
|
||||
// or your sibblings with (possible several) wrapper frames around you
|
||||
// can make you wonder what is going on. For example, the direct parent
|
||||
// of the subscript within <msub> is not <msub>, but instead the wrapper
|
||||
// frame that was insterted to alter the style context of the subscript!
|
||||
// You will seldom need to find out who is exactly your parent. You should
|
||||
// first rethink your code to see if you can avoid finding who is your parent.
|
||||
// Be careful, there are wrapper frames all over the place, and probably
|
||||
// one or many are wrapping you if you are in a position where the
|
||||
// scriptlevel is non zero.
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLWrapperFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLWrapperFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLWrapperFrame* it = new nsMathMLWrapperFrame;
|
||||
nsMathMLWrapperFrame* it = new (aPresShell) nsMathMLWrapperFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -525,26 +994,6 @@ nsMathMLWrapperFrame::~nsMathMLWrapperFrame()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLWrapperFrame::Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize)
|
||||
{
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
if (childFrame) {
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
nsresult rv = childFrame->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
aMathMLFrame->Stretch(aPresContext, aRenderingContext, aStretchDirection,
|
||||
aContainerSize, aDesiredStretchSize);
|
||||
childFrame->SetRect(aPresContext, nsRect(0,0,aDesiredStretchSize.width,aDesiredStretchSize.height));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLWrapperFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
@ -561,13 +1010,43 @@ nsMathMLWrapperFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
nsHTMLReflowState childReflowState(aPresContext, aReflowState, childFrame, availSize);
|
||||
rv = ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowState, childStatus);
|
||||
childFrame->SetRect(aPresContext, nsRect(0,0,childDesiredSize.width,childDesiredSize.height));
|
||||
childFrame->SetRect(aPresContext,
|
||||
nsRect(childDesiredSize.descent,childDesiredSize.ascent,
|
||||
childDesiredSize.width,childDesiredSize.height));
|
||||
aDesiredSize = childDesiredSize;
|
||||
aStatus = childStatus;
|
||||
}
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
FinalizeReflow(0, aPresContext, renderingContext, aDesiredSize);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLWrapperFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
if (childFrame) {
|
||||
nsRect rect;
|
||||
childFrame->GetRect(rect);
|
||||
|
||||
aDesiredSize.descent = rect.x;
|
||||
aDesiredSize.ascent = rect.y;
|
||||
aDesiredSize.width = rect.width;
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nsHTMLReflowMetrics childSize(nsnull);
|
||||
childSize.width = rect.width;
|
||||
childSize.height = rect.height;
|
||||
|
||||
// childFrame->SetRect(aPresContext, nsRect(0,0,rect.width,rect.height));
|
||||
FinishReflowChild(childFrame, aPresContext, childSize, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
* Base class for MathML container frames. It acts like an inferred
|
||||
* mrow. By default, this frame uses its Reflow() method to lay its
|
||||
* children horizontally and ensure that their baselines are aligned.
|
||||
* The Reflow() method relies upon Place() to position children.
|
||||
* By overloading Place() in derived classes, it is therefore possible
|
||||
* to position children in various customized ways.
|
||||
*
|
||||
* This frame is a *math-aware frame* in the sense that given the markup
|
||||
* <tag>base arguments</tag>, the method InsertScriptLevelStyleContext()
|
||||
|
@ -46,9 +49,9 @@
|
|||
* msubsup, mover, munder, munderover, mmultiscripts. All are derived
|
||||
* from this base class. They use SetInitialChildList() to trigger
|
||||
* InsertScriptLevelStyleContext() for the very first time as soon as all
|
||||
* their children are known. However, each of these tags has its own Reflow()
|
||||
* method to lay its children as appropriate, thus overriding the default
|
||||
* Reflow() method in this base class.
|
||||
* their children are known. However, each of these tags has its own
|
||||
* Reflow() and/or Place() methods to lay its children as appropriate,
|
||||
* thus overriding the default behavior in this base class.
|
||||
*
|
||||
* Other tags like mi that do not have 'arguments' can be derived from
|
||||
* this base class as well. The class caters for empty arguments.
|
||||
|
@ -61,17 +64,51 @@
|
|||
class nsMathMLContainerFrame : public nsHTMLContainerFrame, public nsIMathMLFrame {
|
||||
public:
|
||||
|
||||
// nsIMathMLFrame methods
|
||||
|
||||
// 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_IMETHOD Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize);
|
||||
NS_IMETHOD
|
||||
GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics);
|
||||
|
||||
NS_IMETHOD
|
||||
SetBoundingMetrics(const nsBoundingMetrics& aBoundingMetrics);
|
||||
/*
|
||||
NS_IMETHOD
|
||||
GetReference(nsPoint& aReference);
|
||||
|
||||
NS_IMETHOD
|
||||
SetReference(const nsPoint& aReference);
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize);
|
||||
#if 0
|
||||
NS_IMETHOD
|
||||
GetDesiredStretchSize(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchMetrics& aDesiredStretchSize);
|
||||
#endif
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
EmbellishOperator();
|
||||
|
||||
NS_IMETHOD
|
||||
GetEmbellishState(nsEmbellishState& aEmbellishState);
|
||||
|
||||
NS_IMETHOD
|
||||
SetEmbellishState(const nsEmbellishState& aEmbellishState);
|
||||
|
||||
NS_IMETHOD
|
||||
GetPresentationData(PRInt32* aScriptLevel,
|
||||
PRBool* aDisplayStyle);
|
||||
|
@ -105,7 +142,16 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
// helper to reflow our children. We are inline frames, and we don't
|
||||
NS_IMETHOD
|
||||
DidReflow(nsIPresContext* aPresContext,
|
||||
nsDidReflowStatus aStatus)
|
||||
|
||||
{
|
||||
mEmbellish.flags &= ~NS_MATHML_STRETCH_DONE;
|
||||
return nsHTMLContainerFrame::DidReflow(aPresContext, aStatus);
|
||||
}
|
||||
|
||||
// helper method to reflow a child frame. We are inline frames, and we don't
|
||||
// know our positions until reflow is finished. That's why we ask the
|
||||
// base method not to worry about our position.
|
||||
nsresult
|
||||
|
@ -115,20 +161,54 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
return nsHTMLContainerFrame::ReflowChild(aKidFrame, aPresContext, aDesiredSize, aReflowState,
|
||||
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
||||
|
||||
return nsHTMLContainerFrame::ReflowChild(aKidFrame, aPresContext, aDesiredSize, aReflowState,
|
||||
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
|
||||
}
|
||||
|
||||
// helper method for altering the style contexts of subscript/superscript elements
|
||||
// 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 embellish
|
||||
// operators don't terminate their Reflow without receiving a Stretch command.
|
||||
NS_IMETHOD
|
||||
FinalizeReflow(PRInt32 aDirection,
|
||||
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
|
||||
InsertScriptLevelStyleContext(nsIPresContext* aPresContext);
|
||||
|
||||
// helper methods for processing empty MathML frames (with whitespace only)
|
||||
// helper to check if a frame is an embellished container
|
||||
static PRBool
|
||||
IsEmbellishOperator(nsIFrame* aFrame);
|
||||
|
||||
// helper methods for processing empty MathML frames (with whitespace only)
|
||||
static PRBool
|
||||
IsOnlyWhitespace(nsIFrame* aFrame);
|
||||
|
||||
|
@ -144,6 +224,12 @@ protected:
|
|||
PRBool mDisplayStyle; // displaystyle="false" is intended to slightly alter how the
|
||||
// rendering is done in inline mode.
|
||||
|
||||
nsEmbellishState mEmbellish; // information about a container that is an embellished operator
|
||||
|
||||
nsBoundingMetrics mBoundingMetrics; // Metrics that _exactly_ enclose the text of the frame
|
||||
/*
|
||||
nsPoint mReference; // Reference point of the frame: mReference.x is the baseline
|
||||
*/
|
||||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
};
|
||||
|
||||
|
@ -151,13 +237,7 @@ protected:
|
|||
// has some provisions for MathML
|
||||
class nsMathMLWrapperFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLWrapperFrame(nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize);
|
||||
friend nsresult NS_NewMathMLWrapperFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
|
@ -165,6 +245,12 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
protected:
|
||||
nsMathMLWrapperFrame();
|
||||
virtual ~nsMathMLWrapperFrame();
|
||||
|
|
|
@ -26,23 +26,23 @@
|
|||
#include "nsISupports.h"
|
||||
|
||||
// Factory methods for creating MathML objects
|
||||
extern nsresult NS_NewMathMLmrowFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmiFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmoFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmphantomFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmpaddedFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmfencedFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmfracFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsubFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsupFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsubsupFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmunderFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmoverFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmunderoverFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmmultiscriptsFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmstyleFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmtdFrame ( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsqrtFrame( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmrootFrame( nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmrowFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmiFrame ( 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 );
|
||||
extern nsresult NS_NewMathMLmfencedFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmfracFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsubFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsubsupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmunderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmoverFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
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_NewMathMLmtdFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmsqrtFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
extern nsresult NS_NewMathMLmrootFrame( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
||||
|
||||
#endif /* nsMathMLParts_h___ */
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmfencedFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmfencedFrame* it = new nsMathMLmfencedFrame;
|
||||
nsMathMLmfencedFrame* it = new (aPresShell) nsMathMLmfencedFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
|
|||
// see if the opening fence is there ...
|
||||
data = '('; // default as per the MathML REC
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::open, value)) {
|
||||
nsMathMLAtoms::open_, value)) {
|
||||
value.Trim(" ");
|
||||
data = value;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
|
|||
// see if the closing fence is there ...
|
||||
data = ')'; // default as per the MathML REC
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::close, value)) {
|
||||
nsMathMLAtoms::close_, value)) {
|
||||
value.Trim(" ");
|
||||
data = value;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ nsMathMLmfencedFrame::ReCreateFencesAndSeparators()
|
|||
// see if separators are there ...
|
||||
data = ','; // default as per the MathML REC
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::separators, value)) {
|
||||
nsMathMLAtoms::separators_, value)) {
|
||||
value.Trim(" ");
|
||||
data = value;
|
||||
}
|
||||
|
@ -263,14 +263,14 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Ask stretchy children to stretch themselves
|
||||
|
||||
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
|
||||
nsCharMetrics parentSize(aDesiredSize);
|
||||
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);
|
||||
nsCharMetrics childSize(rect.x, rect.y, rect.width, rect.height);
|
||||
nsStretchMetrics childSize(rect.x, rect.y, rect.width, rect.height);
|
||||
//////////
|
||||
// Stretch ...
|
||||
// Only directed at frames that implement the nsIMathMLFrame interface
|
||||
|
@ -312,7 +312,7 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
|
|||
fm->GetMaxAscent(fontAscent);
|
||||
fm->GetMaxDescent(fontDescent);
|
||||
em = NSToCoordRound(float(font.mFont.size));
|
||||
parentSize = nsCharMetrics(aDesiredSize);
|
||||
parentSize = nsStretchMetrics(aDesiredSize);
|
||||
|
||||
nscoord dx = 0; // running x-origin of children ...
|
||||
|
||||
|
@ -351,7 +351,12 @@ nsMathMLmfencedFrame::Reflow(nsIPresContext* aPresContext,
|
|||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
childFrame->GetRect(rect);
|
||||
childFrame->MoveTo(aPresContext, rect.x, aDesiredSize.ascent - rect.y);
|
||||
|
||||
// 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);
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
|
@ -387,12 +392,12 @@ nsMathMLmfencedFrame::ReflowChar(nsIPresContext* aPresContext,
|
|||
nscoord fontAscent,
|
||||
nscoord fontDescent,
|
||||
nscoord em,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nscoord& aX)
|
||||
{
|
||||
if (aMathMLChar && 0 < aMathMLChar->Length()) {
|
||||
nsCharMetrics aCharSize(fontDescent, fontAscent, 0, fontDescent + fontAscent);
|
||||
nsStretchMetrics aCharSize(fontDescent, fontAscent, 0, fontDescent + fontAscent);
|
||||
aRenderingContext.GetWidth(aMathMLChar->GetUnicode(),
|
||||
PRUint32(aMathMLChar->Length()),
|
||||
aCharSize.width);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmfencedFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmfencedFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmfencedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
@ -80,7 +80,7 @@ protected:
|
|||
nscoord fontAscent,
|
||||
nscoord fontDescent,
|
||||
nscoord em,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nscoord& aX);
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmfracFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmfracFrame* it = new nsMathMLmfracFrame;
|
||||
nsMathMLmfracFrame* it = new (aPresShell) nsMathMLmfracFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// see if the linethickness attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::linethickness, value))
|
||||
nsMathMLAtoms::linethickness_, value))
|
||||
{
|
||||
if (value == "thin")
|
||||
aLineThickness = THIN_FRACTION_LINE_THICKNESS;
|
||||
|
@ -237,9 +237,15 @@ nsMathMLmfracFrame::Reflow(nsIPresContext* aPresContext,
|
|||
rect[1].x = (aDesiredSize.width - rect[1].width) / 2;
|
||||
rect[0].y = 0;
|
||||
rect[1].y = aDesiredSize.height - rect[1].height;
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
|
||||
// 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);
|
||||
}
|
||||
SetLineOrigin(nsPoint(0,rect[0].height)); // position the fraction bar
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
|
|
|
@ -96,7 +96,7 @@ pc picas (1 pica = 12 points)
|
|||
|
||||
class nsMathMLmfracFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmfracFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmfracFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -48,13 +48,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmiFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmiFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmiFrame* it = new nsMathMLmiFrame;
|
||||
nsMathMLmiFrame* it = new (aPresShell) nsMathMLmiFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -137,8 +137,11 @@ nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
|
||||
if (newStyleContext && newStyleContext.get() != mStyleContext) {
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
|
||||
nsIFrame* newFrame = nsnull;
|
||||
NS_NewMathMLWrapperFrame(&newFrame);
|
||||
NS_NewMathMLWrapperFrame(shell, &newFrame);
|
||||
NS_ASSERTION(newFrame, "Failed to create new frame");
|
||||
|
||||
newFrame->Init(aPresContext, mContent, this, newStyleContext, nsnull);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmiFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmiFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmiFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmmultiscriptsFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmmultiscriptsFrame* it = new nsMathMLmmultiscriptsFrame;
|
||||
nsMathMLmmultiscriptsFrame* it = new (aPresShell) nsMathMLmmultiscriptsFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -67,19 +67,12 @@ nsMathMLmmultiscriptsFrame::~nsMathMLmmultiscriptsFrame()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
nsresult rv;
|
||||
nsIFrame* mprescriptsFrame = nsnull; // frame of <mprescripts/>, if there.
|
||||
PRBool isSubscript = PR_FALSE;
|
||||
nscoord ascent, descent, width, height;
|
||||
|
@ -88,71 +81,44 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
nsIFrame* baseFrame = nsnull;
|
||||
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 {
|
||||
nsRect childRect;
|
||||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
|
||||
nsCOMPtr<nsIContent> childContent;
|
||||
nsCOMPtr<nsIAtom> childTag;
|
||||
childFrame->GetContent(getter_AddRefs(childContent));
|
||||
childContent->GetTag(*getter_AddRefs(childTag));
|
||||
|
||||
if (childTag.get() == nsMathMLAtoms::mprescripts) {
|
||||
// NS_ASSERTION(mprescriptsFrame == nsnull,"duplicate <mprescripts/>");
|
||||
//printf("mprescripts Found ...\n"); // should ignore?
|
||||
if (childTag.get() == nsMathMLAtoms::mprescripts_) {
|
||||
mprescriptsFrame = childFrame;
|
||||
}
|
||||
else if (childTag.get() == nsMathMLAtoms::none) {
|
||||
childDesiredSize.height = 0;
|
||||
childDesiredSize.width = 0;
|
||||
childDesiredSize.ascent = 0;
|
||||
childDesiredSize.descent = 0;
|
||||
}
|
||||
else {
|
||||
//printf("child count: %d...\n", 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;
|
||||
}
|
||||
|
||||
else if (childTag.get() != nsMathMLAtoms::none_) {
|
||||
childFrame->GetRect(childRect);
|
||||
if (0 == count) {
|
||||
baseFrame = childFrame;
|
||||
ascent = childDesiredSize.ascent;
|
||||
descent = childDesiredSize.descent;
|
||||
height = childDesiredSize.height;
|
||||
subsupWidth = childDesiredSize.width;
|
||||
descent = childRect.x;
|
||||
ascent = childRect.y;
|
||||
height = childRect.height;
|
||||
subsupWidth = childRect.width;
|
||||
subHeight = supHeight = height;
|
||||
supAscent = ascent;
|
||||
subDescent = descent;
|
||||
}
|
||||
else {
|
||||
if (isSubscript) {
|
||||
subDescent = PR_MAX(subDescent, childDesiredSize.descent);
|
||||
subHeight = PR_MAX(subHeight, childDesiredSize.height);
|
||||
width = childDesiredSize.width;
|
||||
subDescent = PR_MAX(subDescent, childRect.x);
|
||||
subHeight = PR_MAX(subHeight, childRect.height);
|
||||
width = childRect.width;
|
||||
}
|
||||
else {
|
||||
supAscent = PR_MAX(supAscent, childDesiredSize.ascent);
|
||||
supHeight = PR_MAX(supHeight, childDesiredSize.height);
|
||||
width = PR_MAX(width, childDesiredSize.width);
|
||||
supAscent = PR_MAX(supAscent, childRect.y);
|
||||
supHeight = PR_MAX(supHeight, childRect.height);
|
||||
width = PR_MAX(width, childRect.width);
|
||||
subsupWidth += width;
|
||||
}
|
||||
}
|
||||
|
||||
// At this stage, the origin points of the children have no use, so we will use the
|
||||
// origins to store the child's ascent and descent. At the next pass, 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));
|
||||
isSubscript = !isSubscript;
|
||||
count++;
|
||||
}
|
||||
|
@ -161,9 +127,6 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
// Get the subscript and superscript offsets
|
||||
nscoord subscriptOffset, superscriptOffset, leading;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
|
@ -182,15 +145,12 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.height = aDesiredSize.descent + aDesiredSize.ascent;
|
||||
aDesiredSize.width = subsupWidth;
|
||||
|
||||
// Place prescripts, followed by base, and then postscripts.
|
||||
// The list of frames is in the order: {base} {postscripts} {prescripts}
|
||||
// We go over the list in a circular manner, starting at <prescripts/>
|
||||
|
||||
nscoord offset = 0;
|
||||
nsIFrame* child[2];
|
||||
nsRect rect[2];
|
||||
|
||||
count = 0;
|
||||
nsHTMLReflowMetrics childSize(nsnull);
|
||||
childFrame = mprescriptsFrame;
|
||||
do {
|
||||
if (nsnull == childFrame) { // end of prescripts,
|
||||
|
@ -199,7 +159,12 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
childFrame->GetRect(rect[0]);
|
||||
rect[0].x = offset;
|
||||
rect[0].y = aDesiredSize.height - subHeight;
|
||||
childFrame->SetRect(aPresContext, rect[0]);
|
||||
if (aPlaceOrigin) {
|
||||
// childFrame->SetRect(aPresContext, rect[0]);
|
||||
childSize.width = rect[0].width;
|
||||
childSize.height = rect[0].height;
|
||||
FinishReflowChild(child[0], aPresContext, childSize, rect[0].x, rect[0].y, 0);
|
||||
}
|
||||
offset += rect[0].width;
|
||||
}
|
||||
else if (mprescriptsFrame != childFrame) {
|
||||
|
@ -208,7 +173,6 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
child[count++] = childFrame;
|
||||
if (2 == count) { // place a sub-sup pair
|
||||
count = 0;
|
||||
//printf("Placing the sub-sup pair...\n");
|
||||
|
||||
child[0]->GetRect(rect[0]);
|
||||
|
@ -220,9 +184,18 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
rect[0].x = offset + (width - rect[0].width) / 2; // centering
|
||||
rect[1].x = offset + (width - rect[1].width) / 2;
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
offset += width;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +207,6 @@ nsMathMLmmultiscriptsFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
|
||||
class nsMathMLmmultiscriptsFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmmultiscriptsFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
|
@ -48,7 +48,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the postscripts and prescripts
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code is Mozilla MathML Project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
* Queensland. Portions created by The University Of Queensland are
|
||||
* Copyright (C) 1999 The University Of Queensland. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
*/
|
||||
|
@ -44,23 +44,23 @@
|
|||
// <mo> -- operator, fence, or separator - implementation
|
||||
//
|
||||
|
||||
// TODO:
|
||||
// TODO:
|
||||
// * Handle embellished operators
|
||||
// See the section "Exception for embellished operators"
|
||||
// in http://www.w3.org/TR/REC-MathML/chap3_2.html
|
||||
//
|
||||
// * For a markup <mo>content</mo>, if "content" is not found in
|
||||
// the operator dictionary, the REC sets default attributes :
|
||||
// fence = false
|
||||
// separator = false
|
||||
// lspace = .27777em
|
||||
// rspace = .27777em
|
||||
// stretchy = false
|
||||
// fence = false
|
||||
// separator = false
|
||||
// lspace = .27777em
|
||||
// rspace = .27777em
|
||||
// stretchy = false
|
||||
// symmetric = true
|
||||
// maxsize = infinity
|
||||
// minsize = 1
|
||||
// largeop = false
|
||||
// movablelimits = false
|
||||
// movablelimits = false
|
||||
// accent = false
|
||||
//
|
||||
// We only have to handle *lspace* and *rspace*, perhaps via a CSS padding rule
|
||||
|
@ -69,32 +69,32 @@
|
|||
|
||||
// * The spacing is wrong in certain situations, e.g.// <mrow> <mo>∀</mo> <mo>+</mo></mrow>
|
||||
//
|
||||
// The REC tells more about lspace and rspace attributes:
|
||||
// The REC tells more about lspace and rspace attributes:
|
||||
//
|
||||
// The values for lspace and rspace given here range from 0 to 6/18 em in
|
||||
// The values for lspace and rspace given here range from 0 to 6/18 em in
|
||||
// units of 1/18 em. For the invisible operators whose content is
|
||||
// "⁢" or "⁡", it is suggested that MathML
|
||||
// "⁢" or "⁡", it is suggested that MathML
|
||||
// renderers choose spacing in a context-sensitive way (which is an exception to
|
||||
// the static values given in the following table). For <mo>⁡</mo>,
|
||||
// the static values given in the following table). For <mo>⁡</mo>,
|
||||
// the total spacing (lspace + rspace) in expressions such as "sin x"
|
||||
// (where the right operand doesn't start with a fence) should be greater
|
||||
// (where the right operand doesn't start with a fence) should be greater
|
||||
// than 0; for <mo>⁢</mo>, the total spacing should be greater
|
||||
// than 0 when both operands (or the nearest tokens on either side, if on
|
||||
// the baseline) are identifiers displayed in a non-slanted font (i.e., under
|
||||
// the suggested rules, when both operands are multi-character identifiers).
|
||||
// than 0 when both operands (or the nearest tokens on either side, if on
|
||||
// the baseline) are identifiers displayed in a non-slanted font (i.e., under
|
||||
// the suggested rules, when both operands are multi-character identifiers).
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmoFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmoFrame* it = new nsMathMLmoFrame;
|
||||
nsMathMLmoFrame* it = new (aPresShell) nsMathMLmoFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*aNewFrame = it;
|
||||
*aNewFrame = it;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -116,14 +116,14 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
|
|||
|
||||
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
|
||||
NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
rv = mMathMLChar.Paint(aPresContext,
|
||||
rv = mMathMLChar.Paint(aPresContext,
|
||||
aRenderingContext,
|
||||
mStyleContext);
|
||||
}
|
||||
else { // let the base class worry about the painting
|
||||
rv = nsMathMLContainerFrame::Paint(aPresContext,
|
||||
rv = nsMathMLContainerFrame::Paint(aPresContext,
|
||||
aRenderingContext,
|
||||
aDirtyRect,
|
||||
aDirtyRect,
|
||||
aWhichLayer);
|
||||
}
|
||||
return rv;
|
||||
|
@ -147,9 +147,13 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsMathMLmoFrame::InitData()
|
||||
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;
|
||||
|
@ -161,52 +165,91 @@ nsMathMLmoFrame::InitData()
|
|||
for (PRInt32 kid=0; kid<numKids; kid++) {
|
||||
nsCOMPtr<nsIContent> kidContent;
|
||||
mContent->ChildAt(kid, *getter_AddRefs(kidContent));
|
||||
if (kidContent.get()) {
|
||||
if (kidContent.get()) {
|
||||
nsCOMPtr<nsIDOMText> kidText(do_QueryInterface(kidContent));
|
||||
if (kidText.get()) {
|
||||
// PRUint32 kidLength;
|
||||
// kidText->GetLength(&kidLength);
|
||||
// aLength += kidLength;
|
||||
// aLength += kidLength;
|
||||
nsAutoString kidData;
|
||||
kidText->GetData(kidData);
|
||||
aData += kidData;
|
||||
}
|
||||
}
|
||||
}
|
||||
// cache the operator
|
||||
mMathMLChar.SetData(aData);
|
||||
|
||||
// find our form
|
||||
// for consistency, set the first non-empty child as the embellished child
|
||||
nsIFrame* firstChild = mFrames.FirstChild();
|
||||
while (firstChild) {
|
||||
if (!IsOnlyWhitespace(firstChild)) {
|
||||
mEmbellish.flags = NS_MATHML_EMBELLISH_OPERATOR;
|
||||
mEmbellish.firstChild = firstChild;
|
||||
mEmbellish.core = this;
|
||||
mEmbellish.direction = mMathMLChar.GetStretchDirection();
|
||||
break;
|
||||
}
|
||||
firstChild->GetNextSibling(&firstChild);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsMathMLmoFrame::InitData()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mFlags = 0;
|
||||
|
||||
// find our form
|
||||
nsAutoString value;
|
||||
nsOperatorFlags aForm = NS_MATHML_OPERATOR_FORM_INFIX;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::form, value)) {
|
||||
if (value == "prefix")
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
PRBool hasEmbellishAncestor = PR_FALSE;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::form_, value)) {
|
||||
if (value == "prefix")
|
||||
aForm = NS_MATHML_OPERATOR_FORM_PREFIX;
|
||||
else if (value == "postfix")
|
||||
else if (value == "postfix")
|
||||
aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
|
||||
}
|
||||
else { // look at our position from our parent (frames are singly-linked together).
|
||||
|
||||
// flag if we have an embellished ancestor
|
||||
hasEmbellishAncestor = IsEmbellishOperator(mParent);
|
||||
}
|
||||
else {
|
||||
// Get our outermost embellished container and its parent
|
||||
nsIFrame* aParent = this;
|
||||
nsIFrame* aEmbellish = this;
|
||||
do {
|
||||
aEmbellish = aParent;
|
||||
aParent->GetParent(&aParent);
|
||||
} while (IsEmbellishOperator(aParent));
|
||||
// flag if we have an embellished ancestor
|
||||
if (aEmbellish != this) {
|
||||
hasEmbellishAncestor = PR_TRUE;
|
||||
}
|
||||
|
||||
// Find the position of our outermost embellished container w.r.t
|
||||
// its sibblings (frames are singly-linked together).
|
||||
//////////////
|
||||
// WHITESPACE: don't forget that whitespace doesn't count in MathML!
|
||||
// Here is the situation: we may have empty frames between us:
|
||||
// [space*] [prev] [space*] [this] [space*] [next]
|
||||
// We want to skip them...
|
||||
// [space*] [prev] [space*] [aEmbellish] [space*] [next]
|
||||
// We want to skip them...
|
||||
// The problem looks like a regexp, we ask a little flag to help us.
|
||||
|
||||
PRInt32 state = 0;
|
||||
nsIFrame* prev = nsnull;
|
||||
nsIFrame* next = nsnull;
|
||||
nsIFrame* aFrame;
|
||||
|
||||
mParent->FirstChild(nsnull, &aFrame);
|
||||
while (nsnull != aFrame) {
|
||||
if (aFrame == this) { // we start looking for next
|
||||
|
||||
aParent->FirstChild(nsnull, &aFrame);
|
||||
while (aFrame) {
|
||||
if (aFrame == aEmbellish) { // we start looking for next
|
||||
state++;
|
||||
}
|
||||
else if (!IsOnlyWhitespace(aFrame)) {
|
||||
if (0 == state) { // we are still looking for prev
|
||||
prev = aFrame;
|
||||
prev = aFrame;
|
||||
}
|
||||
else if (1 == state) { // we got next
|
||||
next = aFrame;
|
||||
|
@ -215,86 +258,95 @@ nsMathMLmoFrame::InitData()
|
|||
}
|
||||
aFrame->GetNextSibling(&aFrame);
|
||||
}
|
||||
|
||||
// set our form flag depending on our position
|
||||
if (nsnull == prev && nsnull != next)
|
||||
|
||||
// set our form flag depending on the position
|
||||
if (!prev && next)
|
||||
aForm = NS_MATHML_OPERATOR_FORM_PREFIX;
|
||||
else if (nsnull != prev && nsnull == next)
|
||||
else if (prev && !next)
|
||||
aForm = NS_MATHML_OPERATOR_FORM_POSTFIX;
|
||||
}
|
||||
|
||||
// cache our form
|
||||
mFlags |= aForm;
|
||||
// Lookup the operator dictionary
|
||||
nsAutoString aData;
|
||||
mMathMLChar.GetData(aData);
|
||||
PRBool found = nsMathMLOperators::LookupOperator(aData, aForm,
|
||||
&mFlags, &mLeftSpace, &mRightSpace);
|
||||
|
||||
// Now that we know our text an our form, we can lookup the operator dictionary
|
||||
PRBool found;
|
||||
found = nsMathMLOperators::LookupOperator(aData, aForm,
|
||||
&mFlags, &mLeftSpace, &mRightSpace);
|
||||
// All operators are symmetric. But this symmetric flag is *not* stored in the
|
||||
// operator dictionary and operaptors are treated as non-symmetric...
|
||||
// Uncomment the folllowing line to change this behavior.
|
||||
// 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)) {
|
||||
mFlags |= NS_MATHML_OPERATOR_MUTABLE;
|
||||
}
|
||||
|
||||
// If we don't want extra space when we are a script
|
||||
if (mScriptLevel > 0) {
|
||||
// Set the flag if the operator has an embellished ancestor
|
||||
if (hasEmbellishAncestor) {
|
||||
mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;
|
||||
}
|
||||
|
||||
// If we don't want too much extra space when we are a script
|
||||
if (!hasEmbellishAncestor && 0 < mScriptLevel) {
|
||||
mLeftSpace /= 2.0f;
|
||||
mRightSpace /= 2.0f;
|
||||
}
|
||||
|
||||
// XXX Factor all this in nsMathMLAttributes.cpp
|
||||
|
||||
// Now see if there are user-defined attributes that override the dictionary.
|
||||
// XXX If an attribute can be forced to be true when it is false in the
|
||||
// Now see if there are user-defined attributes that override the dictionary.
|
||||
// XXX If an attribute can be forced to be true when it is false in the
|
||||
// dictionary, then the following code has to change...
|
||||
|
||||
|
||||
// For each attribute disabled by the user, turn off its bit flag.
|
||||
// movablelimits|separator|largeop|accent|fence|stretchy|form
|
||||
|
||||
nsAutoString kfalse("false");
|
||||
nsAutoString kfalse("false"), ktrue("true");
|
||||
if (NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::stretchy, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::stretchy_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::fence, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::fence_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_FENCE;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_ACCENT(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::accent, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::accent_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_ACCENT;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::largeop, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::largeop_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::separator, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::separator_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
|
||||
}
|
||||
if (NS_MATHML_OPERATOR_IS_MOVABLELIMITS(mFlags)) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::movablelimits, value) && value == kfalse)
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::movablelimits_, value) && value == kfalse)
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MOVABLELIMITS;
|
||||
}
|
||||
|
||||
// TODO: add also lspace and rspace, minsize, maxsize later ...
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::symmetric_, value)) {
|
||||
if (value == ktrue) mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
if (value == kfalse) mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
|
||||
}
|
||||
|
||||
// TODO: add also lspace and rspace, minsize, maxsize, later ...
|
||||
|
||||
// If the stretchy attribute has been disabled, the operator is not mutable
|
||||
if (!found || !NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
// cache the operator
|
||||
mMathMLChar.SetData(aData);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: aDesiredStretchSize is an IN/OUT parameter
|
||||
|
@ -304,62 +356,100 @@ NS_IMETHODIMP
|
|||
nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize)
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize)
|
||||
{
|
||||
if (0 == mFlags) { // first time...
|
||||
InitData();
|
||||
if (NS_MATHML_STRETCH_WAS_DONE(mEmbellish.flags)) {
|
||||
printf("WARNING *** it is wrong to fire stretch more than once on a frame...\n");
|
||||
return NS_OK;
|
||||
}
|
||||
mEmbellish.flags |= NS_MATHML_STRETCH_DONE;
|
||||
|
||||
// get the value of 'em';
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
|
||||
nscoord em = NSToCoordRound(float(aFont->mFont.size));
|
||||
// if (0 == mFlags) { // first time...
|
||||
InitData();
|
||||
// }
|
||||
|
||||
nscoord dx = nscoord( mLeftSpace * em );
|
||||
nscoord dy = 0;
|
||||
|
||||
// see if it is okay to stretch
|
||||
/////////
|
||||
// See if it is okay to stretch
|
||||
|
||||
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
nsCharMetrics old(aDesiredStretchSize);
|
||||
nsStretchMetrics container(aContainerSize);
|
||||
// little adjustments if the operator is symmetric
|
||||
// XXX Also use maxsize and minsize to find what size we should
|
||||
// really suggest to our MathMLChar.
|
||||
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;
|
||||
}
|
||||
|
||||
// let the MathMLChar stretch itself...
|
||||
nsStretchMetrics old(aDesiredStretchSize);
|
||||
mMathMLChar.Stretch(aPresContext, aRenderingContext,
|
||||
mStyleContext, aStretchDirection,
|
||||
aContainerSize, aDesiredStretchSize);
|
||||
|
||||
container, aDesiredStretchSize);
|
||||
if (old == aDesiredStretchSize) { // hasn't changed !
|
||||
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
|
||||
}
|
||||
else {
|
||||
nscoord gap;
|
||||
if (aDesiredStretchSize == NS_STRETCH_DIRECTION_VERTICAL) {
|
||||
gap = aContainerSize.ascent - aDesiredStretchSize.ascent;
|
||||
if (0 < gap) dy += gap;
|
||||
} else if (aDesiredStretchSize == NS_STRETCH_DIRECTION_HORIZONTAL) {
|
||||
gap = (aContainerSize.width - aDesiredStretchSize.width)/2;
|
||||
if (0 < gap) dx += gap;
|
||||
}
|
||||
mMathMLChar.SetRect(nsRect(dx, dy, aDesiredStretchSize.width,
|
||||
aDesiredStretchSize.height));
|
||||
}
|
||||
}
|
||||
|
||||
// adjust our children's offsets to leave the spacing
|
||||
if (0 < dx || 0 < dy) {
|
||||
/////////
|
||||
// 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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
aDesiredStretchSize.leftSpace = mLeftSpace;
|
||||
aDesiredStretchSize.rightSpace = mRightSpace;
|
||||
|
||||
// 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 );
|
||||
nscoord dx = nscoord( mLeftSpace * em );
|
||||
if (0 == dx) return NS_OK;
|
||||
|
||||
// adjust the offsets
|
||||
nsRect rect;
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (nsnull != childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame)) {
|
||||
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
|
||||
mMathMLChar.GetRect(rect);
|
||||
mMathMLChar.SetRect(nsRect(rect.x + dx, rect.y, rect.width, rect.height));
|
||||
}
|
||||
else {
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
childFrame->GetRect(rect);
|
||||
childFrame->MoveTo(aPresContext, rect.x + dx, rect.y + dy);
|
||||
dx += rect.width;
|
||||
childFrame->MoveTo(aPresContext, rect.x + dx, rect.y);
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// account the spacing
|
||||
aDesiredStretchSize.width += nscoord( (mLeftSpace + mRightSpace) * em );
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmoFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmoFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmoFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
@ -41,6 +41,11 @@ public:
|
|||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList);
|
||||
|
||||
NS_IMETHOD
|
||||
Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
|
@ -53,12 +58,12 @@ public:
|
|||
Stretch(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
nsStretchDirection aStretchDirection,
|
||||
nsCharMetrics& aContainerSize,
|
||||
nsCharMetrics& aDesiredStretchSize);
|
||||
nsStretchMetrics& aContainerSize,
|
||||
nsStretchMetrics& aDesiredStretchSize);
|
||||
|
||||
// helper method to lookup the operator dictionary and initialize our member data
|
||||
void InitData();
|
||||
|
||||
|
||||
protected:
|
||||
nsMathMLmoFrame();
|
||||
virtual ~nsMathMLmoFrame();
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmoverFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmoverFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmoverFrame* it = new nsMathMLmoverFrame;
|
||||
nsMathMLmoverFrame* it = new (aPresShell) nsMathMLmoverFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -66,91 +66,104 @@ nsMathMLmoverFrame::~nsMathMLmoverFrame()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mEmbellish.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
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;
|
||||
nscoord width[2];
|
||||
nscoord maxWidth = 0;
|
||||
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(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && aMathMLFrame, "Mystery!");
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsRect rect;
|
||||
nsEmbellishState embellishState;
|
||||
aMathMLFrame->GetEmbellishState(embellishState);
|
||||
embellishState.core->GetRect(rect);
|
||||
width[count] = rect.width + embellishState.leftSpace + embellishState.rightSpace;
|
||||
}
|
||||
}
|
||||
maxWidth = PR_MAX(maxWidth, width[count]); // clean up and use "if" later
|
||||
}
|
||||
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
if (0 == count) {
|
||||
aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
|
||||
aDesiredSize.ascent = rect[0].y;
|
||||
aDesiredSize.descent = rect[0].x;
|
||||
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
|
||||
|
||||
/////////////
|
||||
// Ask stretchy children to stretch themselves
|
||||
|
||||
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_HORIZONTAL;
|
||||
nsCharMetrics parentSize(aDesiredSize);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
//////////
|
||||
// Stretch ...
|
||||
// Only directed at frames that implement the nsIMathMLFrame interface
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = child[i]->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsCharMetrics childSize(rect[i].x, rect[i].y, rect[i].width, rect[i].height);
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
aMathMLFrame->Stretch(aPresContext, renderingContext,
|
||||
stretchDir, parentSize, childSize);
|
||||
// store the updated metrics
|
||||
rect[i] = nsRect(childSize.descent, childSize.ascent,
|
||||
childSize.width, childSize.height);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
aDesiredSize.ascent += rect[1].height;
|
||||
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
|
||||
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[1].y = 0;
|
||||
rect[0].y = rect[1].height;
|
||||
|
||||
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;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
|
@ -162,14 +175,20 @@ nsMathMLmoverFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.height -= leading;
|
||||
aDesiredSize.ascent -= leading;
|
||||
rect[0].y -= leading;
|
||||
//
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
|
||||
//
|
||||
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;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,14 @@
|
|||
|
||||
class nsMathMLmoverFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmoverFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmoverFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
|
@ -40,6 +47,12 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -48,7 +61,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the overscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmpaddedFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmpaddedFrame* it = new nsMathMLmpaddedFrame;
|
||||
nsMathMLmpaddedFrame* it = new (aPresShell) nsMathMLmpaddedFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmpaddedFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmpaddedFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmphantomFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmphantomFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmphantomFrame* it = new nsMathMLmphantomFrame;
|
||||
nsMathMLmphantomFrame* it = new (aPresShell) nsMathMLmphantomFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmphantomFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmphantomFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmphantomFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Paint(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -45,13 +45,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmrootFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmrootFrame* it = new nsMathMLmrootFrame;
|
||||
nsMathMLmrootFrame* it = new (aPresShell) nsMathMLmrootFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -63,10 +63,8 @@ nsMathMLmrootFrame::nsMathMLmrootFrame() :
|
|||
mSqrChar(),
|
||||
mBarChar()
|
||||
{
|
||||
nsAutoString sqr(PRUnichar(0x221A)),
|
||||
bar(PRUnichar(0xF8E5));
|
||||
mSqrChar.SetData(sqr);
|
||||
mBarChar.SetData(bar);
|
||||
mSqrChar.SetEnum(eMathMLChar_Radical);
|
||||
mBarChar.SetEnum(eMathMLChar_RadicalBar);
|
||||
}
|
||||
|
||||
nsMathMLmrootFrame::~nsMathMLmrootFrame()
|
||||
|
@ -190,10 +188,10 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nscoord heightBar = bmBar.ascent - bmBar.descent; // height of the overline bar
|
||||
|
||||
// Stretch the sqrt symbol to the appropriate height if it is not big enough.
|
||||
nsCharMetrics contSize(aDesiredSize);
|
||||
nsCharMetrics desSize(fontDescent, fontAscent, widthSqr, fontAscent + fontDescent);
|
||||
nsStretchMetrics contSize(aDesiredSize);
|
||||
nsStretchMetrics desSize(fontDescent, fontAscent, widthSqr, fontAscent + fontDescent);
|
||||
mSqrChar.Stretch(aPresContext, renderingContext, mStyleContext,
|
||||
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
|
||||
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
|
||||
widthSqr = desSize.width;
|
||||
if (aDesiredSize.ascent < desSize.ascent) {
|
||||
aDesiredSize.ascent = desSize.ascent;
|
||||
|
@ -209,9 +207,9 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
|
|||
dx = bmSqr.rightBearing;
|
||||
|
||||
// Stretch the overline bar to the appropriate width if it is not big enough.
|
||||
contSize = nsCharMetrics(aDesiredSize);
|
||||
desSize = nsCharMetrics(fontDescent, fontAscent, bmBar.rightBearing-bmBar.leftBearing, fontAscent + fontDescent);
|
||||
nsCharMetrics oldSize = desSize;
|
||||
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);
|
||||
|
||||
|
@ -250,8 +248,14 @@ nsMathMLmrootFrame::Reflow(nsIPresContext* aPresContext,
|
|||
rect[3].x += dx; // x-origin of bar
|
||||
}
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
// 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);
|
||||
}
|
||||
mSqrChar.SetRect(rect[2]);
|
||||
mBarChar.SetRect(rect[3]);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmrootFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmrootFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmrootFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmrowFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmrowFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmrowFrame* it = new nsMathMLmrowFrame;
|
||||
nsMathMLmrowFrame* it = new (aPresShell) nsMathMLmrowFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ nsMathMLmrowFrame::Init(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mEmbellish.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
|
||||
|
||||
// XXX Attributes?
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmrowFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmrowFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmrowFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -45,13 +45,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmsqrtFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmsqrtFrame* it = new nsMathMLmsqrtFrame;
|
||||
nsMathMLmsqrtFrame* it = new (aPresShell) nsMathMLmsqrtFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -63,10 +63,8 @@ nsMathMLmsqrtFrame::nsMathMLmsqrtFrame() :
|
|||
mSqrChar(),
|
||||
mBarChar()
|
||||
{
|
||||
nsAutoString sqr(PRUnichar(0x221A)),
|
||||
bar(PRUnichar(0xF8E5));
|
||||
mSqrChar.SetData(sqr);
|
||||
mBarChar.SetData(bar);
|
||||
mSqrChar.SetEnum(eMathMLChar_Radical);
|
||||
mBarChar.SetEnum(eMathMLChar_RadicalBar);
|
||||
}
|
||||
|
||||
nsMathMLmsqrtFrame::~nsMathMLmsqrtFrame()
|
||||
|
@ -83,9 +81,8 @@ nsMathMLmsqrtFrame::Init(nsIPresContext* aPresContext,
|
|||
nsresult rv = NS_OK;
|
||||
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
|
||||
aContext, aPrevInFlow);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mEmbellish.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
|
||||
|
||||
// TODO: other attributes...
|
||||
return rv;
|
||||
|
@ -146,6 +143,10 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
|
|||
fm->GetMaxAscent(fontAscent);
|
||||
fm->GetMaxDescent(fontDescent);
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
|
||||
|
||||
nsBoundingMetrics bmSqr, bmBar;
|
||||
nscoord dx, dy;
|
||||
|
||||
|
@ -158,10 +159,10 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nscoord thickspace = bmBar.ascent - bmBar.descent; // height of the overline bar
|
||||
|
||||
// Stretch the sqrt symbol to the appropriate height if it is not big enough.
|
||||
nsCharMetrics contSize(aDesiredSize);
|
||||
nsCharMetrics desSize(fontDescent, fontAscent, charWidth, fontAscent + fontDescent);
|
||||
nsStretchMetrics contSize(aDesiredSize);
|
||||
nsStretchMetrics desSize(fontDescent, fontAscent, charWidth, fontAscent + fontDescent);
|
||||
mSqrChar.Stretch(aPresContext, renderingContext, mStyleContext,
|
||||
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
|
||||
NS_STRETCH_DIRECTION_VERTICAL, contSize, desSize);
|
||||
charWidth = desSize.width;
|
||||
if (aDesiredSize.ascent < desSize.ascent) {
|
||||
aDesiredSize.ascent = desSize.ascent;
|
||||
|
@ -172,31 +173,32 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
dx = 0;
|
||||
dy = bmSqr.ascent - fontAscent;
|
||||
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 = nsCharMetrics(aDesiredSize);
|
||||
desSize = nsCharMetrics(fontDescent, fontAscent, bmBar.rightBearing-bmBar.leftBearing, fontAscent + fontDescent);
|
||||
nsCharMetrics oldSize = desSize;
|
||||
|
||||
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;
|
||||
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
|
||||
}
|
||||
dy = bmBar.ascent - fontAscent;
|
||||
mBarChar.SetRect(nsRect(dx, dy, desSize.width, thickspace));
|
||||
// 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 += thickspace;
|
||||
aDesiredSize.ascent += 2*onePixel + thickspace;
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
||||
//////////////////
|
||||
// Place Children now by setting the origin of each child.
|
||||
// Adjust the origins to leave room for the sqrt char and the overline bar
|
||||
|
||||
nsRect rect;
|
||||
dx = charWidth;
|
||||
|
|
|
@ -56,7 +56,7 @@ TODO:
|
|||
|
||||
class nsMathMLmsqrtFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmsqrtFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmsqrtFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmstyleFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmstyleFrame* it = new nsMathMLmstyleFrame;
|
||||
nsMathMLmstyleFrame* it = new (aPresShell) nsMathMLmstyleFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
|
|||
// see if the displaystyle attribute is there
|
||||
nsAutoString value;
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::displaystyle, value)) {
|
||||
nsMathMLAtoms::displaystyle_, value)) {
|
||||
if (value == "true") {
|
||||
mDisplayStyle = PR_TRUE;
|
||||
mFlags |= NS_MATHML_MSTYLE_DISPLAYSTYLE;
|
||||
|
@ -95,7 +95,7 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// see if the scriptlevel attribute is there
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute(kNameSpaceID_None,
|
||||
nsMathMLAtoms::scriptlevel, value)) {
|
||||
nsMathMLAtoms::scriptlevel_, value)) {
|
||||
PRInt32 aErrorCode, aUserValue;
|
||||
aUserValue = value.ToInteger(&aErrorCode);
|
||||
if (NS_SUCCEEDED(aErrorCode)) {
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
class nsMathMLmstyleFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmstyleFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmsubFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmsubFrame* it = new nsMathMLmsubFrame;
|
||||
nsMathMLmsubFrame* it = new (aPresShell) nsMathMLmsubFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -67,56 +67,24 @@ nsMathMLmsubFrame::~nsMathMLmsubFrame()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmsubFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsMathMLmsubFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
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 (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame) && 2 > count) {
|
||||
childFrame->GetRect(rect[count]);
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
if (0 == count) {
|
||||
aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
aDesiredSize.ascent = rect[0].y;
|
||||
|
||||
// Get the subscript offset
|
||||
nscoord subscriptOffset, leading;
|
||||
|
@ -151,13 +119,15 @@ subscriptOffset = PR_MAX(subscriptOffset,fmAscent-(xHeight*4)/5);
|
|||
rect[1].y = aDesiredSize.height - rect[1].height;
|
||||
aDesiredSize.descent = aDesiredSize.height - aDesiredSize.ascent;
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
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);
|
||||
}
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
|
||||
class nsMathMLmsubFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmsubFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
|
@ -48,7 +48,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the subscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmsubsupFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmsubsupFrame* it = new nsMathMLmsubsupFrame;
|
||||
nsMathMLmsubsupFrame* it = new (aPresShell) nsMathMLmsubsupFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -67,59 +67,30 @@ nsMathMLmsubsupFrame::~nsMathMLmsubsupFrame()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmsubsupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
nsresult rv;
|
||||
aDesiredSize.width = aDesiredSize.height = aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
nscoord ascent, descent;
|
||||
nscoord count = 0;
|
||||
nsRect rect[3];
|
||||
nsIFrame* child[3];
|
||||
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 (3 > 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 (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame) && 3 > count) {
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
if (0 == count) {
|
||||
ascent = childDesiredSize.ascent;
|
||||
descent = childDesiredSize.descent;
|
||||
}
|
||||
childFrame->GetRect(rect[count]);
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
descent = rect[0].x;
|
||||
ascent = rect[0].y;
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
// Get the subscript and superscript offsets
|
||||
nscoord subscriptOffset, superscriptOffset, leading;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
|
@ -158,15 +129,21 @@ subscriptOffset = PR_MAX(subscriptOffset,fmAscent-(xHeight*4)/5);
|
|||
rect[2].y = 0;
|
||||
rect[1].y = aDesiredSize.height - rect[1].height;
|
||||
rect[0].y = aDesiredSize.height - subHeight;
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
child[2]->SetRect(aPresContext, rect[2]);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
|
||||
class nsMathMLmsubsupFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmsubsupFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
|
@ -48,7 +48,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the subscript and superscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmsupFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmsupFrame* it = new nsMathMLmsupFrame;
|
||||
nsMathMLmsupFrame* it = new (aPresShell) nsMathMLmsupFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -67,58 +67,25 @@ nsMathMLmsupFrame::~nsMathMLmsupFrame()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmsupFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
if (0 == count) {
|
||||
aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame) && 2 > count) {
|
||||
childFrame->GetRect(rect[count]);
|
||||
child[count] = childFrame;
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
aDesiredSize.descent = rect[0].x;
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
// Get the superscript offset
|
||||
nscoord superscriptOffset, leading;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
|
@ -137,14 +104,20 @@ nsMathMLmsupFrame::Reflow(nsIPresContext* aPresContext,
|
|||
rect[1].y = 0;
|
||||
rect[0].y = aDesiredSize.height - rect[0].height;
|
||||
aDesiredSize.ascent = aDesiredSize.height - aDesiredSize.descent;
|
||||
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
|
||||
class nsMathMLmsupFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmsupFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
|
@ -48,7 +48,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the superscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,13 +45,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmtdFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmtdFrame* it = new nsMathMLmtdFrame;
|
||||
nsMathMLmtdFrame* it = new (aPresShell) nsMathMLmtdFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
class nsMathMLmtdFrame : public nsAreaFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmtdFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmtdFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmunderFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmunderFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmunderFrame* it = new nsMathMLmunderFrame;
|
||||
nsMathMLmunderFrame* it = new (aPresShell) nsMathMLmunderFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -66,93 +66,73 @@ nsMathMLmunderFrame::~nsMathMLmunderFrame()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mEmbellish.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
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;
|
||||
}
|
||||
/////////////
|
||||
// Reflow children
|
||||
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
|
||||
if (0 == count) {
|
||||
aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
|
||||
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;
|
||||
nsCharMetrics parentSize(aDesiredSize);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
//////////
|
||||
// Stretch ...
|
||||
// Only directed at frames that implement the nsIMathMLFrame interface
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = child[i]->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsCharMetrics childSize(rect[i].x, rect[i].y, rect[i].width, rect[i].height);
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
aMathMLFrame->Stretch(aPresContext, renderingContext,
|
||||
stretchDir, parentSize, childSize);
|
||||
// store the updated metrics
|
||||
rect[i] = nsRect(childSize.descent, childSize.ascent,
|
||||
childSize.width, childSize.height);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nscoord count = 0;
|
||||
nsRect rect[2];
|
||||
nsIFrame* child[2];
|
||||
nsIFrame* childFrame = mFrames.FirstChild();
|
||||
while (childFrame) {
|
||||
if (!IsOnlyWhitespace(childFrame) && 2 > count) {
|
||||
childFrame->GetRect(rect[count]);
|
||||
child[count] = childFrame;
|
||||
count++;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
aDesiredSize.descent = rect[0].x;
|
||||
aDesiredSize.ascent = rect[0].y;
|
||||
|
||||
#if 0
|
||||
// Get the underline offset and align the top of the under-element with it
|
||||
nscoord underOffset, underThickness;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
|
||||
aPresContext->GetMetricsFor(aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetUnderline(underOffset, underThickness);
|
||||
#endif
|
||||
|
||||
aDesiredSize.descent += rect[1].height;
|
||||
aDesiredSize.width = PR_MAX(rect[0].width, rect[1].width);
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
|
@ -174,13 +154,19 @@ nsMathMLmunderFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.descent -= leading;
|
||||
rect[1].y -= leading;
|
||||
//
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
|
||||
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;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,14 @@
|
|||
|
||||
class nsMathMLmunderFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmunderFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmunderFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
|
@ -40,6 +47,12 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -48,7 +61,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the underscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Original Code is Mozilla MathML Project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
*
|
||||
* The Initial Developer of the Original Code is The University Of
|
||||
* Queensland. Portions created by The University Of Queensland are
|
||||
* Copyright (C) 1999 The University Of Queensland. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roger B. Sidje <rbs@maths.uq.edu.au>
|
||||
* David J. Fiddes <D.J.Fiddes@hw.ac.uk>
|
||||
*/
|
||||
|
@ -44,13 +44,13 @@
|
|||
//
|
||||
|
||||
nsresult
|
||||
NS_NewMathMLmunderoverFrame(nsIFrame** aNewFrame)
|
||||
NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsMathMLmunderoverFrame* it = new nsMathMLmunderoverFrame;
|
||||
nsMathMLmunderoverFrame* it = new (aPresShell) nsMathMLmunderoverFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -66,121 +66,110 @@ nsMathMLmunderoverFrame::~nsMathMLmunderoverFrame()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderoverFrame::Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
mEmbellish.flags = NS_MATHML_STRETCH_ALL_CHILDREN;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderoverFrame::Reflow(nsIPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsReflowStatus childStatus;
|
||||
nsHTMLReflowMetrics childDesiredSize(aDesiredSize.maxElementSize);
|
||||
nsSize availSize(aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
|
||||
aDesiredSize.width = 0;
|
||||
/////////////
|
||||
// Reflow children to stretch themselves
|
||||
|
||||
//////////////////
|
||||
// Reflow Children
|
||||
|
||||
nscoord count = 0;
|
||||
nsRect rect[3];
|
||||
nsIFrame* child[3];
|
||||
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 (3 > 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;
|
||||
}
|
||||
|
||||
child[count] = childFrame;
|
||||
rect[count].width = childDesiredSize.width;
|
||||
rect[count].height = childDesiredSize.height;
|
||||
|
||||
if (aDesiredSize.width < childDesiredSize.width) {
|
||||
aDesiredSize.width = childDesiredSize.width;
|
||||
}
|
||||
if (0 == count) {
|
||||
aDesiredSize.ascent = childDesiredSize.ascent;
|
||||
aDesiredSize.descent = childDesiredSize.descent;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// else { invalid markup... }
|
||||
|
||||
rv = childFrame->GetNextSibling(&childFrame);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get next child");
|
||||
}
|
||||
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;
|
||||
nsCharMetrics parentSize(aDesiredSize);
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
//////////
|
||||
// Stretch ...
|
||||
// Only directed at frames that implement the nsIMathMLFrame interface
|
||||
nsIMathMLFrame* aMathMLFrame = nsnull;
|
||||
rv = child[i]->QueryInterface(nsIMathMLFrame::GetIID(), (void**)&aMathMLFrame);
|
||||
if (NS_SUCCEEDED(rv) && aMathMLFrame) {
|
||||
nsCharMetrics childSize(rect[i].x, rect[i].y, rect[i].width, rect[i].height);
|
||||
nsIRenderingContext& renderingContext = *aReflowState.rendContext;
|
||||
aMathMLFrame->Stretch(aPresContext, renderingContext,
|
||||
stretchDir, parentSize, childSize);
|
||||
// store the updated metrics
|
||||
rect[i] = nsRect(childSize.descent, childSize.ascent,
|
||||
childSize.width, childSize.height);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Place Children
|
||||
|
||||
aDesiredSize.ascent += rect[1].height;
|
||||
aDesiredSize.descent += rect[2].height;
|
||||
aDesiredSize.height = aDesiredSize.ascent + aDesiredSize.descent;
|
||||
StretchChildren(aPresContext, renderingContext, stretchDir, containerSize);
|
||||
|
||||
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[1].height;
|
||||
rect[1].y = aDesiredSize.height - rect[1].height;
|
||||
rect[2].y = 0;
|
||||
|
||||
//ignore the leading (line spacing) that is attached to the text
|
||||
nscoord leading;
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
const nsStyleFont* aFont =
|
||||
(const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
|
||||
aPresContext->GetMetricsFor(aFont->mFont, getter_AddRefs(fm));
|
||||
fm->GetLeading(leading);
|
||||
|
||||
aDesiredSize.height -= 2*leading;
|
||||
aDesiredSize.ascent -= leading;
|
||||
aDesiredSize.descent -= leading;
|
||||
rect[0].y -= leading;
|
||||
rect[1].y -= 2*leading;
|
||||
//
|
||||
child[0]->SetRect(aPresContext, rect[0]);
|
||||
child[1]->SetRect(aPresContext, rect[1]);
|
||||
child[2]->SetRect(aPresContext, rect[2]);
|
||||
/////////////
|
||||
// Place children now by re-adjusting the origins to align the baselines
|
||||
FinalizeReflow(1, aPresContext, renderingContext, aDesiredSize);
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
nscoord count = 0;
|
||||
nsRect rect[3];
|
||||
nsIFrame* child[3];
|
||||
aDesiredSize.width = 0;
|
||||
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;
|
||||
count++;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
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);
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
aPresContext->GetMetricsFor(font.mFont, getter_AddRefs(fm));
|
||||
nscoord leading;
|
||||
fm->GetLeading(leading);
|
||||
|
||||
aDesiredSize.height -= 2*leading;
|
||||
aDesiredSize.ascent -= leading;
|
||||
aDesiredSize.descent -= leading;
|
||||
rect[0].y -= leading;
|
||||
rect[1].y -= 2*leading;
|
||||
//
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,14 @@
|
|||
|
||||
class nsMathMLmunderoverFrame : public nsMathMLContainerFrame {
|
||||
public:
|
||||
friend nsresult NS_NewMathMLmunderoverFrame(nsIFrame** aNewFrame);
|
||||
friend nsresult NS_NewMathMLmunderoverFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
||||
|
||||
NS_IMETHOD
|
||||
Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD
|
||||
Reflow(nsIPresContext* aPresContext,
|
||||
|
@ -40,6 +47,12 @@ public:
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
|
||||
NS_IMETHOD
|
||||
Place(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize);
|
||||
|
||||
NS_IMETHOD
|
||||
SetInitialChildList(nsIPresContext* aPresContext,
|
||||
nsIAtom* aListName,
|
||||
|
@ -48,7 +61,10 @@ public:
|
|||
nsresult rv;
|
||||
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
UpdatePresentationDataFromChildAt(1, 1, PR_FALSE);
|
||||
// switch the style of the underscript and the overscript
|
||||
InsertScriptLevelStyleContext(aPresContext);
|
||||
// check whether or not this is an embellished operator
|
||||
EmbellishOperator();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче