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.
git-svn-id: svn://10.0.0.236/trunk@216738 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -50,7 +50,6 @@
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsReflowPath.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsFrameManager.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
@@ -211,7 +210,11 @@ nsInlineFrame::AppendFrames(nsIAtom* aListName,
|
||||
#ifdef IBMBIDI
|
||||
if (nsnull == aListName)
|
||||
#endif
|
||||
ReflowDirtyChild(GetPresContext()->PresShell(), nsnull);
|
||||
{
|
||||
AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
GetPresContext()->PresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -241,7 +244,9 @@ nsInlineFrame::InsertFrames(nsIAtom* aListName,
|
||||
if (nsnull == aListName)
|
||||
#endif
|
||||
// Ask the parent frame to reflow me.
|
||||
ReflowDirtyChild(GetPresContext()->PresShell(), nsnull);
|
||||
AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
GetPresContext()->PresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -296,7 +301,9 @@ nsInlineFrame::RemoveFrame(nsIAtom* aListName,
|
||||
|
||||
if (generateReflowCommand) {
|
||||
// Ask the parent frame to reflow me.
|
||||
ReflowDirtyChild(GetPresContext()->PresShell(), nsnull);
|
||||
AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
GetPresContext()->PresShell()->
|
||||
FrameNeedsReflow(this, nsIPresShell::eTreeChange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,13 +331,37 @@ nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Reflow methods
|
||||
|
||||
/* virtual */ void
|
||||
nsInlineFrame::AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
|
||||
nsIFrame::InlineMinWidthData *aData)
|
||||
{
|
||||
DoInlineIntrinsicWidth(aRenderingContext, aData, nsLayoutUtils::MIN_WIDTH);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsInlineFrame::AddInlinePrefWidth(nsIRenderingContext *aRenderingContext,
|
||||
nsIFrame::InlinePrefWidthData *aData)
|
||||
{
|
||||
DoInlineIntrinsicWidth(aRenderingContext, aData, nsLayoutUtils::PREF_WIDTH);
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
nsInlineFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
nsSize aMargin, nsSize aBorder, nsSize aPadding,
|
||||
PRBool aShrinkWrap)
|
||||
{
|
||||
// Inlines and text don't compute size before reflow.
|
||||
return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aMetrics,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT("nsInlineFrame", aReflowState.reason);
|
||||
DO_GLOBAL_REFLOW_COUNT("nsInlineFrame");
|
||||
DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
|
||||
if (nsnull == aReflowState.mLineLayout) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
@@ -349,7 +380,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLContainerFrame::ReparentFrameViewList(aPresContext, prevOverflowFrames,
|
||||
prevInFlow, this);
|
||||
|
||||
if (aReflowState.reason == eReflowReason_Initial) {
|
||||
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||
// If it's the initial reflow, then our child list must be empty, so
|
||||
// just set the child list rather than calling InsertFrame(). This avoids
|
||||
// having to get the last child frame in the list.
|
||||
@@ -370,7 +401,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
// It's also possible that we have an overflow list for ourselves
|
||||
#ifdef DEBUG
|
||||
if (aReflowState.reason == eReflowReason_Initial) {
|
||||
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||
// If it's our initial reflow, then we should not have an overflow list.
|
||||
// However, add an assertion in case we get reflowed more than once with
|
||||
// the initial reflow reason
|
||||
@@ -378,7 +409,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
NS_ASSERTION(!overflowFrames, "overflow list is not empty for initial reflow");
|
||||
}
|
||||
#endif
|
||||
if (aReflowState.reason != eReflowReason_Initial) {
|
||||
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||
nsIFrame* overflowFrames = GetOverflowFrames(aPresContext, PR_TRUE);
|
||||
if (overflowFrames) {
|
||||
NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
|
||||
@@ -429,36 +460,11 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInlineFrame::CanContinueTextRun(PRBool& aContinueTextRun) const
|
||||
/* virtual */ PRBool
|
||||
nsInlineFrame::CanContinueTextRun() const
|
||||
{
|
||||
// We can continue a text run through an inline frame
|
||||
aContinueTextRun = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInlineFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild)
|
||||
{
|
||||
// The inline container frame does not handle the reflow
|
||||
// request. It passes it up to its parent container.
|
||||
|
||||
// If you don't already have dirty children,
|
||||
if (!(mState & NS_FRAME_HAS_DIRTY_CHILDREN)) {
|
||||
if (mParent) {
|
||||
// Record that you are dirty and have dirty children
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
|
||||
// Pass the reflow request up to the parent
|
||||
mParent->ReflowDirtyChild(aPresShell, this);
|
||||
}
|
||||
else {
|
||||
NS_ERROR("No parent to pass the reflow request up to.");
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -571,8 +577,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||
// that are empty we force to empty so that things like collapsed
|
||||
// whitespace in an inline element don't affect the line-height.
|
||||
nsSize size;
|
||||
lineLayout->EndSpan(this, size,
|
||||
aMetrics.mComputeMEW ? &aMetrics.mMaxElementWidth : nsnull);
|
||||
lineLayout->EndSpan(this, size);
|
||||
if ((0 == size.height) && (0 == size.width) &&
|
||||
((nsnull != GetPrevInFlow()) || (nsnull != GetNextInFlow()))) {
|
||||
// This is a continuation of a previous inline. Therefore make
|
||||
@@ -581,9 +586,6 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||
aMetrics.height = 0;
|
||||
aMetrics.ascent = 0;
|
||||
aMetrics.descent = 0;
|
||||
if (aMetrics.mComputeMEW) {
|
||||
aMetrics.mMaxElementWidth = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Compute final width
|
||||
@@ -633,9 +635,6 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||
ListTag(stdout);
|
||||
printf(": metrics=%d,%d ascent=%d descent=%d\n",
|
||||
aMetrics.width, aMetrics.height, aMetrics.ascent, aMetrics.descent);
|
||||
if (aMetrics.mComputeMEW) {
|
||||
printf(" maxElementWidth %d\n", aMetrics.mMaxElementWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
@@ -652,7 +651,7 @@ void MarkPercentAwareFrame(nsPresContext *aPresContext,
|
||||
nsInlineFrame *aInline,
|
||||
nsIFrame *aFrame)
|
||||
{
|
||||
if (aFrame->GetStateBits() & NS_FRAME_REPLACED_ELEMENT)
|
||||
if (aFrame->IsFrameOfType(nsIFrame::eReplaced))
|
||||
{ // aFrame is a replaced element, check it's style
|
||||
if (nsLineLayout::IsPercentageAwareReplacedElement(aPresContext, aFrame)) {
|
||||
SetContainsPercentAwareChild(aInline);
|
||||
@@ -1190,20 +1189,13 @@ nsPositionedInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||
nscoord containingBlockHeight =
|
||||
aDesiredSize.height - computedBorder.TopBottom();
|
||||
|
||||
// Do any incremental reflows ... would be nice to merge with
|
||||
// the reflows below but that would be more work, and more risky
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState,
|
||||
containingBlockWidth,
|
||||
containingBlockHeight);
|
||||
}
|
||||
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
// Don't include this frame's bounds, nor its inline descendants' bounds,
|
||||
// and don't store the overflow property.
|
||||
// That will all be done by nsLineLayout::RelativePositionFrames.
|
||||
rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
|
||||
containingBlockWidth, containingBlockHeight,
|
||||
PR_TRUE, PR_TRUE, // XXX could be optimized
|
||||
&aDesiredSize.mOverflowArea);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user