зеркало из https://github.com/mozilla/pjs.git
Fix bug 416073: invalidate more things as needed during table reflow to prevent glitches. r+sr=roc
This commit is contained in:
Родитель
7d5dd48b52
Коммит
d6526d103e
|
@ -2486,3 +2486,21 @@ nsLayoutUtils::GetTextRunFlagsForStyle(nsStyleContext* aStyleContext,
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsLayoutUtils::GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
|
||||||
|
nsRect* aHStrip, nsRect* aVStrip) {
|
||||||
|
NS_ASSERTION(aR1.TopLeft() == aR2.TopLeft(),
|
||||||
|
"expected rects at the same position");
|
||||||
|
nsRect unionRect(aR1.x, aR1.y, PR_MAX(aR1.width, aR2.width),
|
||||||
|
PR_MAX(aR1.height, aR2.height));
|
||||||
|
nscoord VStripStart = PR_MIN(aR1.width, aR2.width);
|
||||||
|
nscoord HStripStart = PR_MIN(aR1.height, aR2.height);
|
||||||
|
*aVStrip = unionRect;
|
||||||
|
aVStrip->x += VStripStart;
|
||||||
|
aVStrip->width -= VStripStart;
|
||||||
|
*aHStrip = unionRect;
|
||||||
|
aHStrip->y += HStripStart;
|
||||||
|
aHStrip->height -= HStripStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -754,6 +754,15 @@ public:
|
||||||
const nsStyleText* aStyleText,
|
const nsStyleText* aStyleText,
|
||||||
const nsStyleFont* aStyleFont);
|
const nsStyleFont* aStyleFont);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes two rectangles whose origins must be the same, and computes
|
||||||
|
* the difference between their union and their intersection as two
|
||||||
|
* rectangles. (This difference is a superset of the difference
|
||||||
|
* between the two rectangles.)
|
||||||
|
*/
|
||||||
|
static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
|
||||||
|
nsRect* aHStrip, nsRect* aVStrip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the nsIFrame::GetUsedXXX assertions in nsFrame.cpp should
|
* Indicates if the nsIFrame::GetUsedXXX assertions in nsFrame.cpp should
|
||||||
* disabled.
|
* disabled.
|
||||||
|
|
|
@ -2234,28 +2234,6 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes two rectangles whose origins must be the same, and computes
|
|
||||||
* the difference between their union and their intersection as two
|
|
||||||
* rectangles. (This difference is a superset of the difference
|
|
||||||
* between the two rectangles.)
|
|
||||||
*/
|
|
||||||
static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
|
|
||||||
nsRect* aHStrip, nsRect* aVStrip) {
|
|
||||||
NS_ASSERTION(aR1.TopLeft() == aR2.TopLeft(),
|
|
||||||
"expected rects at the same position");
|
|
||||||
nsRect unionRect(aR1.x, aR1.y, PR_MAX(aR1.width, aR2.width),
|
|
||||||
PR_MAX(aR1.height, aR2.height));
|
|
||||||
nscoord VStripStart = PR_MIN(aR1.width, aR2.width);
|
|
||||||
nscoord HStripStart = PR_MIN(aR1.height, aR2.height);
|
|
||||||
*aVStrip = unionRect;
|
|
||||||
aVStrip->x += VStripStart;
|
|
||||||
aVStrip->width -= VStripStart;
|
|
||||||
*aHStrip = unionRect;
|
|
||||||
aHStrip->y += HStripStart;
|
|
||||||
aHStrip->height -= HStripStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflow a line. The line will either contain a single block frame
|
* Reflow a line. The line will either contain a single block frame
|
||||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||||
|
@ -2305,10 +2283,11 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState,
|
||||||
} else {
|
} else {
|
||||||
nsRect combinedAreaHStrip, combinedAreaVStrip;
|
nsRect combinedAreaHStrip, combinedAreaVStrip;
|
||||||
nsRect boundsHStrip, boundsVStrip;
|
nsRect boundsHStrip, boundsVStrip;
|
||||||
GetRectDifferenceStrips(oldBounds, newBounds,
|
nsLayoutUtils::GetRectDifferenceStrips(oldBounds, newBounds,
|
||||||
&boundsHStrip, &boundsVStrip);
|
&boundsHStrip, &boundsVStrip);
|
||||||
GetRectDifferenceStrips(oldCombinedArea, lineCombinedArea,
|
nsLayoutUtils::GetRectDifferenceStrips(oldCombinedArea, lineCombinedArea,
|
||||||
&combinedAreaHStrip, &combinedAreaVStrip);
|
&combinedAreaHStrip,
|
||||||
|
&combinedAreaVStrip);
|
||||||
|
|
||||||
#ifdef NOISY_BLOCK_INVALIDATE
|
#ifdef NOISY_BLOCK_INVALIDATE
|
||||||
printf("%p invalidate boundsVStrip (%d, %d, %d, %d)\n",
|
printf("%p invalidate boundsVStrip (%d, %d, %d, %d)\n",
|
||||||
|
|
|
@ -743,6 +743,11 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame,
|
||||||
aKidFrame->WillReflow(aPresContext);
|
aKidFrame->WillReflow(aPresContext);
|
||||||
|
|
||||||
if (0 == (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
|
if (0 == (aFlags & NS_FRAME_NO_MOVE_FRAME)) {
|
||||||
|
if ((aFlags & NS_FRAME_INVALIDATE_ON_MOVE) &&
|
||||||
|
!(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) &&
|
||||||
|
aKidFrame->GetPosition() != nsPoint(aX, aY)) {
|
||||||
|
aKidFrame->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
aKidFrame->SetPosition(nsPoint(aX, aY));
|
aKidFrame->SetPosition(nsPoint(aX, aY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,9 @@
|
||||||
#define NS_FRAME_NO_MOVE_FRAME (0x0002 | NS_FRAME_NO_MOVE_VIEW)
|
#define NS_FRAME_NO_MOVE_FRAME (0x0002 | NS_FRAME_NO_MOVE_VIEW)
|
||||||
#define NS_FRAME_NO_SIZE_VIEW 0x0004
|
#define NS_FRAME_NO_SIZE_VIEW 0x0004
|
||||||
#define NS_FRAME_NO_VISIBILITY 0x0008
|
#define NS_FRAME_NO_VISIBILITY 0x0008
|
||||||
|
// Only applies to ReflowChild: if true, invalidate the child if it's
|
||||||
|
// being moved
|
||||||
|
#define NS_FRAME_INVALIDATE_ON_MOVE 0x0010
|
||||||
|
|
||||||
class nsOverflowContinuationTracker;
|
class nsOverflowContinuationTracker;
|
||||||
|
|
||||||
|
|
|
@ -3600,6 +3600,21 @@ nsIFrame::InvalidateInternal(const nsRect& aDamageRect, nscoord aX, nscoord aY,
|
||||||
InvalidateInternal(aDamageRect, aX + mRect.x, aY + mRect.y, this, aImmediate);
|
InvalidateInternal(aDamageRect, aX + mRect.x, aY + mRect.y, this, aImmediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIFrame::InvalidateRectDifference(const nsRect& aR1, const nsRect& aR2)
|
||||||
|
{
|
||||||
|
nsRect sizeHStrip, sizeVStrip;
|
||||||
|
nsLayoutUtils::GetRectDifferenceStrips(aR1, aR2, &sizeHStrip, &sizeVStrip);
|
||||||
|
Invalidate(sizeVStrip);
|
||||||
|
Invalidate(sizeHStrip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIFrame::InvalidateOverflowRect()
|
||||||
|
{
|
||||||
|
Invalidate(GetOverflowRect());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsIFrame::InvalidateRoot(const nsRect& aDamageRect,
|
nsIFrame::InvalidateRoot(const nsRect& aDamageRect,
|
||||||
nscoord aX, nscoord aY, PRBool aImmediate)
|
nscoord aX, nscoord aY, PRBool aImmediate)
|
||||||
|
|
|
@ -1655,6 +1655,21 @@ public:
|
||||||
nscoord aOffsetX, nscoord aOffsetY,
|
nscoord aOffsetX, nscoord aOffsetY,
|
||||||
nsIFrame* aForChild, PRBool aImmediate);
|
nsIFrame* aForChild, PRBool aImmediate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take two rectangles in the coordinate system of this frame which
|
||||||
|
* have the same origin and invalidate the difference between them.
|
||||||
|
* This is a helper method to be used when a frame is being resized.
|
||||||
|
*
|
||||||
|
* @param aR1 the first rectangle
|
||||||
|
* @param aR2 the second rectangle
|
||||||
|
*/
|
||||||
|
void InvalidateRectDifference(const nsRect& aR1, const nsRect& aR2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate the overflow rect of this frame
|
||||||
|
*/
|
||||||
|
void InvalidateOverflowRect();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes a rect that encompasses everything that might be painted by
|
* Computes a rect that encompasses everything that might be painted by
|
||||||
* this frame. This includes this frame, all its descendent frames, this
|
* this frame. This includes this frame, all its descendent frames, this
|
||||||
|
|
|
@ -593,6 +593,11 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
|
||||||
// if the content is larger than the cell height align from top
|
// if the content is larger than the cell height align from top
|
||||||
kidYTop = PR_MAX(0, kidYTop);
|
kidYTop = PR_MAX(0, kidYTop);
|
||||||
|
|
||||||
|
if (kidYTop != kidRect.y) {
|
||||||
|
// Invalidate at the old position first
|
||||||
|
firstKid->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
|
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop));
|
||||||
nsHTMLReflowMetrics desiredSize;
|
nsHTMLReflowMetrics desiredSize;
|
||||||
desiredSize.width = mRect.width;
|
desiredSize.width = mRect.width;
|
||||||
|
@ -604,6 +609,9 @@ void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent)
|
||||||
// Make sure any child views are correctly positioned. We know the inner table
|
// Make sure any child views are correctly positioned. We know the inner table
|
||||||
// cell won't have a view
|
// cell won't have a view
|
||||||
nsContainerFrame::PositionChildViews(firstKid);
|
nsContainerFrame::PositionChildViews(firstKid);
|
||||||
|
|
||||||
|
// Invalidate new overflow rect
|
||||||
|
firstKid->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
if (HasView()) {
|
if (HasView()) {
|
||||||
nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
|
nsContainerFrame::SyncFrameViewAfterReflow(PresContext(), this,
|
||||||
|
@ -861,15 +869,19 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPoint kidOrigin(leftInset, topInset);
|
nsPoint kidOrigin(leftInset, topInset);
|
||||||
|
nsRect origRect = firstKid->GetRect();
|
||||||
|
PRBool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
||||||
|
|
||||||
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
|
||||||
kidOrigin.x, kidOrigin.y, 0, aStatus);
|
kidOrigin.x, kidOrigin.y, NS_FRAME_INVALIDATE_ON_MOVE, aStatus);
|
||||||
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
|
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
|
||||||
// Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it
|
// Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it
|
||||||
//XXX should paginate overflow as overflow, but not in this patch (bug 379349)
|
//XXX should paginate overflow as overflow, but not in this patch (bug 379349)
|
||||||
NS_FRAME_SET_INCOMPLETE(aStatus);
|
NS_FRAME_SET_INCOMPLETE(aStatus);
|
||||||
printf("Set table cell incomplete %p\n", this);
|
printf("Set table cell incomplete %p\n", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXXbz is this invalidate actually needed, really?
|
||||||
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
|
||||||
Invalidate(GetOverflowRect(), PR_FALSE);
|
Invalidate(GetOverflowRect(), PR_FALSE);
|
||||||
}
|
}
|
||||||
|
@ -886,6 +898,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
||||||
FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
|
FinishReflowChild(firstKid, aPresContext, &kidReflowState, kidSize,
|
||||||
kidOrigin.x, kidOrigin.y, 0);
|
kidOrigin.x, kidOrigin.y, 0);
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(firstKid, origRect, firstReflow);
|
||||||
|
|
||||||
// first, compute the height which can be set w/o being restricted by aMaxSize.height
|
// first, compute the height which can be set w/o being restricted by aMaxSize.height
|
||||||
nscoord cellHeight = kidSize.height;
|
nscoord cellHeight = kidSize.height;
|
||||||
|
|
||||||
|
|
|
@ -1957,6 +1957,11 @@ NS_METHOD nsTableFrame::Reflow(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||||
|
// Fulfill the promise InvalidateFrame makes.
|
||||||
|
Invalidate(aDesiredSize.mOverflowArea);
|
||||||
|
}
|
||||||
|
|
||||||
FinishAndStoreOverflow(&aDesiredSize);
|
FinishAndStoreOverflow(&aDesiredSize);
|
||||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -2578,13 +2583,18 @@ nsTableFrame::InitChildReflowState(nsHTMLReflowState& aReflowState)
|
||||||
// aKidRect is relative to the upper-left origin of our frame
|
// aKidRect is relative to the upper-left origin of our frame
|
||||||
void nsTableFrame::PlaceChild(nsTableReflowState& aReflowState,
|
void nsTableFrame::PlaceChild(nsTableReflowState& aReflowState,
|
||||||
nsIFrame* aKidFrame,
|
nsIFrame* aKidFrame,
|
||||||
nsHTMLReflowMetrics& aKidDesiredSize)
|
nsHTMLReflowMetrics& aKidDesiredSize,
|
||||||
|
const nsRect& aOriginalKidRect)
|
||||||
{
|
{
|
||||||
|
PRBool isFirstReflow =
|
||||||
|
(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
||||||
|
|
||||||
// Place and size the child
|
// Place and size the child
|
||||||
FinishReflowChild(aKidFrame, PresContext(), nsnull, aKidDesiredSize,
|
FinishReflowChild(aKidFrame, PresContext(), nsnull, aKidDesiredSize,
|
||||||
aReflowState.x, aReflowState.y, 0);
|
aReflowState.x, aReflowState.y, 0);
|
||||||
|
|
||||||
|
InvalidateFrame(aKidFrame, aOriginalKidRect, isFirstReflow);
|
||||||
|
|
||||||
// Adjust the running y-offset
|
// Adjust the running y-offset
|
||||||
aReflowState.y += aKidDesiredSize.height;
|
aReflowState.y += aKidDesiredSize.height;
|
||||||
|
|
||||||
|
@ -2936,7 +2946,8 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||||
reorder = PR_TRUE;
|
reorder = PR_TRUE;
|
||||||
|
|
||||||
rv = ReflowChild(kidFrame, presContext, desiredSize, kidReflowState,
|
rv = ReflowChild(kidFrame, presContext, desiredSize, kidReflowState,
|
||||||
aReflowState.x, aReflowState.y, 0, aStatus);
|
aReflowState.x, aReflowState.y,
|
||||||
|
NS_FRAME_INVALIDATE_ON_MOVE, aStatus);
|
||||||
|
|
||||||
if (reorder) {
|
if (reorder) {
|
||||||
// reorder row groups the reflow may have changed the nextinflows
|
// reorder row groups the reflow may have changed the nextinflows
|
||||||
|
@ -2957,7 +2968,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||||
if (childX+1 < rowGroups.Length()) {
|
if (childX+1 < rowGroups.Length()) {
|
||||||
nsIFrame* nextRowGroupFrame = rowGroups[childX + 1];
|
nsIFrame* nextRowGroupFrame = rowGroups[childX + 1];
|
||||||
if (nextRowGroupFrame) {
|
if (nextRowGroupFrame) {
|
||||||
PlaceChild(aReflowState, kidFrame, desiredSize);
|
PlaceChild(aReflowState, kidFrame, desiredSize, oldKidRect);
|
||||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
PushChildren(rowGroups, childX + 1);
|
PushChildren(rowGroups, childX + 1);
|
||||||
aLastChildReflowed = kidFrame;
|
aLastChildReflowed = kidFrame;
|
||||||
|
@ -2988,7 +2999,7 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place the child
|
// Place the child
|
||||||
PlaceChild(aReflowState, kidFrame, desiredSize);
|
PlaceChild(aReflowState, kidFrame, desiredSize, oldKidRect);
|
||||||
|
|
||||||
// Remember where we just were in case we end up pushing children
|
// Remember where we just were in case we end up pushing children
|
||||||
prevKidFrame = kidFrame;
|
prevKidFrame = kidFrame;
|
||||||
|
@ -3036,10 +3047,14 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||||
-1, -1, PR_FALSE);
|
-1, -1, PR_FALSE);
|
||||||
InitChildReflowState(footerReflowState);
|
InitChildReflowState(footerReflowState);
|
||||||
aReflowState.y += cellSpacingY;
|
aReflowState.y += cellSpacingY;
|
||||||
|
|
||||||
|
nsRect origTfootRect = tfoot->GetRect();
|
||||||
|
|
||||||
nsReflowStatus footerStatus;
|
nsReflowStatus footerStatus;
|
||||||
rv = ReflowChild(tfoot, presContext, desiredSize, footerReflowState,
|
rv = ReflowChild(tfoot, presContext, desiredSize, footerReflowState,
|
||||||
aReflowState.x, aReflowState.y, 0, footerStatus);
|
aReflowState.x, aReflowState.y,
|
||||||
PlaceChild(aReflowState, tfoot, desiredSize);
|
NS_FRAME_INVALIDATE_ON_MOVE, footerStatus);
|
||||||
|
PlaceChild(aReflowState, tfoot, desiredSize, origTfootRect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3048,11 +3063,13 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
|
||||||
aReflowState.y += cellSpacingY;
|
aReflowState.y += cellSpacingY;
|
||||||
nsRect kidRect = kidFrame->GetRect();
|
nsRect kidRect = kidFrame->GetRect();
|
||||||
if (kidRect.y != aReflowState.y) {
|
if (kidRect.y != aReflowState.y) {
|
||||||
Invalidate(kidRect); // invalidate the old position
|
// invalidate the old position
|
||||||
|
kidFrame->InvalidateOverflowRect();
|
||||||
kidRect.y = aReflowState.y;
|
kidRect.y = aReflowState.y;
|
||||||
kidFrame->SetRect(kidRect); // move to the new position
|
kidFrame->SetRect(kidRect); // move to the new position
|
||||||
RePositionViews(kidFrame);
|
RePositionViews(kidFrame);
|
||||||
Invalidate(kidRect); // invalidate the new position
|
// invalidate the new position
|
||||||
|
kidFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
aReflowState.y += kidRect.height;
|
aReflowState.y += kidRect.height;
|
||||||
|
|
||||||
|
@ -3226,7 +3243,9 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
nscoord pctHeight = rowFrame->GetHeight(pctBasis);
|
nscoord pctHeight = rowFrame->GetHeight(pctBasis);
|
||||||
nscoord amountForRow = PR_MIN(aAmount - amountUsed, pctHeight - rowRect.height);
|
nscoord amountForRow = PR_MIN(aAmount - amountUsed, pctHeight - rowRect.height);
|
||||||
if (amountForRow > 0) {
|
if (amountForRow > 0) {
|
||||||
|
nsRect oldRowRect = rowRect;
|
||||||
rowRect.height += amountForRow;
|
rowRect.height += amountForRow;
|
||||||
|
// XXXbz we don't need to change rowRect.y to be yOriginRow?
|
||||||
rowFrame->SetRect(rowRect);
|
rowFrame->SetRect(rowRect);
|
||||||
yOriginRow += rowRect.height + cellSpacingY;
|
yOriginRow += rowRect.height + cellSpacingY;
|
||||||
yEndRG += rowRect.height + cellSpacingY;
|
yEndRG += rowRect.height + cellSpacingY;
|
||||||
|
@ -3234,12 +3253,17 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
amountUsedByRG += amountForRow;
|
amountUsedByRG += amountForRow;
|
||||||
//rowFrame->DidResize();
|
//rowFrame->DidResize();
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
|
||||||
|
rgFrame->InvalidateRectDifference(oldRowRect, rowRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0 && yOriginRow != rowRect.y &&
|
||||||
|
!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||||
|
rowFrame->InvalidateOverflowRect();
|
||||||
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
rowFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
yOriginRow += rowRect.height + cellSpacingY;
|
yOriginRow += rowRect.height + cellSpacingY;
|
||||||
yEndRG += rowRect.height + cellSpacingY;
|
yEndRG += rowRect.height + cellSpacingY;
|
||||||
|
@ -3247,15 +3271,27 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
rowFrame = rowFrame->GetNextRow();
|
rowFrame = rowFrame->GetNextRow();
|
||||||
}
|
}
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0) {
|
||||||
|
if (rgRect.y != yOriginRG) {
|
||||||
|
rgFrame->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect origRgRect = rgRect;
|
||||||
|
|
||||||
rgRect.y = yOriginRG;
|
rgRect.y = yOriginRG;
|
||||||
rgRect.height += amountUsedByRG;
|
rgRect.height += amountUsedByRG;
|
||||||
|
|
||||||
rgFrame->SetRect(rgRect);
|
rgFrame->SetRect(rgRect);
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(rgFrame, origRgRect, PR_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (amountUsed > 0) {
|
else if (amountUsed > 0 && yOriginRG != rgFrame->GetPosition().y) {
|
||||||
|
NS_ASSERTION(rgFrame->GetPosition().x == 0, "Unexpected position");
|
||||||
|
rgFrame->InvalidateOverflowRect();
|
||||||
rgFrame->SetPosition(nsPoint(0, yOriginRG));
|
rgFrame->SetPosition(nsPoint(0, yOriginRG));
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
nsTableFrame::RePositionViews(rgFrame);
|
nsTableFrame::RePositionViews(rgFrame);
|
||||||
|
rgFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
yOriginRG = yEndRG;
|
yOriginRG = yEndRG;
|
||||||
}
|
}
|
||||||
|
@ -3360,9 +3396,16 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
nscoord amountForRow = (rowFrame == lastEligibleRow)
|
nscoord amountForRow = (rowFrame == lastEligibleRow)
|
||||||
? aAmount - amountUsed : NSToCoordRound(((float)(heightToDistribute)) * ratio);
|
? aAmount - amountUsed : NSToCoordRound(((float)(heightToDistribute)) * ratio);
|
||||||
amountForRow = PR_MIN(amountForRow, aAmount - amountUsed);
|
amountForRow = PR_MIN(amountForRow, aAmount - amountUsed);
|
||||||
|
|
||||||
|
if (yOriginRow != rowRect.y) {
|
||||||
|
rowFrame->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
// update the row height
|
// update the row height
|
||||||
nsRect newRowRect(rowRect.x, yOriginRow, rowRect.width, rowRect.height + amountForRow);
|
nsRect newRowRect(rowRect.x, yOriginRow, rowRect.width,
|
||||||
|
rowRect.height + amountForRow);
|
||||||
rowFrame->SetRect(newRowRect);
|
rowFrame->SetRect(newRowRect);
|
||||||
|
|
||||||
yOriginRow += newRowRect.height + cellSpacingY;
|
yOriginRow += newRowRect.height + cellSpacingY;
|
||||||
yEndRG += newRowRect.height + cellSpacingY;
|
yEndRG += newRowRect.height + cellSpacingY;
|
||||||
|
|
||||||
|
@ -3371,11 +3414,15 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
NS_ASSERTION((amountUsed <= aAmount), "invalid row allocation");
|
NS_ASSERTION((amountUsed <= aAmount), "invalid row allocation");
|
||||||
//rowFrame->DidResize();
|
//rowFrame->DidResize();
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(rowFrame, rowRect, PR_FALSE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0 && yOriginRow != rowRect.y) {
|
||||||
|
rowFrame->InvalidateOverflowRect();
|
||||||
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
rowFrame->SetPosition(nsPoint(rowRect.x, yOriginRow));
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
rowFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
yOriginRow += rowRect.height + cellSpacingY;
|
yOriginRow += rowRect.height + cellSpacingY;
|
||||||
yEndRG += rowRect.height + cellSpacingY;
|
yEndRG += rowRect.height + cellSpacingY;
|
||||||
|
@ -3383,17 +3430,25 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
|
||||||
rowFrame = rowFrame->GetNextRow();
|
rowFrame = rowFrame->GetNextRow();
|
||||||
}
|
}
|
||||||
if (amountUsed > 0) {
|
if (amountUsed > 0) {
|
||||||
rgRect.y = yOriginRG;
|
if (rgRect.y != yOriginRG) {
|
||||||
rgRect.height += amountUsedByRG;
|
rgFrame->InvalidateOverflowRect();
|
||||||
rgFrame->SetRect(rgRect);
|
}
|
||||||
|
|
||||||
|
rgFrame->SetRect(nsRect(rgRect.x, yOriginRG, rgRect.width,
|
||||||
|
rgRect.height + amountUsedByRG));
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(rgFrame, rgRect, PR_FALSE);
|
||||||
}
|
}
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
// XXX what happens if childFrame is a scroll frame and this gets skipped? see also below
|
// XXX what happens if childFrame is a scroll frame and this gets skipped? see also below
|
||||||
}
|
}
|
||||||
else if (amountUsed > 0) {
|
else if (amountUsed > 0 && yOriginRG != rgFrame->GetPosition().y) {
|
||||||
|
NS_ASSERTION(rgFrame->GetPosition().x == 0, "Unexpected position");
|
||||||
|
rgFrame->InvalidateOverflowRect();
|
||||||
rgFrame->SetPosition(nsPoint(0, yOriginRG));
|
rgFrame->SetPosition(nsPoint(0, yOriginRG));
|
||||||
// Make sure child views are properly positioned
|
// Make sure child views are properly positioned
|
||||||
nsTableFrame::RePositionViews(rgFrame);
|
nsTableFrame::RePositionViews(rgFrame);
|
||||||
|
rgFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
yOriginRG = yEndRG;
|
yOriginRG = yEndRG;
|
||||||
}
|
}
|
||||||
|
@ -6718,6 +6773,27 @@ nsTableFrame::GetProperty(nsIFrame* aFrame,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void
|
||||||
|
nsTableFrame::InvalidateFrame(nsIFrame* aFrame, const nsRect& aOrigRect,
|
||||||
|
PRBool aIsFirstReflow)
|
||||||
|
{
|
||||||
|
nsIFrame* parent = aFrame->GetParent();
|
||||||
|
NS_ASSERTION(parent, "What happened here?");
|
||||||
|
|
||||||
|
if (parent->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
|
||||||
|
// Don't bother; we'll invalidate the parent's overflow rect when
|
||||||
|
// we finish reflowing it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aIsFirstReflow || aOrigRect.TopLeft() != aFrame->GetPosition()) {
|
||||||
|
aFrame->InvalidateOverflowRect();
|
||||||
|
} else {
|
||||||
|
parent->InvalidateRectDifference(aOrigRect, aFrame->GetRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define MAX_SIZE 128
|
#define MAX_SIZE 128
|
||||||
#define MIN_INDENT 30
|
#define MIN_INDENT 30
|
||||||
|
|
|
@ -480,6 +480,20 @@ public:
|
||||||
PRBool HasCellSpanningPctCol() const;
|
PRBool HasCellSpanningPctCol() const;
|
||||||
void SetHasCellSpanningPctCol(PRBool aValue);
|
void SetHasCellSpanningPctCol(PRBool aValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be called on a frame by its parent after setting its size/position and
|
||||||
|
* calling DidReflow (possibly via FinishReflowChild()). This can also be
|
||||||
|
* used for child frames which are not being reflown but did have their size
|
||||||
|
* or position changed.
|
||||||
|
*
|
||||||
|
* @param aFrame The frame to invalidate
|
||||||
|
* @param aOrigRect The original rect of aFrame (before the change).
|
||||||
|
* @param aIsFirstReflow True if the size/position change is due to the
|
||||||
|
* first reflow of aFrame.
|
||||||
|
*/
|
||||||
|
static void InvalidateFrame(nsIFrame* aFrame, const nsRect& aOrigRect,
|
||||||
|
PRBool aIsFirstReflow);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** protected constructor.
|
/** protected constructor.
|
||||||
|
@ -567,7 +581,8 @@ protected:
|
||||||
|
|
||||||
void PlaceChild(nsTableReflowState& aReflowState,
|
void PlaceChild(nsTableReflowState& aReflowState,
|
||||||
nsIFrame* aKidFrame,
|
nsIFrame* aKidFrame,
|
||||||
nsHTMLReflowMetrics& aKidDesiredSize);
|
nsHTMLReflowMetrics& aKidDesiredSize,
|
||||||
|
const nsRect& aOriginalKidRect);
|
||||||
|
|
||||||
nsIFrame* GetFirstBodyRowGroupFrame();
|
nsIFrame* GetFirstBodyRowGroupFrame();
|
||||||
PRBool MoveOverflowToChildList(nsPresContext* aPresContext);
|
PRBool MoveOverflowToChildList(nsPresContext* aPresContext);
|
||||||
|
|
|
@ -353,16 +353,24 @@ nsTableRowFrame::DidResize()
|
||||||
nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
|
nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
|
||||||
|
|
||||||
// resize the cell's height
|
// resize the cell's height
|
||||||
//if (cellFrameSize.height!=cellHeight)
|
nsRect cellRect = cellFrame->GetRect();
|
||||||
|
if (cellRect.height != cellHeight)
|
||||||
{
|
{
|
||||||
cellFrame->SetSize(nsSize(cellFrame->GetSize().width, cellHeight));
|
cellFrame->SetSize(nsSize(cellRect.width, cellHeight));
|
||||||
// realign cell content based on the new height
|
nsTableFrame::InvalidateFrame(cellFrame, cellRect, PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// realign cell content based on the new height. We might be able to
|
||||||
|
// skip this if the height didn't change... maybe. Hard to tell.
|
||||||
cellFrame->VerticallyAlignChild(mMaxCellAscent);
|
cellFrame->VerticallyAlignChild(mMaxCellAscent);
|
||||||
|
|
||||||
|
// Always store the overflow, even if the height didn't change, since
|
||||||
|
// we'll lose part of our overflow area otherwise.
|
||||||
ConsiderChildOverflow(desiredSize.mOverflowArea, cellFrame);
|
ConsiderChildOverflow(desiredSize.mOverflowArea, cellFrame);
|
||||||
|
|
||||||
// Note that if the cell's *content* needs to change in response
|
// Note that if the cell's *content* needs to change in response
|
||||||
// to this height, it will get a special height reflow.
|
// to this height, it will get a special height reflow.
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Get the next child
|
// Get the next child
|
||||||
childFrame = iter.Next();
|
childFrame = iter.Next();
|
||||||
}
|
}
|
||||||
|
@ -855,6 +863,10 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
|
||||||
|
|
||||||
// Reflow the child frame
|
// Reflow the child frame
|
||||||
|
nsRect kidRect = kidFrame->GetRect();
|
||||||
|
PRBool firstReflow =
|
||||||
|
(kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
||||||
|
|
||||||
if (doReflowChild) {
|
if (doReflowChild) {
|
||||||
// Calculate the available width for the table cell using the known column widths
|
// Calculate the available width for the table cell using the known column widths
|
||||||
nscoord availColWidth, availCellWidth;
|
nscoord availColWidth, availCellWidth;
|
||||||
|
@ -889,7 +901,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
|
|
||||||
nsReflowStatus status;
|
nsReflowStatus status;
|
||||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||||
x, 0, 0, status);
|
x, 0, NS_FRAME_INVALIDATE_ON_MOVE, status);
|
||||||
|
|
||||||
// allow the table to determine if/how the table needs to be rebalanced
|
// allow the table to determine if/how the table needs to be rebalanced
|
||||||
// If any of the cells are not complete, then we're not complete
|
// If any of the cells are not complete, then we're not complete
|
||||||
|
@ -898,6 +910,10 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (x != kidRect.x) {
|
||||||
|
kidFrame->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
desiredSize.width = cellDesiredSize.width;
|
desiredSize.width = cellDesiredSize.width;
|
||||||
desiredSize.height = cellDesiredSize.height;
|
desiredSize.height = cellDesiredSize.height;
|
||||||
nsRect *overflowArea =
|
nsRect *overflowArea =
|
||||||
|
@ -950,16 +966,19 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
|
|
||||||
FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0);
|
FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0);
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(kidFrame, kidRect, firstReflow);
|
||||||
|
|
||||||
x += desiredSize.width;
|
x += desiredSize.width;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nsRect kidRect = kidFrame->GetRect();
|
|
||||||
if (kidRect.x != x) {
|
if (kidRect.x != x) {
|
||||||
Invalidate(kidRect); // invalidate the old position
|
// Invalidate the old position
|
||||||
kidRect.x = x;
|
kidFrame->InvalidateOverflowRect();
|
||||||
kidFrame->SetRect(kidRect); // move to the new position
|
// move to the new position
|
||||||
|
kidFrame->SetPosition(nsPoint(x, kidRect.y));
|
||||||
nsTableFrame::RePositionViews(kidFrame);
|
nsTableFrame::RePositionViews(kidFrame);
|
||||||
Invalidate(kidRect); // invalidate the new position
|
// invalidate the new position
|
||||||
|
kidFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
// we need to account for the cell's width even if it isn't reflowed
|
// we need to account for the cell's width even if it isn't reflowed
|
||||||
x += kidRect.width;
|
x += kidRect.width;
|
||||||
|
@ -1066,9 +1085,9 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext,
|
||||||
ABORT1(NS_ERROR_NULL_POINTER);
|
ABORT1(NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
// Reflow the cell frame with the specified height. Use the existing width
|
// Reflow the cell frame with the specified height. Use the existing width
|
||||||
nsSize cellSize = aCellFrame->GetSize();
|
nsRect cellRect = aCellFrame->GetRect();
|
||||||
|
|
||||||
nsSize availSize(cellSize.width, aAvailableHeight);
|
nsSize availSize(cellRect.width, aAvailableHeight);
|
||||||
PRBool borderCollapse = ((nsTableFrame*)tableFrame->GetFirstInFlow())->IsBorderCollapse();
|
PRBool borderCollapse = ((nsTableFrame*)tableFrame->GetFirstInFlow())->IsBorderCollapse();
|
||||||
nsTableCellReflowState cellReflowState(aPresContext, aReflowState,
|
nsTableCellReflowState cellReflowState(aPresContext, aReflowState,
|
||||||
aCellFrame, availSize, PR_FALSE);
|
aCellFrame, availSize, PR_FALSE);
|
||||||
|
@ -1083,7 +1102,11 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext,
|
||||||
if (fullyComplete) {
|
if (fullyComplete) {
|
||||||
desiredSize.height = aAvailableHeight;
|
desiredSize.height = aAvailableHeight;
|
||||||
}
|
}
|
||||||
aCellFrame->SetSize(nsSize(cellSize.width, desiredSize.height));
|
aCellFrame->SetSize(nsSize(cellRect.width, desiredSize.height));
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(aCellFrame, cellRect,
|
||||||
|
(aCellFrame->GetStateBits() &
|
||||||
|
NS_FRAME_FIRST_REFLOW) != 0);
|
||||||
|
|
||||||
// XXX What happens if this cell has 'vertical-align: baseline' ?
|
// XXX What happens if this cell has 'vertical-align: baseline' ?
|
||||||
// XXX Why is it assumed that the cell's ascent hasn't changed ?
|
// XXX Why is it assumed that the cell's ascent hasn't changed ?
|
||||||
|
@ -1110,7 +1133,14 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
||||||
tableFrame->SetNeedToCollapse(PR_TRUE);
|
tableFrame->SetNeedToCollapse(PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aRowOffset != 0) {
|
||||||
|
// We're moving, so invalidate our old position
|
||||||
|
InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
nsRect rowRect = GetRect();
|
nsRect rowRect = GetRect();
|
||||||
|
nsRect oldRect = rowRect;
|
||||||
|
|
||||||
rowRect.y -= aRowOffset;
|
rowRect.y -= aRowOffset;
|
||||||
rowRect.width = aWidth;
|
rowRect.width = aWidth;
|
||||||
nsRect overflowArea(0, 0, 0, 0);
|
nsRect overflowArea(0, 0, 0, 0);
|
||||||
|
@ -1124,6 +1154,13 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
||||||
shift = rowRect.height + cellSpacingY;
|
shift = rowRect.height + cellSpacingY;
|
||||||
while (cellFrame) {
|
while (cellFrame) {
|
||||||
nsRect cRect = cellFrame->GetRect();
|
nsRect cRect = cellFrame->GetRect();
|
||||||
|
// If aRowOffset != 0, there's no point in invalidating the cells, since
|
||||||
|
// we've already invalidated our overflow area. Note that we _do_ still
|
||||||
|
// need to invalidate if our row is not moving, because the cell might
|
||||||
|
// span out of this row, so invalidating our row rect won't do enough.
|
||||||
|
if (aRowOffset == 0) {
|
||||||
|
Invalidate(cRect);
|
||||||
|
}
|
||||||
cRect.height = 0;
|
cRect.height = 0;
|
||||||
cellFrame->SetRect(cRect);
|
cellFrame->SetRect(cRect);
|
||||||
cellFrame = cellFrame->GetNextCell();
|
cellFrame = cellFrame->GetNextCell();
|
||||||
|
@ -1161,7 +1198,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
||||||
*tableFrame, cellSpacingX, iter.IsLeftToRight(),
|
*tableFrame, cellSpacingX, iter.IsLeftToRight(),
|
||||||
PR_TRUE);
|
PR_TRUE);
|
||||||
}
|
}
|
||||||
nsRect cRect(x, 0, 0,rowRect.height);
|
nsRect cRect(x, 0, 0, rowRect.height);
|
||||||
|
|
||||||
// remember the rightmost (ltr) or leftmost (rtl) column this cell
|
// remember the rightmost (ltr) or leftmost (rtl) column this cell
|
||||||
// spans into
|
// spans into
|
||||||
|
@ -1216,23 +1253,40 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
|
||||||
}
|
}
|
||||||
rowFrame = rowFrame->GetNextRow();
|
rowFrame = rowFrame->GetNextRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsRect oldCellRect = cellFrame->GetRect();
|
||||||
|
|
||||||
|
if (aRowOffset == 0 && cRect.TopLeft() != oldCellRect.TopLeft()) {
|
||||||
|
// We're moving the cell. Invalidate the old overflow area
|
||||||
|
cellFrame->InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
cellFrame->SetRect(cRect);
|
cellFrame->SetRect(cRect);
|
||||||
|
|
||||||
|
// XXXbz This looks completely bogus in the cases when we didn't
|
||||||
|
// collapse the cell!
|
||||||
nsRect cellOverflow = nsRect(0, 0, cRect.width, cRect.height);
|
nsRect cellOverflow = nsRect(0, 0, cRect.width, cRect.height);
|
||||||
cellFrame->FinishAndStoreOverflow(&cellOverflow, nsSize(cRect.width,
|
cellFrame->FinishAndStoreOverflow(&cellOverflow, nsSize(cRect.width,
|
||||||
cRect.height));
|
cRect.height));
|
||||||
nsTableFrame::RePositionViews(cellFrame);
|
nsTableFrame::RePositionViews(cellFrame);
|
||||||
ConsiderChildOverflow(overflowArea, cellFrame);
|
ConsiderChildOverflow(overflowArea, cellFrame);
|
||||||
|
|
||||||
|
if (aRowOffset == 0) {
|
||||||
|
nsTableFrame::InvalidateFrame(cellFrame, oldCellRect, PR_FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
kidFrame = iter.Next(); // Get the next child
|
kidFrame = iter.Next(); // Get the next child
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetRect(rowRect);
|
SetRect(rowRect);
|
||||||
overflowArea.UnionRect(nsRect(0,0,rowRect.width, rowRect.height),
|
overflowArea.UnionRect(nsRect(0,0,rowRect.width, rowRect.height),
|
||||||
overflowArea);
|
overflowArea);
|
||||||
FinishAndStoreOverflow(&overflowArea, nsSize(rowRect.width,
|
FinishAndStoreOverflow(&overflowArea, nsSize(rowRect.width,
|
||||||
rowRect.height));
|
rowRect.height));
|
||||||
|
|
||||||
nsTableFrame::RePositionViews(this);
|
nsTableFrame::RePositionViews(this);
|
||||||
|
nsTableFrame::InvalidateFrame(this, oldRect, PR_FALSE);
|
||||||
return shift;
|
return shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,10 +294,17 @@ void
|
||||||
nsTableRowGroupFrame::PlaceChild(nsPresContext* aPresContext,
|
nsTableRowGroupFrame::PlaceChild(nsPresContext* aPresContext,
|
||||||
nsRowGroupReflowState& aReflowState,
|
nsRowGroupReflowState& aReflowState,
|
||||||
nsIFrame* aKidFrame,
|
nsIFrame* aKidFrame,
|
||||||
nsHTMLReflowMetrics& aDesiredSize)
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
|
const nsRect& aOriginalKidRect)
|
||||||
{
|
{
|
||||||
|
PRBool isFirstReflow =
|
||||||
|
(aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
|
||||||
|
|
||||||
// Place and size the child
|
// Place and size the child
|
||||||
FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, 0, aReflowState.y, 0);
|
FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, 0,
|
||||||
|
aReflowState.y, 0);
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(aKidFrame, aOriginalKidRect, isFirstReflow);
|
||||||
|
|
||||||
// Adjust the running y-offset
|
// Adjust the running y-offset
|
||||||
aReflowState.y += aDesiredSize.height;
|
aReflowState.y += aDesiredSize.height;
|
||||||
|
@ -384,7 +391,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
(aReflowState.reflowState.mFlags.mSpecialHeightReflow &&
|
(aReflowState.reflowState.mFlags.mSpecialHeightReflow &&
|
||||||
(isPaginated || (kidFrame->GetStateBits() &
|
(isPaginated || (kidFrame->GetStateBits() &
|
||||||
NS_FRAME_CONTAINS_RELATIVE_HEIGHT)))) {
|
NS_FRAME_CONTAINS_RELATIVE_HEIGHT)))) {
|
||||||
nsSize oldKidSize = kidFrame->GetSize();
|
nsRect oldKidRect = kidFrame->GetRect();
|
||||||
|
|
||||||
// XXXldb We used to only pass aDesiredSize.mFlags through for the
|
// XXXldb We used to only pass aDesiredSize.mFlags through for the
|
||||||
// incremental reflow codepath.
|
// incremental reflow codepath.
|
||||||
|
@ -410,10 +417,12 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||||
0, aReflowState.y, 0, aStatus);
|
0, aReflowState.y, NS_FRAME_INVALIDATE_ON_MOVE,
|
||||||
|
aStatus);
|
||||||
|
|
||||||
// Place the child
|
// Place the child
|
||||||
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize);
|
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
|
||||||
|
oldKidRect);
|
||||||
aReflowState.y += cellSpacingY;
|
aReflowState.y += cellSpacingY;
|
||||||
|
|
||||||
if (!reflowAllKids) {
|
if (!reflowAllKids) {
|
||||||
|
@ -436,7 +445,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||||
Invalidate(dirtyRect);
|
Invalidate(dirtyRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (oldKidSize.height != desiredSize.height)
|
else if (oldKidRect.height != desiredSize.height)
|
||||||
needToCalcRowHeights = PR_TRUE;
|
needToCalcRowHeights = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
needToCalcRowHeights = PR_TRUE;
|
needToCalcRowHeights = PR_TRUE;
|
||||||
|
@ -798,13 +807,19 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext,
|
||||||
nscoord rowHeight = (rowInfo[rowIndex].height > 0) ? rowInfo[rowIndex].height : 0;
|
nscoord rowHeight = (rowInfo[rowIndex].height > 0) ? rowInfo[rowIndex].height : 0;
|
||||||
|
|
||||||
if (movedFrame || (rowHeight != rowBounds.height)) {
|
if (movedFrame || (rowHeight != rowBounds.height)) {
|
||||||
// Resize the row to its final size and position
|
// Resize/move the row to its final size and position
|
||||||
rowBounds.y = yOrigin;
|
if (movedFrame) {
|
||||||
rowBounds.height = rowHeight;
|
rowFrame->InvalidateOverflowRect();
|
||||||
rowFrame->SetRect(rowBounds);
|
}
|
||||||
|
|
||||||
|
rowFrame->SetRect(nsRect(rowBounds.x, yOrigin, rowBounds.width,
|
||||||
|
rowHeight));
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(rowFrame, rowBounds, PR_FALSE);
|
||||||
}
|
}
|
||||||
if (movedFrame) {
|
if (movedFrame) {
|
||||||
nsTableFrame::RePositionViews(rowFrame);
|
nsTableFrame::RePositionViews(rowFrame);
|
||||||
|
// XXXbz we don't need to update our overflow area?
|
||||||
}
|
}
|
||||||
yOrigin += rowHeight + cellSpacingY;
|
yOrigin += rowHeight + cellSpacingY;
|
||||||
}
|
}
|
||||||
|
@ -845,6 +860,8 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect groupRect = GetRect();
|
nsRect groupRect = GetRect();
|
||||||
|
nsRect oldGroupRect = groupRect;
|
||||||
|
|
||||||
groupRect.height -= yGroupOffset;
|
groupRect.height -= yGroupOffset;
|
||||||
if (didCollapse) {
|
if (didCollapse) {
|
||||||
// add back the cellspacing between rowgroups
|
// add back the cellspacing between rowgroups
|
||||||
|
@ -853,12 +870,19 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
|
||||||
|
|
||||||
groupRect.y -= aYTotalOffset;
|
groupRect.y -= aYTotalOffset;
|
||||||
groupRect.width = aWidth;
|
groupRect.width = aWidth;
|
||||||
|
|
||||||
|
if (aYTotalOffset != 0) {
|
||||||
|
InvalidateOverflowRect();
|
||||||
|
}
|
||||||
|
|
||||||
SetRect(groupRect);
|
SetRect(groupRect);
|
||||||
overflowArea.UnionRect(nsRect(0, 0, groupRect.width, groupRect.height),
|
overflowArea.UnionRect(nsRect(0, 0, groupRect.width, groupRect.height),
|
||||||
overflowArea);
|
overflowArea);
|
||||||
FinishAndStoreOverflow(&overflowArea, nsSize(groupRect.width,
|
FinishAndStoreOverflow(&overflowArea, nsSize(groupRect.width,
|
||||||
groupRect.height));
|
groupRect.height));
|
||||||
nsTableFrame::RePositionViews(this);
|
nsTableFrame::RePositionViews(this);
|
||||||
|
nsTableFrame::InvalidateFrame(this, oldGroupRect, PR_FALSE);
|
||||||
|
|
||||||
return yGroupOffset;
|
return yGroupOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,8 +904,10 @@ nsTableRowGroupFrame::SlideChild(nsRowGroupReflowState& aReflowState,
|
||||||
nsPoint newPosition = oldPosition;
|
nsPoint newPosition = oldPosition;
|
||||||
newPosition.y = aReflowState.y;
|
newPosition.y = aReflowState.y;
|
||||||
if (oldPosition.y != newPosition.y) {
|
if (oldPosition.y != newPosition.y) {
|
||||||
|
aKidFrame->InvalidateOverflowRect();
|
||||||
aKidFrame->SetPosition(newPosition);
|
aKidFrame->SetPosition(newPosition);
|
||||||
nsTableFrame::RePositionViews(aKidFrame);
|
nsTableFrame::RePositionViews(aKidFrame);
|
||||||
|
aKidFrame->InvalidateOverflowRect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,6 +1105,9 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
|
||||||
rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
|
rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page
|
||||||
nsHTMLReflowMetrics rowMetrics;
|
nsHTMLReflowMetrics rowMetrics;
|
||||||
|
|
||||||
|
// Get the old size before we reflow.
|
||||||
|
nsRect oldRowRect = rowFrame->GetRect();
|
||||||
|
|
||||||
// Reflow the cell with the constrained height. A cell with rowspan >1 will get this
|
// Reflow the cell with the constrained height. A cell with rowspan >1 will get this
|
||||||
// reflow later during SplitSpanningCells.
|
// reflow later during SplitSpanningCells.
|
||||||
rv = ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowState,
|
rv = ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowState,
|
||||||
|
@ -1088,6 +1117,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext,
|
||||||
rowFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
rowFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
||||||
rowFrame->DidResize();
|
rowFrame->DidResize();
|
||||||
|
|
||||||
|
nsTableFrame::InvalidateFrame(rowFrame, oldRowRect, PR_FALSE);
|
||||||
|
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
// The row frame is incomplete and all of the rowspan 1 cells' block frames split
|
// The row frame is incomplete and all of the rowspan 1 cells' block frames split
|
||||||
if ((rowMetrics.height <= rowReflowState.availableHeight) || isTopOfPage) {
|
if ((rowMetrics.height <= rowReflowState.availableHeight) || isTopOfPage) {
|
||||||
|
|
|
@ -313,7 +313,8 @@ protected:
|
||||||
void PlaceChild(nsPresContext* aPresContext,
|
void PlaceChild(nsPresContext* aPresContext,
|
||||||
nsRowGroupReflowState& aReflowState,
|
nsRowGroupReflowState& aReflowState,
|
||||||
nsIFrame* aKidFrame,
|
nsIFrame* aKidFrame,
|
||||||
nsHTMLReflowMetrics& aDesiredSize);
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
|
const nsRect& aOriginalKidRect);
|
||||||
|
|
||||||
void CalculateRowHeights(nsPresContext* aPresContext,
|
void CalculateRowHeights(nsPresContext* aPresContext,
|
||||||
nsHTMLReflowMetrics& aDesiredSize,
|
nsHTMLReflowMetrics& aDesiredSize,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче