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:
dbaron@dbaron.org
2006-12-08 05:38:33 +00:00
parent 0f0fb052ce
commit d21cb374bd
201 changed files with 8724 additions and 18251 deletions
+35 -55
View File
@@ -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