Bug 300030: Move intrinsic width computation out of nsIFrame::Reflow and into its own methods on nsIFrame. Replace reflow reasons, types, and commands with dirty bits/notifications. Thanks to bzbarsky for almost all of the HTML form controls (mozilla/layout/forms) changes, and many others for help testing and patching. For detailed commit logs, see REFLOW_YYYYMMDD_BRANCH, where YYYYMMDD is one of 20061031, 20060830, 20060603, 20060302, 20060119, 20051011, 20050804, 20050429, 20050315, 20050111, and 20041213.
This commit is contained in:
@@ -41,7 +41,6 @@
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsReflowPath.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsIView.h"
|
||||
@@ -101,6 +100,8 @@ public:
|
||||
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@@ -281,9 +282,8 @@ CanvasFrame::AppendFrames(nsIAtom* aListName,
|
||||
#endif
|
||||
mFrames.AppendFrame(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the newly inserted frame
|
||||
rv = GetPresContext()->PresShell()->
|
||||
AppendReflowCommand(this, eReflowType_ReflowDirty, nsnull);
|
||||
GetPresContext()->PresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@@ -329,9 +329,8 @@ CanvasFrame::RemoveFrame(nsIAtom* aListName,
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aOldFrame);
|
||||
|
||||
// Generate a reflow command so we get reflowed
|
||||
rv = GetPresContext()->PresShell()->
|
||||
AppendReflowCommand(this, eReflowType_ReflowDirty, nsnull);
|
||||
GetPresContext()->PresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange);
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
@@ -525,53 +524,45 @@ CanvasFrame::PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt)
|
||||
nsnull);
|
||||
}
|
||||
|
||||
/* virtual */ nscoord
|
||||
CanvasFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
|
||||
{
|
||||
nscoord result;
|
||||
DISPLAY_MIN_WIDTH(this, result);
|
||||
if (mFrames.IsEmpty())
|
||||
result = 0;
|
||||
else
|
||||
result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* virtual */ nscoord
|
||||
CanvasFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
||||
{
|
||||
nscoord result;
|
||||
DISPLAY_PREF_WIDTH(this, result);
|
||||
if (mFrames.IsEmpty())
|
||||
result = 0;
|
||||
else
|
||||
result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("CanvasFrame", aReflowState.reason);
|
||||
DO_GLOBAL_REFLOW_COUNT("CanvasFrame");
|
||||
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
|
||||
NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow");
|
||||
//NS_PRECONDITION(!aDesiredSize.mComputeMEW, "unexpected request");
|
||||
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
PRBool isStyleChange = PR_FALSE;
|
||||
PRBool isDirtyChildReflow = PR_FALSE;
|
||||
|
||||
// Check for an incremental reflow
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// See if we're the target frame
|
||||
nsHTMLReflowCommand *command = aReflowState.path->mReflowCommand;
|
||||
if (command) {
|
||||
// Get the reflow type
|
||||
switch (command->Type()) {
|
||||
case eReflowType_ReflowDirty:
|
||||
isDirtyChildReflow = PR_TRUE;
|
||||
break;
|
||||
|
||||
case eReflowType_StyleChanged:
|
||||
// Remember it's a style change so we can set the reflow reason below
|
||||
isStyleChange = PR_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(PR_FALSE, "unexpected reflow command type");
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
nsReflowPath::iterator iter = aReflowState.path->FirstChild();
|
||||
NS_ASSERTION(*iter == mFrames.FirstChild(), "unexpected next reflow command frame");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Reflow our one and only child frame
|
||||
nsHTMLReflowMetrics kidDesiredSize(nsnull);
|
||||
nsHTMLReflowMetrics kidDesiredSize;
|
||||
if (mFrames.IsEmpty()) {
|
||||
// We have no child frame, so return an empty size
|
||||
aDesiredSize.width = aDesiredSize.height = 0;
|
||||
@@ -579,24 +570,13 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
} else {
|
||||
nsIFrame* kidFrame = mFrames.FirstChild();
|
||||
|
||||
nsReflowReason reason;
|
||||
if (isDirtyChildReflow) {
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
reason = eReflowReason_Initial;
|
||||
} else if (isStyleChange) {
|
||||
reason = eReflowReason_StyleChange;
|
||||
} else {
|
||||
reason = aReflowState.reason;
|
||||
}
|
||||
PRBool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
|
||||
|
||||
// We must specify an unconstrained available height, because constrained
|
||||
// is only for when we're paginated...
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
|
||||
nsSize(aReflowState.availableWidth,
|
||||
NS_UNCONSTRAINEDSIZE),
|
||||
reason);
|
||||
NS_UNCONSTRAINEDSIZE));
|
||||
|
||||
// Reflow the frame
|
||||
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
||||
@@ -610,7 +590,7 @@ CanvasFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
// If the child frame was just inserted, then we're responsible for making sure
|
||||
// it repaints
|
||||
if (isDirtyChildReflow) {
|
||||
if (kidDirty) {
|
||||
// But we have a new child, which will affect our background, so
|
||||
// invalidate our whole rect.
|
||||
// Note: Even though we request to be sized to our child's size, our
|
||||
|
||||
Reference in New Issue
Block a user