diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index b9543f33b27..5749485f6b8 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -219,7 +219,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont nscoord horOffset; // get the reduction in available horizontal space due to borders and padding if (mTableFrame->IsBorderCollapse()) { - nsMargin offset = mTableFrame->GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin offset = mTableFrame->GetChildAreaOffset(aPresContext, &aReflowState); horOffset = offset.left + offset.right; } else { @@ -1235,7 +1235,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(nsIPresContext& aPresCon rawPctValues[colX] = 0.0f; } - nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState); + nsMargin borderPadding = mTableFrame->GetContentAreaOffset(&aPresContext, &aReflowState); nscoord availWidth = aAvailWidthIn; if (NS_UNCONSTRAINEDSIZE != availWidth) { // adjust the avail width to exclude table border, padding and cell spacing @@ -1369,7 +1369,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(nsIPresContext& aPresCo : aAvailWidth; // adjust the basis to exclude table border, padding and cell spacing - nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState); + nsMargin borderPadding = mTableFrame->GetContentAreaOffset(&aPresContext, &aReflowState); basis -= borderPadding.left + borderPadding.right + mCellSpacingTotal; nscoord colPctTotal = 0; diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index 36699b96fb9..abc518dd7b5 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -345,7 +345,7 @@ nsTableCellFrame::DecorateForSelection(nsIPresContext* aPresContext, result = frameSelection->GetTableCellSelection(&tableCellSelectionMode); if (NS_SUCCEEDED(result) && tableCellSelectionMode) { nscolor bordercolor; - if(displaySelection == nsISelectionController::SELECTION_DISABLED) { + if (displaySelection == nsISelectionController::SELECTION_DISABLED) { bordercolor = NS_RGB(176,176,176);// disabled color } else { @@ -642,6 +642,12 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex kidYTop = nsTableFrame::RoundToPixel(kidYTop, p2t, eAlwaysRoundDown); } firstKid->SetPosition(nsPoint(kidRect.x, kidYTop)); + nsHTMLReflowMetrics desiredSize(PR_FALSE); + desiredSize.width = mRect.width; + desiredSize.height = mRect.height; + desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height); + ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid); + StoreOverflow(aPresContext, desiredSize); if (kidYTop != kidRect.y) { // Make sure any child views are correctly positioned. We know the inner table // cell won't have a view @@ -1018,6 +1024,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.ascent += kidSize.ascent; aDesiredSize.descent += kidSize.descent; + + // the overflow area will be computed when the child will be vertically aligned if (aDesiredSize.mComputeMEW) { aDesiredSize.mMaxElementWidth = diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 7a0a6f2cb00..0923c90d2d0 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -124,7 +124,7 @@ struct nsTableReflowState { reason = aReason; nsTableFrame* table = (nsTableFrame*)aTableFrame.GetFirstInFlow(); - nsMargin borderPadding = table->GetChildAreaOffset(aPresContext, &reflowState); + nsMargin borderPadding = table->GetChildAreaOffset(&aPresContext, &reflowState); x = borderPadding.left; y = borderPadding.top; @@ -1960,20 +1960,22 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, case eReflowReason_Initial: case eReflowReason_StyleChange: { if ((eReflowReason_Initial == aReflowState.reason) && HadInitialReflow()) { - // XXX put this back in when bug 70150 is fixed - // NS_ASSERTION(PR_FALSE, "intial reflow called twice"); + // XXX this could be an assertion and the if removed + NS_NOTREACHED("intial reflow called twice"); } else { if (!mPrevInFlow) { // only do pass1 on a first in flow if (IsAutoLayout()) { // only do pass1 reflow on an auto layout table - nsReflowReason reason = (eReflowReason_Initial == aReflowState.reason) - ? eReflowReason_Initial : eReflowReason_StyleChange; - nsTableReflowState reflowState(*aPresContext, aReflowState, *this, reason, - NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + nsTableReflowState reflowState(*aPresContext, aReflowState, *this, + aReflowState.reason, + NS_UNCONSTRAINEDSIZE, + NS_UNCONSTRAINEDSIZE); // reflow the children nsIFrame *lastReflowed; - ReflowChildren(aPresContext, reflowState, !HaveReflowedColGroups(), PR_FALSE, aStatus, lastReflowed); + ReflowChildren(aPresContext, reflowState, !HaveReflowedColGroups(), + PR_FALSE, aStatus, lastReflowed, + aDesiredSize.mOverflowArea); } mTableLayoutStrategy->Initialize(aPresContext, aReflowState); } @@ -1997,10 +1999,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, case eReflowReason_Resize: // do the resize reflow below if (!HadInitialReflow()) { - // NS_ASSERTION(HadInitialReflow(), "intial reflow not called"); + NS_ASSERTION(HadInitialReflow(), "intial reflow not called"); nextReason = eReflowReason_Initial; } - //NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth, "this doesn't do anything"); + NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth, + "this doesn't do anything"); SetNeedStrategyBalance(PR_TRUE); break; default: @@ -2061,9 +2064,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { // if there is an incomplete child, then set the desired height to include it but not the next one - nsRect childRect = lastChildReflowed->GetRect(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); - aDesiredSize.height = borderPadding.top + GetCellSpacingY() + childRect.height; + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); + aDesiredSize.height = borderPadding.top + GetCellSpacingY() + + lastChildReflowed->GetSize().height; } haveDesiredHeight = PR_TRUE; reflowedChildren = PR_TRUE; @@ -2088,7 +2091,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, ProcessRowInserted(aPresContext, *this, PR_TRUE, aDesiredSize.height); } - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); SetColumnDimensions(aPresContext, aDesiredSize.height, borderPadding); if (doCollapse) { AdjustForCollapsingRows(aPresContext, aDesiredSize.height); @@ -2122,7 +2125,14 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, if (aDesiredSize.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aDesiredSize.mMaximumWidth = GetPreferredWidth(); } - + if (NS_STYLE_OVERFLOW_HIDDEN != aReflowState.mStyleDisplay->mOverflow) { + // collapsed border may leak out + nsMargin bcMargin = GetBCMargin(aPresContext); + nsRect tableRect(0, 0, aDesiredSize.width, aDesiredSize.height) ; + tableRect.Inflate(bcMargin); + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, tableRect); + } + if (aReflowState.mFlags.mSpecialHeightReflow) { SetNeedSpecialReflow(PR_FALSE); SetNeedToInitiateSpecialReflow(PR_FALSE); @@ -2134,10 +2144,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, // If we reflowed all the rows, then invalidate the largest possible area that either the // table occupied before this reflow or will occupy after. if (reflowedChildren) { - Invalidate(aPresContext, nsRect(0, 0, PR_MAX(mRect.width, aDesiredSize.width), - PR_MAX(mRect.height, aDesiredSize.height))); + nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width), + PR_MAX(mRect.height, aDesiredSize.height)); + damage.UnionRect(damage, aDesiredSize.mOverflowArea); + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + if (oldOverflowArea) { + damage.UnionRect(damage, *oldOverflowArea); + } + Invalidate(aPresContext, damage); } + StoreOverflow(aPresContext, aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -2179,7 +2196,8 @@ nsTableFrame::ReflowTable(nsIPresContext* aPresContext, aDesiredSize.width = GetDesiredWidth(); nsTableReflowState reflowState(*aPresContext, aReflowState, *this, aReason, aDesiredSize.width, aAvailHeight); - ReflowChildren(aPresContext, reflowState, haveReflowedColGroups, PR_FALSE, aStatus, aLastChildReflowed); + ReflowChildren(aPresContext, reflowState, haveReflowedColGroups, PR_FALSE, + aStatus, aLastChildReflowed, aDesiredSize.mOverflowArea); if (eReflowReason_Resize == aReflowState.reason) { if (!DidResizeReflow()) { @@ -2739,7 +2757,9 @@ nsTableFrame::IR_TargetIsMe(nsIPresContext* aPresContext, aReflowState.availSize.width, aReflowState.availSize.height); nsIFrame* lastReflowed; PRBool reflowedAtLeastOne; - ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_TRUE, aStatus, lastReflowed, &reflowedAtLeastOne); + nsRect overflowArea; + ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_TRUE, aStatus, + lastReflowed, overflowArea, &reflowedAtLeastOne); if (!reflowedAtLeastOne) // XXX For now assume the worse SetNeedStrategyInit(PR_TRUE); @@ -2761,7 +2781,8 @@ NS_METHOD nsTableFrame::IR_StyleChanged(nsIPresContext* aPresContext, nsTableReflowState reflowState(*aPresContext, aReflowState.reflowState, *this, eReflowReason_StyleChange, aReflowState.availSize.width, aReflowState.availSize.height); nsIFrame* lastReflowed; - return ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_FALSE, aStatus, lastReflowed); + nsRect overflowArea; + return ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_FALSE, aStatus, lastReflowed, overflowArea); } static void @@ -2773,47 +2794,74 @@ DivideBCBorderSize(nscoord aPixelSize, aLargeHalf = ((aSmallHalf + aSmallHalf) < aPixelSize) ? aSmallHalf + 1 : aSmallHalf; } -nsMargin* -nsTableFrame::GetBCBorder(nsIPresContext& aPresContext, - PRBool aInnerBorderOnly, - nsMargin& aBorder) const +nsMargin +nsTableFrame::GetBCBorder(nsIPresContext* aPresContext) const { - aBorder.top = aBorder.right = aBorder.bottom = aBorder.left = 0; + nsMargin border(0, 0, 0, 0); - GET_PIXELS_TO_TWIPS(&aPresContext, p2t); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); BCPropertyData* propData = - (BCPropertyData*)nsTableFrame::GetProperty(&aPresContext, (nsIFrame*)this, nsLayoutAtoms::tableBCProperty, PR_FALSE); + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)this, nsLayoutAtoms::tableBCProperty, PR_FALSE); if (propData) { nsCompatibility mode; - aPresContext.GetCompatibilityMode(&mode); - if ((eCompatibility_NavQuirks != mode) || aInnerBorderOnly) { + aPresContext->GetCompatibilityMode(&mode); + if (eCompatibility_NavQuirks != mode) { nscoord smallHalf, largeHalf; DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); - aBorder.top += NSToCoordRound(p2t * (float)smallHalf); + border.top += NSToCoordRound(p2t * (float)smallHalf); DivideBCBorderSize(propData->mRightBorderWidth, smallHalf, largeHalf); - aBorder.right += NSToCoordRound(p2t * (float)largeHalf); + border.right += NSToCoordRound(p2t * (float)largeHalf); DivideBCBorderSize(propData->mBottomBorderWidth, smallHalf, largeHalf); - aBorder.bottom += NSToCoordRound(p2t * (float)largeHalf); + border.bottom += NSToCoordRound(p2t * (float)largeHalf); DivideBCBorderSize(propData->mLeftBorderWidth, smallHalf, largeHalf); - aBorder.left += NSToCoordRound(p2t * (float)smallHalf); + border.left += NSToCoordRound(p2t * (float)smallHalf); } else { - aBorder.top += NSToCoordRound(p2t * (float)propData->mTopBorderWidth); - aBorder.right += NSToCoordRound(p2t * (float)propData->mRightBorderWidth); - aBorder.bottom += NSToCoordRound(p2t * (float)propData->mBottomBorderWidth); - aBorder.left += NSToCoordRound(p2t * (float)propData->mLeftBorderWidth); + border.top += NSToCoordRound(p2t * (float)propData->mTopBorderWidth); + border.right += NSToCoordRound(p2t * (float)propData->mRightBorderWidth); + border.bottom += NSToCoordRound(p2t * (float)propData->mBottomBorderWidth); + border.left += NSToCoordRound(p2t * (float)propData->mLeftBorderWidth); } } - return &aBorder; + return border; } +nsMargin +nsTableFrame::GetBCMargin(nsIPresContext* aPresContext) const +{ + nsMargin overflow(0, 0, 0, 0); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); + BCPropertyData* propData = + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)this, + nsLayoutAtoms::tableBCProperty, + PR_FALSE); + if (propData) { + nsCompatibility mode; + aPresContext->GetCompatibilityMode(&mode); + if (eCompatibility_NavQuirks != mode) { + nscoord smallHalf, largeHalf; + + DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); + overflow.top += NSToCoordRound(p2t * (float)largeHalf); + + DivideBCBorderSize(propData->mRightBorderWidth, smallHalf, largeHalf); + overflow.right += NSToCoordRound(p2t * (float)smallHalf); + + DivideBCBorderSize(propData->mBottomBorderWidth, smallHalf, largeHalf); + overflow.bottom += NSToCoordRound(p2t * (float)smallHalf); + + DivideBCBorderSize(propData->mLeftBorderWidth, smallHalf, largeHalf); + overflow.left += NSToCoordRound(p2t * (float)largeHalf); + } + } + return overflow; +} static -void GetSeparateModelBorderPadding(nsIPresContext& aPresContext, - const nsHTMLReflowState* aReflowState, +void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState, nsStyleContext& aStyleContext, nsMargin& aBorderPadding) { @@ -2825,19 +2873,19 @@ void GetSeparateModelBorderPadding(nsIPresContext& aPresContext, } nsMargin -nsTableFrame::GetChildAreaOffset(nsIPresContext& aPresContext, +nsTableFrame::GetChildAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const { nsMargin offset(0,0,0,0); if (IsBorderCollapse()) { nsCompatibility mode; - aPresContext.GetCompatibilityMode(&mode); + aPresContext->GetCompatibilityMode(&mode); if (eCompatibility_NavQuirks == mode) { nsTableFrame* firstInFlow = (nsTableFrame*)GetFirstInFlow(); if (!firstInFlow) ABORT1(offset); nscoord smallHalf, largeHalf; - GET_PIXELS_TO_TWIPS(&aPresContext, p2t); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); BCPropertyData* propData = - (BCPropertyData*)nsTableFrame::GetProperty(&aPresContext, (nsIFrame*)firstInFlow, nsLayoutAtoms::tableBCProperty, PR_FALSE); + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)firstInFlow, nsLayoutAtoms::tableBCProperty, PR_FALSE); if (!propData) ABORT1(offset); DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); @@ -2854,23 +2902,21 @@ nsTableFrame::GetChildAreaOffset(nsIPresContext& aPresContext, } } else { - if (!mStyleContext) ABORT1(offset); - GetSeparateModelBorderPadding(aPresContext, aReflowState, *mStyleContext, offset); + GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset); } return offset; } nsMargin -nsTableFrame::GetContentAreaOffset(nsIPresContext& aPresContext, +nsTableFrame::GetContentAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const { nsMargin offset(0,0,0,0); if (IsBorderCollapse()) { - GetBCBorder(aPresContext, PR_FALSE, offset); + offset = GetBCBorder(aPresContext); } else { - if (!mStyleContext) ABORT1(offset); - GetSeparateModelBorderPadding(aPresContext, aReflowState, *mStyleContext, offset); + GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset); } return offset; } @@ -2883,7 +2929,7 @@ nsTableFrame::RecoverState(nsIPresContext& aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame) { - nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState.reflowState); + nsMargin borderPadding = GetChildAreaOffset(&aPresContext, &aReflowState.reflowState); aReflowState.y = borderPadding.top; nscoord cellSpacingY = GetCellSpacingY(); @@ -2970,7 +3016,7 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, nsRect oldKidRect = aNextFrame->GetRect(); // Pass along the reflow command, don't request a max element size, rows will do that - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); nsSize kidAvailSize(aReflowState.availSize); nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, aNextFrame, kidAvailSize, aReflowState.reason); @@ -3027,17 +3073,19 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, void nsTableFrame::PlaceChild(nsIPresContext* aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame, - nsHTMLReflowMetrics& aDesiredSize) + nsHTMLReflowMetrics& aKidDesiredSize) { + // Place and size the child - FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, aReflowState.x, aReflowState.y, 0); + FinishReflowChild(aKidFrame, aPresContext, nsnull, aKidDesiredSize, + aReflowState.x, aReflowState.y, 0); // Adjust the running y-offset - aReflowState.y += aDesiredSize.height; + aReflowState.y += aKidDesiredSize.height; // If our height is constrained, then update the available height if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) { - aReflowState.availSize.height -= aDesiredSize.height; + aReflowState.availSize.height -= aKidDesiredSize.height; } const nsStyleDisplay* childDisplay = aKidFrame->GetStyleDisplay(); @@ -3157,6 +3205,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, PRBool aDirtyOnly, nsReflowStatus& aStatus, nsIFrame*& aLastChildReflowed, + nsRect& aOverflowArea, PRBool* aReflowedAtLeastOne) { aStatus = NS_FRAME_COMPLETE; @@ -3169,6 +3218,8 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, PRBool isPaginated; aPresContext->IsPaginated(&isPaginated); + aOverflowArea = nsRect (0, 0, 0, 0); + nsAutoVoidArray rowGroups; PRUint32 numRowGroups; nsTableRowGroupFrame *thead, *tfoot; @@ -3210,7 +3261,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, } } - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0; if (childX < numRowGroups) { @@ -3244,6 +3295,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, nsIFrame* nextKid = (childX + 1 < numRowGroups) ? (nsIFrame*)rowGroups.ElementAt(childX + 1) : nsnull; pageBreak = PageBreakAfter(*kidFrame, nextKid); } + // Place the child PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize); @@ -3303,11 +3355,12 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, } aReflowState.y += cellSpacingY + kidRect.height; } + ConsiderChildOverflow(aPresContext, aOverflowArea, kidFrame); } - + // if required, give the colgroups their initial reflows if (aDoColGroups) { - nsHTMLReflowMetrics kidMet(nsnull); + nsHTMLReflowMetrics kidMet(PR_FALSE); for (nsIFrame* kidFrame = mColGroups.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame, @@ -3410,7 +3463,7 @@ nsTableFrame::CalcDesiredWidth(nsIPresContext& aPresContext, tableWidth = PR_MAX(tableWidth, compWidth); // Add the width between the border edge and the child area - nsMargin childOffset = GetChildAreaOffset(aPresContext, &aReflowState); + nsMargin childOffset = GetChildAreaOffset(&aPresContext, &aReflowState); tableWidth += childOffset.left + childOffset.right; return tableWidth; @@ -3427,7 +3480,7 @@ nsTableFrame::CalcDesiredHeight(nsIPresContext* aPresContext, return 0; } nscoord cellSpacingY = GetCellSpacingY(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); // get the natural height based on the last child's (row group or scroll frame) rect nsAutoVoidArray rowGroups; @@ -3468,15 +3521,35 @@ void ResizeCells(nsTableFrame& aTableFrame, nsAutoVoidArray rowGroups; PRUint32 numRowGroups; aTableFrame.OrderRowGroups(rowGroups, numRowGroups, nsnull); + nsHTMLReflowMetrics tableDesiredSize(PR_FALSE); + nsRect tableRect = aTableFrame.GetRect(); + tableDesiredSize.width = tableRect.width; + tableDesiredSize.height = tableRect.height; + tableDesiredSize.mOverflowArea = nsRect(0, 0, tableRect.width, + tableRect.height); for (PRUint32 rgX = 0; (rgX < numRowGroups); rgX++) { nsTableRowGroupFrame* rgFrame = aTableFrame.GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX)); + + nsRect rowGroupRect = rgFrame->GetRect(); + nsHTMLReflowMetrics groupDesiredSize(PR_FALSE); + groupDesiredSize.width = rowGroupRect.width; + groupDesiredSize.height = rowGroupRect.height; + groupDesiredSize.mOverflowArea = nsRect(0, 0, groupDesiredSize.width, + groupDesiredSize.height); nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { rowFrame->DidResize(aPresContext, aReflowState); + rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame); rowFrame = rowFrame->GetNextRow(); } + rgFrame->StoreOverflow(aPresContext, groupDesiredSize); + // make the coordinates of |desiredSize.mOverflowArea| incorrect + // since it's about to go away: + groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition()); + tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea); } + aTableFrame.StoreOverflow(aPresContext, tableDesiredSize); } void @@ -3489,7 +3562,7 @@ nsTableFrame::DistributeHeightToRows(nsIPresContext* aPresContext, nscoord cellSpacingY = GetCellSpacingY(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); nsVoidArray rowGroups; PRUint32 numRowGroups; @@ -4120,7 +4193,7 @@ nsTableFrame::CalcBorderBoxWidth(nsIPresContext* aPresContext, } } else if (width != NS_UNCONSTRAINEDSIZE) { - nsMargin borderPadding = GetContentAreaOffset(*aPresContext, &aState); + nsMargin borderPadding = GetContentAreaOffset(aPresContext, &aState); width += borderPadding.left + borderPadding.right; } width = PR_MAX(width, 0); @@ -4140,7 +4213,7 @@ nsTableFrame::CalcBorderBoxHeight(nsIPresContext* aPresContext, { nscoord height = aState.mComputedHeight; if (NS_AUTOHEIGHT != height) { - nsMargin borderPadding = GetContentAreaOffset(*aPresContext, &aState); + nsMargin borderPadding = GetContentAreaOffset(aPresContext, &aState); height += borderPadding.top + borderPadding.bottom; } height = PR_MAX(0, height); @@ -4204,7 +4277,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext, } // if it is not a degenerate table, add the last spacing on the right and the borderPadding if (numCols > 0) { - nsMargin childAreaOffset = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin childAreaOffset = GetChildAreaOffset(aPresContext, &aReflowState); nscoord extra = spacingX + childAreaOffset.left + childAreaOffset.right; aMinWidth += extra; aPrefWidth += extra; @@ -4231,7 +4304,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext, else { // a specified fix width becomes the min or preferred width nscoord compWidth = aReflowState.mComputedWidth; if ((NS_UNCONSTRAINEDSIZE != compWidth) && (0 != compWidth) && !isPctWidth) { - nsMargin contentOffset = GetContentAreaOffset(*aPresContext, &aReflowState); + nsMargin contentOffset = GetContentAreaOffset(aPresContext, &aReflowState); compWidth += contentOffset.left + contentOffset.right; aMinWidth = PR_MAX(aMinWidth, compWidth); aPrefWidth = PR_MAX(aMinWidth, compWidth); @@ -6565,7 +6638,7 @@ nsTableFrame::PaintBCBorders(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) { - nsMargin childAreaOffset = GetChildAreaOffset(*aPresContext, nsnull); + nsMargin childAreaOffset = GetChildAreaOffset(aPresContext, nsnull); nsTableFrame* firstInFlow = (nsTableFrame*)GetFirstInFlow(); if (!firstInFlow) ABORT0(); GET_PIXELS_TO_TWIPS(aPresContext, p2t); diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index 8e12f995cdd..3cb6546e133 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -272,11 +272,11 @@ public: nsIFrame* aOldFrame); // Get the offset from the border box to the area where the row groups fit - nsMargin GetChildAreaOffset(nsIPresContext& aPresContext, + nsMargin GetChildAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const; // Get the offset from the border box to the area where the content fits - nsMargin GetContentAreaOffset(nsIPresContext& aPresContext, + nsMargin GetContentAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const; /** helper method to find the table parent of any table frame object */ @@ -331,9 +331,11 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); - nsMargin* GetBCBorder(nsIPresContext& aPresContext, - PRBool aInnerBorderOnly, - nsMargin& aBorder) const; + nsMargin GetBCBorder(nsIPresContext* aPresContext) const; + + // get the area that the border leak out from the inner table frame into + // the surrounding margin space + nsMargin GetBCMargin(nsIPresContext* aPresContext) const; void SetBCDamageArea(nsIPresContext& aPresContext, const nsRect& aValue); @@ -615,6 +617,7 @@ protected: PRBool aDirtyOnly, nsReflowStatus& aStatus, nsIFrame*& aLastChildReflowed, + nsRect& aOverflowArea, PRBool* aReflowedAtLeastOne = nsnull); // begin incremental reflow methods @@ -716,7 +719,7 @@ protected: void PlaceChild(nsIPresContext* aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aKidDesiredSize); /** assign widths for each column, taking into account the table content, the effective style, * the layout constraints, and the compatibility mode. diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index 87ca85c3267..2c49f6ad116 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -469,7 +469,8 @@ nsTableOuterFrame::InitChildReflowState(nsIPresContext& aPresContext, if (mInnerTableFrame->NeedToCalcBCBorders()) { mInnerTableFrame->CalcBCBorders(aPresContext); } - pCollapseBorder = mInnerTableFrame->GetBCBorder(aPresContext, PR_FALSE, collapseBorder); + collapseBorder = mInnerTableFrame->GetBCBorder(&aPresContext); + pCollapseBorder = &collapseBorder; pCollapsePadding = &collapsePadding; } aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, pCollapsePadding); @@ -558,13 +559,21 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, PRUint8 aCaptionSide, nsSize& aOuterSize, PRBool aInnerChanged, - PRBool aCaptionChanged) + PRBool aCaptionChanged, + nsRect* aOldOverflowArea) { if (!aInnerChanged && !aCaptionChanged) return; nsRect damage; if (aInnerChanged && aCaptionChanged) { damage = nsRect(0, 0, aOuterSize.width, aOuterSize.height); + if (aOldOverflowArea) { + damage.UnionRect(damage, *aOldOverflowArea); + } + nsRect* overflowArea = GetOverflowAreaProperty(aPresContext); + if (overflowArea) { + damage.UnionRect(damage, *overflowArea); + } } else { nsRect captionRect(0,0,0,0); @@ -572,7 +581,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, if (mCaptionFrame) { captionRect = mCaptionFrame->GetRect(); } - // only works for vertical captions { + damage.x = 0; damage.width = aOuterSize.width; switch(aCaptionSide) { @@ -612,7 +621,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, damage.height = innerRect.YMost(); } break; - default: // NS_SIDE_LEFT + default: // NS_SIDE_TOP if (aCaptionChanged) { damage.y = 0; damage.height = innerRect.y; @@ -623,6 +632,12 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, } break; } + + nsIFrame* kidFrame = aCaptionChanged ? mCaptionFrame : mInnerTableFrame; + ConsiderChildOverflow(aPresContext, damage, kidFrame); + if (aOldOverflowArea) { + damage.UnionRect(damage, *aOldOverflowArea); + } } Invalidate(aPresContext, damage); } @@ -713,12 +728,12 @@ nsTableOuterFrame::GetInnerTableAvailWidth(nsIPresContext* aPresContext PRUint8 captionSide = GetCaptionSide(); switch (captionSide) { case NS_SIDE_LEFT: - if(captionWidth > marginIgnore.left) { + if (captionWidth > marginIgnore.left) { availWidth -= captionWidth - aInnerMargin.left; } break; case NS_SIDE_RIGHT: - if(captionWidth > marginIgnore.right) { + if (captionWidth > marginIgnore.right) { availWidth -= captionWidth - aInnerMargin.right; } break; @@ -748,7 +763,7 @@ nsTableOuterFrame::GetMaxElementWidth(PRUint8 aCaptionSide, } break; case NS_SIDE_RIGHT: - if(capWidth > aInnerMargin.right) { + if (capWidth > aInnerMargin.right) { width += capWidth - aInnerMargin.right; } break; @@ -1351,57 +1366,13 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext, if (aMet.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aMet.mMaximumWidth = GetMaxWidth(aCaptionSide, aInnerMarginNoAuto, aCaptionMarginNoAuto); } - // see if the caption or the inner table frame leaks out - // the overflow area of the inner table and caption frame needs to be factored in once - // one can retrieve them from the frames (see bug 197581) - switch (aCaptionSide) { - case NS_SIDE_LEFT: - aMet.mOverflowArea.x = PR_MIN(0, aCaptionMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(0, aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.top), aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.bottom), aInnerMarginNoAuto.bottom); - break; - case NS_SIDE_RIGHT: - aMet.mOverflowArea.x = PR_MIN(0, aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(0, aCaptionMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.top), aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.bottom), aInnerMarginNoAuto.bottom); - break; - case NS_SIDE_BOTTOM: - aMet.mOverflowArea.x = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.left), aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.right), aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(0, aCaptionMarginNoAuto.bottom); - break; - case NS_SIDE_TOP: - aMet.mOverflowArea.x = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.left), aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.right), aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aCaptionMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(0, aInnerMarginNoAuto.bottom); - break; - default: // no caption - aMet.mOverflowArea.x = PR_MIN(0, aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - PR_MIN(0, aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - PR_MIN(0, aInnerMarginNoAuto.bottom); + + aMet.mOverflowArea = nsRect(0, 0, aMet.width, aMet.height); + ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mInnerTableFrame); + if (mCaptionFrame) { + ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame); } - if ((aMet.mOverflowArea.x < 0) || - (aMet.mOverflowArea.y < 0) || - (aMet.mOverflowArea.XMost() > aMet.width) || - (aMet.mOverflowArea.YMost() > aMet.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } - else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + StoreOverflow(aPresContext, aMet); } nsresult @@ -1543,7 +1514,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex nsPoint captionOrigin; if (needInnerReflow) { nsSize innerSize; - nsHTMLReflowMetrics innerMet(nsnull); + nsHTMLReflowMetrics innerMet(PR_FALSE); nscoord availWidth = GetInnerTableAvailWidth(aPresContext, mInnerTableFrame, aOuterRS, &capMin, innerMargin, innerPadding); OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, availWidth, innerSize, @@ -1572,12 +1543,13 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aDesiredSize.width, aDesiredSize.height); PRBool innerMoved = (innerOrigin.x != prevInnerRect.x) || (innerOrigin.y != prevInnerRect.y); - InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE); + InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE, + oldOverflowArea); return rv; } @@ -1622,9 +1594,12 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext, aDesiredSize.height = innerRect.YMost() + innerMargin.bottom; sizeSet = PR_TRUE; // Repaint the inner's entire bounds if it moved - if ((innerRect.x != innerOrigin.x) || (innerRect.y != innerOrigin.y)) { - Invalidate(aPresContext, nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); - } + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + PRBool innerMoved = (innerRect.x != innerOrigin.x) || + (innerRect.y != innerOrigin.y); + InvalidateDamage(aPresContext, NO_SIDE, nsSize(aDesiredSize.width, + aDesiredSize.height), innerMoved, PR_FALSE, + oldOverflowArea); } if (!sizeSet) { // set our desired size to what it was before @@ -1774,11 +1749,13 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, if (aOuterMet.mComputeMEW) { aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth; } - + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aOuterMet, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aOuterMet.width, aOuterMet.height); - InvalidateDamage(aPresContext, captionSide, desSize, (innerSize.width != priorInnerSize.width), captionMoved); + InvalidateDamage(aPresContext, captionSide, desSize, + (innerSize.width != priorInnerSize.width), captionMoved, + oldOverflowArea); return rv; } @@ -1856,11 +1833,13 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext, rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aDesiredSize.width, aDesiredSize.height); PRBool innerMoved = innerOrigin != prevInnerOrigin; - InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE); + InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE, + oldOverflowArea); return rv; } @@ -2004,7 +1983,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, // reflow the caption nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, captionMargin, ignorePadding, &innerSize.width, &innerMarginNoAuto, &innerMargin); - nsHTMLReflowMetrics captionMet(nsnull); + nsHTMLReflowMetrics captionMet(PR_FALSE); nsReflowStatus capStatus; // don't let the caption cause incomplete rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, availWidth, captionSize, captionMargin, captionMarginNoAuto, diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h index f63c38d8244..dcceb619c5c 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.h +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h @@ -396,7 +396,8 @@ protected: PRUint8 aCaptionSide, nsSize& aOuterSize, PRBool aInnerChanged, - PRBool aCaptionChanged); + PRBool aCaptionChanged, + nsRect* aOldOverflowArea); // Get the margin and padding, aMarginNoAuto is aMargin, but with auto // margins set to 0 diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index 9558e6de846..d30a70947d6 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -213,27 +213,6 @@ nsTableRowFrame::Init(nsIPresContext* aPresContext, } -NS_IMETHODIMP -nsTableRowFrame::SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList) -{ - nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList); - // see if the row has a cell with a row span > 1 - for (nsIFrame* kidFrame = mFrames.FirstChild(); - kidFrame && !(GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN); - kidFrame = kidFrame->GetNextSibling()) { - nsCOMPtr frameType; - kidFrame->GetFrameType(getter_AddRefs(frameType)); - if (IS_TABLE_CELL(frameType.get())) { - if (((nsTableCellFrame*)kidFrame)->GetRowSpan() > 1) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } - } - } - return rv; -} - NS_IMETHODIMP nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, @@ -255,9 +234,6 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext, tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex()); // XXX this could be optimized with some effort tableFrame->SetNeedStrategyInit(PR_TRUE); - if (!(mState & NS_FRAME_OUTSIDE_CHILDREN) && (((nsTableCellFrame*)childFrame)->GetRowSpan() > 1)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } } } @@ -292,9 +268,6 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext, cellChildren.AppendElement(childFrame); // XXX this could be optimized with some effort tableFrame->SetNeedStrategyInit(PR_TRUE); - if (!(mState & NS_FRAME_OUTSIDE_CHILDREN) && (((nsTableCellFrame*)childFrame)->GetRowSpan() > 1)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } } } // insert the cells into the cell map @@ -398,9 +371,15 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, nsTableFrame* tableFrame; nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) return; - + nsTableIterator iter(aPresContext, *this, eTableDIR); nsIFrame* childFrame = iter.First(); + + nsHTMLReflowMetrics desiredSize(PR_FALSE); + desiredSize.width = mRect.width; + desiredSize.height = mRect.height; + desiredSize.mOverflowArea = nsRect(0, 0, desiredSize.width, + desiredSize.height); while (childFrame) { nsCOMPtr frameType; @@ -429,12 +408,13 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, //ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status); cellFrame->VerticallyAlignChild(aPresContext, aReflowState, mMaxCellAscent); + ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, cellFrame); } } // Get the next child childFrame = iter.Next(); } - + StoreOverflow(aPresContext, desiredSize); // Let our base class do the usual work } @@ -620,44 +600,6 @@ nsTableRowFrame::GetSkipSides() const return skip; } -/** overloaded method from nsContainerFrame. The difference is that - * we don't want to clip our children, so a cell can do a rowspan - */ -void nsTableRowFrame::PaintChildren(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer, - PRUint32 aFlags) -{ - nsIFrame* kid = mFrames.FirstChild(); - while (nsnull != kid) { - if (!kid->HasView()) { - nsRect kidRect = kid->GetRect(); - nsRect damageArea; - PRBool overlap = damageArea.IntersectRect(aDirtyRect, kidRect); - if (overlap) { - PRBool clipState; - // Translate damage area into kid's coordinate system - nsRect kidDamageArea(damageArea.x - kidRect.x, - damageArea.y - kidRect.y, - damageArea.width, damageArea.height); - aRenderingContext.PushState(); - aRenderingContext.Translate(kidRect.x, kidRect.y); - kid->Paint(aPresContext, aRenderingContext, kidDamageArea, - aWhichLayer, aFlags); -#ifdef DEBUG - if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && - GetShowFrameBorders()) { - aRenderingContext.SetColor(NS_RGB(255,0,0)); - aRenderingContext.DrawRect(0, 0, kidRect.width, kidRect.height); - } -#endif - aRenderingContext.PopState(clipState); - } - } - kid = kid->GetNextSibling(); - } -} /* we overload this here because rows have children that can span outside of themselves. * so the default "get the child rect, see if it contains the event point" action isn't @@ -969,7 +911,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex; - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); // If the avail width is not the same as last time we reflowed the cell or // the cell wants to be bigger than what was available last time or @@ -1061,7 +1003,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, nsSize priorSize = cellFrame->GetDesiredSize(); desiredSize.width = priorSize.width; desiredSize.height = priorSize.height; - + // if we are in a floated table, our position is not yet established, so we cannot reposition our views // the containing glock will do this for us after positioning the table if (!aTableFrame.GetStyleDisplay()->IsFloating()) { @@ -1099,13 +1041,14 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, } FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0); + x += desiredSize.width; } else {// it's an unknown frame type, give it a generic reflow and ignore the results nsTableCellReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsSize(0,0), eReflowReason_Resize); InitChildReflowState(*aPresContext, nsSize(0,0), PR_FALSE, p2t, kidReflowState); - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); nsReflowStatus status; ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status); kidFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED); @@ -1115,7 +1058,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, // we need to account for the cell's width even if it isn't reflowed x += kidFrame->GetSize().width; } - + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, kidFrame); kidFrame = iter.Next(); // Get the next child // if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan // if the last kid wasn't a colspan, then we still have the colspan of the last real cell @@ -1154,7 +1097,9 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, aDesiredSize.height = PR_MIN(aDesiredSize.height, aReflowState.availableHeight); } } - + nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height); + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect); + StoreOverflow(aPresContext, aDesiredSize); return rv; } @@ -1377,6 +1322,8 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, cellFrame->VerticallyAlignChild(aPresContext, aReflowState, mMaxCellAscent); nsRect dirtyRect = cellFrame->GetRect(); dirtyRect.height = mRect.height; + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cellFrame); + dirtyRect.UnionRect(dirtyRect, aDesiredSize.mOverflowArea); Invalidate(aPresContext, dirtyRect); } } @@ -1519,7 +1466,7 @@ nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext, eReflowReason_Resize); InitChildReflowState(*aPresContext, availSize, borderCollapse, p2t, cellReflowState); - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState, 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus); diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h index 85130f9244a..14fd196ef1a 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowFrame.h @@ -72,9 +72,6 @@ public: nsStyleContext* aContext, nsIFrame* aPrevInFlow); - NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList); NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, @@ -106,16 +103,6 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); - - /** ask all children to paint themselves, without clipping (for cells with rowspan>1) - * @see nsIFrame::Paint - */ - virtual void PaintChildren(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer, - PRUint32 aFlags = 0); - NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, @@ -141,8 +128,8 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); - virtual void DidResize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState); + void DidResize(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState); /** * Get the "type" of the frame diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 5d4f60741dc..4679910b738 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -377,7 +377,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, nsSize kidAvailSize(aReflowState.availSize); if (0 >= kidAvailSize.height) kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0; // Reflow the child into the available space, giving it as much height as @@ -442,6 +442,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, // Adjust the running y-offset so we know where the next row should be placed aReflowState.y += kidFrame->GetSize().height + cellSpacingY; } + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, kidFrame); } // adjust the rows after the ones that were reflowed @@ -503,6 +504,7 @@ UpdateHeights(RowInfo& aRowInfo, void nsTableRowGroupFrame::DidResizeRows(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, nsTableRowFrame* aStartRowFrameIn) { // update the cells spanning rows with their new heights @@ -510,8 +512,13 @@ nsTableRowGroupFrame::DidResizeRows(nsIPresContext& aPresContext, PRInt32 rowIndex; nsTableRowFrame* rowFrame; nsTableRowFrame* startRowFrame = (aStartRowFrameIn) ? aStartRowFrameIn: GetFirstRow(); + if (!aStartRowFrameIn || startRowFrame == GetFirstRow()) { + // Reset the overflow area + aDesiredSize.mOverflowArea = nsRect(0, 0, 0, 0); + } for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) { rowFrame->DidResize(&aPresContext, aReflowState); + ConsiderChildOverflow(&aPresContext, aDesiredSize.mOverflowArea, rowFrame); } } @@ -842,7 +849,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext, CacheRowHeightsForPrinting(aPresContext, GetFirstRow()); } - DidResizeRows(*aPresContext, aReflowState, startRowFrame); + DidResizeRows(*aPresContext, aReflowState, aDesiredSize, startRowFrame); aDesiredSize.height = rowGroupHeight; // Adjust our desired size delete [] rowInfo; // cleanup @@ -1068,7 +1075,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext, eReflowReason_Resize); InitChildReflowState(*aPresContext, borderCollapse, p2t, rowReflowState); rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page - nsHTMLReflowMetrics rowMetrics(nsnull); + nsHTMLReflowMetrics rowMetrics(PR_FALSE); // Reflow the cell with the constrained height. A cell with rowspan >1 will get this // reflow later during SplitSpanningCells. @@ -1287,7 +1294,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, // but we need to correctly calculate the row group height and we can't if there // are row spans unless we do this step if (aReflowState.mFlags.mSpecialHeightReflow) { - DidResizeRows(*aPresContext, aReflowState); + DidResizeRows(*aPresContext, aReflowState, aDesiredSize); if (isPaginated) { CacheRowHeightsForPrinting(aPresContext, GetFirstRow()); } @@ -1325,6 +1332,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.height = GetHeightOfRows(aPresContext); } + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width, + aDesiredSize.height)); + StoreOverflow(aPresContext, aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif @@ -1711,6 +1721,8 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext, } else { // Inform the row of its new height. ((nsTableRowFrame*)aNextFrame)->DidResize(aPresContext, aReflowState.reflowState); + // the overflow area may have changed inflate the overflow area + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, aNextFrame); if (aReflowState.tableFrame->IsAutoHeight()) { // Because other cells in the row may need to be be aligned differently, // repaint the entire row @@ -1853,7 +1865,7 @@ nsTableRowGroupFrame::GetBCBorderWidth(float aPixelsToTwips, nsTableRowFrame* firstRowFrame = nsnull; nsTableRowFrame* lastRowFrame = nsnull; for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) { - if(!firstRowFrame) { + if (!firstRowFrame) { firstRowFrame = rowFrame; } lastRowFrame = rowFrame; @@ -1899,21 +1911,21 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber, return NS_ERROR_FAILURE; nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; - if(aLineNumber >= cellMap->GetRowCount()) + if (aLineNumber >= cellMap->GetRowCount()) return NS_ERROR_INVALID_ARG; *aLineFlags = 0;/// should we fill these in later? // not gonna touch aLineBounds right now CellData* firstCellData = cellMap->GetDataAt(aLineNumber, 0); - if(!firstCellData) + if (!firstCellData) return NS_ERROR_FAILURE; *aFirstFrameOnLine = (nsIFrame*)firstCellData->GetCellFrame(); - if(!(*aFirstFrameOnLine)) + if (!(*aFirstFrameOnLine)) { while((aLineNumber > 0)&&(!(*aFirstFrameOnLine))) { @@ -1984,7 +1996,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, nsTableFrame* parentFrame = nsnull; nsTableFrame::GetTableFrame(this, parentFrame); nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; colCount = cellMap->GetColCount(); @@ -2002,7 +2014,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, continue; tempFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!tempFrame) + if (!tempFrame) continue; nsRect tempRect = tempFrame->GetRect();//offsetting x to be in row coordinates @@ -2016,13 +2028,13 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, gotParentRect = PR_TRUE; } - if(i==0 &&(aX <= 0))//short circuit for negative x coords + if (i==0 &&(aX <= 0))//short circuit for negative x coords { *aXIsBeforeFirstFrame = PR_TRUE; *aFrameFound = tempFrame; return NS_OK; } - if(aX < tempRect.x) + if (aX < tempRect.x) { return NS_ERROR_FAILURE; } @@ -2035,7 +2047,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, //x coord not found in frame, return last frame *aXIsAfterLastFrame = PR_TRUE; *aFrameFound = tempFrame; - if(!(*aFrameFound)) + if (!(*aFrameFound)) return NS_ERROR_FAILURE; return NS_OK; } @@ -2048,13 +2060,13 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, nsITableCellLayout* cellFrame; nsresult result = CallQueryInterface(aFrame, &cellFrame); - if(NS_FAILED(result)) + if (NS_FAILED(result)) return result; nsTableFrame* parentFrame = nsnull; result = nsTableFrame::GetTableFrame(this, parentFrame); nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; @@ -2064,10 +2076,10 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, CellData* cellData = cellMap->GetDataAt(aLineNumber, colIndex + 1); - if(!cellData)// if this isnt a valid cell, drop down and check the next line + if (!cellData)// if this isnt a valid cell, drop down and check the next line { cellData = cellMap->GetDataAt(aLineNumber + 1, 0); - if(!cellData) + if (!cellData) { //*aFrame = nsnull; return NS_ERROR_FAILURE; @@ -2075,19 +2087,19 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, } aFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!aFrame) + if (!aFrame) { //PRInt32 numCellsInRow = cellMap->GetNumCellsOriginatingInRow(aLineNumber) - 1; PRInt32 tempCol = colIndex + 1; PRInt32 tempRow = aLineNumber; - while((tempCol > 0) && (!aFrame)) + while ((tempCol > 0) && (!aFrame)) { tempCol--; cellData = cellMap->GetDataAt(aLineNumber, tempCol); aFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!aFrame && (tempCol==0)) + if (!aFrame && (tempCol==0)) { - while((tempRow > 0) && (!aFrame)) + while ((tempRow > 0) && (!aFrame)) { tempRow--; cellData = cellMap->GetDataAt(tempRow, 0); diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h index 94d3bae2125..1cb44d2fdb3 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.h @@ -272,6 +272,7 @@ protected: void DidResizeRows(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, nsTableRowFrame* aStartRowFrameIn = nsnull); /** Incremental Reflow attempts to do column balancing with the minimum number of reflow diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index b9543f33b27..5749485f6b8 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -219,7 +219,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont nscoord horOffset; // get the reduction in available horizontal space due to borders and padding if (mTableFrame->IsBorderCollapse()) { - nsMargin offset = mTableFrame->GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin offset = mTableFrame->GetChildAreaOffset(aPresContext, &aReflowState); horOffset = offset.left + offset.right; } else { @@ -1235,7 +1235,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(nsIPresContext& aPresCon rawPctValues[colX] = 0.0f; } - nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState); + nsMargin borderPadding = mTableFrame->GetContentAreaOffset(&aPresContext, &aReflowState); nscoord availWidth = aAvailWidthIn; if (NS_UNCONSTRAINEDSIZE != availWidth) { // adjust the avail width to exclude table border, padding and cell spacing @@ -1369,7 +1369,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(nsIPresContext& aPresCo : aAvailWidth; // adjust the basis to exclude table border, padding and cell spacing - nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState); + nsMargin borderPadding = mTableFrame->GetContentAreaOffset(&aPresContext, &aReflowState); basis -= borderPadding.left + borderPadding.right + mCellSpacingTotal; nscoord colPctTotal = 0; diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index 36699b96fb9..abc518dd7b5 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -345,7 +345,7 @@ nsTableCellFrame::DecorateForSelection(nsIPresContext* aPresContext, result = frameSelection->GetTableCellSelection(&tableCellSelectionMode); if (NS_SUCCEEDED(result) && tableCellSelectionMode) { nscolor bordercolor; - if(displaySelection == nsISelectionController::SELECTION_DISABLED) { + if (displaySelection == nsISelectionController::SELECTION_DISABLED) { bordercolor = NS_RGB(176,176,176);// disabled color } else { @@ -642,6 +642,12 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex kidYTop = nsTableFrame::RoundToPixel(kidYTop, p2t, eAlwaysRoundDown); } firstKid->SetPosition(nsPoint(kidRect.x, kidYTop)); + nsHTMLReflowMetrics desiredSize(PR_FALSE); + desiredSize.width = mRect.width; + desiredSize.height = mRect.height; + desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height); + ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid); + StoreOverflow(aPresContext, desiredSize); if (kidYTop != kidRect.y) { // Make sure any child views are correctly positioned. We know the inner table // cell won't have a view @@ -1018,6 +1024,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.ascent += kidSize.ascent; aDesiredSize.descent += kidSize.descent; + + // the overflow area will be computed when the child will be vertically aligned if (aDesiredSize.mComputeMEW) { aDesiredSize.mMaxElementWidth = diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 7a0a6f2cb00..0923c90d2d0 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -124,7 +124,7 @@ struct nsTableReflowState { reason = aReason; nsTableFrame* table = (nsTableFrame*)aTableFrame.GetFirstInFlow(); - nsMargin borderPadding = table->GetChildAreaOffset(aPresContext, &reflowState); + nsMargin borderPadding = table->GetChildAreaOffset(&aPresContext, &reflowState); x = borderPadding.left; y = borderPadding.top; @@ -1960,20 +1960,22 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, case eReflowReason_Initial: case eReflowReason_StyleChange: { if ((eReflowReason_Initial == aReflowState.reason) && HadInitialReflow()) { - // XXX put this back in when bug 70150 is fixed - // NS_ASSERTION(PR_FALSE, "intial reflow called twice"); + // XXX this could be an assertion and the if removed + NS_NOTREACHED("intial reflow called twice"); } else { if (!mPrevInFlow) { // only do pass1 on a first in flow if (IsAutoLayout()) { // only do pass1 reflow on an auto layout table - nsReflowReason reason = (eReflowReason_Initial == aReflowState.reason) - ? eReflowReason_Initial : eReflowReason_StyleChange; - nsTableReflowState reflowState(*aPresContext, aReflowState, *this, reason, - NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + nsTableReflowState reflowState(*aPresContext, aReflowState, *this, + aReflowState.reason, + NS_UNCONSTRAINEDSIZE, + NS_UNCONSTRAINEDSIZE); // reflow the children nsIFrame *lastReflowed; - ReflowChildren(aPresContext, reflowState, !HaveReflowedColGroups(), PR_FALSE, aStatus, lastReflowed); + ReflowChildren(aPresContext, reflowState, !HaveReflowedColGroups(), + PR_FALSE, aStatus, lastReflowed, + aDesiredSize.mOverflowArea); } mTableLayoutStrategy->Initialize(aPresContext, aReflowState); } @@ -1997,10 +1999,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, case eReflowReason_Resize: // do the resize reflow below if (!HadInitialReflow()) { - // NS_ASSERTION(HadInitialReflow(), "intial reflow not called"); + NS_ASSERTION(HadInitialReflow(), "intial reflow not called"); nextReason = eReflowReason_Initial; } - //NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth, "this doesn't do anything"); + NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth, + "this doesn't do anything"); SetNeedStrategyBalance(PR_TRUE); break; default: @@ -2061,9 +2064,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { // if there is an incomplete child, then set the desired height to include it but not the next one - nsRect childRect = lastChildReflowed->GetRect(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); - aDesiredSize.height = borderPadding.top + GetCellSpacingY() + childRect.height; + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); + aDesiredSize.height = borderPadding.top + GetCellSpacingY() + + lastChildReflowed->GetSize().height; } haveDesiredHeight = PR_TRUE; reflowedChildren = PR_TRUE; @@ -2088,7 +2091,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, ProcessRowInserted(aPresContext, *this, PR_TRUE, aDesiredSize.height); } - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); SetColumnDimensions(aPresContext, aDesiredSize.height, borderPadding); if (doCollapse) { AdjustForCollapsingRows(aPresContext, aDesiredSize.height); @@ -2122,7 +2125,14 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, if (aDesiredSize.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aDesiredSize.mMaximumWidth = GetPreferredWidth(); } - + if (NS_STYLE_OVERFLOW_HIDDEN != aReflowState.mStyleDisplay->mOverflow) { + // collapsed border may leak out + nsMargin bcMargin = GetBCMargin(aPresContext); + nsRect tableRect(0, 0, aDesiredSize.width, aDesiredSize.height) ; + tableRect.Inflate(bcMargin); + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, tableRect); + } + if (aReflowState.mFlags.mSpecialHeightReflow) { SetNeedSpecialReflow(PR_FALSE); SetNeedToInitiateSpecialReflow(PR_FALSE); @@ -2134,10 +2144,17 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, // If we reflowed all the rows, then invalidate the largest possible area that either the // table occupied before this reflow or will occupy after. if (reflowedChildren) { - Invalidate(aPresContext, nsRect(0, 0, PR_MAX(mRect.width, aDesiredSize.width), - PR_MAX(mRect.height, aDesiredSize.height))); + nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width), + PR_MAX(mRect.height, aDesiredSize.height)); + damage.UnionRect(damage, aDesiredSize.mOverflowArea); + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + if (oldOverflowArea) { + damage.UnionRect(damage, *oldOverflowArea); + } + Invalidate(aPresContext, damage); } + StoreOverflow(aPresContext, aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -2179,7 +2196,8 @@ nsTableFrame::ReflowTable(nsIPresContext* aPresContext, aDesiredSize.width = GetDesiredWidth(); nsTableReflowState reflowState(*aPresContext, aReflowState, *this, aReason, aDesiredSize.width, aAvailHeight); - ReflowChildren(aPresContext, reflowState, haveReflowedColGroups, PR_FALSE, aStatus, aLastChildReflowed); + ReflowChildren(aPresContext, reflowState, haveReflowedColGroups, PR_FALSE, + aStatus, aLastChildReflowed, aDesiredSize.mOverflowArea); if (eReflowReason_Resize == aReflowState.reason) { if (!DidResizeReflow()) { @@ -2739,7 +2757,9 @@ nsTableFrame::IR_TargetIsMe(nsIPresContext* aPresContext, aReflowState.availSize.width, aReflowState.availSize.height); nsIFrame* lastReflowed; PRBool reflowedAtLeastOne; - ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_TRUE, aStatus, lastReflowed, &reflowedAtLeastOne); + nsRect overflowArea; + ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_TRUE, aStatus, + lastReflowed, overflowArea, &reflowedAtLeastOne); if (!reflowedAtLeastOne) // XXX For now assume the worse SetNeedStrategyInit(PR_TRUE); @@ -2761,7 +2781,8 @@ NS_METHOD nsTableFrame::IR_StyleChanged(nsIPresContext* aPresContext, nsTableReflowState reflowState(*aPresContext, aReflowState.reflowState, *this, eReflowReason_StyleChange, aReflowState.availSize.width, aReflowState.availSize.height); nsIFrame* lastReflowed; - return ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_FALSE, aStatus, lastReflowed); + nsRect overflowArea; + return ReflowChildren(aPresContext, reflowState, PR_FALSE, PR_FALSE, aStatus, lastReflowed, overflowArea); } static void @@ -2773,47 +2794,74 @@ DivideBCBorderSize(nscoord aPixelSize, aLargeHalf = ((aSmallHalf + aSmallHalf) < aPixelSize) ? aSmallHalf + 1 : aSmallHalf; } -nsMargin* -nsTableFrame::GetBCBorder(nsIPresContext& aPresContext, - PRBool aInnerBorderOnly, - nsMargin& aBorder) const +nsMargin +nsTableFrame::GetBCBorder(nsIPresContext* aPresContext) const { - aBorder.top = aBorder.right = aBorder.bottom = aBorder.left = 0; + nsMargin border(0, 0, 0, 0); - GET_PIXELS_TO_TWIPS(&aPresContext, p2t); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); BCPropertyData* propData = - (BCPropertyData*)nsTableFrame::GetProperty(&aPresContext, (nsIFrame*)this, nsLayoutAtoms::tableBCProperty, PR_FALSE); + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)this, nsLayoutAtoms::tableBCProperty, PR_FALSE); if (propData) { nsCompatibility mode; - aPresContext.GetCompatibilityMode(&mode); - if ((eCompatibility_NavQuirks != mode) || aInnerBorderOnly) { + aPresContext->GetCompatibilityMode(&mode); + if (eCompatibility_NavQuirks != mode) { nscoord smallHalf, largeHalf; DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); - aBorder.top += NSToCoordRound(p2t * (float)smallHalf); + border.top += NSToCoordRound(p2t * (float)smallHalf); DivideBCBorderSize(propData->mRightBorderWidth, smallHalf, largeHalf); - aBorder.right += NSToCoordRound(p2t * (float)largeHalf); + border.right += NSToCoordRound(p2t * (float)largeHalf); DivideBCBorderSize(propData->mBottomBorderWidth, smallHalf, largeHalf); - aBorder.bottom += NSToCoordRound(p2t * (float)largeHalf); + border.bottom += NSToCoordRound(p2t * (float)largeHalf); DivideBCBorderSize(propData->mLeftBorderWidth, smallHalf, largeHalf); - aBorder.left += NSToCoordRound(p2t * (float)smallHalf); + border.left += NSToCoordRound(p2t * (float)smallHalf); } else { - aBorder.top += NSToCoordRound(p2t * (float)propData->mTopBorderWidth); - aBorder.right += NSToCoordRound(p2t * (float)propData->mRightBorderWidth); - aBorder.bottom += NSToCoordRound(p2t * (float)propData->mBottomBorderWidth); - aBorder.left += NSToCoordRound(p2t * (float)propData->mLeftBorderWidth); + border.top += NSToCoordRound(p2t * (float)propData->mTopBorderWidth); + border.right += NSToCoordRound(p2t * (float)propData->mRightBorderWidth); + border.bottom += NSToCoordRound(p2t * (float)propData->mBottomBorderWidth); + border.left += NSToCoordRound(p2t * (float)propData->mLeftBorderWidth); } } - return &aBorder; + return border; } +nsMargin +nsTableFrame::GetBCMargin(nsIPresContext* aPresContext) const +{ + nsMargin overflow(0, 0, 0, 0); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); + BCPropertyData* propData = + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)this, + nsLayoutAtoms::tableBCProperty, + PR_FALSE); + if (propData) { + nsCompatibility mode; + aPresContext->GetCompatibilityMode(&mode); + if (eCompatibility_NavQuirks != mode) { + nscoord smallHalf, largeHalf; + + DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); + overflow.top += NSToCoordRound(p2t * (float)largeHalf); + + DivideBCBorderSize(propData->mRightBorderWidth, smallHalf, largeHalf); + overflow.right += NSToCoordRound(p2t * (float)smallHalf); + + DivideBCBorderSize(propData->mBottomBorderWidth, smallHalf, largeHalf); + overflow.bottom += NSToCoordRound(p2t * (float)smallHalf); + + DivideBCBorderSize(propData->mLeftBorderWidth, smallHalf, largeHalf); + overflow.left += NSToCoordRound(p2t * (float)largeHalf); + } + } + return overflow; +} static -void GetSeparateModelBorderPadding(nsIPresContext& aPresContext, - const nsHTMLReflowState* aReflowState, +void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState, nsStyleContext& aStyleContext, nsMargin& aBorderPadding) { @@ -2825,19 +2873,19 @@ void GetSeparateModelBorderPadding(nsIPresContext& aPresContext, } nsMargin -nsTableFrame::GetChildAreaOffset(nsIPresContext& aPresContext, +nsTableFrame::GetChildAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const { nsMargin offset(0,0,0,0); if (IsBorderCollapse()) { nsCompatibility mode; - aPresContext.GetCompatibilityMode(&mode); + aPresContext->GetCompatibilityMode(&mode); if (eCompatibility_NavQuirks == mode) { nsTableFrame* firstInFlow = (nsTableFrame*)GetFirstInFlow(); if (!firstInFlow) ABORT1(offset); nscoord smallHalf, largeHalf; - GET_PIXELS_TO_TWIPS(&aPresContext, p2t); + GET_PIXELS_TO_TWIPS(aPresContext, p2t); BCPropertyData* propData = - (BCPropertyData*)nsTableFrame::GetProperty(&aPresContext, (nsIFrame*)firstInFlow, nsLayoutAtoms::tableBCProperty, PR_FALSE); + (BCPropertyData*)nsTableFrame::GetProperty(aPresContext, (nsIFrame*)firstInFlow, nsLayoutAtoms::tableBCProperty, PR_FALSE); if (!propData) ABORT1(offset); DivideBCBorderSize(propData->mTopBorderWidth, smallHalf, largeHalf); @@ -2854,23 +2902,21 @@ nsTableFrame::GetChildAreaOffset(nsIPresContext& aPresContext, } } else { - if (!mStyleContext) ABORT1(offset); - GetSeparateModelBorderPadding(aPresContext, aReflowState, *mStyleContext, offset); + GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset); } return offset; } nsMargin -nsTableFrame::GetContentAreaOffset(nsIPresContext& aPresContext, +nsTableFrame::GetContentAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const { nsMargin offset(0,0,0,0); if (IsBorderCollapse()) { - GetBCBorder(aPresContext, PR_FALSE, offset); + offset = GetBCBorder(aPresContext); } else { - if (!mStyleContext) ABORT1(offset); - GetSeparateModelBorderPadding(aPresContext, aReflowState, *mStyleContext, offset); + GetSeparateModelBorderPadding(aReflowState, *mStyleContext, offset); } return offset; } @@ -2883,7 +2929,7 @@ nsTableFrame::RecoverState(nsIPresContext& aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame) { - nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState.reflowState); + nsMargin borderPadding = GetChildAreaOffset(&aPresContext, &aReflowState.reflowState); aReflowState.y = borderPadding.top; nscoord cellSpacingY = GetCellSpacingY(); @@ -2970,7 +3016,7 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, nsRect oldKidRect = aNextFrame->GetRect(); // Pass along the reflow command, don't request a max element size, rows will do that - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); nsSize kidAvailSize(aReflowState.availSize); nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, aNextFrame, kidAvailSize, aReflowState.reason); @@ -3027,17 +3073,19 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, void nsTableFrame::PlaceChild(nsIPresContext* aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame, - nsHTMLReflowMetrics& aDesiredSize) + nsHTMLReflowMetrics& aKidDesiredSize) { + // Place and size the child - FinishReflowChild(aKidFrame, aPresContext, nsnull, aDesiredSize, aReflowState.x, aReflowState.y, 0); + FinishReflowChild(aKidFrame, aPresContext, nsnull, aKidDesiredSize, + aReflowState.x, aReflowState.y, 0); // Adjust the running y-offset - aReflowState.y += aDesiredSize.height; + aReflowState.y += aKidDesiredSize.height; // If our height is constrained, then update the available height if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) { - aReflowState.availSize.height -= aDesiredSize.height; + aReflowState.availSize.height -= aKidDesiredSize.height; } const nsStyleDisplay* childDisplay = aKidFrame->GetStyleDisplay(); @@ -3157,6 +3205,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, PRBool aDirtyOnly, nsReflowStatus& aStatus, nsIFrame*& aLastChildReflowed, + nsRect& aOverflowArea, PRBool* aReflowedAtLeastOne) { aStatus = NS_FRAME_COMPLETE; @@ -3169,6 +3218,8 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, PRBool isPaginated; aPresContext->IsPaginated(&isPaginated); + aOverflowArea = nsRect (0, 0, 0, 0); + nsAutoVoidArray rowGroups; PRUint32 numRowGroups; nsTableRowGroupFrame *thead, *tfoot; @@ -3210,7 +3261,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, } } - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0; if (childX < numRowGroups) { @@ -3244,6 +3295,7 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, nsIFrame* nextKid = (childX + 1 < numRowGroups) ? (nsIFrame*)rowGroups.ElementAt(childX + 1) : nsnull; pageBreak = PageBreakAfter(*kidFrame, nextKid); } + // Place the child PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize); @@ -3303,11 +3355,12 @@ nsTableFrame::ReflowChildren(nsIPresContext* aPresContext, } aReflowState.y += cellSpacingY + kidRect.height; } + ConsiderChildOverflow(aPresContext, aOverflowArea, kidFrame); } - + // if required, give the colgroups their initial reflows if (aDoColGroups) { - nsHTMLReflowMetrics kidMet(nsnull); + nsHTMLReflowMetrics kidMet(PR_FALSE); for (nsIFrame* kidFrame = mColGroups.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame, @@ -3410,7 +3463,7 @@ nsTableFrame::CalcDesiredWidth(nsIPresContext& aPresContext, tableWidth = PR_MAX(tableWidth, compWidth); // Add the width between the border edge and the child area - nsMargin childOffset = GetChildAreaOffset(aPresContext, &aReflowState); + nsMargin childOffset = GetChildAreaOffset(&aPresContext, &aReflowState); tableWidth += childOffset.left + childOffset.right; return tableWidth; @@ -3427,7 +3480,7 @@ nsTableFrame::CalcDesiredHeight(nsIPresContext* aPresContext, return 0; } nscoord cellSpacingY = GetCellSpacingY(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); // get the natural height based on the last child's (row group or scroll frame) rect nsAutoVoidArray rowGroups; @@ -3468,15 +3521,35 @@ void ResizeCells(nsTableFrame& aTableFrame, nsAutoVoidArray rowGroups; PRUint32 numRowGroups; aTableFrame.OrderRowGroups(rowGroups, numRowGroups, nsnull); + nsHTMLReflowMetrics tableDesiredSize(PR_FALSE); + nsRect tableRect = aTableFrame.GetRect(); + tableDesiredSize.width = tableRect.width; + tableDesiredSize.height = tableRect.height; + tableDesiredSize.mOverflowArea = nsRect(0, 0, tableRect.width, + tableRect.height); for (PRUint32 rgX = 0; (rgX < numRowGroups); rgX++) { nsTableRowGroupFrame* rgFrame = aTableFrame.GetRowGroupFrame((nsIFrame*)rowGroups.ElementAt(rgX)); + + nsRect rowGroupRect = rgFrame->GetRect(); + nsHTMLReflowMetrics groupDesiredSize(PR_FALSE); + groupDesiredSize.width = rowGroupRect.width; + groupDesiredSize.height = rowGroupRect.height; + groupDesiredSize.mOverflowArea = nsRect(0, 0, groupDesiredSize.width, + groupDesiredSize.height); nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { rowFrame->DidResize(aPresContext, aReflowState); + rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame); rowFrame = rowFrame->GetNextRow(); } + rgFrame->StoreOverflow(aPresContext, groupDesiredSize); + // make the coordinates of |desiredSize.mOverflowArea| incorrect + // since it's about to go away: + groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition()); + tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea); } + aTableFrame.StoreOverflow(aPresContext, tableDesiredSize); } void @@ -3489,7 +3562,7 @@ nsTableFrame::DistributeHeightToRows(nsIPresContext* aPresContext, nscoord cellSpacingY = GetCellSpacingY(); - nsMargin borderPadding = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin borderPadding = GetChildAreaOffset(aPresContext, &aReflowState); nsVoidArray rowGroups; PRUint32 numRowGroups; @@ -4120,7 +4193,7 @@ nsTableFrame::CalcBorderBoxWidth(nsIPresContext* aPresContext, } } else if (width != NS_UNCONSTRAINEDSIZE) { - nsMargin borderPadding = GetContentAreaOffset(*aPresContext, &aState); + nsMargin borderPadding = GetContentAreaOffset(aPresContext, &aState); width += borderPadding.left + borderPadding.right; } width = PR_MAX(width, 0); @@ -4140,7 +4213,7 @@ nsTableFrame::CalcBorderBoxHeight(nsIPresContext* aPresContext, { nscoord height = aState.mComputedHeight; if (NS_AUTOHEIGHT != height) { - nsMargin borderPadding = GetContentAreaOffset(*aPresContext, &aState); + nsMargin borderPadding = GetContentAreaOffset(aPresContext, &aState); height += borderPadding.top + borderPadding.bottom; } height = PR_MAX(0, height); @@ -4204,7 +4277,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext, } // if it is not a degenerate table, add the last spacing on the right and the borderPadding if (numCols > 0) { - nsMargin childAreaOffset = GetChildAreaOffset(*aPresContext, &aReflowState); + nsMargin childAreaOffset = GetChildAreaOffset(aPresContext, &aReflowState); nscoord extra = spacingX + childAreaOffset.left + childAreaOffset.right; aMinWidth += extra; aPrefWidth += extra; @@ -4231,7 +4304,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext, else { // a specified fix width becomes the min or preferred width nscoord compWidth = aReflowState.mComputedWidth; if ((NS_UNCONSTRAINEDSIZE != compWidth) && (0 != compWidth) && !isPctWidth) { - nsMargin contentOffset = GetContentAreaOffset(*aPresContext, &aReflowState); + nsMargin contentOffset = GetContentAreaOffset(aPresContext, &aReflowState); compWidth += contentOffset.left + contentOffset.right; aMinWidth = PR_MAX(aMinWidth, compWidth); aPrefWidth = PR_MAX(aMinWidth, compWidth); @@ -6565,7 +6638,7 @@ nsTableFrame::PaintBCBorders(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) { - nsMargin childAreaOffset = GetChildAreaOffset(*aPresContext, nsnull); + nsMargin childAreaOffset = GetChildAreaOffset(aPresContext, nsnull); nsTableFrame* firstInFlow = (nsTableFrame*)GetFirstInFlow(); if (!firstInFlow) ABORT0(); GET_PIXELS_TO_TWIPS(aPresContext, p2t); diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 8e12f995cdd..3cb6546e133 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -272,11 +272,11 @@ public: nsIFrame* aOldFrame); // Get the offset from the border box to the area where the row groups fit - nsMargin GetChildAreaOffset(nsIPresContext& aPresContext, + nsMargin GetChildAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const; // Get the offset from the border box to the area where the content fits - nsMargin GetContentAreaOffset(nsIPresContext& aPresContext, + nsMargin GetContentAreaOffset(nsIPresContext* aPresContext, const nsHTMLReflowState* aReflowState) const; /** helper method to find the table parent of any table frame object */ @@ -331,9 +331,11 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); - nsMargin* GetBCBorder(nsIPresContext& aPresContext, - PRBool aInnerBorderOnly, - nsMargin& aBorder) const; + nsMargin GetBCBorder(nsIPresContext* aPresContext) const; + + // get the area that the border leak out from the inner table frame into + // the surrounding margin space + nsMargin GetBCMargin(nsIPresContext* aPresContext) const; void SetBCDamageArea(nsIPresContext& aPresContext, const nsRect& aValue); @@ -615,6 +617,7 @@ protected: PRBool aDirtyOnly, nsReflowStatus& aStatus, nsIFrame*& aLastChildReflowed, + nsRect& aOverflowArea, PRBool* aReflowedAtLeastOne = nsnull); // begin incremental reflow methods @@ -716,7 +719,7 @@ protected: void PlaceChild(nsIPresContext* aPresContext, nsTableReflowState& aReflowState, nsIFrame* aKidFrame, - nsHTMLReflowMetrics& aDesiredSize); + nsHTMLReflowMetrics& aKidDesiredSize); /** assign widths for each column, taking into account the table content, the effective style, * the layout constraints, and the compatibility mode. diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index 87ca85c3267..2c49f6ad116 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -469,7 +469,8 @@ nsTableOuterFrame::InitChildReflowState(nsIPresContext& aPresContext, if (mInnerTableFrame->NeedToCalcBCBorders()) { mInnerTableFrame->CalcBCBorders(aPresContext); } - pCollapseBorder = mInnerTableFrame->GetBCBorder(aPresContext, PR_FALSE, collapseBorder); + collapseBorder = mInnerTableFrame->GetBCBorder(&aPresContext); + pCollapseBorder = &collapseBorder; pCollapsePadding = &collapsePadding; } aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, pCollapsePadding); @@ -558,13 +559,21 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, PRUint8 aCaptionSide, nsSize& aOuterSize, PRBool aInnerChanged, - PRBool aCaptionChanged) + PRBool aCaptionChanged, + nsRect* aOldOverflowArea) { if (!aInnerChanged && !aCaptionChanged) return; nsRect damage; if (aInnerChanged && aCaptionChanged) { damage = nsRect(0, 0, aOuterSize.width, aOuterSize.height); + if (aOldOverflowArea) { + damage.UnionRect(damage, *aOldOverflowArea); + } + nsRect* overflowArea = GetOverflowAreaProperty(aPresContext); + if (overflowArea) { + damage.UnionRect(damage, *overflowArea); + } } else { nsRect captionRect(0,0,0,0); @@ -572,7 +581,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, if (mCaptionFrame) { captionRect = mCaptionFrame->GetRect(); } - // only works for vertical captions { + damage.x = 0; damage.width = aOuterSize.width; switch(aCaptionSide) { @@ -612,7 +621,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, damage.height = innerRect.YMost(); } break; - default: // NS_SIDE_LEFT + default: // NS_SIDE_TOP if (aCaptionChanged) { damage.y = 0; damage.height = innerRect.y; @@ -623,6 +632,12 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, } break; } + + nsIFrame* kidFrame = aCaptionChanged ? mCaptionFrame : mInnerTableFrame; + ConsiderChildOverflow(aPresContext, damage, kidFrame); + if (aOldOverflowArea) { + damage.UnionRect(damage, *aOldOverflowArea); + } } Invalidate(aPresContext, damage); } @@ -713,12 +728,12 @@ nsTableOuterFrame::GetInnerTableAvailWidth(nsIPresContext* aPresContext PRUint8 captionSide = GetCaptionSide(); switch (captionSide) { case NS_SIDE_LEFT: - if(captionWidth > marginIgnore.left) { + if (captionWidth > marginIgnore.left) { availWidth -= captionWidth - aInnerMargin.left; } break; case NS_SIDE_RIGHT: - if(captionWidth > marginIgnore.right) { + if (captionWidth > marginIgnore.right) { availWidth -= captionWidth - aInnerMargin.right; } break; @@ -748,7 +763,7 @@ nsTableOuterFrame::GetMaxElementWidth(PRUint8 aCaptionSide, } break; case NS_SIDE_RIGHT: - if(capWidth > aInnerMargin.right) { + if (capWidth > aInnerMargin.right) { width += capWidth - aInnerMargin.right; } break; @@ -1351,57 +1366,13 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext, if (aMet.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aMet.mMaximumWidth = GetMaxWidth(aCaptionSide, aInnerMarginNoAuto, aCaptionMarginNoAuto); } - // see if the caption or the inner table frame leaks out - // the overflow area of the inner table and caption frame needs to be factored in once - // one can retrieve them from the frames (see bug 197581) - switch (aCaptionSide) { - case NS_SIDE_LEFT: - aMet.mOverflowArea.x = PR_MIN(0, aCaptionMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(0, aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.top), aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.bottom), aInnerMarginNoAuto.bottom); - break; - case NS_SIDE_RIGHT: - aMet.mOverflowArea.x = PR_MIN(0, aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(0, aCaptionMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.top), aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.bottom), aInnerMarginNoAuto.bottom); - break; - case NS_SIDE_BOTTOM: - aMet.mOverflowArea.x = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.left), aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.right), aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(0, aCaptionMarginNoAuto.bottom); - break; - case NS_SIDE_TOP: - aMet.mOverflowArea.x = PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.left), aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - - PR_MIN(PR_MIN(0, aCaptionMarginNoAuto.right), aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aCaptionMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - - PR_MIN(0, aInnerMarginNoAuto.bottom); - break; - default: // no caption - aMet.mOverflowArea.x = PR_MIN(0, aInnerMarginNoAuto.left); - aMet.mOverflowArea.width = aMet.width - aMet.mOverflowArea.x - PR_MIN(0, aInnerMarginNoAuto.right); - aMet.mOverflowArea.y = PR_MIN(0, aInnerMarginNoAuto.top); - aMet.mOverflowArea.height = aMet.height - aMet.mOverflowArea.y - PR_MIN(0, aInnerMarginNoAuto.bottom); + + aMet.mOverflowArea = nsRect(0, 0, aMet.width, aMet.height); + ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mInnerTableFrame); + if (mCaptionFrame) { + ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame); } - if ((aMet.mOverflowArea.x < 0) || - (aMet.mOverflowArea.y < 0) || - (aMet.mOverflowArea.XMost() > aMet.width) || - (aMet.mOverflowArea.YMost() > aMet.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } - else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + StoreOverflow(aPresContext, aMet); } nsresult @@ -1543,7 +1514,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex nsPoint captionOrigin; if (needInnerReflow) { nsSize innerSize; - nsHTMLReflowMetrics innerMet(nsnull); + nsHTMLReflowMetrics innerMet(PR_FALSE); nscoord availWidth = GetInnerTableAvailWidth(aPresContext, mInnerTableFrame, aOuterRS, &capMin, innerMargin, innerPadding); OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, availWidth, innerSize, @@ -1572,12 +1543,13 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aDesiredSize.width, aDesiredSize.height); PRBool innerMoved = (innerOrigin.x != prevInnerRect.x) || (innerOrigin.y != prevInnerRect.y); - InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE); + InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE, + oldOverflowArea); return rv; } @@ -1622,9 +1594,12 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext, aDesiredSize.height = innerRect.YMost() + innerMargin.bottom; sizeSet = PR_TRUE; // Repaint the inner's entire bounds if it moved - if ((innerRect.x != innerOrigin.x) || (innerRect.y != innerOrigin.y)) { - Invalidate(aPresContext, nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); - } + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + PRBool innerMoved = (innerRect.x != innerOrigin.x) || + (innerRect.y != innerOrigin.y); + InvalidateDamage(aPresContext, NO_SIDE, nsSize(aDesiredSize.width, + aDesiredSize.height), innerMoved, PR_FALSE, + oldOverflowArea); } if (!sizeSet) { // set our desired size to what it was before @@ -1774,11 +1749,13 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, if (aOuterMet.mComputeMEW) { aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth; } - + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aOuterMet, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aOuterMet.width, aOuterMet.height); - InvalidateDamage(aPresContext, captionSide, desSize, (innerSize.width != priorInnerSize.width), captionMoved); + InvalidateDamage(aPresContext, captionSide, desSize, + (innerSize.width != priorInnerSize.width), captionMoved, + oldOverflowArea); return rv; } @@ -1856,11 +1833,13 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext, rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); + nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); UpdateReflowMetrics(aPresContext, captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, innerPadding, captionMargin, captionMarginNoAuto, aOuterRS.availableWidth); nsSize desSize(aDesiredSize.width, aDesiredSize.height); PRBool innerMoved = innerOrigin != prevInnerOrigin; - InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE); + InvalidateDamage(aPresContext, captionSide, desSize, innerMoved, PR_TRUE, + oldOverflowArea); return rv; } @@ -2004,7 +1983,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, // reflow the caption nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, captionMargin, ignorePadding, &innerSize.width, &innerMarginNoAuto, &innerMargin); - nsHTMLReflowMetrics captionMet(nsnull); + nsHTMLReflowMetrics captionMet(PR_FALSE); nsReflowStatus capStatus; // don't let the caption cause incomplete rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, availWidth, captionSize, captionMargin, captionMarginNoAuto, diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h index f63c38d8244..dcceb619c5c 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.h +++ b/mozilla/layout/tables/nsTableOuterFrame.h @@ -396,7 +396,8 @@ protected: PRUint8 aCaptionSide, nsSize& aOuterSize, PRBool aInnerChanged, - PRBool aCaptionChanged); + PRBool aCaptionChanged, + nsRect* aOldOverflowArea); // Get the margin and padding, aMarginNoAuto is aMargin, but with auto // margins set to 0 diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index 9558e6de846..d30a70947d6 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -213,27 +213,6 @@ nsTableRowFrame::Init(nsIPresContext* aPresContext, } -NS_IMETHODIMP -nsTableRowFrame::SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList) -{ - nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList); - // see if the row has a cell with a row span > 1 - for (nsIFrame* kidFrame = mFrames.FirstChild(); - kidFrame && !(GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN); - kidFrame = kidFrame->GetNextSibling()) { - nsCOMPtr frameType; - kidFrame->GetFrameType(getter_AddRefs(frameType)); - if (IS_TABLE_CELL(frameType.get())) { - if (((nsTableCellFrame*)kidFrame)->GetRowSpan() > 1) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } - } - } - return rv; -} - NS_IMETHODIMP nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, @@ -255,9 +234,6 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext, tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex()); // XXX this could be optimized with some effort tableFrame->SetNeedStrategyInit(PR_TRUE); - if (!(mState & NS_FRAME_OUTSIDE_CHILDREN) && (((nsTableCellFrame*)childFrame)->GetRowSpan() > 1)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } } } @@ -292,9 +268,6 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext, cellChildren.AppendElement(childFrame); // XXX this could be optimized with some effort tableFrame->SetNeedStrategyInit(PR_TRUE); - if (!(mState & NS_FRAME_OUTSIDE_CHILDREN) && (((nsTableCellFrame*)childFrame)->GetRowSpan() > 1)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } } } // insert the cells into the cell map @@ -398,9 +371,15 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, nsTableFrame* tableFrame; nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) return; - + nsTableIterator iter(aPresContext, *this, eTableDIR); nsIFrame* childFrame = iter.First(); + + nsHTMLReflowMetrics desiredSize(PR_FALSE); + desiredSize.width = mRect.width; + desiredSize.height = mRect.height; + desiredSize.mOverflowArea = nsRect(0, 0, desiredSize.width, + desiredSize.height); while (childFrame) { nsCOMPtr frameType; @@ -429,12 +408,13 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, //ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status); cellFrame->VerticallyAlignChild(aPresContext, aReflowState, mMaxCellAscent); + ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, cellFrame); } } // Get the next child childFrame = iter.Next(); } - + StoreOverflow(aPresContext, desiredSize); // Let our base class do the usual work } @@ -620,44 +600,6 @@ nsTableRowFrame::GetSkipSides() const return skip; } -/** overloaded method from nsContainerFrame. The difference is that - * we don't want to clip our children, so a cell can do a rowspan - */ -void nsTableRowFrame::PaintChildren(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer, - PRUint32 aFlags) -{ - nsIFrame* kid = mFrames.FirstChild(); - while (nsnull != kid) { - if (!kid->HasView()) { - nsRect kidRect = kid->GetRect(); - nsRect damageArea; - PRBool overlap = damageArea.IntersectRect(aDirtyRect, kidRect); - if (overlap) { - PRBool clipState; - // Translate damage area into kid's coordinate system - nsRect kidDamageArea(damageArea.x - kidRect.x, - damageArea.y - kidRect.y, - damageArea.width, damageArea.height); - aRenderingContext.PushState(); - aRenderingContext.Translate(kidRect.x, kidRect.y); - kid->Paint(aPresContext, aRenderingContext, kidDamageArea, - aWhichLayer, aFlags); -#ifdef DEBUG - if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && - GetShowFrameBorders()) { - aRenderingContext.SetColor(NS_RGB(255,0,0)); - aRenderingContext.DrawRect(0, 0, kidRect.width, kidRect.height); - } -#endif - aRenderingContext.PopState(clipState); - } - } - kid = kid->GetNextSibling(); - } -} /* we overload this here because rows have children that can span outside of themselves. * so the default "get the child rect, see if it contains the event point" action isn't @@ -969,7 +911,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex; - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); // If the avail width is not the same as last time we reflowed the cell or // the cell wants to be bigger than what was available last time or @@ -1061,7 +1003,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, nsSize priorSize = cellFrame->GetDesiredSize(); desiredSize.width = priorSize.width; desiredSize.height = priorSize.height; - + // if we are in a floated table, our position is not yet established, so we cannot reposition our views // the containing glock will do this for us after positioning the table if (!aTableFrame.GetStyleDisplay()->IsFloating()) { @@ -1099,13 +1041,14 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, } FinishReflowChild(kidFrame, aPresContext, nsnull, desiredSize, x, 0, 0); + x += desiredSize.width; } else {// it's an unknown frame type, give it a generic reflow and ignore the results nsTableCellReflowState kidReflowState(aPresContext, aReflowState, kidFrame, nsSize(0,0), eReflowReason_Resize); InitChildReflowState(*aPresContext, nsSize(0,0), PR_FALSE, p2t, kidReflowState); - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); nsReflowStatus status; ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status); kidFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED); @@ -1115,7 +1058,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, // we need to account for the cell's width even if it isn't reflowed x += kidFrame->GetSize().width; } - + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, kidFrame); kidFrame = iter.Next(); // Get the next child // if this was the last child, and it had a colspan>1, add in the cellSpacing for the colspan // if the last kid wasn't a colspan, then we still have the colspan of the last real cell @@ -1154,7 +1097,9 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, aDesiredSize.height = PR_MIN(aDesiredSize.height, aReflowState.availableHeight); } } - + nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height); + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect); + StoreOverflow(aPresContext, aDesiredSize); return rv; } @@ -1377,6 +1322,8 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, cellFrame->VerticallyAlignChild(aPresContext, aReflowState, mMaxCellAscent); nsRect dirtyRect = cellFrame->GetRect(); dirtyRect.height = mRect.height; + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cellFrame); + dirtyRect.UnionRect(dirtyRect, aDesiredSize.mOverflowArea); Invalidate(aPresContext, dirtyRect); } } @@ -1519,7 +1466,7 @@ nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext, eReflowReason_Resize); InitChildReflowState(*aPresContext, availSize, borderCollapse, p2t, cellReflowState); - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState, 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus); diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h index 85130f9244a..14fd196ef1a 100644 --- a/mozilla/layout/tables/nsTableRowFrame.h +++ b/mozilla/layout/tables/nsTableRowFrame.h @@ -72,9 +72,6 @@ public: nsStyleContext* aContext, nsIFrame* aPrevInFlow); - NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, - nsIAtom* aListName, - nsIFrame* aChildList); NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, @@ -106,16 +103,6 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); - - /** ask all children to paint themselves, without clipping (for cells with rowspan>1) - * @see nsIFrame::Paint - */ - virtual void PaintChildren(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer, - PRUint32 aFlags = 0); - NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, @@ -141,8 +128,8 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); - virtual void DidResize(nsIPresContext* aPresContext, - const nsHTMLReflowState& aReflowState); + void DidResize(nsIPresContext* aPresContext, + const nsHTMLReflowState& aReflowState); /** * Get the "type" of the frame diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 5d4f60741dc..4679910b738 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -377,7 +377,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, nsSize kidAvailSize(aReflowState.availSize); if (0 >= kidAvailSize.height) kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet - nsHTMLReflowMetrics desiredSize(nsnull); + nsHTMLReflowMetrics desiredSize(PR_FALSE); desiredSize.width = desiredSize.height = desiredSize.ascent = desiredSize.descent = 0; // Reflow the child into the available space, giving it as much height as @@ -442,6 +442,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext, // Adjust the running y-offset so we know where the next row should be placed aReflowState.y += kidFrame->GetSize().height + cellSpacingY; } + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, kidFrame); } // adjust the rows after the ones that were reflowed @@ -503,6 +504,7 @@ UpdateHeights(RowInfo& aRowInfo, void nsTableRowGroupFrame::DidResizeRows(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, nsTableRowFrame* aStartRowFrameIn) { // update the cells spanning rows with their new heights @@ -510,8 +512,13 @@ nsTableRowGroupFrame::DidResizeRows(nsIPresContext& aPresContext, PRInt32 rowIndex; nsTableRowFrame* rowFrame; nsTableRowFrame* startRowFrame = (aStartRowFrameIn) ? aStartRowFrameIn: GetFirstRow(); + if (!aStartRowFrameIn || startRowFrame == GetFirstRow()) { + // Reset the overflow area + aDesiredSize.mOverflowArea = nsRect(0, 0, 0, 0); + } for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) { rowFrame->DidResize(&aPresContext, aReflowState); + ConsiderChildOverflow(&aPresContext, aDesiredSize.mOverflowArea, rowFrame); } } @@ -842,7 +849,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext, CacheRowHeightsForPrinting(aPresContext, GetFirstRow()); } - DidResizeRows(*aPresContext, aReflowState, startRowFrame); + DidResizeRows(*aPresContext, aReflowState, aDesiredSize, startRowFrame); aDesiredSize.height = rowGroupHeight; // Adjust our desired size delete [] rowInfo; // cleanup @@ -1068,7 +1075,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext, eReflowReason_Resize); InitChildReflowState(*aPresContext, borderCollapse, p2t, rowReflowState); rowReflowState.mFlags.mIsTopOfPage = isTopOfPage; // set top of page - nsHTMLReflowMetrics rowMetrics(nsnull); + nsHTMLReflowMetrics rowMetrics(PR_FALSE); // Reflow the cell with the constrained height. A cell with rowspan >1 will get this // reflow later during SplitSpanningCells. @@ -1287,7 +1294,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, // but we need to correctly calculate the row group height and we can't if there // are row spans unless we do this step if (aReflowState.mFlags.mSpecialHeightReflow) { - DidResizeRows(*aPresContext, aReflowState); + DidResizeRows(*aPresContext, aReflowState, aDesiredSize); if (isPaginated) { CacheRowHeightsForPrinting(aPresContext, GetFirstRow()); } @@ -1325,6 +1332,9 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.height = GetHeightOfRows(aPresContext); } + aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width, + aDesiredSize.height)); + StoreOverflow(aPresContext, aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif @@ -1711,6 +1721,8 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext, } else { // Inform the row of its new height. ((nsTableRowFrame*)aNextFrame)->DidResize(aPresContext, aReflowState.reflowState); + // the overflow area may have changed inflate the overflow area + ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, aNextFrame); if (aReflowState.tableFrame->IsAutoHeight()) { // Because other cells in the row may need to be be aligned differently, // repaint the entire row @@ -1853,7 +1865,7 @@ nsTableRowGroupFrame::GetBCBorderWidth(float aPixelsToTwips, nsTableRowFrame* firstRowFrame = nsnull; nsTableRowFrame* lastRowFrame = nsnull; for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) { - if(!firstRowFrame) { + if (!firstRowFrame) { firstRowFrame = rowFrame; } lastRowFrame = rowFrame; @@ -1899,21 +1911,21 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber, return NS_ERROR_FAILURE; nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; - if(aLineNumber >= cellMap->GetRowCount()) + if (aLineNumber >= cellMap->GetRowCount()) return NS_ERROR_INVALID_ARG; *aLineFlags = 0;/// should we fill these in later? // not gonna touch aLineBounds right now CellData* firstCellData = cellMap->GetDataAt(aLineNumber, 0); - if(!firstCellData) + if (!firstCellData) return NS_ERROR_FAILURE; *aFirstFrameOnLine = (nsIFrame*)firstCellData->GetCellFrame(); - if(!(*aFirstFrameOnLine)) + if (!(*aFirstFrameOnLine)) { while((aLineNumber > 0)&&(!(*aFirstFrameOnLine))) { @@ -1984,7 +1996,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, nsTableFrame* parentFrame = nsnull; nsTableFrame::GetTableFrame(this, parentFrame); nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; colCount = cellMap->GetColCount(); @@ -2002,7 +2014,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, continue; tempFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!tempFrame) + if (!tempFrame) continue; nsRect tempRect = tempFrame->GetRect();//offsetting x to be in row coordinates @@ -2016,13 +2028,13 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, gotParentRect = PR_TRUE; } - if(i==0 &&(aX <= 0))//short circuit for negative x coords + if (i==0 &&(aX <= 0))//short circuit for negative x coords { *aXIsBeforeFirstFrame = PR_TRUE; *aFrameFound = tempFrame; return NS_OK; } - if(aX < tempRect.x) + if (aX < tempRect.x) { return NS_ERROR_FAILURE; } @@ -2035,7 +2047,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber, //x coord not found in frame, return last frame *aXIsAfterLastFrame = PR_TRUE; *aFrameFound = tempFrame; - if(!(*aFrameFound)) + if (!(*aFrameFound)) return NS_ERROR_FAILURE; return NS_OK; } @@ -2048,13 +2060,13 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, nsITableCellLayout* cellFrame; nsresult result = CallQueryInterface(aFrame, &cellFrame); - if(NS_FAILED(result)) + if (NS_FAILED(result)) return result; nsTableFrame* parentFrame = nsnull; result = nsTableFrame::GetTableFrame(this, parentFrame); nsTableCellMap* cellMap = parentFrame->GetCellMap(); - if(!cellMap) + if (!cellMap) return NS_ERROR_FAILURE; @@ -2064,10 +2076,10 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, CellData* cellData = cellMap->GetDataAt(aLineNumber, colIndex + 1); - if(!cellData)// if this isnt a valid cell, drop down and check the next line + if (!cellData)// if this isnt a valid cell, drop down and check the next line { cellData = cellMap->GetDataAt(aLineNumber + 1, 0); - if(!cellData) + if (!cellData) { //*aFrame = nsnull; return NS_ERROR_FAILURE; @@ -2075,19 +2087,19 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame, } aFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!aFrame) + if (!aFrame) { //PRInt32 numCellsInRow = cellMap->GetNumCellsOriginatingInRow(aLineNumber) - 1; PRInt32 tempCol = colIndex + 1; PRInt32 tempRow = aLineNumber; - while((tempCol > 0) && (!aFrame)) + while ((tempCol > 0) && (!aFrame)) { tempCol--; cellData = cellMap->GetDataAt(aLineNumber, tempCol); aFrame = (nsIFrame*)cellData->GetCellFrame(); - if(!aFrame && (tempCol==0)) + if (!aFrame && (tempCol==0)) { - while((tempRow > 0) && (!aFrame)) + while ((tempRow > 0) && (!aFrame)) { tempRow--; cellData = cellMap->GetDataAt(tempRow, 0); diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.h b/mozilla/layout/tables/nsTableRowGroupFrame.h index 94d3bae2125..1cb44d2fdb3 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.h +++ b/mozilla/layout/tables/nsTableRowGroupFrame.h @@ -272,6 +272,7 @@ protected: void DidResizeRows(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, + nsHTMLReflowMetrics& aDesiredSize, nsTableRowFrame* aStartRowFrameIn = nsnull); /** Incremental Reflow attempts to do column balancing with the minimum number of reflow