зеркало из https://github.com/mozilla/gecko-dev.git
Call DidReflow() on child frames where needed in case of errors. b=366012 r+sr=rbs
This commit is contained in:
Родитель
9e11670efb
Коммит
fd36f101fc
|
@ -399,7 +399,11 @@ nsMathMLContainerFrame::Stretch(nsIRenderingContext& aRenderingContext,
|
|||
}
|
||||
|
||||
// re-position all our children
|
||||
Place(aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
nsresult rv = Place(aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
|
||||
// Make sure the child frames get their DidReflow() calls.
|
||||
DidReflowChildren(mFrames.FirstChild());
|
||||
}
|
||||
|
||||
// If our parent is not embellished, it means we are the outermost embellished
|
||||
// container and so we put the spacing, otherwise we don't include the spacing,
|
||||
|
@ -469,11 +473,17 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
|||
PRBool placeOrigin = !NS_MATHML_IS_EMBELLISH_OPERATOR(mEmbellishData.flags) ||
|
||||
(mEmbellishData.coreFrame != this && !mPresentationData.baseFrame &&
|
||||
mEmbellishData.direction == NS_STRETCH_DIRECTION_UNSUPPORTED);
|
||||
Place(aRenderingContext, placeOrigin, aDesiredSize);
|
||||
nsresult rv = Place(aRenderingContext, placeOrigin, aDesiredSize);
|
||||
|
||||
// exit now if the frame was flagged as having invalid markup
|
||||
if (NS_MATHML_HAS_ERROR(mPresentationData.flags)) {
|
||||
return NS_OK;
|
||||
// Place() will call FinishReflowChild() when placeOrigin is true but if
|
||||
// it returns before reaching FinishReflowChild() due to errors we need
|
||||
// to fulfill the reflow protocol by calling DidReflow for the child frames
|
||||
// that still needs it here (or we may crash - bug 366012).
|
||||
// If placeOrigin is false we should reach Place() with aPlaceOrigin == true
|
||||
// through Stretch() eventually.
|
||||
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
|
||||
DidReflowChildren(GetFirstChild(nsnull));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!placeOrigin) {
|
||||
|
@ -516,6 +526,17 @@ nsMathMLContainerFrame::FinalizeReflow(nsIRenderingContext& aRenderingContext,
|
|||
}
|
||||
Stretch(aRenderingContext, NS_STRETCH_DIRECTION_DEFAULT, defaultSize,
|
||||
aDesiredSize);
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
// The Place() call above didn't request FinishReflowChild(),
|
||||
// so let's check that we eventually did through Stretch().
|
||||
nsIFrame* childFrame = GetFirstChild(nsnull);
|
||||
for ( ; childFrame; childFrame = childFrame->GetNextSibling()) {
|
||||
NS_ASSERTION(!(childFrame->GetStateBits() & NS_FRAME_IN_REFLOW),
|
||||
"DidReflow() was never called");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Also return our bounding metrics
|
||||
|
@ -1033,7 +1054,11 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext,
|
|||
rv = ReflowChild(childFrame, aPresContext, childDesiredSize,
|
||||
childReflowState, childStatus);
|
||||
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
// Call DidReflow() for the child frames we successfully did reflow.
|
||||
DidReflowChildren(mFrames.FirstChild(), childFrame);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// At this stage, the origin points of the children have no use, so we will use the
|
||||
// origins as placeholders to store the child's ascent and descent. Later on,
|
||||
|
@ -1388,7 +1413,22 @@ nsMathMLContainerFrame::FixInterFrameSpacing(nsHTMLReflowMetrics& aDesiredSize)
|
|||
return gap;
|
||||
}
|
||||
|
||||
void
|
||||
nsMathMLContainerFrame::DidReflowChildren(nsIFrame* aFirst, nsIFrame* aStop)
|
||||
|
||||
{
|
||||
NS_PRECONDITION(aFirst, "expected a frame");
|
||||
|
||||
for (nsIFrame* frame = aFirst;
|
||||
frame != aStop;
|
||||
frame = frame->GetNextSibling()) {
|
||||
NS_ASSERTION(frame, "aStop isn't a sibling");
|
||||
if (frame->GetStateBits() & NS_FRAME_IN_REFLOW) {
|
||||
frame->DidReflow(frame->GetPresContext(), nsnull,
|
||||
NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
|
||||
class nsMathMLContainerFrame : public nsHTMLContainerFrame,
|
||||
public nsMathMLFrame {
|
||||
friend class nsMathMLmfencedFrame;
|
||||
public:
|
||||
nsMathMLContainerFrame(nsStyleContext* aContext) : nsHTMLContainerFrame(aContext) {}
|
||||
|
||||
|
@ -305,6 +306,13 @@ public:
|
|||
|
||||
protected:
|
||||
virtual PRIntn GetSkipSides() const { return 0; }
|
||||
|
||||
/**
|
||||
* Call DidReflow() if the NS_FRAME_IN_REFLOW frame bit is set on aFirst and
|
||||
* all its next siblings up to, but not including, aStop.
|
||||
* aStop == nsnull meaning all next siblings with the bit set.
|
||||
*/
|
||||
void DidReflowChildren(nsIFrame* aFirst, nsIFrame* aStop = nsnull);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -142,7 +142,11 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
|
|||
rv = ReflowChild(childFrame, aPresContext, childDesiredSize,
|
||||
childReflowState, aStatus);
|
||||
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
// Call DidReflow() for the child frames we successfully did reflow.
|
||||
DidReflowChildren(GetFirstChild(nsnull), childFrame);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// origins are used as placeholders to store the child's ascent and descent.
|
||||
childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
|
||||
|
|
|
@ -303,7 +303,11 @@ nsMathMLmfencedFrame::doReflow(nsPresContext* aPresContext,
|
|||
rv = mathMLFrame->ReflowChild(childFrame, aPresContext, childDesiredSize,
|
||||
childReflowState, childStatus);
|
||||
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
// Call DidReflow() for the child frames we successfully did reflow.
|
||||
mathMLFrame->DidReflowChildren(firstChild, childFrame);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// At this stage, the origin points of the children have no use, so we will use the
|
||||
// origins as placeholders to store the child's ascent and descent. Later on,
|
||||
|
|
|
@ -788,7 +788,11 @@ nsMathMLmoFrame::Stretch(nsIRenderingContext& aRenderingContext,
|
|||
|
||||
// Place our children using the default method
|
||||
// This will allow our child text frame to get its DidReflow()
|
||||
Place(aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
nsresult rv = Place(aRenderingContext, PR_TRUE, aDesiredStretchSize);
|
||||
if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
|
||||
// Make sure the child frames get their DidReflow() calls.
|
||||
DidReflowChildren(mFrames.FirstChild());
|
||||
}
|
||||
|
||||
// Fixup for the final height.
|
||||
// On one hand, our stretchy height can sometimes be shorter than surrounding
|
||||
|
|
|
@ -186,7 +186,11 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext,
|
|||
rv = ReflowChild(childFrame, aPresContext,
|
||||
childDesiredSize, childReflowState, childStatus);
|
||||
//NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
// Call DidReflow() for the child frames we successfully did reflow.
|
||||
DidReflowChildren(mFrames.FirstChild(), childFrame);
|
||||
return rv;
|
||||
}
|
||||
if (0 == count) {
|
||||
// base
|
||||
baseFrame = childFrame;
|
||||
|
|
|
@ -117,15 +117,10 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aFrame,
|
||||
nsMathMLContainerFrame* aFrame,
|
||||
nscoord aUserSubScriptShift,
|
||||
nscoord aScriptSpace)
|
||||
{
|
||||
// the caller better be a mathml frame
|
||||
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
|
||||
aScriptSpace = PR_MAX(nsPresContext::CSSPixelsToAppUnits(1), aScriptSpace);
|
||||
|
||||
|
@ -195,7 +190,7 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
|
|||
boundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
boundingMetrics.rightBearing = PR_MAX(bmBase.rightBearing, bmBase.width +
|
||||
PR_MAX(bmSubScript.width + aScriptSpace, bmSubScript.rightBearing));
|
||||
mathMLFrame->SetBoundingMetrics (boundingMetrics);
|
||||
aFrame->SetBoundingMetrics (boundingMetrics);
|
||||
|
||||
// reflow metrics
|
||||
aDesiredSize.ascent =
|
||||
|
@ -206,7 +201,7 @@ nsMathMLmsubFrame::PlaceSubScript (nsPresContext* aPresContext,
|
|||
aDesiredSize.width = boundingMetrics.width;
|
||||
aDesiredSize.mBoundingMetrics = boundingMetrics;
|
||||
|
||||
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
aFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aForFrame,
|
||||
nsMathMLContainerFrame* aForFrame,
|
||||
nscoord aUserSubScriptShift,
|
||||
nscoord aScriptSpace);
|
||||
|
||||
|
|
|
@ -133,16 +133,11 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aFrame,
|
||||
nsMathMLContainerFrame* aFrame,
|
||||
nscoord aUserSubScriptShift,
|
||||
nscoord aUserSupScriptShift,
|
||||
nscoord aScriptSpace)
|
||||
{
|
||||
// the caller better be a mathml frame
|
||||
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
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
aScriptSpace = PR_MAX(onePixel, aScriptSpace);
|
||||
|
@ -258,7 +253,7 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
|
|||
// Rule 18c, App. G, TeXbook
|
||||
nscoord supScriptShift;
|
||||
nsPresentationData presentationData;
|
||||
mathMLFrame->GetPresentationData(presentationData);
|
||||
aFrame->GetPresentationData(presentationData);
|
||||
if ( presentationData.scriptLevel == 0 &&
|
||||
NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) &&
|
||||
!NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
|
||||
|
@ -325,7 +320,7 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
|
|||
boundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
boundingMetrics.rightBearing = bmBase.width +
|
||||
PR_MAX((italicCorrection + bmSupScript.rightBearing), bmSubScript.rightBearing);
|
||||
mathMLFrame->SetBoundingMetrics(boundingMetrics);
|
||||
aFrame->SetBoundingMetrics(boundingMetrics);
|
||||
|
||||
// reflow metrics
|
||||
aDesiredSize.ascent =
|
||||
|
@ -339,7 +334,7 @@ nsMathMLmsubsupFrame::PlaceSubSupScript(nsPresContext* aPresContext,
|
|||
aDesiredSize.width = boundingMetrics.width;
|
||||
aDesiredSize.mBoundingMetrics = boundingMetrics;
|
||||
|
||||
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
aFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aForFrame,
|
||||
nsMathMLContainerFrame* aForFrame,
|
||||
nscoord aUserSubScriptShift,
|
||||
nscoord aUserSupScriptShift,
|
||||
nscoord aScriptSpace);
|
||||
|
|
|
@ -117,15 +117,10 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aFrame,
|
||||
nsMathMLContainerFrame* aFrame,
|
||||
nscoord aUserSupScriptShift,
|
||||
nscoord aScriptSpace)
|
||||
{
|
||||
// the caller better be a mathml frame
|
||||
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
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
aScriptSpace = PR_MAX(onePixel, aScriptSpace);
|
||||
|
@ -195,7 +190,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
|
|||
// Rule 18c, App. G, TeXbook
|
||||
nscoord supScriptShift;
|
||||
nsPresentationData presentationData;
|
||||
mathMLFrame->GetPresentationData (presentationData);
|
||||
aFrame->GetPresentationData (presentationData);
|
||||
if ( presentationData.scriptLevel == 0 &&
|
||||
NS_MATHML_IS_DISPLAYSTYLE(presentationData.flags) &&
|
||||
!NS_MATHML_IS_COMPRESSED(presentationData.flags)) {
|
||||
|
@ -233,7 +228,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
|
|||
boundingMetrics.leftBearing = bmBase.leftBearing;
|
||||
boundingMetrics.rightBearing = bmBase.width + italicCorrection +
|
||||
bmSupScript.rightBearing;
|
||||
mathMLFrame->SetBoundingMetrics(boundingMetrics);
|
||||
aFrame->SetBoundingMetrics(boundingMetrics);
|
||||
|
||||
// reflow metrics
|
||||
aDesiredSize.ascent =
|
||||
|
@ -244,7 +239,7 @@ nsMathMLmsupFrame::PlaceSuperScript(nsPresContext* aPresContext,
|
|||
aDesiredSize.width = boundingMetrics.width;
|
||||
aDesiredSize.mBoundingMetrics = boundingMetrics;
|
||||
|
||||
mathMLFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
aFrame->SetReference(nsPoint(0, aDesiredSize.ascent));
|
||||
|
||||
if (aPlaceOrigin) {
|
||||
nscoord dx, dy;
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
nsIRenderingContext& aRenderingContext,
|
||||
PRBool aPlaceOrigin,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsIFrame* aForFrame,
|
||||
nsMathMLContainerFrame* aForFrame,
|
||||
nscoord aUserSupScriptShift,
|
||||
nscoord aScriptSpace);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче