зеркало из https://github.com/mozilla/gecko-dev.git
Work in progress for incremental reflow
This commit is contained in:
Родитель
1d25c373d2
Коммит
36e45e1fac
|
@ -202,36 +202,110 @@ nsresult nsTableOuterFrame::RecoverState(OuterTableReflowState& aState,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsTableOuterFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& 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->MoveTo(origin.x, origin.y);
|
||||||
|
|
||||||
|
// Get the next frame
|
||||||
|
lastKidFrame = kidFrame;
|
||||||
|
kidFrame->GetNextSibling(kidFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Get the last frame
|
||||||
|
LastChild(lastKidFrame);
|
||||||
|
|
||||||
|
// Set our running y-offset
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
nsReflowMetrics& aDesiredSize,
|
nsReflowMetrics& aDesiredSize,
|
||||||
const nsReflowState& aReflowState,
|
const nsReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus)
|
nsReflowStatus& aStatus)
|
||||||
{
|
{
|
||||||
OuterTableReflowState state(aPresContext, aReflowState);
|
|
||||||
|
|
||||||
// Get the next frame in the reflow chain
|
// Get the next frame in the reflow chain
|
||||||
nsIFrame* next;
|
nsIFrame* kidFrame;
|
||||||
aReflowState.reflowCommand->GetNext(next);
|
aReflowState.reflowCommand->GetNext(kidFrame);
|
||||||
|
|
||||||
// Recover the reflow state
|
// Recover our reflow state
|
||||||
RecoverState(state, next);
|
RecoverState(aState, kidFrame);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Pass along the reflow command
|
// Pass along the reflow command
|
||||||
// XXX Check if we're the target...
|
// XXX Check if we're the target...
|
||||||
nsReflowState reflowState(next, aReflowState, kidMaxSize);
|
nsSize kidMaxElementSize(0,0);
|
||||||
|
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
|
||||||
|
&kidMaxElementSize : nsnull;
|
||||||
|
nsReflowMetrics kidSize(pKidMaxElementSize);
|
||||||
|
nsRect oldKidRect;
|
||||||
|
|
||||||
SetReflowState(aState, next);
|
kidFrame->GetRect(oldKidRect);
|
||||||
next->WillReflow(*aPresContext);
|
SetReflowState(aState, kidFrame);
|
||||||
status = ReflowChild(next, aPresContext, kidSize, state.availSize,
|
|
||||||
pKidMaxElementSize, state);
|
|
||||||
|
|
||||||
// Place the child frame
|
// Get the top margin for the child
|
||||||
|
const nsStyleSpacing* kidSpacing;
|
||||||
|
kidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing);
|
||||||
|
nsMargin kidMargin;
|
||||||
|
kidSpacing->CalcMarginFor(kidFrame, kidMargin);
|
||||||
|
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
|
||||||
|
nscoord bottomMargin = kidMargin.bottom;
|
||||||
|
|
||||||
|
// Figure out the amount of available size for the child (subtract
|
||||||
|
// off the top margin we are going to apply to it)
|
||||||
|
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||||
|
aState.availSize.height -= topMargin;
|
||||||
|
}
|
||||||
|
// Subtract off for left and right margin
|
||||||
|
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||||
|
aState.availSize.width -= kidMargin.left + kidMargin.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now do the reflow
|
||||||
aState.y += topMargin;
|
aState.y += topMargin;
|
||||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
kidFrame->WillReflow(*aPresContext);
|
||||||
kidRect.x += kidMargin.left;
|
kidFrame->MoveTo(kidMargin.left, aState.y);
|
||||||
kidRect.y += aState.y;
|
aStatus = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
pKidMaxElementSize, aState);
|
||||||
|
|
||||||
|
// Place the child frame after taking into account its margin
|
||||||
|
nsRect kidRect (kidMargin.left, aState.y, kidSize.width, kidSize.height);
|
||||||
|
PlaceChild(aState, kidFrame, kidRect, aDesiredSize.maxElementSize, kidMaxElementSize);
|
||||||
if (bottomMargin < 0) {
|
if (bottomMargin < 0) {
|
||||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,9 +313,8 @@ nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the frames that follow
|
// Adjust the frames that follow
|
||||||
#endif
|
return AdjustSiblingsAfterReflow(aPresContext, aState, kidFrame,
|
||||||
|
kidRect.YMost() - oldKidRect.YMost());
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -276,8 +349,11 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
aDesiredSize.maxElementSize->height = 0;
|
aDesiredSize.maxElementSize->height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize our local reflow state
|
||||||
|
OuterTableReflowState state(aPresContext, aReflowState);
|
||||||
|
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||||
; // IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
IncrementalReflow(aPresContext, state, aDesiredSize, aReflowState, aStatus);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PRBool reflowMappedOK = PR_TRUE;
|
PRBool reflowMappedOK = PR_TRUE;
|
||||||
|
@ -305,8 +381,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
OuterTableReflowState state(aPresContext, aReflowState);
|
|
||||||
|
|
||||||
// lay out captions pass 1, if necessary
|
// lay out captions pass 1, if necessary
|
||||||
if (PR_FALSE==IsFirstPassValid())
|
if (PR_FALSE==IsFirstPassValid())
|
||||||
{
|
{
|
||||||
|
@ -383,6 +457,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FRAME_IS_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_COMPLETE(aStatus)) {
|
||||||
// Don't forget to add in the bottom margin from our last child.
|
// Don't forget to add in the bottom margin from our last child.
|
||||||
|
@ -423,7 +498,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
// replace with a check that does not assume linear placement of children
|
// replace with a check that does not assume linear placement of children
|
||||||
// PostReflowCheck(status);
|
// PostReflowCheck(status);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
|
|
@ -229,10 +229,14 @@ protected:
|
||||||
|
|
||||||
nsresult RecoverState(OuterTableReflowState& aState, nsIFrame* aKidFrame);
|
nsresult RecoverState(OuterTableReflowState& aState, nsIFrame* aKidFrame);
|
||||||
nsresult IncrementalReflow(nsIPresContext* aPresContext,
|
nsresult IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
nsReflowMetrics& aDesiredSize,
|
nsReflowMetrics& aDesiredSize,
|
||||||
const nsReflowState& aReflowState,
|
const nsReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
|
nsIFrame* aKidFrame,
|
||||||
|
nscoord aDeltaY);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** used to keep track of this frame's children */
|
/** used to keep track of this frame's children */
|
||||||
|
|
|
@ -202,36 +202,110 @@ nsresult nsTableOuterFrame::RecoverState(OuterTableReflowState& aState,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsTableOuterFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& 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->MoveTo(origin.x, origin.y);
|
||||||
|
|
||||||
|
// Get the next frame
|
||||||
|
lastKidFrame = kidFrame;
|
||||||
|
kidFrame->GetNextSibling(kidFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Get the last frame
|
||||||
|
LastChild(lastKidFrame);
|
||||||
|
|
||||||
|
// Set our running y-offset
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
nsReflowMetrics& aDesiredSize,
|
nsReflowMetrics& aDesiredSize,
|
||||||
const nsReflowState& aReflowState,
|
const nsReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus)
|
nsReflowStatus& aStatus)
|
||||||
{
|
{
|
||||||
OuterTableReflowState state(aPresContext, aReflowState);
|
|
||||||
|
|
||||||
// Get the next frame in the reflow chain
|
// Get the next frame in the reflow chain
|
||||||
nsIFrame* next;
|
nsIFrame* kidFrame;
|
||||||
aReflowState.reflowCommand->GetNext(next);
|
aReflowState.reflowCommand->GetNext(kidFrame);
|
||||||
|
|
||||||
// Recover the reflow state
|
// Recover our reflow state
|
||||||
RecoverState(state, next);
|
RecoverState(aState, kidFrame);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Pass along the reflow command
|
// Pass along the reflow command
|
||||||
// XXX Check if we're the target...
|
// XXX Check if we're the target...
|
||||||
nsReflowState reflowState(next, aReflowState, kidMaxSize);
|
nsSize kidMaxElementSize(0,0);
|
||||||
|
nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ?
|
||||||
|
&kidMaxElementSize : nsnull;
|
||||||
|
nsReflowMetrics kidSize(pKidMaxElementSize);
|
||||||
|
nsRect oldKidRect;
|
||||||
|
|
||||||
SetReflowState(aState, next);
|
kidFrame->GetRect(oldKidRect);
|
||||||
next->WillReflow(*aPresContext);
|
SetReflowState(aState, kidFrame);
|
||||||
status = ReflowChild(next, aPresContext, kidSize, state.availSize,
|
|
||||||
pKidMaxElementSize, state);
|
|
||||||
|
|
||||||
// Place the child frame
|
// Get the top margin for the child
|
||||||
|
const nsStyleSpacing* kidSpacing;
|
||||||
|
kidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing);
|
||||||
|
nsMargin kidMargin;
|
||||||
|
kidSpacing->CalcMarginFor(kidFrame, kidMargin);
|
||||||
|
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
|
||||||
|
nscoord bottomMargin = kidMargin.bottom;
|
||||||
|
|
||||||
|
// Figure out the amount of available size for the child (subtract
|
||||||
|
// off the top margin we are going to apply to it)
|
||||||
|
if (PR_FALSE == aState.unconstrainedHeight) {
|
||||||
|
aState.availSize.height -= topMargin;
|
||||||
|
}
|
||||||
|
// Subtract off for left and right margin
|
||||||
|
if (PR_FALSE == aState.unconstrainedWidth) {
|
||||||
|
aState.availSize.width -= kidMargin.left + kidMargin.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now do the reflow
|
||||||
aState.y += topMargin;
|
aState.y += topMargin;
|
||||||
nsRect kidRect (0, 0, kidSize.width, kidSize.height);
|
kidFrame->WillReflow(*aPresContext);
|
||||||
kidRect.x += kidMargin.left;
|
kidFrame->MoveTo(kidMargin.left, aState.y);
|
||||||
kidRect.y += aState.y;
|
aStatus = ReflowChild(kidFrame, aPresContext, kidSize, aState.availSize,
|
||||||
PlaceChild(aState, kidFrame, kidRect, aMaxElementSize, kidMaxElementSize);
|
pKidMaxElementSize, aState);
|
||||||
|
|
||||||
|
// Place the child frame after taking into account its margin
|
||||||
|
nsRect kidRect (kidMargin.left, aState.y, kidSize.width, kidSize.height);
|
||||||
|
PlaceChild(aState, kidFrame, kidRect, aDesiredSize.maxElementSize, kidMaxElementSize);
|
||||||
if (bottomMargin < 0) {
|
if (bottomMargin < 0) {
|
||||||
aState.prevMaxNegBottomMargin = -bottomMargin;
|
aState.prevMaxNegBottomMargin = -bottomMargin;
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,9 +313,8 @@ nsresult nsTableOuterFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust the frames that follow
|
// Adjust the frames that follow
|
||||||
#endif
|
return AdjustSiblingsAfterReflow(aPresContext, aState, kidFrame,
|
||||||
|
kidRect.YMost() - oldKidRect.YMost());
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -276,8 +349,11 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
aDesiredSize.maxElementSize->height = 0;
|
aDesiredSize.maxElementSize->height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize our local reflow state
|
||||||
|
OuterTableReflowState state(aPresContext, aReflowState);
|
||||||
|
|
||||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||||
; // IncrementalReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
IncrementalReflow(aPresContext, state, aDesiredSize, aReflowState, aStatus);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PRBool reflowMappedOK = PR_TRUE;
|
PRBool reflowMappedOK = PR_TRUE;
|
||||||
|
@ -305,8 +381,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
OuterTableReflowState state(aPresContext, aReflowState);
|
|
||||||
|
|
||||||
// lay out captions pass 1, if necessary
|
// lay out captions pass 1, if necessary
|
||||||
if (PR_FALSE==IsFirstPassValid())
|
if (PR_FALSE==IsFirstPassValid())
|
||||||
{
|
{
|
||||||
|
@ -383,6 +457,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FRAME_IS_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_COMPLETE(aStatus)) {
|
||||||
// Don't forget to add in the bottom margin from our last child.
|
// Don't forget to add in the bottom margin from our last child.
|
||||||
|
@ -423,7 +498,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
|
||||||
// replace with a check that does not assume linear placement of children
|
// replace with a check that does not assume linear placement of children
|
||||||
// PostReflowCheck(status);
|
// PostReflowCheck(status);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
|
|
@ -229,10 +229,14 @@ protected:
|
||||||
|
|
||||||
nsresult RecoverState(OuterTableReflowState& aState, nsIFrame* aKidFrame);
|
nsresult RecoverState(OuterTableReflowState& aState, nsIFrame* aKidFrame);
|
||||||
nsresult IncrementalReflow(nsIPresContext* aPresContext,
|
nsresult IncrementalReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
nsReflowMetrics& aDesiredSize,
|
nsReflowMetrics& aDesiredSize,
|
||||||
const nsReflowState& aReflowState,
|
const nsReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
nsresult AdjustSiblingsAfterReflow(nsIPresContext* aPresContext,
|
||||||
|
OuterTableReflowState& aState,
|
||||||
|
nsIFrame* aKidFrame,
|
||||||
|
nscoord aDeltaY);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** used to keep track of this frame's children */
|
/** used to keep track of this frame's children */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче