diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index e913b9dffe7..e59ab0e1558 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -1069,12 +1069,29 @@ BasicTableLayoutStrategy::ReduceOverSpecifiedPctCols(nscoord aExcess) } } +#ifdef DEBUG_TABLE_REFLOW_TIMING +nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame, + const nsHTMLReflowState& aReflowState, + nscoord aValue) +{ + nsTableFrame::DebugTimePctCols(*aTableFrame, (nsHTMLReflowState&)aReflowState, PR_FALSE); + return aValue; +} +#else +inline nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame, + const nsHTMLReflowState& aReflowState, + nscoord aValue) +{ + return aValue; +} +#endif + // Determine percentage col widths for each col frame nscoord -BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowState, - nscoord aBasisIn, - PRBool aTableIsAutoWidth, - float aPixelToTwips) +BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflowState, + nscoord aBasisIn, + PRBool aTableIsAutoWidth, + float aPixelToTwips) { #ifdef DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugTimePctCols(*mTableFrame, (nsHTMLReflowState&)aReflowState, PR_TRUE); @@ -1088,7 +1105,8 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS nscoord basis; // basis to use for percentage based calculations if (!aTableIsAutoWidth) { if (NS_UNCONSTRAINEDSIZE == aBasisIn) { - return 0; // don't do the calculations on unconstrained basis + // don't do the calculations on unconstrained basis + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } basis = aBasisIn; } @@ -1179,11 +1197,11 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS delete [] rawPctValues; // destroy the raw pct values // If there are no pct cells or cols, there is nothing to do. if ((0 == numPerCols) || (0.0f == perTotal)) { - return 0; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } // If there is only one col and it is % based, it won't affect anything if ((1 == numCols) && (numCols == numPerCols)) { - return 0; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } // compute a basis considering total percentages and the desired width of everything else @@ -1379,10 +1397,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis)); } -#ifdef DEBUG_TABLE_REFLOW_TIMING - nsTableFrame::DebugTimePctCols(*mTableFrame, (nsHTMLReflowState&)aReflowState, PR_FALSE); -#endif - return basis; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, basis); } nscoord BasicTableLayoutStrategy::GetTableMinWidth() const diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h index 52152b98cc3..acc1a4f64f4 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h @@ -139,10 +139,10 @@ protected: PRInt32& aLimitType, float aPixelToTwips); - nscoord AssignPctColumnWidths(const nsHTMLReflowState aReflowState, - nscoord aBasis, - PRBool aTableIsAutoWidth, - float aPixelToTwips); + nscoord AssignPctColumnWidths(const nsHTMLReflowState& aReflowState, + nscoord aBasis, + PRBool aTableIsAutoWidth, + float aPixelToTwips); void ReduceOverSpecifiedPctCols(nscoord aExcess); diff --git a/mozilla/layout/html/table/src/makefile.win b/mozilla/layout/html/table/src/makefile.win index 08fa04d9d7c..d299feae08e 100644 --- a/mozilla/layout/html/table/src/makefile.win +++ b/mozilla/layout/html/table/src/makefile.win @@ -24,7 +24,7 @@ DEPTH=..\..\..\.. LIBRARY_NAME=raptorhtmltable_s MODULE=raptor -DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN +DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN -DoffDEBUG_TABLE_REFLOW_TIMING -DoffDEBUG_TABLE_REFLOW_TIMING_DETAIL CPPSRCS= nsCellMap.cpp \ nsTableCellFrame.cpp \ diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index e38441b08c0..0dfd15a136c 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -653,41 +653,23 @@ PRInt32 nsTableCellFrame::GetColSpan() return colSpan; } - +#define PROBABLY_TOO_LARGE 1000000 static void DebugCheckChildSize(nsIFrame* aChild, nsHTMLReflowMetrics& aMet, nsSize& aAvailSize, PRBool aIsPass2Reflow) { - -/* approved for commenting out by rickg - if (aMet.width > aAvailSize.width) { - nsAutoString tmp; - aChild->GetFrameName(tmp); - printf("WARNING: cell "); - fputs(tmp, stdout); - printf(" content has desired width %d given avail width %d\n", - aMet.width, aAvailSize.width); - } -*/ if (aIsPass2Reflow) { - if ((aMet.width < 0) || (aMet.width > 60000)) { + if ((aMet.width < 0) || (aMet.width > PROBABLY_TOO_LARGE)) { printf("WARNING: cell content %p has large width %d \n", aChild, aMet.width); } - if ((aMet.height < 0) || (aMet.height > 60000)) { - printf("WARNING: cell content %p has large height %d \n", aChild, aMet.height); - } } if (aMet.maxElementSize) { nscoord tmp = aMet.maxElementSize->width; - if ((tmp < 0) || (tmp > 60000)) { + if ((tmp < 0) || (tmp > PROBABLY_TOO_LARGE)) { printf("WARNING: cell content %p has large max element width %d \n", aChild, tmp); } - tmp = aMet.maxElementSize->height; - if ((tmp < 0) || (tmp > 60000)) { - printf("WARNING: cell content %p has large max element height %d \n", aChild, tmp); - } } } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 212af65d0f4..c7fb62ca839 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -1769,10 +1769,6 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, } } else if (!IsMaximumWidthValid()) { - // Initialize the strategy and have it compute the natural size of - // the table - mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE, aReflowState); - // Ask the strategy for the natural width of the content area aDesiredSize.mMaximumWidth = mTableLayoutStrategy->GetTableMaxWidth(aReflowState); @@ -1785,17 +1781,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mMaximumWidth += aReflowState.mComputedPadding.left + aReflowState.mComputedPadding.right; + // XXX to see if this is necessary SetPreferredWidth(aDesiredSize.mMaximumWidth); // cache the value - // Initializing the table layout strategy assigns preliminary column - // widths. We can't leave the column widths this way, and so we need to - // balance the column widths to get them back to what we had previously. - // XXX It would be nice to have a cleaner way to calculate the updated - // maximum width - BalanceColumnWidths(aPresContext, aReflowState, - nsSize(aReflowState.availableWidth, aReflowState.availableHeight), - aDesiredSize.maxElementSize); - // Now the maximum width is valid mBits.mMaximumWidthValid = PR_TRUE; } else { aDesiredSize.mMaximumWidth = GetPreferredWidth(); @@ -4844,6 +4832,7 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, nsHTMLReflowMetrics* aMetrics, nsReflowStatus aStatus) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // get the parent timer const nsHTMLReflowState* parentRS = aState.parentReflowState; nsReflowTimer* parentTimer = nsnull; @@ -4852,12 +4841,14 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, if (parentTimer) break; parentRS = parentRS->parentReflowState; } +#endif // get the the frame summary timer nsCOMPtr frameType = nsnull; aFrame->GetFrameType(getter_AddRefs(frameType)); nsReflowTimer* frameTimer = GetFrameTimer(aFrame, frameType.get()); if (!frameTimer) {NS_ASSERTION(PR_FALSE, "no frame timer");return;} if (!aMetrics) { // start +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // create the reflow timer nsReflowTimer* timer = new nsReflowTimer(aFrame); // create the aux table timers if they don't exist @@ -4876,10 +4867,12 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, if (parentTimer) { parentTimer->mChildren.AppendElement(timer); } +#endif // start the frame summary timer frameTimer->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // stop the reflow timer nsReflowTimer* timer = (nsReflowTimer *)aState.mDebugHook; if (timer) { @@ -4894,12 +4887,15 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, } else {NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");return;} // stop the frame summary timer +#endif frameTimer->Stop(); +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL if (!parentTimer) { // print out all of the reflow timers DebugReflowPrint(*timer, 0, PR_FALSE); timer->Destroy(); } +#endif } } @@ -4909,11 +4905,15 @@ void nsTableFrame::DebugTimeNonPctCols(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->Stop(); } } @@ -4924,11 +4924,15 @@ void nsTableFrame::DebugTimeNonPctColspans(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->Stop(); } } @@ -4939,11 +4943,15 @@ void nsTableFrame::DebugTimePctCols(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->mNextSibling->Stop(); } } diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index bd8982f9001..97f30310014 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -95,6 +95,7 @@ NS_IMPL_RELEASE_INHERITED(nsTableOuterFrame, nsHTMLContainerFrame) nsTableOuterFrame::nsTableOuterFrame() { + mPriorAvailWidth = 0; #ifdef DEBUG_TABLE_REFLOW_TIMING mTimer = new nsReflowTimer(this); #endif @@ -1440,64 +1441,75 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, mMinCaptionWidth = maxElementSize.width; } } - - // At this point, we must have an inner table frame, and we might have a caption - NS_ASSERTION(mFrames.NotEmpty() && mInnerTableFrame, "incomplete children"); - nsSize innerSize; - nsMargin innerMargin, innerMarginNoAuto, innerPadding; - - // First reflow the inner table - nsHTMLReflowMetrics innerMet(aDesiredSize.maxElementSize); - rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, - nsnull, innerSize, innerMargin, innerMarginNoAuto, - innerPadding, aOuterRS.reason, aStatus); - if (NS_FAILED(rv)) return rv; - - if (NS_UNCONSTRAINEDSIZE == aOuterRS.availableWidth) { - // Remember the inner table's maximum width - mInnerTableMaximumWidth = innerMet.width; + if ((eReflowReason_Resize == aOuterRS.reason) && + (aOuterRS.availableWidth == mPriorAvailWidth) && + !mPrevInFlow) { + // don't do much if we are resize reflowed exactly like last time + nsRect rect; + GetRect(rect); + aDesiredSize.width = rect.width; + aDesiredSize.height = rect.height; + aStatus = NS_FRAME_COMPLETE; } + else { + // At this point, we must have an inner table frame, and we might have a caption + NS_ASSERTION(mFrames.NotEmpty() && mInnerTableFrame, "incomplete children"); + nsSize innerSize; + nsMargin innerMargin, innerMarginNoAuto, innerPadding; - nsPoint innerOrigin(0,0); - nsMargin captionMargin(0,0,0,0), captionMarginNoAuto(0,0,0,0), ignorePadding; - nsSize captionSize(0,0); - nsSize containSize = GetContainingBlockSize(aOuterRS); - - // Now that we know the table width we can reflow the caption, and - // place the caption and the inner table - if (mCaptionFrame) { - // reflow the caption - nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, - &innerSize.width, &innerMarginNoAuto); - nsHTMLReflowMetrics captionMet(nsnull); - nsReflowStatus capStatus; // don't let the caption cause incomplete - rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, - &availWidth, captionSize, captionMargin, captionMarginNoAuto, - ignorePadding, aOuterRS.reason, capStatus); + // First reflow the inner table + nsHTMLReflowMetrics innerMet(aDesiredSize.maxElementSize); + rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, + nsnull, innerSize, innerMargin, innerMarginNoAuto, + innerPadding, aOuterRS.reason, aStatus); if (NS_FAILED(rv)) return rv; - nsPoint captionOrigin; + if (NS_UNCONSTRAINEDSIZE == aOuterRS.availableWidth) { + // Remember the inner table's maximum width + mInnerTableMaximumWidth = innerMet.width; + } - GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, - innerMargin, captionSize, captionMargin, captionOrigin); - FinishReflowChild(mCaptionFrame, aPresContext, captionMet, - captionOrigin.x, captionOrigin.y, 0); + nsPoint innerOrigin(0,0); + nsMargin captionMargin(0,0,0,0), captionMarginNoAuto(0,0,0,0), ignorePadding; + nsSize captionSize(0,0); + nsSize containSize = GetContainingBlockSize(aOuterRS); - GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, + // Now that we know the table width we can reflow the caption, and + // place the caption and the inner table + if (mCaptionFrame) { + // reflow the caption + nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, + &innerSize.width, &innerMarginNoAuto); + nsHTMLReflowMetrics captionMet(nsnull); + nsReflowStatus capStatus; // don't let the caption cause incomplete + rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, + &availWidth, captionSize, captionMargin, captionMarginNoAuto, + ignorePadding, aOuterRS.reason, capStatus); + if (NS_FAILED(rv)) return rv; + + nsPoint captionOrigin; + + GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, + innerMargin, captionSize, captionMargin, captionOrigin); + FinishReflowChild(mCaptionFrame, aPresContext, captionMet, + captionOrigin.x, captionOrigin.y, 0); + + GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, + captionMargin, innerSize, innerMargin, innerOrigin); + + // XXX If the height is constrained then we need to check whether the inner table still fits... + } + else { + GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, captionMargin, innerSize, innerMargin, innerOrigin); + } - // XXX If the height is constrained then we need to check whether the inner table still fits... - } - else { - GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, - captionMargin, innerSize, innerMargin, innerOrigin); + FinishReflowChild(mInnerTableFrame, aPresContext, innerMet, + innerOrigin.x, innerOrigin.y, 0); + + UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, + innerPadding, captionMargin, captionMarginNoAuto); } - - FinishReflowChild(mInnerTableFrame, aPresContext, innerMet, - innerOrigin.x, innerOrigin.y, 0); - - UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, - innerPadding, captionMargin, captionMarginNoAuto); } // Return our desired rect @@ -1511,6 +1523,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mMaximumWidth = ((nsTableFrame*)mInnerTableFrame)->GetPreferredWidth(); } } + mPriorAvailWidth = aOuterRS.availableWidth; #if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus); diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.h b/mozilla/layout/html/table/src/nsTableOuterFrame.h index 823aaaf962a..a86487886c9 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.h +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.h @@ -358,6 +358,7 @@ private: nsSize mMaxElementSize; nscoord mInnerTableMaximumWidth; + nscoord mPriorAvailWidth; #ifdef DEBUG_TABLE_REFLOW_TIMING public: diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index e913b9dffe7..e59ab0e1558 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -1069,12 +1069,29 @@ BasicTableLayoutStrategy::ReduceOverSpecifiedPctCols(nscoord aExcess) } } +#ifdef DEBUG_TABLE_REFLOW_TIMING +nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame, + const nsHTMLReflowState& aReflowState, + nscoord aValue) +{ + nsTableFrame::DebugTimePctCols(*aTableFrame, (nsHTMLReflowState&)aReflowState, PR_FALSE); + return aValue; +} +#else +inline nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame, + const nsHTMLReflowState& aReflowState, + nscoord aValue) +{ + return aValue; +} +#endif + // Determine percentage col widths for each col frame nscoord -BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowState, - nscoord aBasisIn, - PRBool aTableIsAutoWidth, - float aPixelToTwips) +BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflowState, + nscoord aBasisIn, + PRBool aTableIsAutoWidth, + float aPixelToTwips) { #ifdef DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugTimePctCols(*mTableFrame, (nsHTMLReflowState&)aReflowState, PR_TRUE); @@ -1088,7 +1105,8 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS nscoord basis; // basis to use for percentage based calculations if (!aTableIsAutoWidth) { if (NS_UNCONSTRAINEDSIZE == aBasisIn) { - return 0; // don't do the calculations on unconstrained basis + // don't do the calculations on unconstrained basis + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } basis = aBasisIn; } @@ -1179,11 +1197,11 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS delete [] rawPctValues; // destroy the raw pct values // If there are no pct cells or cols, there is nothing to do. if ((0 == numPerCols) || (0.0f == perTotal)) { - return 0; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } // If there is only one col and it is % based, it won't affect anything if ((1 == numCols) && (numCols == numPerCols)) { - return 0; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, 0); } // compute a basis considering total percentages and the desired width of everything else @@ -1379,10 +1397,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState aReflowS ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis)); } -#ifdef DEBUG_TABLE_REFLOW_TIMING - nsTableFrame::DebugTimePctCols(*mTableFrame, (nsHTMLReflowState&)aReflowState, PR_FALSE); -#endif - return basis; + return WrapupAssignPctColumnWidths(mTableFrame, aReflowState, basis); } nscoord BasicTableLayoutStrategy::GetTableMinWidth() const diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h index 52152b98cc3..acc1a4f64f4 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.h +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h @@ -139,10 +139,10 @@ protected: PRInt32& aLimitType, float aPixelToTwips); - nscoord AssignPctColumnWidths(const nsHTMLReflowState aReflowState, - nscoord aBasis, - PRBool aTableIsAutoWidth, - float aPixelToTwips); + nscoord AssignPctColumnWidths(const nsHTMLReflowState& aReflowState, + nscoord aBasis, + PRBool aTableIsAutoWidth, + float aPixelToTwips); void ReduceOverSpecifiedPctCols(nscoord aExcess); diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index e38441b08c0..0dfd15a136c 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -653,41 +653,23 @@ PRInt32 nsTableCellFrame::GetColSpan() return colSpan; } - +#define PROBABLY_TOO_LARGE 1000000 static void DebugCheckChildSize(nsIFrame* aChild, nsHTMLReflowMetrics& aMet, nsSize& aAvailSize, PRBool aIsPass2Reflow) { - -/* approved for commenting out by rickg - if (aMet.width > aAvailSize.width) { - nsAutoString tmp; - aChild->GetFrameName(tmp); - printf("WARNING: cell "); - fputs(tmp, stdout); - printf(" content has desired width %d given avail width %d\n", - aMet.width, aAvailSize.width); - } -*/ if (aIsPass2Reflow) { - if ((aMet.width < 0) || (aMet.width > 60000)) { + if ((aMet.width < 0) || (aMet.width > PROBABLY_TOO_LARGE)) { printf("WARNING: cell content %p has large width %d \n", aChild, aMet.width); } - if ((aMet.height < 0) || (aMet.height > 60000)) { - printf("WARNING: cell content %p has large height %d \n", aChild, aMet.height); - } } if (aMet.maxElementSize) { nscoord tmp = aMet.maxElementSize->width; - if ((tmp < 0) || (tmp > 60000)) { + if ((tmp < 0) || (tmp > PROBABLY_TOO_LARGE)) { printf("WARNING: cell content %p has large max element width %d \n", aChild, tmp); } - tmp = aMet.maxElementSize->height; - if ((tmp < 0) || (tmp > 60000)) { - printf("WARNING: cell content %p has large max element height %d \n", aChild, tmp); - } } } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 212af65d0f4..c7fb62ca839 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -1769,10 +1769,6 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, } } else if (!IsMaximumWidthValid()) { - // Initialize the strategy and have it compute the natural size of - // the table - mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE, aReflowState); - // Ask the strategy for the natural width of the content area aDesiredSize.mMaximumWidth = mTableLayoutStrategy->GetTableMaxWidth(aReflowState); @@ -1785,17 +1781,9 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mMaximumWidth += aReflowState.mComputedPadding.left + aReflowState.mComputedPadding.right; + // XXX to see if this is necessary SetPreferredWidth(aDesiredSize.mMaximumWidth); // cache the value - // Initializing the table layout strategy assigns preliminary column - // widths. We can't leave the column widths this way, and so we need to - // balance the column widths to get them back to what we had previously. - // XXX It would be nice to have a cleaner way to calculate the updated - // maximum width - BalanceColumnWidths(aPresContext, aReflowState, - nsSize(aReflowState.availableWidth, aReflowState.availableHeight), - aDesiredSize.maxElementSize); - // Now the maximum width is valid mBits.mMaximumWidthValid = PR_TRUE; } else { aDesiredSize.mMaximumWidth = GetPreferredWidth(); @@ -4844,6 +4832,7 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, nsHTMLReflowMetrics* aMetrics, nsReflowStatus aStatus) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // get the parent timer const nsHTMLReflowState* parentRS = aState.parentReflowState; nsReflowTimer* parentTimer = nsnull; @@ -4852,12 +4841,14 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, if (parentTimer) break; parentRS = parentRS->parentReflowState; } +#endif // get the the frame summary timer nsCOMPtr frameType = nsnull; aFrame->GetFrameType(getter_AddRefs(frameType)); nsReflowTimer* frameTimer = GetFrameTimer(aFrame, frameType.get()); if (!frameTimer) {NS_ASSERTION(PR_FALSE, "no frame timer");return;} if (!aMetrics) { // start +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // create the reflow timer nsReflowTimer* timer = new nsReflowTimer(aFrame); // create the aux table timers if they don't exist @@ -4876,10 +4867,12 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, if (parentTimer) { parentTimer->mChildren.AppendElement(timer); } +#endif // start the frame summary timer frameTimer->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL // stop the reflow timer nsReflowTimer* timer = (nsReflowTimer *)aState.mDebugHook; if (timer) { @@ -4894,12 +4887,15 @@ void nsTableFrame::DebugReflow(nsIFrame* aFrame, } else {NS_ASSERTION(PR_FALSE, "bad DebugTimeReflow");return;} // stop the frame summary timer +#endif frameTimer->Stop(); +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL if (!parentTimer) { // print out all of the reflow timers DebugReflowPrint(*timer, 0, PR_FALSE); timer->Destroy(); } +#endif } } @@ -4909,11 +4905,15 @@ void nsTableFrame::DebugTimeNonPctCols(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->Stop(); } } @@ -4924,11 +4924,15 @@ void nsTableFrame::DebugTimeNonPctColspans(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->Stop(); } } @@ -4939,11 +4943,15 @@ void nsTableFrame::DebugTimePctCols(nsTableFrame& aFrame, { nsReflowTimer* timer = (nsReflowTimer*)aState.mDebugHook; if (aStart) { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->mNextSibling->Start(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->mNextSibling->Start(); } else { +#ifdef DEBUG_TABLE_REFLOW_TIMING_DETAIL timer->mNextSibling->mNextSibling->mNextSibling->Stop(); +#endif aFrame.mTimer->mNextSibling->mNextSibling->mNextSibling->Stop(); } } diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index bd8982f9001..97f30310014 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -95,6 +95,7 @@ NS_IMPL_RELEASE_INHERITED(nsTableOuterFrame, nsHTMLContainerFrame) nsTableOuterFrame::nsTableOuterFrame() { + mPriorAvailWidth = 0; #ifdef DEBUG_TABLE_REFLOW_TIMING mTimer = new nsReflowTimer(this); #endif @@ -1440,64 +1441,75 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, mMinCaptionWidth = maxElementSize.width; } } - - // At this point, we must have an inner table frame, and we might have a caption - NS_ASSERTION(mFrames.NotEmpty() && mInnerTableFrame, "incomplete children"); - nsSize innerSize; - nsMargin innerMargin, innerMarginNoAuto, innerPadding; - - // First reflow the inner table - nsHTMLReflowMetrics innerMet(aDesiredSize.maxElementSize); - rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, - nsnull, innerSize, innerMargin, innerMarginNoAuto, - innerPadding, aOuterRS.reason, aStatus); - if (NS_FAILED(rv)) return rv; - - if (NS_UNCONSTRAINEDSIZE == aOuterRS.availableWidth) { - // Remember the inner table's maximum width - mInnerTableMaximumWidth = innerMet.width; + if ((eReflowReason_Resize == aOuterRS.reason) && + (aOuterRS.availableWidth == mPriorAvailWidth) && + !mPrevInFlow) { + // don't do much if we are resize reflowed exactly like last time + nsRect rect; + GetRect(rect); + aDesiredSize.width = rect.width; + aDesiredSize.height = rect.height; + aStatus = NS_FRAME_COMPLETE; } + else { + // At this point, we must have an inner table frame, and we might have a caption + NS_ASSERTION(mFrames.NotEmpty() && mInnerTableFrame, "incomplete children"); + nsSize innerSize; + nsMargin innerMargin, innerMarginNoAuto, innerPadding; - nsPoint innerOrigin(0,0); - nsMargin captionMargin(0,0,0,0), captionMarginNoAuto(0,0,0,0), ignorePadding; - nsSize captionSize(0,0); - nsSize containSize = GetContainingBlockSize(aOuterRS); - - // Now that we know the table width we can reflow the caption, and - // place the caption and the inner table - if (mCaptionFrame) { - // reflow the caption - nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, - &innerSize.width, &innerMarginNoAuto); - nsHTMLReflowMetrics captionMet(nsnull); - nsReflowStatus capStatus; // don't let the caption cause incomplete - rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, - &availWidth, captionSize, captionMargin, captionMarginNoAuto, - ignorePadding, aOuterRS.reason, capStatus); + // First reflow the inner table + nsHTMLReflowMetrics innerMet(aDesiredSize.maxElementSize); + rv = OuterReflowChild(aPresContext, mInnerTableFrame, aOuterRS, innerMet, + nsnull, innerSize, innerMargin, innerMarginNoAuto, + innerPadding, aOuterRS.reason, aStatus); if (NS_FAILED(rv)) return rv; - nsPoint captionOrigin; + if (NS_UNCONSTRAINEDSIZE == aOuterRS.availableWidth) { + // Remember the inner table's maximum width + mInnerTableMaximumWidth = innerMet.width; + } - GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, - innerMargin, captionSize, captionMargin, captionOrigin); - FinishReflowChild(mCaptionFrame, aPresContext, captionMet, - captionOrigin.x, captionOrigin.y, 0); + nsPoint innerOrigin(0,0); + nsMargin captionMargin(0,0,0,0), captionMarginNoAuto(0,0,0,0), ignorePadding; + nsSize captionSize(0,0); + nsSize containSize = GetContainingBlockSize(aOuterRS); - GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, + // Now that we know the table width we can reflow the caption, and + // place the caption and the inner table + if (mCaptionFrame) { + // reflow the caption + nscoord availWidth = GetCaptionAvailWidth(aPresContext, mCaptionFrame, aOuterRS, + &innerSize.width, &innerMarginNoAuto); + nsHTMLReflowMetrics captionMet(nsnull); + nsReflowStatus capStatus; // don't let the caption cause incomplete + rv = OuterReflowChild(aPresContext, mCaptionFrame, aOuterRS, captionMet, + &availWidth, captionSize, captionMargin, captionMarginNoAuto, + ignorePadding, aOuterRS.reason, capStatus); + if (NS_FAILED(rv)) return rv; + + nsPoint captionOrigin; + + GetCaptionOrigin(aPresContext, captionSide, containSize, innerSize, + innerMargin, captionSize, captionMargin, captionOrigin); + FinishReflowChild(mCaptionFrame, aPresContext, captionMet, + captionOrigin.x, captionOrigin.y, 0); + + GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, + captionMargin, innerSize, innerMargin, innerOrigin); + + // XXX If the height is constrained then we need to check whether the inner table still fits... + } + else { + GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, captionMargin, innerSize, innerMargin, innerOrigin); + } - // XXX If the height is constrained then we need to check whether the inner table still fits... - } - else { - GetInnerOrigin(aPresContext, captionSide, containSize, captionSize, - captionMargin, innerSize, innerMargin, innerOrigin); + FinishReflowChild(mInnerTableFrame, aPresContext, innerMet, + innerOrigin.x, innerOrigin.y, 0); + + UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, + innerPadding, captionMargin, captionMarginNoAuto); } - - FinishReflowChild(mInnerTableFrame, aPresContext, innerMet, - innerOrigin.x, innerOrigin.y, 0); - - UpdateReflowMetrics(captionSide, aDesiredSize, innerMargin, innerMarginNoAuto, - innerPadding, captionMargin, captionMarginNoAuto); } // Return our desired rect @@ -1511,6 +1523,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mMaximumWidth = ((nsTableFrame*)mInnerTableFrame)->GetPreferredWidth(); } } + mPriorAvailWidth = aOuterRS.availableWidth; #if defined DEBUG_TABLE_REFLOW | DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aOuterRS, &aDesiredSize, aStatus); diff --git a/mozilla/layout/tables/nsTableOuterFrame.h b/mozilla/layout/tables/nsTableOuterFrame.h index 823aaaf962a..a86487886c9 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.h +++ b/mozilla/layout/tables/nsTableOuterFrame.h @@ -358,6 +358,7 @@ private: nsSize mMaxElementSize; nscoord mInnerTableMaximumWidth; + nscoord mPriorAvailWidth; #ifdef DEBUG_TABLE_REFLOW_TIMING public: