[MathML only - candidate version for 0.9x] * Hooked robust support for advanced dynamic updates via JavaScript and the DOM across the entire MathML module (with particular attention to the numerous presentational attributes that MathML has). * Eliminated some functions (or folded their functionality into recently added APIs). * Reviewed the module as a whole and simplified several chunks of code owing to the benefit of hindsight now. * Added/reviewed the documentation in anticipation of the freezing of Mozilla 1.0, to improve the understanding of people that may read the archived code and learn from it under the appropriate context of this time. * Reviewed the XXX comments and addressed those that could be addressable in this timeframe. * Some renamings (e.g., ReLayout -> ReLayoutChildren to avoid ambiguities as to who does what in terms of the terminology used when referring to the frame hierarchy).

This commit is contained in:
rbs%maths.uq.edu.au 2002-02-07 04:38:08 +00:00
Родитель c56ab16f35
Коммит 6c7c1056cf
47 изменённых файлов: 1633 добавлений и 1659 удалений

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

@ -70,6 +70,11 @@ public:
* Called to ask a stretchy MathML frame to stretch itself depending
* on its context.
*
* An embellished frame is treated in a special way. When it receives a
* Stretch() command, it passes the command to its embellished child and
* the stretched size is bubbled up from the inner-most <mo> frame. In other
* words, the stretch command descend through the embellished hierarchy.
*
* @param aStretchDirection [in] the direction where to attempt to
* stretch.
* @param aContainerSize [in] struct that suggests the maximumn size for
@ -121,36 +126,6 @@ public:
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;
/* GetEmbellishData/SetEmbellishData :
* Get/Set the mEmbellishData member variable.
*/
@ -184,17 +159,37 @@ public:
* within their subtrees.
*
* InheritAutomaticData() is called in a top-down manner [like nsIFrame::Init],
* as we descend the frame tree during its construction, whereas
* TransmitAutomaticData() is called in a bottom-up manner, as we ascend the
* frame tree after its construction [like nsIFrame::SetInitialChildList].
* However, unlike Init() and SetInitialChildList() which are called only
* once during the life-time of a frame, these two methods are called
* whenever we are walking the frame tree to handle dynamic changes that
* happen in the content model.
* as we descend the frame tree, whereas TransmitAutomaticData() is called in a
* bottom-up manner, as we ascend the tree [like nsIFrame::SetInitialChildList].
* However, unlike Init() and SetInitialChildList() which are called only once
* during the life-time of a frame (when initially constructing the frame tree),
* these two methods are called to build automatic data after the <math>...</math>
* subtree has been constructed fully, and are called again as we walk a child's
* subtree to handle dynamic changes that happen in the content model.
*
* As a rule of thumb:
*
* 1. Use InheritAutomaticData() to set properties related to your ancestors:
* - set properties that are intrinsic to yourself
* - set properties that depend on the state that you expect your ancestors
* to have already reached in their own InheritAutomaticData().
* - set properties that your descendants assume that you would have set in
* your InheritAutomaticData() -- this way, they can safely query them and
* the process will feed upon itself.
*
* 2. Use TransmitAutomaticData() to set properties related to your descendants:
* - set properties that depend on the state that you expect your descendants
* to have reached upon processing their own TransmitAutomaticData().
* - transmit properties that your descendants expect that you will transmit to
* them in your TransmitAutomaticData() -- this way, they remain up-to-date.
* - set properties that your ancestors expect that you would set in your
* TransmitAutomaticData() -- this way, they can safely query them and the
* process will feed upon itself.
*/
NS_IMETHOD
InheritAutomaticData(nsIPresContext* aPresContext, nsIFrame* aParent) = 0;
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent) = 0;
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext) = 0;
@ -305,35 +300,64 @@ public:
PRInt32 aParentScriptLevel) = 0;
};
// struct used by a frame to modulate its presentation
struct nsPresentationData {
PRUint32 flags; // bits for: displaystyle, compressed, etc
nsIFrame* mstyle; // up-pointer on the mstyle frame, if any, that defines the scope
PRInt32 scriptLevel; // Relevant to nested frames within: msub, msup, msubsup, munder,
// mover, munderover, mmultiscripts, mfrac, mroot, mtable.
nsPresentationData()
{
flags = 0;
mstyle = nsnull;
scriptLevel = 0;
}
};
// struct used by an embellished container to keep track of its embellished child
// struct used by a container frame to keep track of its embellishments.
// By convention, the data that we keep here is bubbled from the embellished
// hierarchy, and it remains unchanged unless we have to recover from a change
// that occurs in the embellished hierarchy. The struct remains in its nil
// state in those frames that are not part of the embellished hierarchy.
struct nsEmbellishData {
PRUint32 flags;
nsIFrame* nextFrame; // handy pointer on our embellished child to descend the hierarchy
nsIFrame* coreFrame; // pointer on the mo frame at the core of the embellished hierarchy
nsStretchDirection direction;
nscoord leftSpace, rightSpace;
// bits used to mark certain properties of our embellishments
PRUint32 flags;
nsEmbellishData()
{
// handy pointer on our embellished child to descend the embellished hierarchy
nsIFrame* nextFrame;
// pointer on the <mo> frame at the core of the embellished hierarchy
nsIFrame* coreFrame;
// stretchy direction that the nsMathMLChar owned by the core <mo> supports
nsStretchDirection direction;
// spacing that may come from <mo> depending on its 'form'. Since
// the 'form' may also depend on the position of the outermost
// embellished ancestor, the set up of these values may require
// looking up the position of our ancestors.
nscoord leftSpace;
nscoord rightSpace;
nsEmbellishData() {
flags = 0;
nextFrame = nsnull;
coreFrame = nsnull;
direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
leftSpace = rightSpace = 0;
leftSpace = 0;
rightSpace = 0;
}
};
// struct used by a container frame to modulate its presentation.
// By convention, the data that we keep in this struct can change depending
// on any of our ancestors and/or descendants. If a data can be resolved
// solely from the embellished hierarchy, and it remains immutable once
// resolved, we put it in |nsEmbellishData|. If it can be affected by other
// things, it comes here. This struct is updated as we receive information
// transmitted by our ancestors and is kept in sync with changes in our
// descendants that affects us.
struct nsPresentationData {
// bits for: displaystyle, compressed, etc
PRUint32 flags;
// up-pointer on the mstyle frame, if any, that defines the scope
nsIFrame* mstyle;
// level of nested frames within: msub, msup, msubsup, munder,
// mover, munderover, mmultiscripts, mfrac, mroot, mtable.
PRInt32 scriptLevel;
nsPresentationData() {
flags = 0;
mstyle = nsnull;
scriptLevel = 0;
}
};
@ -353,38 +377,40 @@ struct nsEmbellishData {
// Internal use only, cannot be set by the user with an attribute.
#define NS_MATHML_COMPRESSED 0x00000002
// This bit is set if the frame will fire a vertical stretch
// command on all its (non-empty) children.
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
// vertical stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000004
// This bit is set if the frame will fire a horizontal stretch
// command on all its (non-empty) children.
// Tags like munder, mover, munderover, will fire a
// horizontal stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000008
// This bit is set if the frame is actually an <mstyle> frame *and* that
// <mstyle> frame has an explicit attribute scriptlevel="value".
// Note: the flag is not set if the <mstyle> instead has an incremental +/-value.
#define NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL 0x00000004
#define NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL 0x00000010
// This bit is set if the frame is actually an <mstyle> *and* that
// <mstyle> has an explicit attribute displaystyle="true" or "false"
#define NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE 0x00000008
// This bit is set if the frame is an <mover> or <munderover> with
// an accent frame
#define NS_MATHML_ACCENTOVER 0x00000010
// This bit is set if the frame is an <munder> or <munderover> with
// an accentunder frame
#define NS_MATHML_ACCENTUNDER 0x00000020
// This bit is set if the frame is an <mover>, <munder> or <munderover>
// whose base frame is a <mo> frame (or an embellished container with
// a core <mo>) for which the movablelimits attribute is set to true
#define NS_MATHML_MOVABLELIMITS 0x00000040
#define NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE 0x00000020
// This bit is set when the frame cannot be formatted due to an
// error (e.g., invalid markup such as a <msup> without an overscript).
// When set, a visual feedback will be provided to the user.
#define NS_MATHML_ERROR 0x80000000
// a bit used for debug
#define NS_MATHML_STRETCH_DONE 0x20000000
// This bit is used for visual debug. When set, the bounding box
// of your frame is painted. This visual debug enable to ensure that
// you have properly filled your mReference and mBoundingMetrics in
// Place().
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x40000000
#define NS_MATHML_SHOW_BOUNDING_METRICS 0x10000000
// Macros that retrieve those bits
@ -394,24 +420,24 @@ struct nsEmbellishData {
#define NS_MATHML_IS_COMPRESSED(_flags) \
(NS_MATHML_COMPRESSED == ((_flags) & NS_MATHML_COMPRESSED))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
#define NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(_flags) \
(NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE == ((_flags) & NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE))
#define NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(_flags) \
(NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL == ((_flags) & NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL))
#define NS_MATHML_IS_ACCENTOVER(_flags) \
(NS_MATHML_ACCENTOVER == ((_flags) & NS_MATHML_ACCENTOVER))
#define NS_MATHML_IS_ACCENTUNDER(_flags) \
(NS_MATHML_ACCENTUNDER == ((_flags) & NS_MATHML_ACCENTUNDER))
#define NS_MATHML_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_MOVABLELIMITS == ((_flags) & NS_MATHML_MOVABLELIMITS))
#define NS_MATHML_HAS_ERROR(_flags) \
(NS_MATHML_ERROR == ((_flags) & NS_MATHML_ERROR))
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
#define NS_MATHML_PAINT_BOUNDING_METRICS(_flags) \
(NS_MATHML_SHOW_BOUNDING_METRICS == ((_flags) & NS_MATHML_SHOW_BOUNDING_METRICS))
@ -422,47 +448,37 @@ struct nsEmbellishData {
// This bit is set if the frame is an embellished operator.
#define NS_MATHML_EMBELLISH_OPERATOR 0x00000001
// This bit is set if the frame will fire a vertical stretch
// command on all its (non-empty) children.
// Tags like <mrow> (or an inferred mrow), mpadded, etc, will fire a
// vertical stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY 0x00000002
// This bit is set if the frame is an <mo> frame or an embellihsed
// operator for which the core <mo> has movablelimits="true"
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000002
// This bit is set if the frame will fire a horizontal stretch
// command on all its (non-empty) children.
// Tags like munder, mover, munderover, will fire a
// horizontal stretch command on all their non-empty children
#define NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY 0x00000004
// This bit is set if the frame is an <mo> frame or an embellihsed
// operator for which the core <mo> has accent="true"
#define NS_MATHML_EMBELLISH_ACCENT 0x00000004
// This bit is set if the frame is an <mo> frame that should behave
// like an accent XXX since it is <mo> specific, use NS_MATHML_EMBELLISH_MO_ACCENT instead?
#define NS_MATHML_EMBELLISH_ACCENT 0x00000008
// This bit is set if the frame is an <mover> or <munderover> with
// an accent frame
#define NS_MATHML_EMBELLISH_ACCENTOVER 0x00000008
// This bit is set if the frame is an <mo> frame with the movablelimits
// attribute set to true XXX since it is <mo> specific, use NS_MATHML_EMBELLISH_MO_MOVABLELIMITS instead?
#define NS_MATHML_EMBELLISH_MOVABLELIMITS 0x00000010
// a bit used for debug
#define NS_MATHML_STRETCH_DONE 0x80000000
// This bit is set if the frame is an <munder> or <munderover> with
// an accentunder frame
#define NS_MATHML_EMBELLISH_ACCENTUNDER 0x00000010
// Macros that retrieve those bits
#define NS_MATHML_IS_EMBELLISH_OPERATOR(_flags) \
(NS_MATHML_EMBELLISH_OPERATOR == ((_flags) & NS_MATHML_EMBELLISH_OPERATOR))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY))
#define NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(_flags) \
(NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY == ((_flags) & NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY))
#define NS_MATHML_STRETCH_WAS_DONE(_flags) \
(NS_MATHML_STRETCH_DONE == ((_flags) & NS_MATHML_STRETCH_DONE))
#define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
#define NS_MATHML_EMBELLISH_IS_ACCENT(_flags) \
(NS_MATHML_EMBELLISH_ACCENT == ((_flags) & NS_MATHML_EMBELLISH_ACCENT))
#define NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(_flags) \
(NS_MATHML_EMBELLISH_MOVABLELIMITS == ((_flags) & NS_MATHML_EMBELLISH_MOVABLELIMITS))
#define NS_MATHML_EMBELLISH_IS_ACCENTOVER(_flags) \
(NS_MATHML_EMBELLISH_ACCENTOVER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTOVER))
#define NS_MATHML_EMBELLISH_IS_ACCENTUNDER(_flags) \
(NS_MATHML_EMBELLISH_ACCENTUNDER == ((_flags) & NS_MATHML_EMBELLISH_ACCENTUNDER))
#endif /* nsIMathMLFrame_h___ */

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

@ -118,8 +118,7 @@ nsMathMLContainerFrame::PaintError(nsIPresContext* aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
NS_ASSERTION(NS_MATHML_HAS_ERROR(mPresentationData.flags),
"There is nothing wrong with this frame!");
// Set color and font ...
@ -140,7 +139,6 @@ nsMathMLContainerFrame::PaintError(nsIPresContext* aPresContext,
aRenderingContext.DrawString(errorMsg.get(),
PRUint32(errorMsg.Length()),
0, ascent);
}
return NS_OK;
}
@ -150,35 +148,6 @@ nsMathMLContainerFrame::PaintError(nsIPresContext* aPresContext,
* =============================================================================
*/
// 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()
{
nsIFrame* firstChild = mFrames.FirstChild();
if (firstChild && IsEmbellishOperator(firstChild)) {
// Cache the first child
mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = firstChild;
// Cache also the inner-most embellished frame at the core of the hierarchy
nsIMathMLFrame* mathMLFrame;
firstChild->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
nsEmbellishData embellishData;
mathMLFrame->GetEmbellishData(embellishData);
mEmbellishData.coreFrame = embellishData.coreFrame;
mEmbellishData.direction = embellishData.direction;
}
else {
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
}
return NS_OK;
}
// helper method to facilitate getting the reflow and bounding metrics
void
nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFrame,
@ -234,8 +203,8 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIPresContext* aPresContex
else {
// compute a size that doesn't include embellishements
NS_ASSERTION(NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags),
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags),
"invalid call to GetPreferredStretchSize");
nsRect rect;
PRBool firstTime = PR_TRUE;
@ -273,14 +242,14 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIPresContext* aPresContex
if (firstTime) {
firstTime = PR_FALSE;
bm = bmChild;
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags) &&
!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags)) {
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags) &&
!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags)) {
// we may get here for cases such as <msup><mo>...</mo> ... </msup>
break;
}
}
else {
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags)) {
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags)) {
// if we get here, it means this is container that will stack its children
// vertically and fire an horizontal stretch on each them. This is the case
// for \munder, \mover, \munderover. We just sum-up the size vertically.
@ -290,7 +259,7 @@ nsMathMLContainerFrame::GetPreferredStretchSize(nsIPresContext* aPresContex
if (bm.rightBearing < bmChild.rightBearing)
bm.rightBearing = bmChild.rightBearing;
}
else if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags)) {
else if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags)) {
// just sum-up the sizes horizontally.
bm += bmChild;
}
@ -314,11 +283,11 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
{
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
if (NS_MATHML_STRETCH_WAS_DONE(mEmbellishData.flags)) {
if (NS_MATHML_STRETCH_WAS_DONE(mPresentationData.flags)) {
NS_WARNING("it is wrong to fire stretch more than once on a frame");
return NS_OK;
}
mEmbellishData.flags |= NS_MATHML_STRETCH_DONE;
mPresentationData.flags |= NS_MATHML_STRETCH_DONE;
if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
NS_WARNING("it is wrong to fire stretch on a erroneous frame");
@ -334,8 +303,8 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
NS_ASSERTION(mathMLFrame, "Something is wrong somewhere");
if (mathMLFrame) {
PRBool stretchAll =
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags);
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags);
// And the trick is that the child's rect.x is still holding the descent,
// and rect.y is still holding the ascent ...
@ -382,7 +351,7 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
if (stretchAll) {
nsStretchDirection stretchDir =
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) ?
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags) ?
NS_STRETCH_DIRECTION_VERTICAL : NS_STRETCH_DIRECTION_HORIZONTAL;
GetPreferredStretchSize(aPresContext, aRenderingContext, STRETCH_CONSIDER_EMBELLISHMENTS,
@ -416,11 +385,16 @@ nsMathMLContainerFrame::Stretch(nsIPresContext* aPresContext,
// 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)) {
nsEmbellishData parentData;
GetEmbellishDataFrom(mParent, parentData);
// ensure that we are the embellished child, not just a sibling
// (need to test coreFrame since <mfrac> resets other things)
if (parentData.coreFrame != mEmbellishData.coreFrame) {
// (we fetch values from the core since they may use units that depend
// on style data, and style changes could have occured in the core since
// our last visit there)
nsEmbellishData coreData;
mEmbellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
mathMLFrame->GetEmbellishData(coreData);
GetEmbellishDataFrom(mEmbellishData.coreFrame, coreData);
mBoundingMetrics.width += coreData.leftSpace + coreData.rightSpace;
aDesiredStretchSize.width = mBoundingMetrics.width;
@ -484,15 +458,17 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext,
// Don't go without checking to see if our parent will later fire a Stretch() command
// targeted at us. The Stretch() will cause the rect.x and rect.y to clear...
PRBool parentWillFireStretch = PR_FALSE;
nsEmbellishData parentData;
nsIMathMLFrame* mathMLFrame;
mParent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(parentData);
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(parentData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(parentData.flags) ||
(NS_MATHML_IS_EMBELLISH_OPERATOR(parentData.flags)
&& parentData.nextFrame == this))
nsEmbellishData embellishData;
nsPresentationData presentationData;
mathMLFrame->GetEmbellishData(embellishData);
mathMLFrame->GetPresentationData(presentationData);
if (NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(presentationData.flags) ||
(NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags)
&& embellishData.nextFrame == this))
{
parentWillFireStretch = PR_TRUE;
}
@ -501,8 +477,8 @@ nsMathMLContainerFrame::FinalizeReflow(nsIPresContext* aPresContext,
// There is nobody who will fire the stretch for us, we do it ourselves!
PRBool stretchAll =
/* NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) || */
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags);
/* NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags) || */
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags);
nsBoundingMetrics defaultSize;
if (mEmbellishData.coreFrame == this /* case of a bare <mo>...</mo> itself */
@ -860,13 +836,10 @@ nsMathMLContainerFrame::Init(nsIPresContext* aPresContext,
CompressWhitespace(aContent);
// let the base class do its Init()
nsresult rv;
rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
return nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// now, inherit the scriptlevel and displaystyle from our parent
InheritAutomaticData(aPresContext, aParent);
return rv;
// ...We will build our automatic MathML data once the entire <math>...</math>
// tree is constructed.
}
// This method is called in a bottom-up manner, as we ascend the frame tree
@ -877,7 +850,7 @@ nsMathMLContainerFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIFrame* aChildList)
{
// First, let the base class do its job
nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// Next, since we are an inline frame, and since we are a container, we have to
// be very careful with the way we treat our children. Things look okay when
@ -891,63 +864,55 @@ nsMathMLContainerFrame::SetInitialChildList(nsIPresContext* aPresContext,
// So wrap foreign children in nsMathMLForeignFrameWrapper frames
WrapForeignFrames(aPresContext);
return rv;
// Now that our subtree is fully constructed, set the automatic
// presentation data and embellishment data that apply in our subtree
return TransmitAutomaticData(aPresContext);
// ...We will build our automatic MathML data once the entire <math>...</math>
// tree is constructed.
}
// Note that this method re-builds the automatic data in the children -- not
// in aFrame itself (except for those particular operations that the frame
// may do in aFrame->TransmitAutomaticData()). The reason it works this way
// is because a container frame knows what it wants for its children, whereas
// children have no clue who their parent is. For example, it is <mfrac> who
// knows that its children have to be in scriptsizes, and has to transmit this
// information to them. Hence, when changes occur in a child frame, the child
// has to pass the re-build to its parent. Unfortunately, the extra cost for
// this is that it will re-sync in the siblings of the child as well.
// in aParentFrame itself (except for those particular operations that the
// parent frame may do in its TransmitAutomaticData()).
/* static */ void
nsMathMLContainerFrame::RebuildAutomaticDataFor(nsIPresContext* aPresContext,
nsIFrame* aFrame)
nsMathMLContainerFrame::RebuildAutomaticDataForChildren(nsIPresContext* aPresContext,
nsIFrame* aParentFrame)
{
// 1. As we descend the tree, make each child frame inherit data from
// the parent
// 2. As we ascend the tree, transmit any specific change that we want
// down the subtrees
nsIFrame* childFrame;
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
aParentFrame->FirstChild(aPresContext, nsnull, &childFrame);
while (childFrame) {
nsIMathMLFrame* childMathMLFrame;
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&childMathMLFrame);
if (childMathMLFrame) {
childMathMLFrame->InheritAutomaticData(aPresContext, aFrame);
childMathMLFrame->InheritAutomaticData(aPresContext, aParentFrame);
}
RebuildAutomaticDataFor(aPresContext, childFrame);
RebuildAutomaticDataForChildren(aPresContext, childFrame);
childFrame->GetNextSibling(&childFrame);
}
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
aParentFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->TransmitAutomaticData(aPresContext);
}
}
/* static */ nsresult
nsMathMLContainerFrame::ReLayout(nsIPresContext* aPresContext,
nsIFrame* aFrame)
nsMathMLContainerFrame::ReLayoutChildren(nsIPresContext* aPresContext,
nsIFrame* aParentFrame)
{
// walk-up to the first frame that is a MathML frame, stop if we reach <math>
PRInt32 parentScriptLevel = 0;
nsIFrame* frame = aFrame;
nsIFrame* frame = aParentFrame;
while (frame) {
// stop if it is a MathML frame
nsIMathMLFrame* mathMLFrame;
frame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
nsIFrame* parent;
frame->GetParent(&parent);
nsPresentationData parentData;
GetPresentationDataFrom(parent, parentData);
mathMLFrame->GetPresentationData(parentData);
parentScriptLevel = parentData.scriptLevel;
break;
}
@ -971,7 +936,7 @@ nsMathMLContainerFrame::ReLayout(nsIPresContext* aPresContext,
PRBool old = IsEmbellishOperator(frame);
#endif
RebuildAutomaticDataFor(aPresContext, frame);
RebuildAutomaticDataForChildren(aPresContext, frame);
#ifdef DEBUG_rbs
PRBool now = IsEmbellishOperator(frame);
@ -979,8 +944,22 @@ nsMathMLContainerFrame::ReLayout(nsIPresContext* aPresContext,
NS_WARNING("REMIND: case where the embellished hierarchy has to be rebuilt too");
#endif
// re-resolve the style data in our subtree to sync any change of script sizes
PropagateScriptStyleFor(aPresContext, frame, parentScriptLevel);
// re-resolve the style data to sync any change of script sizes
nsIFrame* childFrame;
aParentFrame->FirstChild(aPresContext, nsnull, &childFrame);
while (childFrame) {
nsIMathMLFrame* mathMLFrame;
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
// propagate using the base method to make sure that the control
// is passed on to MathML frames that may be overloading the method
mathMLFrame->ReResolveScriptStyle(aPresContext, parentScriptLevel);
}
else {
PropagateScriptStyleFor(aPresContext, childFrame, parentScriptLevel);
}
childFrame->GetNextSibling(&childFrame);
}
// Ask our parent frame to reflow us
nsCOMPtr<nsIPresShell> presShell;
@ -1000,7 +979,7 @@ nsMathMLContainerFrame::ChildListChanged(nsIPresContext* aPresContext,
// wrap any new foreign child that may have crept in
WrapForeignFrames(aPresContext);
}
return ReLayout(aPresContext, this);
return ReLayoutChildren(aPresContext, this);
}
NS_IMETHODIMP
@ -1084,14 +1063,29 @@ nsMathMLContainerFrame::AttributeChanged(nsIPresContext* aPresContext,
nsresult rv = nsHTMLContainerFrame::AttributeChanged(aPresContext, aChild,
aNameSpaceID, aAttribute, aModType, aHint);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIPresShell> shell;
nsHTMLReflowCommand *reflowCmd;
aPresContext->GetShell(getter_AddRefs(shell));
rv = NS_NewHTMLReflowCommand(&reflowCmd, this,
eReflowType_ContentChanged,
nsnull, aAttribute);
if (NS_SUCCEEDED(rv) && shell) shell->AppendReflowCommand(reflowCmd);
return rv;
// check if this is an attribute that can affect the embellished hierarchy
// in a significant way. We handle this here to avoid duplication of code.
if (nsMathMLAtoms::accent_ == aAttribute ||
nsMathMLAtoms::accentunder_ == aAttribute ||
nsMathMLAtoms::movablelimits_ == aAttribute) {
// set the target as the parent of our outermost embellished container
// (we ensure that we are the core, not just a sibling of the core)
nsIFrame* target = this;
nsEmbellishData embellishData;
do {
target->GetParent(&target);
GetEmbellishDataFrom(target, embellishData);
} while (embellishData.coreFrame == this);
// we have automatic data to update in the children of the target frame
return ReLayoutChildren(aPresContext, target);
}
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
return mParent->ReflowDirtyChild(presShell, this);
}
// helper function to reflow token elements
@ -1319,12 +1313,12 @@ printf("\n");
// after finishing the stretching of the embellished child - bug 117652
if (!NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) &&
(NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mEmbellishData.flags))) {
(NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags) ||
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_HORIZONTALLY(mPresentationData.flags))) {
// get the stretchy direction
nsStretchDirection stretchDir =
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mEmbellishData.flags)
NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(mPresentationData.flags)
? NS_STRETCH_DIRECTION_VERTICAL
: NS_STRETCH_DIRECTION_HORIZONTAL;

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

@ -79,9 +79,6 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
EmbellishOperator();
NS_IMETHOD
UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext,
PRInt32 aFirstIndex,
@ -163,7 +160,7 @@ public:
nsDidReflowStatus aStatus)
{
mEmbellishData.flags &= ~NS_MATHML_STRETCH_DONE;
mPresentationData.flags &= ~NS_MATHML_STRETCH_DONE;
return nsHTMLContainerFrame::DidReflow(aPresContext, aReflowState, aStatus);
}
@ -174,6 +171,23 @@ public:
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
// Notification when an attribute is changed. The MathML module uses the
// following paradigm:
//
// 1. If the MathML frame class doesn't have any cached automatic data that
// depends on the attribute: we just reflow (e.g., this happens with <msub>,
// <msup>, <mmultiscripts>, etc). This is the default behavior implemented
// by this base class.
//
// 2. If the MathML frame class has cached automatic data that depends on
// the attribute:
// 2a. If the automatic data to update resides only within the descendants,
// we just re-layout them using ReLayoutChildren(aPresContext, this);
// (e.g., this happens with <ms>).
// 2b. If the automatic data to update affects us in some way, we ask our parent
// to re-layout its children using ReLayoutChildren(aPresContext, mParent);
// Therefore, there is an overhead here in that our siblings are re-laid
// too (e.g., this happens with <mstyle>, <munder>, <mover>, <munderover>).
NS_IMETHOD
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
@ -185,8 +199,8 @@ public:
// --------------------------------------------------------------------------
// Additional methods
// helper to sync our automatic data and notify our parent to reflow us
// when changes (e.g., append/insert/remove) happen in our child list
// helper to re-sync the automatic data in our children and notify our parent to
// reflow us when changes (e.g., append/insert/remove) happen in our child list
virtual nsresult
ChildListChanged(nsIPresContext* aPresContext,
PRInt32 aModType);
@ -279,7 +293,7 @@ public:
static void
PropagateScriptStyleFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
PRInt32 aFrameScriptLevel);
PRInt32 aParentScriptLevel);
// helper to let the update of presentation data pass through
// a subtree that may contain non-MathML container frames
@ -301,19 +315,31 @@ public:
// helper to let the rebuild of automatic data (presentation data
// and embellishement data) walk through a subtree that may contain
// non-MathML container frames
// non-MathML container frames. Note that this method re-builds the
// automatic data in the children -- not in aParentFrame itself (except
// for those particular operations that the parent frame may do in its
// TransmitAutomaticData()). The reason it works this way is because
// a container frame knows what it wants for its children, whereas children
// have no clue who their parent is. For example, it is <mfrac> who knows
// that its children have to be in scriptsizes, and has to transmit this
// information to them. Hence, when changes occur in a child frame, the child
// has to request the re-build from its parent. Unfortunately, the extra cost
// for this is that it will re-sync in the siblings of the child as well.
static void
RebuildAutomaticDataFor(nsIPresContext* aPresContext,
nsIFrame* aFrame);
RebuildAutomaticDataForChildren(nsIPresContext* aPresContext,
nsIFrame* aParentFrame);
// helper to blow away the automatic data cached in a frame's subtree and
// re-layout its subtree to reflect changes that may have happen. In the
// event where aFrame isn't a MathML frame, it will first walk up to the
// ancestor that is a MathML frame, and re-layout from there -- this is to
// guarantee that automatic data will be rebuilt properly.
// event where aParentFrame isn't a MathML frame, it will first walk up to
// the ancestor that is a MathML frame, and re-layout from there -- this is
// to guarantee that automatic data will be rebuilt properly. Note that this
// method re-builds the automatic data in the children -- not in the parent
// frame itself (except for those particular operations that the parent frame
// may do do its TransmitAutomaticData()). @see RebuildAutomaticDataForChildren
static nsresult
ReLayout(nsIPresContext* aPresContext,
nsIFrame* aFrame);
ReLayoutChildren(nsIPresContext* aPresContext,
nsIFrame* aParentFrame);
protected:
virtual PRIntn GetSkipSides() const { return 0; }
@ -340,7 +366,8 @@ public:
nsIFrame* aChildList)
{
nsresult rv = nsBlockFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// re-resolve our subtree to set any mathml-expected scriptsizes
// re-resolve our subtree to set any mathml-expected data
nsMathMLContainerFrame::RebuildAutomaticDataForChildren(aPresContext, this);
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
return rv;
}
@ -352,7 +379,7 @@ public:
nsIFrame* aFrameList)
{
nsresult rv = nsBlockFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -364,7 +391,7 @@ public:
nsIFrame* aFrameList)
{
nsresult rv = nsBlockFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -376,7 +403,7 @@ public:
nsIFrame* aNewFrame)
{
nsresult rv = nsBlockFrame::ReplaceFrame(aPresContext, aPresShell, aListName, aOldFrame, aNewFrame);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -387,7 +414,7 @@ public:
nsIFrame* aOldFrame)
{
nsresult rv = nsBlockFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -408,7 +435,8 @@ public:
nsIFrame* aChildList)
{
nsresult rv = nsInlineFrame::SetInitialChildList(aPresContext, aListName, aChildList);
// re-resolve our subtree to set any mathml-expected scriptsizes
// re-resolve our subtree to set any mathml-expected data
nsMathMLContainerFrame::RebuildAutomaticDataForChildren(aPresContext, this);
nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, 0);
return rv;
}
@ -420,7 +448,7 @@ public:
nsIFrame* aFrameList)
{
nsresult rv = nsInlineFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -432,7 +460,7 @@ public:
nsIFrame* aFrameList)
{
nsresult rv = nsInlineFrame::InsertFrames(aPresContext, aPresShell, aListName, aPrevFrame, aFrameList);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -444,7 +472,7 @@ public:
nsIFrame* aNewFrame)
{
nsresult rv = nsInlineFrame::ReplaceFrame(aPresContext, aPresShell, aListName, aOldFrame, aNewFrame);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}
@ -455,7 +483,7 @@ public:
nsIFrame* aOldFrame)
{
nsresult rv = nsInlineFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
nsMathMLContainerFrame::ReLayout(aPresContext, this);
nsMathMLContainerFrame::ReLayoutChildren(aPresContext, this);
return rv;
}

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

@ -69,13 +69,7 @@ nsMathMLForeignFrameWrapper::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv;
rv = nsBlockFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// let the base class inherit the scriptlevel and displaystyle from our parent
nsMathMLFrame::InheritAutomaticData(aPresContext, aParent);
return rv;
return nsBlockFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
NS_IMETHODIMP

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

@ -29,18 +29,30 @@ NS_IMETHODIMP
nsMathMLFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
mPresentationData.flags = 0;
mPresentationData.mstyle = nsnull;
mPresentationData.scriptLevel = 0;
mEmbellishData.flags = 0;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
mEmbellishData.leftSpace = mEmbellishData.rightSpace = 0;
mEmbellishData.leftSpace = 0;
mEmbellishData.rightSpace = 0;
mPresentationData.flags = 0;
mPresentationData.mstyle = nsnull;
mPresentationData.scriptLevel = 0;
// by default, just inherit the display & scriptlevel of our parent
GetPresentationDataFrom(aParent, mPresentationData);
nsPresentationData parentData;
GetPresentationDataFrom(aParent, parentData);
mPresentationData.mstyle = parentData.mstyle;
mPresentationData.scriptLevel = parentData.scriptLevel;
if (NS_MATHML_IS_DISPLAYSTYLE(parentData.flags)) {
mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
}
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return NS_OK;
}
@ -72,63 +84,79 @@ nsMathMLFrame::UpdatePresentationData(nsIPresContext* aPresContext,
return NS_OK;
}
/* static */ PRBool
nsMathMLFrame::IsEmbellishOperator(nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "null arg");
if (!aFrame) return PR_FALSE;
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (!mathMLFrame) return PR_FALSE;
nsEmbellishData embellishData;
mathMLFrame->GetEmbellishData(embellishData);
return NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags);
}
// Helper to give a style context suitable for doing the stretching of
// a MathMLChar. Frame classes that use this should ensure that the
// extra leaf style contexts given to the MathMLChars are acessible to
// the Style System via the Get/Set AdditionalStyleContext() APIs.
/* static */ PRBool
/* static */ void
nsMathMLFrame::ResolveMathMLCharStyle(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIStyleContext* aParentStyleContext,
nsMathMLChar* aMathMLChar)
nsMathMLChar* aMathMLChar,
PRBool aIsMutableChar)
{
nsAutoString data;
aMathMLChar->GetData(data);
PRBool isStretchy = nsMathMLOperators::IsMutableOperator(data);
nsIAtom* fontAtom = (isStretchy) ?
nsIAtom* fontAtom = (aIsMutableChar) ?
nsMathMLAtoms::fontstyle_stretchy :
nsMathMLAtoms::fontstyle_anonymous;
nsMathMLAtoms::fontstyle_anonymous; // savings
nsCOMPtr<nsIStyleContext> newStyleContext;
nsresult rv = aPresContext->ResolvePseudoStyleContextFor(aContent, fontAtom,
aParentStyleContext, PR_FALSE,
getter_AddRefs(newStyleContext));
if (NS_SUCCEEDED(rv) && newStyleContext)
aMathMLChar->SetStyleContext(newStyleContext);
}
return isStretchy;
/* static */ PRBool
nsMathMLFrame::IsEmbellishOperator(nsIFrame* aFrame)
{
nsEmbellishData embellishData;
GetEmbellishDataFrom(aFrame, embellishData);
return NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags);
}
/* static */ void
nsMathMLFrame::GetEmbellishDataFrom(nsIFrame* aFrame,
nsEmbellishData& aEmbellishData)
{
// initialize OUT params
aEmbellishData.flags = 0;
aEmbellishData.nextFrame = nsnull;
aEmbellishData.coreFrame = nsnull;
aEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
aEmbellishData.leftSpace = 0;
aEmbellishData.rightSpace = 0;
if (aFrame) {
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(aEmbellishData);
}
}
}
// helper to get the presentation data of a frame, by possibly walking up
// the frame hierarchy if we happen to be surrounded by non-MathML frames.
/* static */ void
nsMathMLFrame::GetPresentationDataFrom(nsIFrame* aFrame,
nsPresentationData& aPresentationData)
nsPresentationData& aPresentationData,
PRBool aClimbTree)
{
// initialize OUT params
aPresentationData.flags = 0;
aPresentationData.mstyle = nsnull;
aPresentationData.scriptLevel = 0;
nsIFrame* frame = aFrame;
while (frame) {
nsIMathMLFrame* mathMLFrame;
frame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
nsPresentationData presentationData;
mathMLFrame->GetPresentationData(presentationData);
aPresentationData.mstyle = presentationData.mstyle;
aPresentationData.scriptLevel = presentationData.scriptLevel;
if (NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags)) {
aPresentationData.flags |= NS_MATHML_DISPLAYSTYLE;
}
mathMLFrame->GetPresentationData(aPresentationData);
break;
}
// stop if the caller doesn't want to lookup beyond the frame
if (!aClimbTree) {
break;
}
// stop if we reach the root <math> tag
@ -148,6 +176,17 @@ nsMathMLFrame::GetPresentationDataFrom(nsIFrame* aFrame,
}
}
/* static */ PRBool
nsMathMLFrame::HasNextSibling(nsIFrame* aFrame)
{
if (aFrame) {
nsIFrame* sibling;
aFrame->GetNextSibling(&sibling);
return sibling != nsnull;
}
return PR_FALSE;
}
// helper to get an attribute from the content or the surrounding <mstyle> hierarchy
/* static */ nsresult
nsMathMLFrame::GetAttribute(nsIContent* aContent,

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

@ -98,11 +98,6 @@ public:
return NS_OK;
}
NS_IMETHOD
EmbellishOperator() {
return NS_OK;
}
NS_IMETHOD
GetEmbellishData(nsEmbellishData& aEmbellishData) {
aEmbellishData = mEmbellishData;
@ -164,24 +159,47 @@ public:
// helper to give a style context suitable for doing the stretching to the
// MathMLChar. Frame classes that use this should make the extra style contexts
// accessible to the Style System via Get/Set AdditionalStyleContext.
// return true if the char is a mutable char
static PRBool
static void
ResolveMathMLCharStyle(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIStyleContext* aParenStyleContext,
nsMathMLChar* aMathMLChar);
nsMathMLChar* aMathMLChar,
PRBool aIsMutableChar);
// helper to check if a frame is embellished
// 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.
static PRBool
IsEmbellishOperator(nsIFrame* aFrame);
// helper to get the presentation data of a frame. If we happen to
// be surrounded by non-MathML helper frames needed for our support,
// we walk up the frame hierarchy until we reach a MathML frame
// or the <root> math element.
// helper to get the mEmbellishData of a frame
static void
GetEmbellishDataFrom(nsIFrame* aFrame,
nsEmbellishData& aEmbellishData);
// helper to get the presentation data of a frame. If aClimbTree is
// set to true and the frame happens to be surrounded by non-MathML
// helper frames needed for its support, we walk up the frame hierarchy
// until we reach a MathML ancestor or the <root> math element.
static void
GetPresentationDataFrom(nsIFrame* aFrame,
nsPresentationData& aPresentationData);
nsPresentationData& aPresentationData,
PRBool aClimbTree = PR_TRUE);
// helper to check if a frame has a next sibling - used to report
// an error when a next sibling is found where unexpected
static PRBool
HasNextSibling(nsIFrame* aFrame);
// helper to check if a content has an attribute. If content is nsnull or if
// the attribute is not there, check if the attribute is on the mstyle hierarchy

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

@ -99,7 +99,6 @@ nsMathMLmactionFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv;
nsAutoString value, prefix;
// Init our local attributes
@ -166,13 +165,7 @@ nsMathMLmactionFrame::Init(nsIPresContext* aPresContext,
}
// Let the base class do the rest
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
return nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
// return the frame whose number is given by the attribute selection="number"
@ -221,23 +214,9 @@ nsMathMLmactionFrame::GetSelectedFrame()
// if the selected child is an embellished operator,
// we become embellished as well
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
if (mSelectedFrame) {
nsIMathMLFrame* mathMLFrame;
mSelectedFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
nsEmbellishData embellishData;
mathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags)) {
mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = mSelectedFrame; // yes!
mEmbellishData.coreFrame = embellishData.coreFrame;
mEmbellishData.direction = embellishData.direction;
}
}
GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
mEmbellishData.nextFrame = mSelectedFrame; // yes!
}
return mSelectedFrame;
@ -316,8 +295,7 @@ nsMathMLmactionFrame::Paint(nsIPresContext* aPresContext,
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// visual debug
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) {
aRenderingContext.SetColor(NS_RGB(0,0,255));
nscoord x = mReference.x + mBoundingMetrics.leftBearing;

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

@ -69,41 +69,46 @@ nsMathMLmfencedFrame::~nsMathMLmfencedFrame()
}
NS_IMETHODIMP
nsMathMLmfencedFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
nsMathMLmfencedFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mOpenChar = nsnull;
mCloseChar = nsnull;
mSeparatorsChar = nsnull;
mSeparatorsCount = 0;
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
return rv;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmfencedFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv;
// First, let the base class do its work
rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
if (NS_FAILED(rv)) return rv;
rv = CreateFencesAndSeparators(aPresContext);
return rv;
// No need to tract the style contexts given to our MathML chars.
// The Style System will use Get/SetAdditionalStyleContext() to keep them
// up-to-date if dynamic changes arise.
return CreateFencesAndSeparators(aPresContext);
}
NS_IMETHODIMP
nsMathMLmfencedFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint)
{
RemoveFencesAndSeparators();
CreateFencesAndSeparators(aPresContext);
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
}
void
@ -112,7 +117,7 @@ nsMathMLmfencedFrame::RemoveFencesAndSeparators()
if (mOpenChar) delete mOpenChar;
if (mCloseChar) delete mCloseChar;
if (mSeparatorsChar) delete[] mSeparatorsChar;
mOpenChar = nsnull;
mCloseChar = nsnull;
mSeparatorsChar = nsnull;
@ -123,8 +128,8 @@ nsresult
nsMathMLmfencedFrame::CreateFencesAndSeparators(nsIPresContext* aPresContext)
{
nsresult rv;
nsAutoString value, data;
PRBool isMutable;
//////////////
// see if the opening fence is there ...
@ -143,7 +148,8 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsIPresContext* aPresContext)
mOpenChar = new nsMathMLChar;
if (!mOpenChar) return NS_ERROR_OUT_OF_MEMORY;
mOpenChar->SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar);
isMutable = nsMathMLOperators::IsMutableOperator(data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar, isMutable);
}
//////////////
@ -163,7 +169,8 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsIPresContext* aPresContext)
mCloseChar = new nsMathMLChar;
if (!mCloseChar) return NS_ERROR_OUT_OF_MEMORY;
mCloseChar->SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar);
isMutable = nsMathMLOperators::IsMutableOperator(data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar, isMutable);
}
//////////////
@ -192,12 +199,16 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsIPresContext* aPresContext)
if (!mSeparatorsChar) return NS_ERROR_OUT_OF_MEMORY;
nsAutoString sepChar;
for (PRInt32 i = 0; i < sepCount; i++) {
if (i < mSeparatorsCount)
if (i < mSeparatorsCount) {
sepChar = data[i];
else
isMutable = nsMathMLOperators::IsMutableOperator(sepChar);
}
else {
sepChar = data[mSeparatorsCount-1];
// keep the value of isMutable that was set earlier
}
mSeparatorsChar[i].SetData(aPresContext, sepChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i]);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i], isMutable);
}
}
mSeparatorsCount = sepCount;
@ -212,12 +223,10 @@ nsMathMLmfencedFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
{
nsresult rv = NS_OK;
/////////////
// paint the content
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
nsresult rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
////////////
// paint fences and separators
if (NS_SUCCEEDED(rv)) {
@ -317,9 +326,9 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
nsBoundingMetrics containerSize;
nsStretchDirection stretchDir = NS_STRETCH_DIRECTION_VERTICAL;
nsEmbellishData embellishData;
mathMLFrame->GetEmbellishData(embellishData);
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(embellishData.flags)) {
nsPresentationData presentationData;
mathMLFrame->GetPresentationData(presentationData);
if (!NS_MATHML_WILL_STRETCH_ALL_CHILDREN_VERTICALLY(presentationData.flags)) {
// case when the call is made for mfrac, we only need to stretch the '/' separator
containerSize = aDesiredSize.mBoundingMetrics; // computed earlier
}
@ -331,8 +340,8 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
childFrame = fisrtChild;
while (childFrame) {
nsIMathMLFrame* mathmlChild;
rv = childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathmlChild);
if (NS_SUCCEEDED(rv) && mathmlChild) {
childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathmlChild);
if (mathmlChild) {
// retrieve the metrics that was stored at the previous pass
GetReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics);
@ -372,9 +381,6 @@ nsMathMLmfencedFrame::doReflow(nsIPresContext* aPresContext,
containerSize.ascent = delta + axisHeight;
containerSize.descent = delta - axisHeight;
nsPresentationData presentationData;
mathMLFrame->GetPresentationData(presentationData);
/////////////////
// opening fence ...
ReflowChar(aPresContext, *aReflowState.rendContext, aOpenChar,

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

@ -42,11 +42,8 @@ public:
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
@ -66,6 +63,14 @@ public:
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
NS_IMETHOD
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint);
// exported routine that both mfenced and mfrac share.
// mfrac uses this when its bevelled attribute is set.
static nsresult

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

@ -88,6 +88,20 @@ nsMathMLmfracFrame::~nsMathMLmfracFrame()
}
}
PRBool
nsMathMLmfracFrame::IsBevelled()
{
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE ==
GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::bevelled_, value)) {
if (value.Equals(NS_LITERAL_STRING("true"))) {
return PR_TRUE;
}
}
return PR_FALSE;
}
NS_IMETHODIMP
nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@ -104,7 +118,7 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
if (mSlashChar) {
nsAutoString slashChar; slashChar.Assign(kSlashChar);
mSlashChar->SetData(aPresContext, slashChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar, PR_TRUE);
}
}
@ -114,10 +128,6 @@ nsMathMLmfracFrame::Init(nsIPresContext* aPresContext,
NS_IMETHODIMP
nsMathMLmfracFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// 1. The REC says:
// The <mfrac> element sets displaystyle to "false", or if it was already
// false increments scriptlevel by 1, within numerator and denominator.
@ -132,14 +142,18 @@ nsMathMLmfracFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 0,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
// check whether or not this is an embellished operator
EmbellishOperator();
// even when embellished, we need to record that <mfrac> won't fire
// Stretch() on its embellished child
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
// break the embellished hierarchy to stop propagating the stretching
// process, but keep access to mEmbellishData.coreFrame for convenience
mEmbellishData.nextFrame = nsnull;
// if our numerator is an embellished operator, let its state bubble to us
GetEmbellishDataFrom(mFrames.FirstChild(), mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
// even when embellished, we need to record that <mfrac> won't fire
// Stretch() on its embellished child
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
// break the embellished hierarchy to stop propagating the stretching
// process, but keep access to mEmbellishData.coreFrame for convenience
mEmbellishData.nextFrame = nsnull;
}
return NS_OK;
}
@ -253,34 +267,20 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmNum, bmDen;
nsHTMLReflowMetrics sizeNum (nsnull);
nsHTMLReflowMetrics sizeDen (nsnull);
nsIFrame* frameNum = nsnull;
nsIFrame* frameDen = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) {
// numerator
frameNum = childFrame;
GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum);
}
else if (1 == count) {
// denominator
frameDen = childFrame;
GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen);
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (2 != count) {
nsIFrame* frameNum = mFrames.FirstChild();
if (frameNum)
frameNum->GetNextSibling(&frameDen);
if (!frameNum || !frameDen || HasNextSibling(frameDen)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(frameNum, sizeNum, bmNum);
GetReflowAndBoundingMetricsFor(frameDen, sizeDen, bmDen);
//////////////////
// Get shifts
@ -300,19 +300,14 @@ nsMathMLmfracFrame::Place(nsIPresContext* aPresContext,
GetAxisHeight(aRenderingContext, fm, axisHeight);
// by default, leave at least one-pixel padding at either end, or use
// lspace & rspace from <mo> if we are an embellished container
nscoord leftSpace = onePixel;
nscoord rightSpace = onePixel;
if (mEmbellishData.coreFrame) {
nsEmbellishData coreData;
nsIMathMLFrame* mathMLFrame;
mEmbellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
mathMLFrame->GetEmbellishData(coreData);
leftSpace = coreData.leftSpace;
rightSpace = coreData.rightSpace;
}
if (leftSpace < onePixel) leftSpace = onePixel;
if (rightSpace < onePixel) rightSpace = onePixel;
// lspace & rspace that may come from <mo> if we are an embellished container
// (we fetch values from the core since they may use units that depend
// on style data, and style changes could have occured in the core since
// our last visit there)
nsEmbellishData coreData;
GetEmbellishDataFrom(mEmbellishData.coreFrame, coreData);
nscoord leftSpace = PR_MAX(onePixel, coreData.leftSpace);
nscoord rightSpace = PR_MAX(onePixel, coreData.rightSpace);
// see if the linethickness attribute is there
nsAutoString value;
@ -476,7 +471,7 @@ nsMathMLmfracFrame::AttributeChanged(nsIPresContext* aPresContext,
if (mSlashChar) {
nsAutoString slashChar; slashChar.Assign(kSlashChar);
mSlashChar->SetData(aPresContext, slashChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mSlashChar, PR_TRUE);
}
}
}

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

@ -144,18 +144,7 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
PRBool
IsBevelled()
{
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE ==
GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::bevelled_, value)) {
if (value.Equals(NS_LITERAL_STRING("true"))) {
return PR_TRUE;
}
}
return PR_FALSE;
}
IsBevelled();
PRInt32 mInnerScriptLevel;
nsRect mLineRect;

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

@ -74,13 +74,9 @@ IsStyleInvariant(PRUnichar aChar)
}
// if our content is not a single character, we turn the font to normal
NS_IMETHODIMP
nsMathMLmiFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
void
nsMathMLmiFrame::ProcessTextData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// Get the text content that we enclose and its length
// our content can include comment-nodes, attribute-nodes, text-nodes...
// we use the DOM to make sure that we are only looking at text-nodes...
@ -119,7 +115,7 @@ nsMathMLmiFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
nsMathMLAtoms::fontstyle_, fontstyle))
{
if (fontstyle.Equals(NS_LITERAL_STRING("italic")))
return NS_OK;
return;
}
}
@ -142,7 +138,20 @@ nsMathMLmiFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmiFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
// First, let the base class do its work
nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
if (NS_FAILED(rv)) return rv;
// re-style our content depending on what it is
ProcessTextData(aPresContext);
return rv;
}
NS_IMETHODIMP
@ -164,3 +173,17 @@ nsMathMLmiFrame::Place(nsIPresContext* aPresContext,
return PlaceTokenFor(this, aPresContext, aRenderingContext,
aPlaceOrigin, aDesiredSize);
}
NS_IMETHODIMP
nsMathMLmiFrame::ReflowDirtyChild(nsIPresShell* aPresShell,
nsIFrame* aChild)
{
// if we get this, it means it was called by the nsTextFrame beneath us, and
// this means something changed in the text content. So re-process our text
nsCOMPtr<nsIPresContext> presContext;
aPresShell->GetPresContext(getter_AddRefs(presContext));
ProcessTextData(presContext);
return mParent->ReflowDirtyChild(aPresShell, this);
}

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

@ -34,12 +34,10 @@ class nsMathMLmiFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmiFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
/* <mi> needs to switch to a normal-font (rather than italics) if
* its text content is not a single character (as per the MathML REC).
* special care is also needed for style-invariant chars - bug 65951
*/
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
@ -53,11 +51,22 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
ReflowDirtyChild(nsIPresShell* aPresShell,
nsIFrame* aChild);
protected:
nsMathMLmiFrame();
virtual ~nsMathMLmiFrame();
virtual PRIntn GetSkipSides() const { return 0; }
/* <mi> needs to switch to a normal-font (rather than italics) if
* its text content is not a single character (as per the MathML REC).
* special care is also needed for style-invariant chars - bug 65951
*/
void
ProcessTextData(nsIPresContext* aPresContext);
};
#endif /* nsMathMLmiFrame_h___ */

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

@ -68,15 +68,63 @@ nsMathMLmmultiscriptsFrame::~nsMathMLmmultiscriptsFrame()
}
NS_IMETHODIMP
nsMathMLmmultiscriptsFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
nsMathMLmmultiscriptsFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
nsresult rv = nsMathMLContainerFrame::Init
(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// if our base is an embellished operator, let its state bubble to us
GetEmbellishDataFrom(mFrames.FirstChild(), mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = mFrames.FirstChild();
// The REC says:
// The <mmultiscripts> element increments scriptlevel by 1, and sets
// displaystyle to "false", within each of its arguments except base
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE);
// The TeXbook (Ch 17. p.141) says the superscript inherits the compression
// while the subscript is compressed. So here we collect subscripts and set
// the compression flag in them.
PRInt32 count = 0;
PRBool isSubScript = PR_FALSE;
nsAutoVoidArray subScriptFrames;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
nsCOMPtr<nsIContent> childContent;
nsCOMPtr<nsIAtom> childTag;
childFrame->GetContent(getter_AddRefs(childContent));
childContent->GetTag(*getter_AddRefs(childTag));
if (childTag.get() == nsMathMLAtoms::mprescripts_) {
// mprescripts frame
}
else if (0 == count) {
// base frame
}
else {
// super/subscript block
if (isSubScript) {
// subscript
subScriptFrames.AppendElement(childFrame);
}
else {
// superscript
}
isSubScript = !isSubScript;
}
count++;
childFrame->GetNextSibling(&childFrame);
}
for (PRInt32 i = subScriptFrames.Count() - 1; i >= 0; i--) {
childFrame = (nsIFrame*)subScriptFrames[i];
PropagatePresentationDataFor(aPresContext, childFrame, 0,
NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED);
}
return NS_OK;
}
void
nsMathMLmmultiscriptsFrame::ProcessAttributes(nsIPresContext* aPresContext)
{
mSubScriptShift = 0;
mSupScriptShift = 0;
mScriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
@ -98,27 +146,6 @@ nsMathMLmmultiscriptsFrame::Init(nsIPresContext* aPresContext,
mSupScriptShift = CalcLength(aPresContext, mStyleContext, cssValue);
}
}
return rv;
}
NS_IMETHODIMP
nsMathMLmmultiscriptsFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// check whether or not this is an embellished operator
EmbellishOperator();
// The REC says:
// The <mmultiscripts> element increments scriptlevel by 1, and sets
// displaystyle to "false", within each of its arguments except base, but
// leaves both attributes unchanged within base.
// XXX Need to update the compression flags in the sub/sup pairs as per TeX
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE);
return NS_OK;
}
NS_IMETHODIMP
@ -127,8 +154,6 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nsresult rv = NS_OK;
////////////////////////////////////
// Get the children's desired sizes
@ -139,16 +164,9 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
// depend only on the current font
////////////////////////////////////////
// get x-height (an ex)
#if 0
nscoord xHeight = 0;
nsCOMPtr<nsIFontMetrics> fm;
const nsStyleFont* aFont =
(const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
aPresContext->GetMetricsFor (aFont->mFont, getter_AddRefs(fm));
fm->GetXHeight (xHeight);
#endif
ProcessAttributes(aPresContext);
// get x-height (an ex)
const nsStyleFont *font = NS_STATIC_CAST(const nsStyleFont*,
mStyleContext->GetStyleData(eStyleStruct_Font));
aRenderingContext.SetFont(font->mFont);
@ -244,11 +262,9 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
nscoord italicCorrection = 0;
// XXX is there an NSPR macro for int_max ???
mBoundingMetrics.ascent = mBoundingMetrics.descent = -10000000;
mBoundingMetrics.width = 0;
aDesiredSize.ascent = aDesiredSize.descent = -10000000;
mBoundingMetrics.ascent = mBoundingMetrics.descent = -0x7FFFFFFF;
aDesiredSize.ascent = aDesiredSize.descent = -0x7FFFFFFF;
aDesiredSize.width = aDesiredSize.height = 0;
nsIFrame* childFrame = mFrames.FirstChild();
@ -259,6 +275,12 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
childContent->GetTag(*getter_AddRefs(childTag));
if (childTag.get() == nsMathMLAtoms::mprescripts_) {
if (mprescriptsFrame) {
// duplicate <mprescripts/> found
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
mprescriptsFrame = childFrame;
firstPrescriptsPair = PR_TRUE;
}
@ -446,5 +468,5 @@ nsMathMLmmultiscriptsFrame::Place(nsIPresContext* aPresContext,
} while (mprescriptsFrame != childFrame);
}
return rv;
return NS_OK;
}

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

@ -35,13 +35,6 @@ class nsMathMLmmultiscriptsFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmmultiscriptsFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
@ -62,6 +55,9 @@ private:
// = 0.5pt in plain TeX
nscoord mSubScriptShift;
nscoord mSupScriptShift;
void
ProcessAttributes(nsIPresContext* aPresContext);
};
#endif /* nsMathMLmmultiscriptsFrame_h___ */

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

