Incremental reflow work-in-progress

This commit is contained in:
troy 1998-07-06 21:39:23 +00:00
parent 0cc888b446
commit 35c2e6b45c
6 changed files with 210 additions and 112 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;