From bec31309df112d302eeb1bdf287d97ce88e6bc12 Mon Sep 17 00:00:00 2001 From: troy Date: Mon, 6 Jul 1998 21:39:23 +0000 Subject: [PATCH] Incremental reflow work-in-progress --- layout/html/table/src/nsTableFrame.cpp | 124 +++++++++++++----- layout/html/table/src/nsTableFrame.h | 5 + .../html/table/src/nsTableRowGroupFrame.cpp | 32 ++--- layout/tables/nsTableFrame.cpp | 124 +++++++++++++----- layout/tables/nsTableFrame.h | 5 + layout/tables/nsTableRowGroupFrame.cpp | 32 ++--- 6 files changed, 210 insertions(+), 112 deletions(-) diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp index bc9e906f7f6..7a3481f3209 100644 --- a/layout/html/table/src/nsTableFrame.cpp +++ b/layout/html/table/src/nsTableFrame.cpp @@ -83,8 +83,6 @@ CellData::~CellData() struct InnerTableReflowState { - // The body's style molecule - // Our reflow state const nsReflowState& reflowState; @@ -1051,6 +1049,47 @@ PRBool nsTableFrame::NeedsReflow(const nsSize& aMaxSize) return result; } +nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext, + InnerTableReflowState& aState, + nsIFrame* aKidFrame, + nscoord aDeltaY) +{ + nsIFrame* lastKidFrame = aKidFrame; + + if (aDeltaY != 0) { + // Move the frames that follow aKidFrame by aDeltaY + nsIFrame* kidFrame; + + aKidFrame->GetNextSibling(kidFrame); + while (nsnull != kidFrame) { + nsPoint origin; + + // XXX We can't just slide the child if it has a next-in-flow + kidFrame->GetOrigin(origin); + origin.y += aDeltaY; + + // XXX We need to send move notifications to the frame... + kidFrame->WillReflow(*aPresContext); + kidFrame->MoveTo(origin.x, origin.y); + + // Get the next frame + lastKidFrame = kidFrame; + kidFrame->GetNextSibling(kidFrame); + } + + } else { + // Get the last frame + LastChild(lastKidFrame); + } + + // Update our running y-offset to reflect the bottommost child + nsRect rect; + lastKidFrame->GetRect(rect); + aState.y = rect.YMost(); + + return NS_OK; +} + // SEC: TODO need to worry about continuing frames prev/next in flow for splitting across pages. // SEC: TODO need to keep "first pass done" state, update it when ContentChanged notifications come in @@ -1085,9 +1124,22 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, PreReflowCheck(); #endif + // Initialize out parameter + if (nsnull != aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = 0; + aDesiredSize.maxElementSize->height = 0; + } + aStatus = NS_FRAME_COMPLETE; if (eReflowReason_Incremental == aReflowState.reason) { + const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin myBorderPadding; + mySpacing->CalcBorderPaddingFor(this, myBorderPadding); + + InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); + nsIFrame* target; aReflowState.reflowCommand->GetTarget(target); if (this == target) { @@ -1098,6 +1150,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsIFrame* kidFrame; aReflowState.reflowCommand->GetNext(kidFrame); + // Remember the old rect + nsRect oldKidRect; + kidFrame->GetRect(oldKidRect); + // Pass along the reflow command nsReflowMetrics desiredSize(nsnull); // XXX Correctly compute the available space... @@ -1105,14 +1161,21 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, kidFrame->WillReflow(*aPresContext); aStatus = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState); + // Resize the row group frame + nsRect kidRect; + kidFrame->GetRect(kidRect); + kidFrame->SizeTo(desiredSize.width, desiredSize.height); + +#if 1 // XXX For the time being just fall through and treat it like a // pass 2 reflow... mPass = kPASS_SECOND; - -#if 0 +#else // XXX Hack... + AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, desiredSize.height - + oldKidRect.height); aDesiredSize.width = mRect.width; - aDesiredSize.height = mRect.height; + aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; return NS_OK; #endif } @@ -1146,6 +1209,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, // set aDesiredSize and aMaxElementSize } + if (gsDebugNT==PR_TRUE) + { + if (nsnull!=aDesiredSize.maxElementSize) + printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n", + this, aDesiredSize.width, aDesiredSize.height, + aDesiredSize.maxElementSize->width, aDesiredSize.maxElementSize->height); + else + printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and NSNULL aMaxElementSize\n", + this, aDesiredSize.width, aDesiredSize.height); + } + #ifdef NS_DEBUG PostReflowCheck(aStatus); #endif @@ -1339,6 +1413,13 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, nsReflowStatus result = NS_FRAME_COMPLETE; + const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin myBorderPadding; + mySpacing->CalcBorderPaddingFor(this, myBorderPadding); + + InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); + // now that we've computed the column width information, reflow all children nsIContent* c = mContent; NS_ASSERTION(nsnull != c, "null kid"); @@ -1352,25 +1433,12 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, //PreReflowCheck(); #endif - // Initialize out parameter - if (nsnull != aDesiredSize.maxElementSize) { - aDesiredSize.maxElementSize->width = 0; - aDesiredSize.maxElementSize->height = 0; - } - PRBool reflowMappedOK = PR_TRUE; nsReflowStatus status = NS_FRAME_COMPLETE; // Check for an overflow list MoveOverflowToChildList(); - const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) - mStyleContext->GetStyleData(eStyleStruct_Spacing); - nsMargin myBorderPadding; - mySpacing->CalcBorderPaddingFor(this, myBorderPadding); - - InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); - // Reflow the existing frames if (nsnull != mFirstChild) { reflowMappedOK = ReflowMappedChildren(aPresContext, state, aDesiredSize.maxElementSize); @@ -1403,6 +1471,9 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } // Return our size and our status + aDesiredSize.width = aReflowState.maxSize.width; + aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; + if (NS_FRAME_IS_NOT_COMPLETE(status)) { // Don't forget to add in the bottom margin from our last child. @@ -1414,23 +1485,6 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } } - // Return our desired rect - aDesiredSize.width = aReflowState.maxSize.width; - aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; - - if (gsDebugNT==PR_TRUE) - { - if (nsnull!=aDesiredSize.maxElementSize) - printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n", - this, aDesiredSize.width, aDesiredSize.height, - aDesiredSize.maxElementSize->width, aDesiredSize.maxElementSize->height); - else - printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and NSNULL aMaxElementSize\n", - this, aDesiredSize.width, aDesiredSize.height); - } - - // SEC: assign our real width and height based on this reflow step and return - mPass = kPASS_UNDEFINED; // we're no longer in-process #ifdef NS_DEBUG diff --git a/layout/html/table/src/nsTableFrame.h b/layout/html/table/src/nsTableFrame.h index 654920edc84..e2276aa7278 100644 --- a/layout/html/table/src/nsTableFrame.h +++ b/layout/html/table/src/nsTableFrame.h @@ -271,6 +271,11 @@ protected: PRInt32 aMinCaptionWidth, PRInt32 mMaxCaptionWidth); + nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext, + InnerTableReflowState& aState, + nsIFrame* aKidFrame, + nscoord aDeltaY); + nscoord GetTopMarginFor(nsIPresContext* aCX, InnerTableReflowState& aState, const nsMargin& aKidMargin); diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp index 8bfe6629fd7..b0206e6e043 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -1043,25 +1043,11 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aP LastChild(lastKidFrame); } -#if 0 // Update our running y-offset to reflect the bottommost child nsRect rect; - lastKidFrame->GetRect(rect); aState.y = rect.YMost(); - // Get the bottom margin for the last child frame - const nsStyleSpacing* kidSpacing; - lastKidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing); - nsMargin margin; - kidSpacing->CalcMarginFor(lastKidFrame, margin); - if (margin.bottom < 0) { - aState.prevMaxNegBottomMargin = -margin.bottom; - } else { - aState.prevMaxPosBottomMargin = margin.bottom; - } -#endif - return NS_OK; } @@ -1102,12 +1088,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, nsIFrame* kidFrame; aReflowState.reflowCommand->GetNext(kidFrame); - // Pass along the reflow command - nsRect oldKidRect; - nsReflowMetrics desiredSize(nsnull); + // Remember the old rect + nsRect oldKidRect; kidFrame->GetRect(oldKidRect); + + // Pass along the reflow command // XXX Correctly compute the available space... - nsReflowState kidReflowState(kidFrame, aReflowState, aReflowState.maxSize); + nsReflowState kidReflowState(kidFrame, aReflowState, aReflowState.maxSize); + nsReflowMetrics desiredSize(nsnull); kidFrame->WillReflow(*aPresContext); aStatus = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState); @@ -1117,10 +1105,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, kidFrame->SizeTo(desiredSize.width, desiredSize.height); // Adjust the frames that follow... - AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, - kidRect.YMost() - oldKidRect.YMost()); + AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, desiredSize.height - + oldKidRect.height); - // XXX Compute desired size... + // Return of desired size + aDesiredSize.width = aReflowState.maxSize.width; + aDesiredSize.height = state.y; } else { PRBool reflowMappedOK = PR_TRUE; diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index bc9e906f7f6..7a3481f3209 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -83,8 +83,6 @@ CellData::~CellData() struct InnerTableReflowState { - // The body's style molecule - // Our reflow state const nsReflowState& reflowState; @@ -1051,6 +1049,47 @@ PRBool nsTableFrame::NeedsReflow(const nsSize& aMaxSize) return result; } +nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext, + InnerTableReflowState& aState, + nsIFrame* aKidFrame, + nscoord aDeltaY) +{ + nsIFrame* lastKidFrame = aKidFrame; + + if (aDeltaY != 0) { + // Move the frames that follow aKidFrame by aDeltaY + nsIFrame* kidFrame; + + aKidFrame->GetNextSibling(kidFrame); + while (nsnull != kidFrame) { + nsPoint origin; + + // XXX We can't just slide the child if it has a next-in-flow + kidFrame->GetOrigin(origin); + origin.y += aDeltaY; + + // XXX We need to send move notifications to the frame... + kidFrame->WillReflow(*aPresContext); + kidFrame->MoveTo(origin.x, origin.y); + + // Get the next frame + lastKidFrame = kidFrame; + kidFrame->GetNextSibling(kidFrame); + } + + } else { + // Get the last frame + LastChild(lastKidFrame); + } + + // Update our running y-offset to reflect the bottommost child + nsRect rect; + lastKidFrame->GetRect(rect); + aState.y = rect.YMost(); + + return NS_OK; +} + // SEC: TODO need to worry about continuing frames prev/next in flow for splitting across pages. // SEC: TODO need to keep "first pass done" state, update it when ContentChanged notifications come in @@ -1085,9 +1124,22 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, PreReflowCheck(); #endif + // Initialize out parameter + if (nsnull != aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width = 0; + aDesiredSize.maxElementSize->height = 0; + } + aStatus = NS_FRAME_COMPLETE; if (eReflowReason_Incremental == aReflowState.reason) { + const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin myBorderPadding; + mySpacing->CalcBorderPaddingFor(this, myBorderPadding); + + InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); + nsIFrame* target; aReflowState.reflowCommand->GetTarget(target); if (this == target) { @@ -1098,6 +1150,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsIFrame* kidFrame; aReflowState.reflowCommand->GetNext(kidFrame); + // Remember the old rect + nsRect oldKidRect; + kidFrame->GetRect(oldKidRect); + // Pass along the reflow command nsReflowMetrics desiredSize(nsnull); // XXX Correctly compute the available space... @@ -1105,14 +1161,21 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, kidFrame->WillReflow(*aPresContext); aStatus = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState); + // Resize the row group frame + nsRect kidRect; + kidFrame->GetRect(kidRect); + kidFrame->SizeTo(desiredSize.width, desiredSize.height); + +#if 1 // XXX For the time being just fall through and treat it like a // pass 2 reflow... mPass = kPASS_SECOND; - -#if 0 +#else // XXX Hack... + AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, desiredSize.height - + oldKidRect.height); aDesiredSize.width = mRect.width; - aDesiredSize.height = mRect.height; + aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; return NS_OK; #endif } @@ -1146,6 +1209,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, // set aDesiredSize and aMaxElementSize } + if (gsDebugNT==PR_TRUE) + { + if (nsnull!=aDesiredSize.maxElementSize) + printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n", + this, aDesiredSize.width, aDesiredSize.height, + aDesiredSize.maxElementSize->width, aDesiredSize.maxElementSize->height); + else + printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and NSNULL aMaxElementSize\n", + this, aDesiredSize.width, aDesiredSize.height); + } + #ifdef NS_DEBUG PostReflowCheck(aStatus); #endif @@ -1339,6 +1413,13 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, nsReflowStatus result = NS_FRAME_COMPLETE; + const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) + mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin myBorderPadding; + mySpacing->CalcBorderPaddingFor(this, myBorderPadding); + + InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); + // now that we've computed the column width information, reflow all children nsIContent* c = mContent; NS_ASSERTION(nsnull != c, "null kid"); @@ -1352,25 +1433,12 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, //PreReflowCheck(); #endif - // Initialize out parameter - if (nsnull != aDesiredSize.maxElementSize) { - aDesiredSize.maxElementSize->width = 0; - aDesiredSize.maxElementSize->height = 0; - } - PRBool reflowMappedOK = PR_TRUE; nsReflowStatus status = NS_FRAME_COMPLETE; // Check for an overflow list MoveOverflowToChildList(); - const nsStyleSpacing* mySpacing = (const nsStyleSpacing*) - mStyleContext->GetStyleData(eStyleStruct_Spacing); - nsMargin myBorderPadding; - mySpacing->CalcBorderPaddingFor(this, myBorderPadding); - - InnerTableReflowState state(aPresContext, aReflowState, myBorderPadding); - // Reflow the existing frames if (nsnull != mFirstChild) { reflowMappedOK = ReflowMappedChildren(aPresContext, state, aDesiredSize.maxElementSize); @@ -1403,6 +1471,9 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } // Return our size and our status + aDesiredSize.width = aReflowState.maxSize.width; + aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; + if (NS_FRAME_IS_NOT_COMPLETE(status)) { // Don't forget to add in the bottom margin from our last child. @@ -1414,23 +1485,6 @@ nsReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext, } } - // Return our desired rect - aDesiredSize.width = aReflowState.maxSize.width; - aDesiredSize.height = state.y + myBorderPadding.top + myBorderPadding.bottom; - - if (gsDebugNT==PR_TRUE) - { - if (nsnull!=aDesiredSize.maxElementSize) - printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and aMaxElementSize=%d,%d\n", - this, aDesiredSize.width, aDesiredSize.height, - aDesiredSize.maxElementSize->width, aDesiredSize.maxElementSize->height); - else - printf("%p: Inner table reflow complete, returning aDesiredSize = %d,%d and NSNULL aMaxElementSize\n", - this, aDesiredSize.width, aDesiredSize.height); - } - - // SEC: assign our real width and height based on this reflow step and return - mPass = kPASS_UNDEFINED; // we're no longer in-process #ifdef NS_DEBUG diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 654920edc84..e2276aa7278 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -271,6 +271,11 @@ protected: PRInt32 aMinCaptionWidth, PRInt32 mMaxCaptionWidth); + nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext, + InnerTableReflowState& aState, + nsIFrame* aKidFrame, + nscoord aDeltaY); + nscoord GetTopMarginFor(nsIPresContext* aCX, InnerTableReflowState& aState, const nsMargin& aKidMargin); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 8bfe6629fd7..b0206e6e043 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1043,25 +1043,11 @@ nsresult nsTableRowGroupFrame::AdjustSiblingsAfterReflow(nsIPresContext* aP LastChild(lastKidFrame); } -#if 0 // Update our running y-offset to reflect the bottommost child nsRect rect; - lastKidFrame->GetRect(rect); aState.y = rect.YMost(); - // Get the bottom margin for the last child frame - const nsStyleSpacing* kidSpacing; - lastKidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing); - nsMargin margin; - kidSpacing->CalcMarginFor(lastKidFrame, margin); - if (margin.bottom < 0) { - aState.prevMaxNegBottomMargin = -margin.bottom; - } else { - aState.prevMaxPosBottomMargin = margin.bottom; - } -#endif - return NS_OK; } @@ -1102,12 +1088,14 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, nsIFrame* kidFrame; aReflowState.reflowCommand->GetNext(kidFrame); - // Pass along the reflow command - nsRect oldKidRect; - nsReflowMetrics desiredSize(nsnull); + // Remember the old rect + nsRect oldKidRect; kidFrame->GetRect(oldKidRect); + + // Pass along the reflow command // XXX Correctly compute the available space... - nsReflowState kidReflowState(kidFrame, aReflowState, aReflowState.maxSize); + nsReflowState kidReflowState(kidFrame, aReflowState, aReflowState.maxSize); + nsReflowMetrics desiredSize(nsnull); kidFrame->WillReflow(*aPresContext); aStatus = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState); @@ -1117,10 +1105,12 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, kidFrame->SizeTo(desiredSize.width, desiredSize.height); // Adjust the frames that follow... - AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, - kidRect.YMost() - oldKidRect.YMost()); + AdjustSiblingsAfterReflow(aPresContext, state, kidFrame, desiredSize.height - + oldKidRect.height); - // XXX Compute desired size... + // Return of desired size + aDesiredSize.width = aReflowState.maxSize.width; + aDesiredSize.height = state.y; } else { PRBool reflowMappedOK = PR_TRUE;