@ -46,46 +46,6 @@
// <mo> -- operator, fence, or separator - implementation
//
// 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
// symmetric = true
// maxsize = infinity
// minsize = 1
// largeop = false
// movablelimits = false
// accent = false
//
// We only have to handle *lspace* and *rspace*, perhaps via a CSS padding rule
// in mathml.css, and override the rule if the content is found?
//
// * The spacing is wrong in certain situations, e.g.// <mrow> <mo>&ForAll;</mo> <mo>+</mo></mrow>
//
// 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
// units of 1/18 em. For the invisible operators whose content is
// "&InvisibleTimes;" or "&ApplyFunction;", 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>&ApplyFunction;</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
// than 0; for <mo>&InvisibleTimes;</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).
// additional style context to be used by our MathMLChar.
#define NS_MATHML_CHAR_STYLE_CONTEXT_INDEX 0
@ -127,8 +87,7 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer &&
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) {
aRenderingContext.SetColor(NS_RGB(0,255,255));
nscoord x = mReference.x + mBoundingMetrics.leftBearing;
nscoord y = mReference.y - mBoundingMetrics.ascent;
@ -145,25 +104,17 @@ nsMathMLmoFrame::Paint(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
// get the text that we enclose and setup our nsMathMLChar
void
nsMathMLmoFrame::ProcessTextData(nsIPresContext* aPresContext)
{
// Let the base class do its Init()
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// Init our local attributes
mFlags = 0;
mMinSize = float(NS_UNCONSTRAINEDSIZE);
mMaxSize = float(NS_UNCONSTRAINEDSIZE);
if (!mFrames.FirstChild())
return;
// get the text that we enclose
nsAutoString data;
// kids can be comment-nodes, attribute-nodes, text-nodes...
// we use the DOM to ensure that we only look at text-nodes...
nsAutoString data;
PRInt32 numKids;
mContent->ChildCount(numKids);
for (PRInt32 kid=0; kid<numKids; kid++) {
@ -178,242 +129,217 @@ nsMathMLmoFrame::Init(nsIPresContext* aPresContext,
}
}
}
// cache the operator
mMathMLChar.SetData(aPresContext, data);
PRBool isMutable = ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mMathMLChar);
if (isMutable) {
// cache the special bits: mutable, accent, movablelimits, centered.
// we need to do this in anticipation of other requirements, and these
// bits don't change. Do not reset these bits unless the text gets changed.
// lookup all the forms under which the operator is listed in the dictionary,
// and record whether the operator has accent="true" or movablelimits="true"
nsOperatorFlags flags[4];
float lspace[4], rspace[4];
nsMathMLOperators::LookupOperators(data, flags, lspace, rspace);
nsOperatorFlags allFlags =
flags[NS_MATHML_OPERATOR_FORM_INFIX] |
flags[NS_MATHML_OPERATOR_FORM_POSTFIX] |
flags[NS_MATHML_OPERATOR_FORM_PREFIX];
mFlags |= allFlags & NS_MATHML_OPERATOR_ACCENT;
mFlags |= allFlags & NS_MATHML_OPERATOR_MOVABLELIMITS;
PRBool isMutable =
NS_MATHML_OPERATOR_IS_STRETCHY(allFlags) ||
NS_MATHML_OPERATOR_IS_LARGEOP(allFlags);
if (isMutable)
mFlags |= NS_MATHML_OPERATOR_MUTABLE;
// see if this is an operator that should be centered to cater for
// fonts that are not math-aware
if (1 == data.Length()) {
PRUnichar ch = data[0];
if ((ch == '+') || (ch == '=') || (ch == '*') ||
(ch == 0x00D7)) { // &times;
mFlags |= NS_MATHML_OPERATOR_CENTERED;
}
}
return rv;
}
NS_IMETHODIMP
nsMathMLmoFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// fill our mEmbellishData member variable
nsIFrame* firstChild = mFrames.FirstChild();
if (firstChild) {
mEmbellishData.direction = mMathMLChar.GetStretchDirection();
mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = this;
// there are two extra things that we need to record so that if our
// parent is <mover>, <munder>, or <munderover>, they will treat us properly:
// 1) do we have accent="true"
// 2) do we have movablelimits="true"
// they need the extra information to decide how to treat their scripts/limits
// (note: <mover>, <munder>, or <munderover> need not necessarily be our
// direct parent -- case of embellished operators)
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT; // default is false
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_MOVABLELIMITS; // default is false
nsAutoString value;
PRBool accentAttribute = PR_FALSE;
PRBool movablelimitsAttribute = PR_FALSE;
// see if the accent attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::accent_, value))
{
accentAttribute = PR_TRUE;
if (value.Equals(NS_LITERAL_STRING("true")))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
}
}
// see if the movablelimits attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::movablelimits_, value))
{
movablelimitsAttribute = PR_TRUE;
if (value.Equals(NS_LITERAL_STRING("true")))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
}
if (!accentAttribute || !movablelimitsAttribute) {
// If we reach here, it means one or both attributes are missing.
// Unfortunately, we have to lookup the dictionary to see who
// we are, i.e., two lookups, counting also the one in Stretch()!
// The lookup in Stretch() assumes that the surrounding frame tree
// is already fully constructed, which is not true at this stage.
// all accent="true" in the dictionary have form="postfix"
// XXX should we check if the form attribute is there?
nsAutoString data;
mMathMLChar.GetData(data);
nsOperatorFlags form = NS_MATHML_OPERATOR_FORM_POSTFIX;
nsOperatorFlags flags = 0;
float leftSpace, rightSpace;
PRBool found = nsMathMLOperators::LookupOperator(data, form,
&flags, &leftSpace, &rightSpace);
if (found && !accentAttribute && NS_MATHML_OPERATOR_IS_ACCENT(flags))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
}
// all movablemits="true" in the dictionary have form="prefix",
// but this doesn't matter here, as the lookup has returned whatever
// is in the dictionary
if (found && !movablelimitsAttribute && NS_MATHML_OPERATOR_IS_MOVABLELIMITS(flags))
{
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
}
}
return NS_OK;
// cache the operator
mMathMLChar.SetData(aPresContext, data);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mMathMLChar, isMutable);
}
// get our 'form' and lookup in the Operator Dictionary to fetch
// our default data that may come from there, the look our attributes.
// The function has to be called during reflow because certain value
// before, we will re-use unchanged things that we computed earlier
void
nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
nsMathMLmoFrame::ProcessOperatorData(nsIPresContext* aPresContext)
{
nsresult rv = NS_OK;
// if we have been here before, we will just use our cached form
nsOperatorFlags form = NS_MATHML_OPERATOR_GET_FORM(mFlags);
nsAutoString value;
// Remember the mutable bit from Init().
// special bits are always kept in mFlags.
// remember the mutable bit from ProcessTextData().
// Some chars are listed under different forms in the dictionary,
// and there could be a form under which the char is mutable.
// If the char is the core of an embellished container, we will keep
// it mutable irrespective of the form of the embellished container
mFlags &= NS_MATHML_OPERATOR_MUTABLE;
// it mutable irrespective of the form of the embellished container.
// Also remember the other special bits that we want to carry forward.
mFlags &= NS_MATHML_OPERATOR_MUTABLE |
NS_MATHML_OPERATOR_ACCENT |
NS_MATHML_OPERATOR_MOVABLELIMITS |
NS_MATHML_OPERATOR_CENTERED;
// Get our outermost embellished container and its parent.
// We ensure that we are the core, not just a sibling of the core
nsIMathMLFrame* mathMLFrame = nsnull;
nsIFrame* embellishAncestor = this;
nsEmbellishData embellishData;
nsIFrame* parentAncestor = this;
do {
embellishAncestor = parentAncestor;
embellishAncestor->GetParent(&parentAncestor);
parentAncestor->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
if (!mEmbellishData.coreFrame) {
// i.e., we haven't been here before, the default form is infix
form = NS_MATHML_OPERATOR_FORM_INFIX;
// reset everything so that we don't keep outdated values around
// in case of dynamic changes
mEmbellishData.flags = 0;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = nsnull;
mEmbellishData.direction = NS_STRETCH_DIRECTION_UNSUPPORTED;
mEmbellishData.leftSpace = 0;
mEmbellishData.rightSpace = 0;
if (!mFrames.FirstChild())
return;
mEmbellishData.flags |= NS_MATHML_EMBELLISH_OPERATOR;
mEmbellishData.nextFrame = nsnull;
mEmbellishData.coreFrame = this;
mEmbellishData.direction = mMathMLChar.GetStretchDirection();
// there are two particular things that we also need to record so that if our
// parent is <mover>, <munder>, or <munderover>, they will treat us properly:
// 1) do we have accent="true"
// 2) do we have movablelimits="true"
// they need the extra information to decide how to treat their scripts/limits
// (note: <mover>, <munder>, or <munderover> need not necessarily be our
// direct parent -- case of embellished operators)
// default values from the Operator Dictionary were obtained in ProcessTextData()
// and these special bits are always kept in mFlags
if (NS_MATHML_OPERATOR_IS_ACCENT(mFlags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
if (NS_MATHML_OPERATOR_IS_MOVABLELIMITS(mFlags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
// see if the accent attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::accent_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
}
// see if the movablelimits attribute is there
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::movablelimits_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_MOVABLELIMITS;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_MOVABLELIMITS;
}
// get our outermost embellished container and its parent.
// (we ensure that we are the core, not just a sibling of the core)
nsIFrame* embellishAncestor = this;
nsEmbellishData embellishData;
nsIFrame* parentAncestor = this;
do {
embellishAncestor = parentAncestor;
embellishAncestor->GetParent(&parentAncestor);
GetEmbellishDataFrom(parentAncestor, embellishData);
} while (embellishData.coreFrame == this);
// flag if we have an embellished ancestor
if (embellishAncestor != this)
mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;
else
mFlags &= ~NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;
// find the position of our outermost embellished container w.r.t
// its siblings (frames are singly-linked together).
nsIFrame* firstChild;
parentAncestor->FirstChild(aPresContext, nsnull, &firstChild);
nsFrameList frameList(firstChild);
nsIFrame* nextSibling;
embellishAncestor->GetNextSibling(&nextSibling);
nsIFrame* prevSibling = frameList.GetPrevSiblingFor(embellishAncestor);
// flag to distinguish from a real infix
if (!prevSibling && !nextSibling)
mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ISOLATED;
else
mFlags &= ~NS_MATHML_OPERATOR_EMBELLISH_ISOLATED;
// find our form
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::form_, value)) {
if (value.Equals(NS_LITERAL_STRING("prefix")))
form = NS_MATHML_OPERATOR_FORM_PREFIX;
else if (value.Equals(NS_LITERAL_STRING("postfix")))
form = NS_MATHML_OPERATOR_FORM_POSTFIX;
}
else {
embellishData.coreFrame = nsnull;
// set our form flag depending on the position
if (!prevSibling && nextSibling)
form = NS_MATHML_OPERATOR_FORM_PREFIX;
else if (prevSibling && !nextSibling)
form = NS_MATHML_OPERATOR_FORM_POSTFIX;
}
} while (embellishData.coreFrame == this);
// flag if we have an embellished ancestor
if (embellishAncestor != this) {
mFlags |= NS_MATHML_OPERATOR_EMBELLISH_ANCESTOR;
}
// find our form
nsAutoString value;
nsOperatorFlags form = NS_MATHML_OPERATOR_FORM_INFIX;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::form_, value)) {
if (value.Equals(NS_LITERAL_STRING("prefix")))
form = NS_MATHML_OPERATOR_FORM_PREFIX;
else if (value.Equals(NS_LITERAL_STRING("postfix")))
form = NS_MATHML_OPERATOR_FORM_POSTFIX;
}
else {
// Find the position of our outermost embellished container w.r.t
// its siblings (frames are singly-linked together).
nsIFrame* prev = nsnull;
nsIFrame* next = nsnull;
nsIFrame* frame;
// lookup the operator dictionary
// the form can be null to mean that the stretching of our mMathMLChar
// failed earlier, in which case we won't bother re-stretching again
if (form) {
float lspace = 0.0f;
float rspace = 0.0f;
nsAutoString data;
mMathMLChar.GetData(data);
mMathMLChar.SetData(aPresContext, data); // XXX hack to reset, bug 45010
PRBool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
if (found) {
// cache the default values of lspace & rspace that we get from the dictionary.
// since these values are relative to the 'em' unit, convert to twips now
nscoord em;
const nsStyleFont* font;
GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font->mFont, getter_AddRefs(fm));
GetEmHeight(fm, em);
embellishAncestor->GetNextSibling(&next);
parentAncestor->FirstChild(aPresContext, nsnull, &frame);
while (frame) {
if (frame == embellishAncestor) break;
prev = frame;
frame->GetNextSibling(&frame);
mEmbellishData.leftSpace = NSToCoordRound(lspace * em);
mEmbellishData.rightSpace = NSToCoordRound(rspace * em);
// tuning if we don't want too much extra space when we are a script.
// (with its fonts, TeX sets lspace=0 & rspace=0 as soon as scriptlevel>0.
// Our fonts can be anything, so...)
if (mPresentationData.scriptLevel > 0) {
if (NS_MATHML_OPERATOR_EMBELLISH_IS_ISOLATED(mFlags)) {
// could be an isolated accent or script, e.g., x^{+}, just zero out
mEmbellishData.leftSpace = 0;
mEmbellishData.rightSpace = 0;
}
else if (!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
mEmbellishData.leftSpace /= 2;
mEmbellishData.rightSpace /= 2;
}
}
}
// set our form flag depending on the position
if (!prev && next)
form = NS_MATHML_OPERATOR_FORM_PREFIX;
else if (prev && !next)
form = NS_MATHML_OPERATOR_FORM_POSTFIX;
}
// Lookup the operator dictionary
nsAutoString data;
mMathMLChar.GetData(data);
mMathMLChar.SetData(aPresContext, data); // XXX hack to reset, bug 45010
float lspace, rspace;
PRBool found = nsMathMLOperators::LookupOperator(data, form, &mFlags, &lspace, &rspace);
// If we don't want too much extra space when we are a script
if ((0 < mPresentationData.scriptLevel) &&
!NS_MATHML_OPERATOR_HAS_EMBELLISH_ANCESTOR(mFlags)) {
lspace /= 2.0f;
rspace /= 2.0f;
}
// Since these values are relative to the 'em' unit, convert to twips now
nscoord leftSpace, rightSpace, em;
const nsStyleFont* font;
GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
nsCOMPtr<nsIFontMetrics> fm;
aPresContext->GetMetricsFor(font->mFont, getter_AddRefs(fm));
GetEmHeight(fm, em);
leftSpace = NSToCoordRound(lspace * em);
rightSpace = NSToCoordRound(rspace * em);
// 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 overriden by the user, turn off its bit flag.
// symmetric|movablelimits|separator|largeop|accent|fence|stretchy|form
nsAutoString kfalse, ktrue;
kfalse.Assign(NS_LITERAL_STRING("false"));
ktrue.Assign(NS_LITERAL_STRING("true"));
if (NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::stretchy_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
}
if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::fence_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_FENCE;
}
if (NS_MATHML_OPERATOR_IS_ACCENT(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::accent_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_ACCENT;
}
if (NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::largeop_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
}
if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::separator_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
}
if (NS_MATHML_OPERATOR_IS_MOVABLELIMITS(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::movablelimits_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_MOVABLELIMITS;
}
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::symmetric_, value)) {
if (value == kfalse) mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
else if (value == ktrue) mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
}
// If we are an accent without explicit lspace="." or rspace=".",
// ignore our default left/right space
// we will ignore our default left/right space
// lspace = number h-unit | namedspace
nscoord leftSpace = mEmbellishData.leftSpace;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::lspace_, value)) {
nsCSSValue cssValue;
@ -431,6 +357,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
}
// rspace = number h-unit | namedspace
nscoord rightSpace = mEmbellishData.rightSpace;
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::rspace_, value)) {
nsCSSValue cssValue;
@ -447,11 +374,53 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
rightSpace = 0;
}
// cache these values
// the values that we get from our attributes override the dictionary
mEmbellishData.leftSpace = leftSpace;
mEmbellishData.rightSpace = rightSpace;
// Nows 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 overriden by the user, turn off its bit flag.
// symmetric|movablelimits|separator|largeop|accent|fence|stretchy|form
// special: accent and movablelimits are handled in ProcessEmbellishData()
// don't process them here
nsAutoString kfalse, ktrue;
kfalse.Assign(NS_LITERAL_STRING("false"));
ktrue.Assign(NS_LITERAL_STRING("true"));
if (NS_MATHML_OPERATOR_IS_STRETCHY(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::stretchy_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_STRETCHY;
}
if (NS_MATHML_OPERATOR_IS_FENCE(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::fence_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_FENCE;
}
if (NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::largeop_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_LARGEOP;
}
if (NS_MATHML_OPERATOR_IS_SEPARATOR(mFlags)) {
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::separator_, value) && value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_SEPARATOR;
}
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::symmetric_, value)) {
if (value == kfalse)
mFlags &= ~NS_MATHML_OPERATOR_SYMMETRIC;
else if (value == ktrue)
mFlags |= NS_MATHML_OPERATOR_SYMMETRIC;
}
// minsize = number [ v-unit | h-unit ] | namedspace
mMinSize = float(NS_UNCONSTRAINEDSIZE);
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::minsize_, value)) {
nsCSSValue cssValue;
@ -484,6 +453,7 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
}
// maxsize = number [ v-unit | h-unit ] | namedspace | infinity
mMaxSize = float(NS_UNCONSTRAINEDSIZE);
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::maxsize_, value)) {
nsCSSValue cssValue;
@ -514,25 +484,6 @@ nsMathMLmoFrame::InitData(nsIPresContext* aPresContext)
}
}
}
// If the stretchy or largeop attributes have been disabled,
// the operator is not mutable
if (!found ||
(!NS_MATHML_OPERATOR_IS_STRETCHY(mFlags) &&
!NS_MATHML_OPERATOR_IS_LARGEOP(mFlags)))
{
mFlags &= ~NS_MATHML_OPERATOR_MUTABLE;
}
// See if this is an operator that should be centered to cater for
// fonts that are not math-aware
if (1 == data.Length()) {
PRUnichar ch = data[0];
if ((ch == '+') || (ch == '=') || (ch == '*') ||
(ch == 0x00D7)) { // &times;
mFlags |= NS_MATHML_OPERATOR_CENTERED;
}
}
}
// NOTE: aDesiredStretchSize is an IN/OUT parameter
@ -545,13 +496,11 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredStretchSize)
{
if (NS_MATHML_STRETCH_WAS_DONE(mEmbellishData.flags)) {
if (NS_MATHML_STRETCH_WAS_DONE(mPresentationData.flags)) {
NS_WARNING("it is wrong to fire stretch more than once on a frame");
return NS_OK;
}
mEmbellishData.flags |= NS_MATHML_STRETCH_DONE;
InitData(aPresContext);
mPresentationData.flags |= NS_MATHML_STRETCH_DONE;
// get the axis height;
const nsStyleFont *font = NS_STATIC_CAST(const nsStyleFont*,
@ -574,8 +523,15 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
PRBool isVertical = PR_FALSE;
PRUint32 stretchHint = NS_STRETCH_NORMAL;
// see if it is okay to stretch
if (NS_MATHML_OPERATOR_IS_MUTABLE(mFlags)) {
// see if it is okay to stretch, starting from what the Operator Dictionary said
PRBool isMutable = NS_MATHML_OPERATOR_IS_MUTABLE(mFlags);
// if the stretchy and largeop attributes have been disabled,
// the operator is not mutable
if (!NS_MATHML_OPERATOR_IS_STRETCHY(mFlags) &&
!NS_MATHML_OPERATOR_IS_LARGEOP(mFlags))
isMutable = PR_FALSE;
if (isMutable) {
container = aContainerSize;
@ -786,12 +742,40 @@ nsMathMLmoFrame::Stretch(nsIPresContext* aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmoFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
{
// First, let the base class do its work
nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
if (NS_FAILED(rv)) return rv;
// No need to tract the style context given to our MathML char.
// The Style System will use Get/SetAdditionalStyleContext() to keep it
// up-to-date if dynamic changes arise.
ProcessTextData(aPresContext);
return rv;
}
NS_IMETHODIMP
nsMathMLmoFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// this will cause us to re-sync our flags from scratch
mEmbellishData.coreFrame = nsnull;
ProcessOperatorData(aPresContext);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmoFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
// certain values use units that depend on our style context, so
// it is safer to just process the whole lot here
ProcessOperatorData(aPresContext);
return ReflowTokenFor(this, aPresContext, aDesiredSize,
aReflowState, aStatus);
}
@ -806,6 +790,31 @@ nsMathMLmoFrame::Place(nsIPresContext* aPresContext,
aPlaceOrigin, aDesiredSize);
}
NS_IMETHODIMP
nsMathMLmoFrame::ReflowDirtyChild(nsIPresShell* aPresShell,
nsIFrame* aChild)
{
// if we get this, it means it was called by the nsTextFrame beneath us, and
// this means something changed in the text content. So blow away everything
// an re-build the automatic data from the parent of our outermost embellished
// container (we ensure that we are the core, not just a sibling of the core)
nsCOMPtr<nsIPresContext> presContext;
aPresShell->GetPresContext(getter_AddRefs(presContext));
ProcessTextData(presContext);
nsIFrame* target = this;
nsEmbellishData embellishData;
do {
target->GetParent(&target);
GetEmbellishDataFrom(target, embellishData);
} while (embellishData.coreFrame == this);
// we have automatic data to update in the children of the target frame
return ReLayoutChildren(presContext, target);
}
// ----------------------
// the Style System will use these to pass the proper style context to our MathMLChar
NS_IMETHODIMP

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

@ -43,11 +43,9 @@ public:
nsIStyleContext** aStyleContext) const;
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD
Paint(nsIPresContext* aPresContext,
@ -56,6 +54,9 @@ public:
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags = 0);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -69,7 +70,8 @@ public:
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
ReflowDirtyChild(nsIPresShell* aPresShell,
nsIFrame* aChild);
// This method is called by the parent frame to ask <mo>
// to stretch itself.
@ -80,10 +82,6 @@ public:
nsBoundingMetrics& aContainerSize,
nsHTMLReflowMetrics& aDesiredStretchSize);
// helper method to lookup the operator dictionary and initialize our member data
void
InitData(nsIPresContext* aPresContext);
protected:
nsMathMLmoFrame();
virtual ~nsMathMLmoFrame();
@ -91,10 +89,19 @@ protected:
virtual PRIntn GetSkipSides() const { return 0; }
nsMathMLChar mMathMLChar; // Here is the MathMLChar that will deal with the operator.
nsOperatorFlags mFlags;
float mMinSize;
float mMaxSize;
// helper to get the text that we enclose and setup our nsMathMLChar
void
ProcessTextData(nsIPresContext* aPresContext);
// helper to get our 'form' and lookup in the Operator Dictionary to fetch
// our default data that may come from there, and to complete the setup
// using attributes that we may have
void
ProcessOperatorData(nsIPresContext* aPresContext);
};
#endif /* nsMathMLmoFrame_h___ */

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

@ -69,6 +69,25 @@ nsMathMLmoverFrame::~nsMathMLmoverFrame()
{
}
NS_IMETHODIMP
nsMathMLmoverFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint)
{
if (nsMathMLAtoms::accent_ == aAttribute) {
// When we have automatic data to update within ourselves, we ask our
// parent to re-layout its children
return ReLayoutChildren(aPresContext, mParent);
}
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
}
NS_IMETHODIMP
nsMathMLmoverFrame::UpdatePresentationData(nsIPresContext* aPresContext,
PRInt32 aScriptLevelIncrement,
@ -78,12 +97,12 @@ nsMathMLmoverFrame::UpdatePresentationData(nsIPresContext* aPresContext,
nsMathMLContainerFrame::UpdatePresentationData(aPresContext,
aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate);
// disable the stretch-all flag if we are going to act like a superscript
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
else {
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
return NS_OK;
}
@ -124,24 +143,28 @@ nsMathMLmoverFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresConte
}
return NS_OK;
// XXX For #2, if the inner <mo> changes, is has to trigger
// XXX a re-computation of all flags that depend on its state
// XXX in the entire embellished hierarchy
// For #2, the base class will trigger a re-build of all automatic data
// in the embellished hierarchy when an accent attribute is changed
}
NS_IMETHODIMP
nsMathMLmoverFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmoverFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accent flag
// At this stage, all our children are in sync and we can fully
// resolve our own mEmbellishData struct
//---------------------------------------------------------------------
/* The REC says:
The default value of accent is false, unless overscript
@ -159,104 +182,65 @@ XXX The winner is the outermost in conflicting settings like these:
</mover>
*/
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* overscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) baseFrame = childFrame;
if (1 == count) { overscriptFrame = childFrame; break; }
count++;
childFrame->GetNextSibling(&childFrame);
}
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&overscriptFrame);
if (!baseFrame || !overscriptFrame)
return NS_OK; // a visual error indicator will be reported later during layout
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsIMathMLFrame* overscriptMathMLFrame = nsnull;
nsIMathMLFrame* mathMLFrame = nsnull;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTOVER; // default of accent is false
// The default value of accent is false, unless the overscript is embellished
// and its core <mo> is an accent
nsEmbellishData embellishData;
GetEmbellishDataFrom(overscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
else
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value.Equals(NS_LITERAL_STRING("true"))) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
mEmbellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
// if we have an accent attribute, it overrides what the overscript said
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accent_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
}
// see if the overscriptFrame is <mo> or an embellished operator
if (overscriptFrame) {
overscriptFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&overscriptMathMLFrame);
if (overscriptMathMLFrame) {
overscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the overscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.coreFrame) {
embellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
// if we have the accent attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
if (value.Equals(NS_LITERAL_STRING("true"))) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals(NS_LITERAL_STRING("false"))) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
mathMLFrame->SetEmbellishData(embellishData);
}
// disable the stretch-all flag if we are going to act like a superscript
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
// sync the presentation data: record whether we have an accent
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTOVER;
}
//XXX should sync the presentation data be at this spot, after the if?
}
}
}
// Now transmit any change that we want to our children so that they
// can update their mPresentationData structs
//---------------------------------------------------------------------
/* The REC says:
Within overscript, <mover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
*/
/*
The TeXBook treats 'over' like a superscript, so p.141 or Rule 13a
say it shouldn't be compressed. However, The TeXBook says
that math accents and \overline change uncramped styles to their
cramped counterparts.
*/
if (overscriptMathMLFrame) {
PRInt32 increment = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)
? 0 : 1;
PRUint32 compress = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)
? NS_MATHML_COMPRESSED : 0;
overscriptMathMLFrame->UpdatePresentationData(aPresContext, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
}
// disable the stretch-all flag if we are going to act like a superscript
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
? 0 : 1;
PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
? NS_MATHML_COMPRESSED : 0;
PropagatePresentationDataFor(aPresContext, overscriptFrame, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
return NS_OK;
}
@ -270,7 +254,7 @@ The REC says:
often used for limits on symbols such as &sum;.
i.e.:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like superscript
}
@ -285,9 +269,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nsresult rv = NS_OK;
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like superscript
return nsMathMLmsupFrame::PlaceSuperScript(aPresContext,
@ -300,33 +282,20 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmOver;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics overSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsHTMLReflowMetrics baseSize(nsnull);
nsHTMLReflowMetrics overSize(nsnull);
nsIFrame* overFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// over
overFrame = childFrame;
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (2 != count) {
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&overFrame);
if (!baseFrame || !overFrame || HasNextSibling(overFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
////////////////////
// Place Children
@ -349,7 +318,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
nscoord correction = 0;
nscoord delta1 = 0; // gap between base and overscript
nscoord delta2 = 0; // extra space above overscript
if (!NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
GetItalicCorrection (bmBase, correction);
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;
@ -424,7 +393,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
dxOver = -bmOver.leftBearing;
}
if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
mBoundingMetrics.width = PR_MAX(bmBase.width, overWidth);
}
else {
@ -443,7 +412,7 @@ nsMathMLmoverFrame::Place(nsIPresContext* aPresContext,
dxBase = (mBoundingMetrics.width - bmBase.width) / 2;
dyBase = aDesiredSize.ascent - baseSize.ascent;
if (NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
if (NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
dxOver += correction + (mBoundingMetrics.width - overWidth)/2;
}
else {

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

@ -41,6 +41,10 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
@ -58,6 +62,14 @@ public:
PRUint32 aFlagsValues,
PRUint32 aFlagsToUpdate);
NS_IMETHOD
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint);
protected:
nsMathMLmoverFrame();
virtual ~nsMathMLmoverFrame();

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

@ -88,6 +88,14 @@ nsMathMLmpaddedFrame::InheritAutomaticData(nsIPresContext* aPresContext,
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return NS_OK;
}
void
nsMathMLmpaddedFrame::ProcessAttributes(nsIPresContext* aPresContext)
{
/*
parse the attributes
@ -135,8 +143,6 @@ nsMathMLmpaddedFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsMathMLAtoms::lspace_, value)) {
ParseAttribute(value, mLeftSpaceSign, mLeftSpace, mLeftSpacePseudoUnit);
}
return NS_OK;
}
PRBool
@ -350,16 +356,14 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
ProcessAttributes(aPresContext);
///////////////
// Let the base class format our content like an inferred mrow
rv = nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize,
aReflowState, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
if (NS_FAILED(rv)) {
return rv;
}
nsresult rv = nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize,
aReflowState, aStatus);
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
if (NS_FAILED(rv)) return rv;
nscoord height = mBoundingMetrics.ascent;
nscoord depth = mBoundingMetrics.descent;

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

@ -33,20 +33,10 @@
class nsMathMLmpaddedFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return NS_OK;
}
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
@ -77,6 +67,9 @@ private:
PRInt32 mLeftSpacePseudoUnit;
// helpers to process the attributes
void
ProcessAttributes(nsIPresContext* aPresContext);
static PRBool
ParseAttribute(nsString& aString,
PRInt32& aSign,

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

@ -67,9 +67,14 @@ nsMathMLmphantomFrame::~nsMathMLmphantomFrame()
}
NS_IMETHODIMP
nsMathMLmphantomFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
nsMathMLmphantomFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return NS_OK;
}

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

@ -35,7 +35,8 @@ public:
friend nsresult NS_NewMathMLmphantomFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
Paint(nsIPresContext* aPresContext,

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

@ -47,8 +47,8 @@
//NOTE:
// The code assumes that TeX fonts are picked.
// There is not fall-back to draw the branches of the sqrt explicitly
// in the case where TeX fonts are not there. In general, there is not
// There is no fall-back to draw the branches of the sqrt explicitly
// in the case where TeX fonts are not there. In general, there are no
// fall-back(s) in MathML when some (freely-downloadable) fonts are missing.
// Otherwise, this will add much work and unnecessary complexity to the core
// MathML engine. Assuming that authors have the free fonts is part of the
@ -91,17 +91,35 @@ nsMathMLmrootFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = NS_OK;
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
// No need to tract the style context given to our MathML char.
// The Style System will use Get/SetAdditionalStyleContext() to keep it
// up-to-date if dynamic changes arise.
nsAutoString sqrChar; sqrChar.Assign(kSqrChar);
mSqrChar.SetData(aPresContext, sqrChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar, PR_TRUE);
return rv;
}
NS_IMETHODIMP
nsMathMLmrootFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// 1. The REC says:
// The <mroot> element increments scriptlevel by 2, and sets displaystyle to
// "false", within index, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says \sqrt is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 2,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
UpdatePresentationDataFromChildAt(aPresContext, 0, 0, 0,
NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmrootFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -109,21 +127,17 @@ nsMathMLmrootFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
{
nsresult rv = NS_OK;
/////////////
// paint the content we are square-rooting
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
nsresult rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
/////////////
// paint the sqrt symbol
if (!NS_MATHML_HAS_ERROR(mPresentationData.flags))
{
if (!NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
mSqrChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// paint the overline bar
const nsStyleColor *color = NS_STATIC_CAST(const nsStyleColor*,
mStyleContext->GetStyleData(eStyleStruct_Color));
@ -133,8 +147,7 @@ nsMathMLmrootFrame::Paint(nsIPresContext* aPresContext,
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) {
nsRect rect;
mSqrChar.GetRect(rect);

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

@ -50,22 +50,7 @@ public:
nsIFrame* aPrevInFlow);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// 1. The REC says:
// The <mroot> element increments scriptlevel by 2, and sets displaystyle to
// "false", within index, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says \sqrt is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 2,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
UpdatePresentationDataFromChildAt(aPresContext, 0, 0, 0,
NS_MATHML_COMPRESSED, NS_MATHML_COMPRESSED);
return NS_OK;
}
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,

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

@ -67,13 +67,13 @@ nsMathMLmrowFrame::~nsMathMLmrowFrame()
}
NS_IMETHODIMP
nsMathMLmrowFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
nsMathMLmrowFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return NS_OK;
}

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

@ -33,14 +33,15 @@
class nsMathMLmrowFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmrowFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
protected:
nsMathMLmrowFrame();
virtual ~nsMathMLmrowFrame();
virtual PRIntn GetSkipSides() const { return 0; }
};

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

@ -37,6 +37,7 @@
#include "nsStyleUtil.h"
#include "nsIDOMText.h"
#include "nsITextContent.h"
#include "nsMathMLmsFrame.h"
@ -67,11 +68,8 @@ nsMathMLmsFrame::~nsMathMLmsFrame()
{
}
NS_IMETHODIMP
nsMathMLmsFrame::SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList)
nsMathMLmsFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// It is assumed that the mathml.css file contains two rules:
// ms:before { content: open-quote; }
@ -86,48 +84,73 @@ nsMathMLmsFrame::SetInitialChildList(nsIPresContext* aPresContext,
// But what if the mathml.css file wasn't loaded?
// We also check that we are not relying on null pointers...
PRInt32 count = 0;
nsIFrame* rightFrame = nsnull;
nsIFrame* leftFrame = nsnull;
nsIFrame* childFrame = aChildList;
while (childFrame) {
if (0 == count) leftFrame = childFrame;
// 1 == count is the the frame for the actual content of <ms>
else if (2 == count) rightFrame = childFrame;
count++;
childFrame->GetNextSibling(&childFrame);
}
nsIFrame* baseFrame = nsnull;
nsIFrame* leftFrame = mFrames.FirstChild();
if (leftFrame)
leftFrame->GetNextSibling(&baseFrame);
if (baseFrame)
baseFrame->GetNextSibling(&rightFrame);
if (!leftFrame || !baseFrame || !rightFrame)
return NS_OK;
if (3 == count && leftFrame && rightFrame) {
nsAutoString value;
nsIFrame* textFrame;
nsCOMPtr<nsIContent> quoteContent;
// lquote
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::lquote_, value)) {
leftFrame->FirstChild(aPresContext, nsnull, &textFrame);
if (textFrame) {
textFrame->GetContent(getter_AddRefs(quoteContent));
if (quoteContent.get()) {
nsCOMPtr<nsIDOMText> domText(do_QueryInterface(quoteContent));
if (domText.get()) domText->SetData(value);
nsAutoString value;
nsIFrame* textFrame;
nsCOMPtr<nsIContent> quoteContent;
// lquote
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::lquote_, value)) {
leftFrame->FirstChild(aPresContext, nsnull, &textFrame);
if (textFrame) {
textFrame->GetContent(getter_AddRefs(quoteContent));
if (quoteContent.get()) {
nsCOMPtr<nsIDOMText> domText(do_QueryInterface(quoteContent));
if (domText.get()) {
nsCOMPtr<nsITextContent> tc(do_QueryInterface(quoteContent));
if (tc) {
tc->SetText(value, PR_FALSE); // no notify since we don't want a reflow yet
}
}
}
}
// rquote
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::rquote_, value)) {
rightFrame->FirstChild(aPresContext, nsnull, &textFrame);
if (textFrame) {
textFrame->GetContent(getter_AddRefs(quoteContent));
if (quoteContent.get()) {
nsCOMPtr<nsIDOMText> domText(do_QueryInterface(quoteContent));
if (domText.get()) domText->SetData(value);
}
// rquote
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(mContent, mPresentationData.mstyle,
nsMathMLAtoms::rquote_, value)) {
rightFrame->FirstChild(aPresContext, nsnull, &textFrame);
if (textFrame) {
textFrame->GetContent(getter_AddRefs(quoteContent));
if (quoteContent.get()) {
nsCOMPtr<nsIDOMText> domText(do_QueryInterface(quoteContent));
if (domText.get()) {
nsCOMPtr<nsITextContent> tc(do_QueryInterface(quoteContent));
if (tc) {
tc->SetText(value, PR_FALSE); // no notify since we don't want a reflow yet
}
}
}
}
}
// let the base class take care of the rest
return nsMathMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint)
{
if (nsMathMLAtoms::lquote_ == aAttribute ||
nsMathMLAtoms::rquote_ == aAttribute) {
// When the automatic data to update are only within our
// children, we just re-layout them
return ReLayoutChildren(aPresContext, this);
}
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
}

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

@ -33,26 +33,17 @@ class nsMathMLmsFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmsFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
#if 0
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
#endif
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
SetInitialChildList(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
#if 0
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
#endif
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint);
protected:
nsMathMLmsFrame();
virtual ~nsMathMLmsFrame();

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

@ -66,17 +66,9 @@ nsMathMLmspaceFrame::~nsMathMLmspaceFrame()
{
}
NS_IMETHODIMP
nsMathMLmspaceFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
void
nsMathMLmspaceFrame::ProcessAttributes(nsIPresContext* aPresContext)
{
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// mEmbellishData.flags = NS_MATHML_SPACELIKE;
/*
parse the attributes
@ -85,9 +77,6 @@ nsMathMLmspaceFrame::Init(nsIPresContext* aPresContext,
depth = number v-unit
*/
// XXX Need to check what will happen in case of style changes
// These may have to be moved in Reflow() to capture style changes
nsAutoString value;
nsCSSValue cssValue;
@ -123,8 +112,6 @@ nsMathMLmspaceFrame::Init(nsIPresContext* aPresContext,
mDepth = CalcLength(aPresContext, mStyleContext, cssValue);
}
}
return rv;
}
NS_IMETHODIMP
@ -132,7 +119,9 @@ nsMathMLmspaceFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
{
ProcessAttributes(aPresContext);
mBoundingMetrics.Clear();
mBoundingMetrics.width = mWidth;
mBoundingMetrics.ascent = mHeight;

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

@ -32,13 +32,6 @@
class nsMathMLmspaceFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmspaceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,
@ -56,6 +49,10 @@ private:
nscoord mWidth;
nscoord mHeight;
nscoord mDepth;
// helper method to initialize our member data
void
ProcessAttributes(nsIPresContext* aPresContext);
};
#endif /* nsMathMLmspaceFrame_h___ */

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

@ -47,8 +47,8 @@
//NOTE:
// The code assumes that TeX fonts are picked.
// There is not fall-back to draw the branches of the sqrt explicitly
// in the case where TeX fonts are not there. In general, there is not
// There is no fall-back to draw the branches of the sqrt explicitly
// in the case where TeX fonts are not there. In general, there are no
// fall-back(s) in MathML when some (freely-downloadable) fonts are missing.
// Otherwise, this will add much work and unnecessary complexity to the core
// MathML engine. Assuming that authors have the free fonts is part of the
@ -91,17 +91,45 @@ nsMathMLmsqrtFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = NS_OK;
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
// No need to tract the style context given to our MathML char.
// The Style System will use Get/SetAdditionalStyleContext() to keep it
// up-to-date if dynamic changes arise.
nsAutoString sqrChar; sqrChar.Assign(kSqrChar);
mSqrChar.SetData(aPresContext, sqrChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar);
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSqrChar, PR_TRUE);
return rv;
}
NS_IMETHODIMP
nsMathMLmsqrtFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsqrtFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// 1. The REC says:
// The <msqrt> element leaves both attributes [displaystyle and scriptlevel]
// unchanged within all its arguments.
// 2. The TeXBook (Ch 17. p.141) says that \sqrt is cramped
UpdatePresentationDataFromChildAt(aPresContext, 0, -1, 0,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsqrtFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -109,21 +137,17 @@ nsMathMLmsqrtFrame::Paint(nsIPresContext* aPresContext,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
{
nsresult rv = NS_OK;
/////////////
// paint the content we are square-rooting
rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
nsresult rv = nsMathMLContainerFrame::Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer);
/////////////
// paint the sqrt symbol
if (!NS_MATHML_HAS_ERROR(mPresentationData.flags))
{
if (!NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
mSqrChar.Paint(aPresContext, aRenderingContext,
aDirtyRect, aWhichLayer, this);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer)
{
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// paint the overline bar
const nsStyleColor *color = NS_STATIC_CAST(const nsStyleColor*,
mStyleContext->GetStyleData(eStyleStruct_Color));
@ -133,8 +157,7 @@ nsMathMLmsqrtFrame::Paint(nsIPresContext* aPresContext,
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
// for visual debug
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags))
{
if (NS_MATHML_PAINT_BOUNDING_METRICS(mPresentationData.flags)) {
nsRect rect;
mSqrChar.GetRect(rect);
@ -160,18 +183,15 @@ nsMathMLmsqrtFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = NS_OK;
nsBoundingMetrics bmSqr, bmBase;
///////////////
// Let the base class format our content like an inferred mrow
nsHTMLReflowMetrics baseSize(aDesiredSize);
rv = nsMathMLContainerFrame::Reflow(aPresContext, baseSize,
aReflowState, aStatus);
nsresult rv = nsMathMLContainerFrame::Reflow(aPresContext, baseSize,
aReflowState, aStatus);
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
if (NS_FAILED(rv)) return rv;
nsBoundingMetrics bmSqr, bmBase;
bmBase = baseSize.mBoundingMetrics;
////////////

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

@ -87,21 +87,10 @@ public:
PRUint32 aFlags = 0);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
// 1. The REC says:
// The <msqrt> element leaves both attributes [displaystyle and scriptlevel]
// unchanged within all its arguments.
// 2. The TeXBook (Ch 17. p.141) says that \sqrt is cramped
UpdatePresentationDataFromChildAt(aPresContext, 0, -1, 0,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
return NS_OK;
}
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
protected:
nsMathMLmsqrtFrame();

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

@ -75,7 +75,7 @@ nsMathMLmstyleFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
// sync with our current state
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
mPresentationData.mstyle = this;
// see if the displaystyle attribute is there
@ -114,8 +114,6 @@ nsMathMLmstyleFrame::InheritAutomaticData(nsIPresContext* aPresContext,
NS_IMETHODIMP
nsMathMLmstyleFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
// Nothing particular to do here, the values that we computed in
// InheritAutomaticData() are the values that we wanted to pass to
// our children. Our children would have inherited these values in
@ -205,17 +203,10 @@ nsMathMLmstyleFrame::AttributeChanged(nsIPresContext* aPresContext,
PRInt32 aModType,
PRInt32 aHint)
{
if (nsMathMLAtoms::displaystyle_ == aAttribute ||
nsMathMLAtoms::scriptlevel_ == aAttribute) {
// These attributes can affect too many things, ask our parent to re-layout
// its children so that we can pick up changes in our attributes & transmit
// them in our subtree. However, our siblings will be re-laid too. We used
// to have a more speedier but more verbose alternative that didn't re-layout
// our siblings. See bug 114909 - attachment 67668.
return ReLayout(aPresContext, mParent);
}
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
// These attributes can affect too many things, ask our parent to re-layout
// its children so that we can pick up changes in our attributes & transmit
// them in our subtree. However, our siblings will be re-laid too. We used
// to have a more speedier but more verbose alternative that didn't re-layout
// our siblings. See bug 114909 - attachment 67668.
return ReLayoutChildren(aPresContext, mParent);
}

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

@ -67,6 +67,26 @@ nsMathMLmsubFrame::~nsMathMLmsubFrame()
{
}
NS_IMETHODIMP
nsMathMLmsubFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// if our base is an embellished operator, let its state bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
// 1. The REC says:
// The <msub> element increments scriptlevel by 1, and sets displaystyle to
// "false", within subscript, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the subscript is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsubFrame::Place (nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -107,13 +127,10 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext,
nscoord aUserSubScriptShift,
nscoord aScriptSpace)
{
nsresult rv = NS_OK;
// the caller better be a mathml frame
nsIMathMLFrame* mathMLFrame = nsnull;
rv = aFrame->QueryInterface (NS_GET_IID(nsIMathMLFrame),
(void**)&mathMLFrame);
if (NS_FAILED(rv) || !mathMLFrame) return rv;
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (!mathMLFrame) return NS_ERROR_INVALID_ARG;
// force the scriptSpace to be atleast 1 pixel
float p2t;
@ -123,38 +140,15 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics subScriptSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* subScriptFrame = nsnull;
// parameter v, Rule 18a, Appendix G of the TeXbook
nscoord minSubScriptShift = 0;
nsBoundingMetrics bmBase, bmSubScript;
nsIFrame* childFrame = nsnull;
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// subscript
subScriptFrame = childFrame;
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
// get the subdrop from the subscript font
nscoord subDrop;
GetSubDropFromChild (aPresContext, subScriptFrame, subDrop);
// parameter v, Rule 18a, App. G, TeXbook
minSubScriptShift = bmBase.descent + subDrop;
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (2 != count) {
nsHTMLReflowMetrics baseSize(nsnull);
nsHTMLReflowMetrics subScriptSize(nsnull);
nsIFrame* baseFrame;
aFrame->FirstChild(aPresContext, nsnull, &baseFrame);
nsIFrame* subScriptFrame = nsnull;
if (baseFrame)
baseFrame->GetNextSibling(&subScriptFrame);
if (!baseFrame || !subScriptFrame || HasNextSibling(subScriptFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return NS_STATIC_CAST(nsMathMLContainerFrame*,
@ -162,6 +156,14 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext,
aRenderingContext,
aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
// get the subdrop from the subscript font
nscoord subDrop;
GetSubDropFromChild(aPresContext, subScriptFrame, subDrop);
// parameter v, Rule 18a, App. G, TeXbook
nscoord minSubScriptShift = bmBase.descent + subDrop;
//////////////////
// Place Children
@ -171,9 +173,6 @@ nsMathMLmsubFrame::PlaceSubScript (nsIPresContext* aPresContext,
nscoord xHeight = 0;
nsCOMPtr<nsIFontMetrics> fm;
// const nsStyleFont* aFont =
// (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
const nsStyleFont* font;
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);

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

@ -35,6 +35,9 @@ class nsMathMLmsubFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmsubFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -50,25 +53,6 @@ public:
nscoord aUserSubScriptShift = 0,
nscoord aScriptSpace = NSFloatPointsToTwips(0.5f));
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// check whether or not this is an embellished operator
EmbellishOperator();
// 1. The REC says:
// The <msub> element increments scriptlevel by 1, and sets displaystyle to
// "false", within subscript, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the subscript is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
return NS_OK;
}
protected:
nsMathMLmsubFrame();
virtual ~nsMathMLmsubFrame();

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

@ -68,10 +68,35 @@ nsMathMLmsubsupFrame::~nsMathMLmsubsupFrame()
}
NS_IMETHODIMP
nsMathMLmsubsupFrame::Place (nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
nsMathMLmsubsupFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// if our base is an embellished operator, let its state bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
// 1. The REC says:
// The <msubsup> element increments scriptlevel by 1, and sets displaystyle to
// "false", within subscript and superscript, but leaves both attributes
// unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the superscript inherits the compression
// while the subscript is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE,
NS_MATHML_DISPLAYSTYLE);
UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 0,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsubsupFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
// extra spacing between base and sup/subscript
nscoord scriptSpace = 0;
@ -96,90 +121,55 @@ nsMathMLmsubsupFrame::Place (nsIPresContext* aPresContext,
}
}
return nsMathMLmsubsupFrame::PlaceSubSupScript (aPresContext,
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this,
subScriptShift,
supScriptShift,
scriptSpace);
return nsMathMLmsubsupFrame::PlaceSubSupScript(aPresContext,
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this,
subScriptShift,
supScriptShift,
scriptSpace);
}
// exported routine that both munderover and msubsup share.
// munderover uses this when movablelimits is set.
nsresult
nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize,
nsIFrame* aFrame,
nscoord aUserSubScriptShift,
nscoord aUserSupScriptShift,
nscoord aScriptSpace)
nsMathMLmsubsupFrame::PlaceSubSupScript(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize,
nsIFrame* aFrame,
nscoord aUserSubScriptShift,
nscoord aUserSupScriptShift,
nscoord aScriptSpace)
{
nsresult rv = NS_OK;
// the caller better be a mathml frame
nsIMathMLFrame* mathMLFrame = nsnull;
rv = aFrame->QueryInterface (NS_GET_IID(nsIMathMLFrame),
(void**)&mathMLFrame);
if (NS_FAILED(rv) || !mathMLFrame) return rv;
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (!mathMLFrame) return NS_ERROR_INVALID_ARG;
// force the scriptSpace to be atleast 1 pixel
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
aScriptSpace = PR_MAX(NSIntPixelsToTwips(1, p2t), aScriptSpace);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
aScriptSpace = PR_MAX(onePixel, aScriptSpace);
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics subScriptSize (nsnull);
nsHTMLReflowMetrics supScriptSize (nsnull);
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
nsIFrame* baseFrame = nsnull;
nsIFrame* subScriptFrame = nsnull;
nsIFrame* supScriptFrame = nsnull;
// parameter v, Rule 18a, Appendix G of the TeXbook
nscoord minSubScriptShift = 0;
// parameter u in Rule 18a, Appendix G of the TeXbook
nscoord minSupScriptShift = 0;
nsBoundingMetrics bmBase, bmSubScript, bmSupScript;
nsIFrame* childFrame = nsnull;
aFrame->FirstChild (aPresContext, nsnull, &childFrame);
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// subscript
subScriptFrame = childFrame;
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
// get the subdrop from the subscript font
nscoord aSubDrop;
GetSubDropFromChild (aPresContext, subScriptFrame, aSubDrop);
// parameter v, Rule 18a, App. G, TeXbook
minSubScriptShift = bmBase.descent + aSubDrop;
}
else if (2 == count) {
// superscript
supScriptFrame = childFrame;
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
// get the supdrop from the supscript font
nscoord aSupDrop;
GetSupDropFromChild (aPresContext, supScriptFrame, aSupDrop);
// parameter u, Rule 18a, App. G, TeXbook
minSupScriptShift = bmBase.ascent - aSupDrop;
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (3 != count) {
aFrame->FirstChild(aPresContext, nsnull, &baseFrame);
if (baseFrame)
baseFrame->GetNextSibling(&subScriptFrame);
if (subScriptFrame)
subScriptFrame->GetNextSibling(&supScriptFrame);
if (!baseFrame || !subScriptFrame || !supScriptFrame || HasNextSibling(supScriptFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return NS_STATIC_CAST(nsMathMLContainerFrame*,
@ -187,6 +177,21 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext,
aRenderingContext,
aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(subScriptFrame, subScriptSize, bmSubScript);
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
// get the subdrop from the subscript font
nscoord subDrop;
GetSubDropFromChild(aPresContext, subScriptFrame, subDrop);
// parameter v, Rule 18a, App. G, TeXbook
nscoord minSubScriptShift = bmBase.descent + subDrop;
// get the supdrop from the supscript font
nscoord supDrop;
GetSupDropFromChild(aPresContext, supScriptFrame, supDrop);
// parameter u, Rule 18a, App. G, TeXbook
nscoord minSupScriptShift = bmBase.ascent - supDrop;
//////////////////
// Place Children
@ -203,9 +208,6 @@ nsMathMLmsubsupFrame::PlaceSubSupScript (nsIPresContext* aPresContext,
// subScriptShift1 = subscriptshift attribute * x-height
nscoord subScriptShift1, subScriptShift2;
// const nsStyleFont* aFont =
// (const nsStyleFont*) mStyleContext->GetStyleData (eStyleStruct_Font);
const nsStyleFont* font;
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);
aRenderingContext.SetFont(font->mFont);

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

@ -35,6 +35,9 @@ class nsMathMLmsubsupFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmsubsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -51,30 +54,6 @@ public:
nscoord aUserSupScriptShift = 0,
nscoord aScriptSpace = NSFloatPointsToTwips(0.5f));
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// check whether or not this is an embellished operator
EmbellishOperator();
// 1. The REC says:
// The <msubsup> element increments scriptlevel by 1, and sets displaystyle to
// "false", within subscript and superscript, but leaves both attributes
// unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the superscript inherits the compression
// while the subscript is compressed
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE,
NS_MATHML_DISPLAYSTYLE);
UpdatePresentationDataFromChildAt(aPresContext, 1, 1, 0,
NS_MATHML_COMPRESSED,
NS_MATHML_COMPRESSED);
return NS_OK;
}
protected:
nsMathMLmsubsupFrame();
virtual ~nsMathMLmsubsupFrame();

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

@ -67,10 +67,31 @@ nsMathMLmsupFrame::~nsMathMLmsupFrame()
}
NS_IMETHODIMP
nsMathMLmsupFrame::Place (nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
nsMathMLmsupFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
// if our base is an embellished operator, its flags bubble to us
nsIFrame* baseFrame = mFrames.FirstChild();
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
// 1. The REC says:
// The <msup> element increments scriptlevel by 1, and sets displaystyle to
// "false", within superscript, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the superscript *inherits* the compression,
// so we don't set the compression flag. Our parent will propagate its own.
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE,
NS_MATHML_DISPLAYSTYLE);
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmsupFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
// extra spacing between base and sup/subscript
nscoord scriptSpace = NSFloatPointsToTwips(0.5f); // 0.5pt as in plain TeX
@ -86,13 +107,13 @@ nsMathMLmsupFrame::Place (nsIPresContext* aPresContext,
}
}
return nsMathMLmsupFrame::PlaceSuperScript (aPresContext,
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this,
supScriptShift,
scriptSpace);
return nsMathMLmsupFrame::PlaceSuperScript(aPresContext,
aRenderingContext,
aPlaceOrigin,
aDesiredSize,
this,
supScriptShift,
scriptSpace);
}
// exported routine that both mover and msup share.
@ -106,13 +127,10 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext,
nscoord aUserSupScriptShift,
nscoord aScriptSpace)
{
nsresult rv = NS_OK;
// the caller better be a mathml frame
nsIMathMLFrame* mathMLFrame = nsnull;
rv = aFrame->QueryInterface (NS_GET_IID(nsIMathMLFrame),
(void**)&mathMLFrame);
if (NS_FAILED(rv) || !mathMLFrame) return rv;
nsIMathMLFrame* mathMLFrame;
aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (!mathMLFrame) return NS_ERROR_INVALID_ARG;
// force the scriptSpace to be at least 1 pixel
float p2t;
@ -123,38 +141,15 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics supScriptSize (nsnull);
nsBoundingMetrics bmBase, bmSupScript;
nsIFrame* baseFrame = nsnull;
nsIFrame* supScriptFrame = nsnull;
// parameter u in Rule 18a, Appendix G of the TeXbook
nscoord minSupScriptShift = 0;
nsBoundingMetrics bmBase, bmSupScript;
nsIFrame* childFrame = nsnull;
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// superscript
supScriptFrame = childFrame;
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
// get the supdrop from the supscript font
nscoord supDrop;
GetSupDropFromChild (aPresContext, supScriptFrame, supDrop);
// parameter u, Rule 18a, App. G, TeXbook
minSupScriptShift = bmBase.ascent - supDrop;
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (2 != count) {
aFrame->FirstChild(aPresContext, nsnull, &baseFrame);
if (baseFrame)
baseFrame->GetNextSibling(&supScriptFrame);
if (!baseFrame || !supScriptFrame || HasNextSibling(supScriptFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return NS_STATIC_CAST(nsMathMLContainerFrame*,
@ -162,6 +157,14 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext,
aRenderingContext,
aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(supScriptFrame, supScriptSize, bmSupScript);
// get the supdrop from the supscript font
nscoord supDrop;
GetSupDropFromChild(aPresContext, supScriptFrame, supDrop);
// parameter u, Rule 18a, App. G, TeXbook
nscoord minSupScriptShift = bmBase.ascent - supDrop;
//////////////////
// Place Children
@ -171,9 +174,6 @@ nsMathMLmsupFrame::PlaceSuperScript(nsIPresContext* aPresContext,
nscoord xHeight = 0;
nsCOMPtr<nsIFontMetrics> fm;
// const nsStyleFont* aFont =
// (const nsStyleFont*) aStyleContext->GetStyleData (eStyleStruct_Font);
const nsStyleFont *font;
baseFrame->GetStyleData(eStyleStruct_Font, (const nsStyleStruct *&)font);

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

@ -35,6 +35,9 @@ class nsMathMLmsupFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmsupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
NS_IMETHOD
Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -50,26 +53,6 @@ public:
nscoord aUserSupScriptShift = 0,
nscoord aScriptSpace = NSFloatPointsToTwips(0.5f));
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// check whether or not this is an embellished operator
EmbellishOperator();
// 1. The REC says:
// The <msup> element increments scriptlevel by 1, and sets displaystyle to
// "false", within superscript, but leaves both attributes unchanged within base.
// 2. The TeXbook (Ch 17. p.141) says the superscript *inherits* the compression,
// so we don't set the compression flag. Our parent will propagate its own.
UpdatePresentationDataFromChildAt(aPresContext, 1, -1, 1,
~NS_MATHML_DISPLAYSTYLE,
NS_MATHML_DISPLAYSTYLE);
return NS_OK;
}
protected:
nsMathMLmsupFrame();
virtual ~nsMathMLmsupFrame();

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

@ -422,12 +422,7 @@ nsMathMLmtableOuterFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = nsTableOuterFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// now, inherit the scriptlevel and displaystyle from our parent
InheritAutomaticData(aPresContext, aParent);
return rv;
return nsTableOuterFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
nsIFrame*
@ -695,15 +690,11 @@ nsMathMLmtdInnerFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv;
rv = nsBlockFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
nsresult rv = nsBlockFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
// record that children that are ignorable whitespace should be excluded
mState |= NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE;
// now, inherit the scriptlevel and displaystyle from our parent
InheritAutomaticData(aPresContext, aParent);
return rv;
}

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

@ -64,18 +64,6 @@ nsMathMLmtextFrame::~nsMathMLmtextFrame()
{
}
NS_IMETHODIMP
nsMathMLmtextFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsresult rv = NS_OK;
rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
return rv;
}
NS_IMETHODIMP
nsMathMLmtextFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,

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

@ -32,13 +32,6 @@
class nsMathMLmtextFrame : public nsMathMLContainerFrame {
public:
friend nsresult NS_NewMathMLmtextFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
NS_IMETHOD
Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD
Reflow(nsIPresContext* aPresContext,

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

@ -69,6 +69,25 @@ nsMathMLmunderFrame::~nsMathMLmunderFrame()
{
}
NS_IMETHODIMP
nsMathMLmunderFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint)
{
if (nsMathMLAtoms::accentunder_ == aAttribute) {
// When we have automatic data to update within ourselves, we ask our
// parent to re-layout its children
return ReLayoutChildren(aPresContext, mParent);
}
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
}
NS_IMETHODIMP
nsMathMLmunderFrame::UpdatePresentationData(nsIPresContext* aPresContext,
PRInt32 aScriptLevelIncrement,
@ -78,12 +97,12 @@ nsMathMLmunderFrame::UpdatePresentationData(nsIPresContext* aPresContext,
nsMathMLContainerFrame::UpdatePresentationData(aPresContext,
aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate);
// disable the stretch-all flag if we are going to act like a subscript
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
else {
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
return NS_OK;
}
@ -124,24 +143,29 @@ nsMathMLmunderFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresCont
}
return NS_OK;
// XXX For #2, if the inner <mo> changes, is has to trigger
// XXX a re-computation of all flags that depend on its state
// XXX in the entire embellished hierarchy
// For #2, the base class will trigger a re-build of all automatic data
// in the embellished hierarchy when an accent attribute is changed
}
NS_IMETHODIMP
nsMathMLmunderFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmunderFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// At this stage, all our children are in sync and we can fully
// resolve our own mEmbellishData struct
//---------------------------------------------------------------------
mEmbellishData.flags = NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accentunder flag
/* The REC says:
The default value of accentunder is false, unless underscript
is an <mo> element or an embellished operator. If underscript is
@ -158,99 +182,61 @@ XXX The winner is the outermost setting in conflicting settings like these:
</munder>
*/
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* underscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) baseFrame = childFrame;
if (1 == count) { underscriptFrame = childFrame; break; }
count++;
childFrame->GetNextSibling(&childFrame);
}
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&underscriptFrame);
if (!baseFrame || !underscriptFrame)
return NS_OK; // a visual error indicator will be reported later during layout
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsIMathMLFrame* underscriptMathMLFrame = nsnull;
nsIMathMLFrame* mathMLFrame = nsnull;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTUNDER; // default of accentunder is false
// The default value of accentunder is false, unless the underscript is embellished
// and its core <mo> is an accent
nsEmbellishData embellishData;
GetEmbellishDataFrom(underscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
else
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value.Equals(NS_LITERAL_STRING("true"))) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
mEmbellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
// if we have an accentunder attribute, it overrides what the underscript said
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
}
// see if the underscriptFrame is <mo> or an embellished operator
if (underscriptFrame) {
underscriptFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&underscriptMathMLFrame);
if (underscriptMathMLFrame) {
underscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the underscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.coreFrame) {
embellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
// if we have the accentunder attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value))
{
if (value.Equals(NS_LITERAL_STRING("true"))) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals(NS_LITERAL_STRING("false"))) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
mathMLFrame->SetEmbellishData(embellishData);
}
// disable the stretch-all flag if we are going to act like a superscript
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
// sync the presentation data: record whether we have an accentunder
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTUNDER;
}
}
}
}
// Now transmit any change that we want to our children so that they
// can update their mPresentationData structs
//---------------------------------------------------------------------
/* The REC says:
Within underscript, <munder> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
*/
/*
The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a
say it should be compressed
*/
if (underscriptMathMLFrame) {
PRInt32 increment;
increment = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(aPresContext, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
}
// disable the stretch-all flag if we are going to act like a subscript
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)
? 0 : 1;
PropagatePresentationDataFor(aPresContext, underscriptFrame, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
return NS_OK;
}
@ -265,7 +251,7 @@ The REC says:
for limits on symbols such as &sum;.
i.e.,:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like subscript
}
@ -280,9 +266,7 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nsresult rv = NS_OK;
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like subscript
return nsMathMLmsubFrame::PlaceSubScript(aPresContext,
@ -295,33 +279,20 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmUnder;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics underSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* underFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// under
underFrame = childFrame;
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (2 != count) {
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&underFrame);
if (!baseFrame || !underFrame || HasNextSibling(underFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
////////////////////
// Place Children
@ -344,7 +315,7 @@ nsMathMLmunderFrame::Place(nsIPresContext* aPresContext,
nscoord italicCorrection = 0;
nscoord delta1 = 0; // gap between base and underscript
nscoord delta2 = 0; // extra space beneath underscript
if (!NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)) {
if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
GetItalicCorrection (bmBase, italicCorrection);
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;

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

@ -41,6 +41,10 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
@ -58,6 +62,14 @@ public:
PRUint32 aFlagsValues,
PRUint32 aFlagsToUpdate);
NS_IMETHOD
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint);
protected:
nsMathMLmunderFrame();
virtual ~nsMathMLmunderFrame();

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

@ -69,6 +69,26 @@ nsMathMLmunderoverFrame::~nsMathMLmunderoverFrame()
{
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint)
{
if (nsMathMLAtoms::accent_ == aAttribute ||
nsMathMLAtoms::accentunder_ == aAttribute) {
// When we have automatic data to update within ourselves, we ask our
// parent to re-layout its children
return ReLayoutChildren(aPresContext, mParent);
}
return nsMathMLContainerFrame::
AttributeChanged(aPresContext, aContent, aNameSpaceID,
aAttribute, aModType, aHint);
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::UpdatePresentationData(nsIPresContext* aPresContext,
PRInt32 aScriptLevelIncrement,
@ -78,12 +98,12 @@ nsMathMLmunderoverFrame::UpdatePresentationData(nsIPresContext* aPresContext,
nsMathMLContainerFrame::UpdatePresentationData(aPresContext,
aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate);
// disable the stretch-all flag if we are going to act like a subscript-superscript pair
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
else {
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
return NS_OK;
}
@ -129,24 +149,29 @@ nsMathMLmunderoverFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPres
}
return NS_OK;
// XXX For #2, if the inner <mo> changes, is has to trigger
// XXX a re-computation of all flags that depend on its state
// XXX in the entire embellished hierarchy
// For #2, the base class will trigger a re-build of all automatic data
// in the embellished hierarchy when an accent attribute is changed
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent)
{
// let the base class get the default from our parent
nsMathMLContainerFrame::InheritAutomaticData(aPresContext, aParent);
mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
return NS_OK;
}
NS_IMETHODIMP
nsMathMLmunderoverFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
{
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
mPresentationData.flags |= NS_MATHML_SHOW_BOUNDING_METRICS;
#endif
// At this stage, all our children are in sync and we can fully
// resolve our own mEmbellishData struct
//---------------------------------------------------------------------
mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
// check whether or not this is an embellished operator
EmbellishOperator();
// set our accent and accentunder flags
/*
The REC says:
@ -158,156 +183,98 @@ nsMathMLmunderoverFrame::TransmitAutomaticData(nsIPresContext* aPresContext)
of accentunder depending on underscript.
*/
// get our overscript and underscript frames
PRInt32 count = 0;
nsIFrame* baseFrame = nsnull;
nsIFrame* underscriptFrame = nsnull;
nsIFrame* overscriptFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) baseFrame = childFrame;
if (1 == count) underscriptFrame = childFrame;
if (2 == count) { overscriptFrame = childFrame; break; }
count++;
childFrame->GetNextSibling(&childFrame);
}
nsIFrame* underscriptFrame = nsnull;
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&underscriptFrame);
if (underscriptFrame)
underscriptFrame->GetNextSibling(&overscriptFrame);
if (!baseFrame || !underscriptFrame || !overscriptFrame)
return NS_OK; // a visual error indicator will be reported later during layout
// if our base is an embellished operator, let its state bubble to us (in particular,
// this is where we get the flag for NS_MATHML_EMBELLISH_MOVABLELIMITS). Our flags
// are reset to the default values of false if the base frame isn't embellished.
GetEmbellishDataFrom(baseFrame, mEmbellishData);
if (NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags))
mEmbellishData.nextFrame = baseFrame;
nsIMathMLFrame* underscriptMathMLFrame = nsnull;
nsIMathMLFrame* overscriptMathMLFrame = nsnull;
nsIMathMLFrame* mathMLFrame;
nsEmbellishData embellishData;
nsAutoString value;
mPresentationData.flags &= ~NS_MATHML_MOVABLELIMITS; // default is false
mPresentationData.flags &= ~NS_MATHML_ACCENTUNDER; // default of accentunder is false
mPresentationData.flags &= ~NS_MATHML_ACCENTOVER; // default of accent is false
// The default value of accentunder is false, unless the underscript is embellished
// and its core <mo> is an accent
nsEmbellishData embellishData;
GetEmbellishDataFrom(underscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
else
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
// see if the baseFrame has movablelimits="true" or if it is an
// embellished operator whose movablelimits attribute is set to true
if (baseFrame && NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags)) {
nsCOMPtr<nsIContent> baseContent;
baseFrame->GetContent(getter_AddRefs(baseContent));
if (NS_CONTENT_ATTR_HAS_VALUE == baseContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::movablelimits_, value)) {
if (value.Equals(NS_LITERAL_STRING("true"))) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
else { // no attribute, get the value from the core
mEmbellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
if (NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(embellishData.flags)) {
mPresentationData.flags |= NS_MATHML_MOVABLELIMITS;
}
}
}
// if we have an accentunder attribute, it overrides what the underscript said
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTUNDER;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTUNDER;
}
// see if the underscriptFrame is <mo> or an embellished operator
if (underscriptFrame) {
underscriptFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&underscriptMathMLFrame);
if (underscriptMathMLFrame) {
underscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the underscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.coreFrame) {
embellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
// if we have the accentunder attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accentunder_, value))
{
if (value.Equals(NS_LITERAL_STRING("true"))) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals(NS_LITERAL_STRING("false"))) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
mathMLFrame->SetEmbellishData(embellishData);
}
// The default value of accent is false, unless the overscript is embellished
// and its core <mo> is an accent
GetEmbellishDataFrom(overscriptFrame, embellishData);
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
else
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
// sync the presentation data: record whether we have an accentunder
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTUNDER;
}
}
}
}
// see if the overscriptFrame is <mo> or an embellished operator
if (overscriptFrame) {
overscriptFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&overscriptMathMLFrame);
if (overscriptMathMLFrame) {
overscriptMathMLFrame->GetEmbellishData(embellishData);
// core of the overscriptFrame
if (NS_MATHML_IS_EMBELLISH_OPERATOR(embellishData.flags) && embellishData.coreFrame) {
embellishData.coreFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame);
if (mathMLFrame) {
mathMLFrame->GetEmbellishData(embellishData);
// if we have the accent attribute, tell the core to behave as
// requested (otherwise leave the core with its default behavior)
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accent_, value))
{
if (value.Equals(NS_LITERAL_STRING("true"))) embellishData.flags |= NS_MATHML_EMBELLISH_ACCENT;
else if (value.Equals(NS_LITERAL_STRING("false"))) embellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENT;
mathMLFrame->SetEmbellishData(embellishData);
}
// sync the presentation data: record whether we have an accent
if (NS_MATHML_EMBELLISH_IS_ACCENT(embellishData.flags))
mPresentationData.flags |= NS_MATHML_ACCENTOVER;
}
}
}
// if we have an accent attribute, it overrides what the overscript said
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None,
nsMathMLAtoms::accent_, value)) {
if (value.Equals(NS_LITERAL_STRING("true")))
mEmbellishData.flags |= NS_MATHML_EMBELLISH_ACCENTOVER;
else if (value.Equals(NS_LITERAL_STRING("false")))
mEmbellishData.flags &= ~NS_MATHML_EMBELLISH_ACCENTOVER;
}
//The REC says:
/*
Within underscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
// disable the stretch-all flag if we are going to act like a superscript
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags))
mPresentationData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
Within overscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
*/
// Now transmit any change that we want to our children so that they
// can update their mPresentationData structs
//---------------------------------------------------------------------
/*
/* The REC says:
Within underscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accentunder is "false".
Within overscript, <munderover> always sets displaystyle to "false",
but increments scriptlevel by 1 only when accent is "false".
The TeXBook treats 'over' like a superscript, so p.141 or Rule 13a
say it shouldn't be compressed. However, The TeXBook says
that math accents and \overline change uncramped styles to their
cramped counterparts.
*/
if (overscriptMathMLFrame)
{
PRInt32 increment = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)
? 0 : 1;
PRUint32 compress = NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)
? NS_MATHML_COMPRESSED : 0;
overscriptMathMLFrame->UpdatePresentationData(aPresContext, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
overscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
}
PRInt32 increment = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
? 0 : 1;
PRUint32 compress = NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)
? NS_MATHML_COMPRESSED : 0;
PropagatePresentationDataFor(aPresContext, overscriptFrame, increment,
~NS_MATHML_DISPLAYSTYLE | compress,
NS_MATHML_DISPLAYSTYLE | compress);
/*
The TeXBook treats 'under' like a subscript, so p.141 or Rule 13a
say it should be compressed
*/
if (underscriptMathMLFrame) {
PRInt32 increment = NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)? 0 : 1;
underscriptMathMLFrame->UpdatePresentationData(aPresContext, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
underscriptMathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
}
// disable the stretch-all flag if we are going to act like a subscript-superscript pair
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
mEmbellishData.flags &= ~NS_MATHML_STRETCH_ALL_CHILDREN_HORIZONTALLY;
}
increment = NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)
? 0 : 1;
PropagatePresentationDataFor(aPresContext, underscriptFrame, increment,
~NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED,
NS_MATHML_DISPLAYSTYLE | NS_MATHML_COMPRESSED);
return NS_OK;
}
@ -322,7 +289,7 @@ The REC says:
used for limits on symbols such as &sum;.
i.e.,:
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishDataflags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like subscript-superscript pair
}
@ -331,16 +298,13 @@ i.e.,:
}
*/
NS_IMETHODIMP
nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize)
{
nsresult rv = NS_OK;
if ( NS_MATHML_IS_MOVABLELIMITS(mPresentationData.flags) &&
if ( NS_MATHML_EMBELLISH_IS_MOVABLELIMITS(mEmbellishData.flags) &&
!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) {
// place like sub-superscript pair
return nsMathMLmsubsupFrame::PlaceSubSupScript(aPresContext,
@ -353,40 +317,25 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
////////////////////////////////////
// Get the children's desired sizes
PRInt32 count = 0;
nsBoundingMetrics bmBase, bmUnder, bmOver;
nsHTMLReflowMetrics baseSize (nsnull);
nsHTMLReflowMetrics underSize (nsnull);
nsHTMLReflowMetrics overSize (nsnull);
nsIFrame* baseFrame = nsnull;
nsIFrame* overFrame = nsnull;
nsIFrame* underFrame = nsnull;
nsIFrame* childFrame = mFrames.FirstChild();
while (childFrame) {
if (0 == count) {
// base
baseFrame = childFrame;
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
}
else if (1 == count) {
// under
underFrame = childFrame;
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
}
else if (2 == count) {
// over
overFrame = childFrame;
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
}
count++;
childFrame->GetNextSibling(&childFrame);
}
if (3 != count) {
nsIFrame* baseFrame = mFrames.FirstChild();
if (baseFrame)
baseFrame->GetNextSibling(&underFrame);
if (underFrame)
underFrame->GetNextSibling(&overFrame);
if (!baseFrame || !underFrame || !overFrame || HasNextSibling(overFrame)) {
// report an error, encourage people to get their markups in order
NS_WARNING("invalid markup");
return ReflowError(aPresContext, aRenderingContext, aDesiredSize);
}
GetReflowAndBoundingMetricsFor(baseFrame, baseSize, bmBase);
GetReflowAndBoundingMetricsFor(underFrame, underSize, bmUnder);
GetReflowAndBoundingMetricsFor(overFrame, overSize, bmOver);
////////////////////
// Place Children
@ -410,7 +359,7 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
nscoord underDelta1 = 0; // gap between base and underscript
nscoord underDelta2 = 0; // extra space beneath underscript
if (!NS_MATHML_IS_ACCENTUNDER(mPresentationData.flags)) {
if (!NS_MATHML_EMBELLISH_IS_ACCENTUNDER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
GetItalicCorrection (bmBase, italicCorrection);
nscoord bigOpSpacing2, bigOpSpacing4, bigOpSpacing5, dummy;
@ -436,7 +385,7 @@ nsMathMLmunderoverFrame::Place(nsIPresContext* aPresContext,
nscoord overDelta1 = 0; // gap between base and overscript
nscoord overDelta2 = 0; // extra space above overscript
if (!NS_MATHML_IS_ACCENTOVER(mPresentationData.flags)) {
if (!NS_MATHML_EMBELLISH_IS_ACCENTOVER(mEmbellishData.flags)) {
// Rule 13a, App. G, TeXbook
GetItalicCorrection (bmBase, italicCorrection);
nscoord bigOpSpacing1, bigOpSpacing3, bigOpSpacing5, dummy;

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

@ -41,6 +41,10 @@ public:
PRBool aPlaceOrigin,
nsHTMLReflowMetrics& aDesiredSize);
NS_IMETHOD
InheritAutomaticData(nsIPresContext* aPresContext,
nsIFrame* aParent);
NS_IMETHOD
TransmitAutomaticData(nsIPresContext* aPresContext);
@ -58,6 +62,14 @@ public:
PRUint32 aFlagsValues,
PRUint32 aFlagsToUpdate);
NS_IMETHOD
AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType,
PRInt32 aHint);
protected:
nsMathMLmunderoverFrame();
virtual ~nsMathMLmunderoverFrame();