From c024f2b0c9df840509a82b8886372473cec50860 Mon Sep 17 00:00:00 2001 From: "buster%netscape.com" Date: Sat, 1 Aug 1998 02:31:55 +0000 Subject: [PATCH] fixed cases where we were not computing the table width correctly fixed cases where we were inappropriately portioning out a spanning cell's min width to the columns it spanned. --- .../table/src/BasicTableLayoutStrategy.cpp | 229 ++++++++++++------ .../html/table/src/BasicTableLayoutStrategy.h | 2 + layout/html/table/src/nsTableColFrame.cpp | 1 + layout/html/table/src/nsTableColFrame.h | 19 +- layout/html/table/src/nsTableOuterFrame.cpp | 1 - layout/tables/BasicTableLayoutStrategy.cpp | 229 ++++++++++++------ layout/tables/BasicTableLayoutStrategy.h | 2 + layout/tables/nsTableColFrame.cpp | 1 + layout/tables/nsTableColFrame.h | 19 +- layout/tables/nsTableOuterFrame.cpp | 1 - 10 files changed, 346 insertions(+), 158 deletions(-) diff --git a/layout/html/table/src/BasicTableLayoutStrategy.cpp b/layout/html/table/src/BasicTableLayoutStrategy.cpp index 987e1444227..42bb98d7c2d 100644 --- a/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext); #ifdef NS_DEBUG -static PRBool gsDebug = PR_FALSE; +static PRBool gsDebug = PR_TRUE; static PRBool gsDebugCLD = PR_FALSE; #else static const PRBool gsDebug = PR_FALSE; @@ -184,13 +184,13 @@ PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyl //availWidth = mMinTableWidth; // bump it up to the min // Step 3 - assign the width of all proportional-width columns in the remaining space - if (PR_TRUE==gsDebug) + //if (PR_TRUE==gsDebug) { printf ("BalanceColumnWidths with aMaxWidth = %d, availWidth = %d\n", aMaxWidth, availWidth); printf ("\t\t specifiedTW = %d, min/maxTW = %d %d\n", specifiedTableWidth, mMinTableWidth, mMaxTableWidth); printf ("\t\t reflow reason = %d\n", aReflowState.reason); } - if (PR_TRUE==gsDebug) + //if (PR_TRUE==gsDebug) { printf("\n%p: BEGIN BALANCE COLUMN WIDTHS\n", mTableFrame); for (PRInt32 i=0; iGetRowCount(); + PRInt32 colIndex, rowIndex; // for every column, determine it's min and max width, and keep track of the table width - for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex); if (nsnull==cellFrame) @@ -426,6 +427,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() colFrame->SetMaxColWidth(effectiveMaxColumnWidth); colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth); colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth); + // this is the default, the real adjustment happens below where we deal with colspans + colFrame->SetAdjustedMinColWidth(effectiveMinColumnWidth); if (PR_TRUE==haveColWidth) mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); else @@ -433,15 +436,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() if (gsDebug) printf ("col %d, set col width to = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); - // add col[i] metrics to the running totals for the table min/max width - if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth) - mMinTableWidth += effectiveMinColumnWidth + colInset; - if (mMinTableWidth<0) - mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow - if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth) - mMaxTableWidth += effectiveMaxColumnWidth + colInset; - if (mMaxTableWidth<0) - mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow if (PR_TRUE==hasColsAttribute) { minColWidthArray[colIndex] = minColWidth; @@ -479,11 +473,36 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() if (nsnull==nextColFrame) break; spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth(); + spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth(); } - if (gsDebug) printf("effective max total = %d\n", spanInfo->effectiveMaxWidthOfSpannedCols); + if (gsDebug) printf("effective min total = %d, max total = %d\n", + spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols); } nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex); nscoord colMinWidth = colFrame->GetMinColWidth(); + + + // compute the spanning cell's contribution to the column min width + // this is the "adjusted" column width, used in SetTableToMinWidth + nscoord spanCellMinWidth; + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) + { + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); + if (gsDebug==PR_TRUE) + printf ("spanCellMinWidth portion = %d \n", spanCellMinWidth); + if (colMinWidth < spanCellMinWidth) + colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col + } + else + { + if (colMinWidth < spanCellMinWidth) + { + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + colFrame->SetAdjustedMinColWidth(spanCellMinWidth); + } + } + // compute the spanning cell's contribution to the column max width nscoord colMaxWidth = colFrame->GetMaxColWidth(); nscoord spanCellMaxWidth; @@ -498,11 +517,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() // make sure we're at least as big as our min spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth); colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col - //mMaxTableWidth += spanCellMaxWidth-colMaxWidth; // add in the col max width delta mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width if (gsDebug==PR_TRUE) { - printf ("set mMaxTableWidth to %d\n", mMaxTableWidth); printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n", colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth); } @@ -531,8 +548,10 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() } } + // now set the min and max table widths + SetMinAndMaxTableWidths(); - // second, handle the COLS attribute (equal column widths) + // then, handle the COLS attribute (equal column widths) // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth if (PR_TRUE==hasColsAttribute) { @@ -600,6 +619,53 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() return PR_TRUE; } +void BasicTableLayoutStrategy::SetMinAndMaxTableWidths() +{ + PRInt32 colIndex, rowIndex; + PRInt32 numRows = mTableFrame->GetRowCount(); + nscoord colInset = mTableFrame->GetCellSpacing(); + for (rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex); + rowMinWidth += colInset; + rowMaxWidth += colInset; + if (nsnull==cellFrame) + { // there is no cell in this row that corresponds to this column + continue; + } + if (colIndex!=cellFrame->GetColIndex()) { + // For cells that span cols, we figured in the cell the first time we saw it + continue; + } + nsSize cellMinSize = cellFrame->GetPass1MaxElementSize(); + nsSize cellMaxSize = cellFrame->GetPass1DesiredSize(); + //PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame); + if (NS_UNCONSTRAINEDSIZE!=rowMinWidth) + rowMinWidth += cellMinSize.width; + if (NS_UNCONSTRAINEDSIZE!=rowMaxWidth) + rowMaxWidth += cellMaxSize.width; + } + printf(" rowMinWidth=%d, rowMaxWidth=%d\n", rowMinWidth, rowMaxWidth); + // the largest row widths are the table widths + mMinTableWidth = PR_MAX(mMinTableWidth, rowMinWidth); + mMaxTableWidth = PR_MAX(mMaxTableWidth, rowMaxWidth); + } + // verify max of min row widths vs. sum of adjusted column min widths. bigger one wins + nscoord sumOfAdjustedColMinWidths=colInset; + for (colIndex = 0; colIndexGetColumnFrame(colIndex, colFrame); + sumOfAdjustedColMinWidths += colFrame->GetAdjustedMinColWidth() + colInset; + } + mMinTableWidth = PR_MAX(mMinTableWidth, sumOfAdjustedColMinWidths); + printf("minTW=%d, maxTW=%d with DMCW=%d\n", mMinTableWidth, mMaxTableWidth, sumOfAdjustedColMinWidths); +} + // take the fixed space spanned by the columns in aColSpanList // and distribute it proportionately (based on desired width) void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList) @@ -709,8 +775,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() PRInt32 numRows = mTableFrame->GetRowCount(); for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex); @@ -721,11 +786,11 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); if (PR_FALSE==IsFixedWidth(colPosition)) { - minColWidth = colFrame->GetMinColWidth(); - mTableFrame->SetColumnWidth(colIndex, minColWidth); + minAdjustedColWidth = colFrame->GetAdjustedMinColWidth(); + mTableFrame->SetColumnWidth(colIndex, minAdjustedColWidth); if (PR_TRUE==hasColsAttribute) { - minColWidthArray[colIndex] = minColWidth; + minColWidthArray[colIndex] = minAdjustedColWidth; } } if (gsDebug==PR_TRUE) @@ -739,7 +804,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() PRInt32 numColsEffected = mNumCols; if (NS_STYLE_TABLE_COLS_ALL!=mCols) numColsEffected = mCols; - PRInt32 maxOfEffectedColWidths=0; + nscoord maxOfEffectedColWidths=0; PRInt32 effectedColIndex; // XXX need to fix this and all similar code if any fixed-width columns intersect COLS for (effectedColIndex=0; effectedColIndexeffectiveMinWidthOfSpannedCols) + PRBool needsExtraMinWidth = PR_FALSE; + /* + if (spanInfo->effectiveMinWidthOfSpannedColscellMinWidth) + needsExtraMinWidth = PR_TRUE; + */ + if (PR_TRUE==needsExtraMinWidth) { - spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / - (spanInfo->effectiveMinWidthOfSpannedCols); - if (gsDebug==PR_TRUE) - printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); - if (minColWidth < spanCellMinWidth) + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) { - minColWidth = spanCellMinWidth; // set the new min width for the col - if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - // if the new min width is greater than the desired width, bump up the desired width - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" and maxColWidth = %d\n", maxColWidth); - } - } - else - { - spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; - if (minColWidth < spanCellMinWidth) - { - minColWidth = spanCellMinWidth; + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); if (gsDebug==PR_TRUE) + printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; // set the new min width for the col + if (gsDebug==PR_TRUE) printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", colIndex, spanInfo->span, minColWidth); - // if the new min width is greater than the desired width, bump up the desired width - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) + // if the new min width is greater than the desired width, bump up the desired width + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) printf (" and maxColWidth = %d\n", maxColWidth); + } + } + else + { + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + // if the new min width is greater than the desired width, bump up the desired width + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" and maxColWidth = %d\n", maxColWidth); + } } } @@ -1319,35 +1392,43 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState& { // compute the spanning cell's contribution to the column min width nscoord spanCellMinWidth; - if (0!=spanInfo->effectiveMinWidthOfSpannedCols) + PRBool needsExtraMinWidth = PR_FALSE; + /* + if (spanInfo->effectiveMinWidthOfSpannedColscellMinWidth) + needsExtraMinWidth = PR_TRUE; + */ + if (PR_TRUE==needsExtraMinWidth) { - spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / - (spanInfo->effectiveMinWidthOfSpannedCols); - if (gsDebug==PR_TRUE) - printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); - if (minColWidth < spanCellMinWidth) + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) { - minColWidth = spanCellMinWidth; // set the new min width for the col + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" maxColWidth = %d\n", maxColWidth); + printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; // set the new min width for the col + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" maxColWidth = %d\n", maxColWidth); + } } - } - else - { - spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; - if (minColWidth < spanCellMinWidth) + else { - minColWidth = spanCellMinWidth; - if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" maxColWidth = %d\n", maxColWidth); + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" maxColWidth = %d\n", maxColWidth); + } } } diff --git a/layout/html/table/src/BasicTableLayoutStrategy.h b/layout/html/table/src/BasicTableLayoutStrategy.h index 83bab50e64f..eed7df42289 100644 --- a/layout/html/table/src/BasicTableLayoutStrategy.h +++ b/layout/html/table/src/BasicTableLayoutStrategy.h @@ -90,6 +90,8 @@ public: */ virtual PRBool AssignPreliminaryColumnWidths(); + virtual void SetMinAndMaxTableWidths(); + /** assign widths for each column that has proportional width inside a table that * has auto width (width set by the content and available space.) * Sets mColumnWidths as a side effect. diff --git a/layout/html/table/src/nsTableColFrame.cpp b/layout/html/table/src/nsTableColFrame.cpp index e90fd2c36a6..f6e9faad98b 100644 --- a/layout/html/table/src/nsTableColFrame.cpp +++ b/layout/html/table/src/nsTableColFrame.cpp @@ -42,6 +42,7 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) mMinColWidth = 0; mMaxEffectiveColWidth = 0; mMinEffectiveColWidth = 0; + mMinAdjustedColWidth = 0; mWidthSource = eWIDTH_SOURCE_NONE; } diff --git a/layout/html/table/src/nsTableColFrame.h b/layout/html/table/src/nsTableColFrame.h index ffe92282e4b..fda51866ddb 100644 --- a/layout/html/table/src/nsTableColFrame.h +++ b/layout/html/table/src/nsTableColFrame.h @@ -68,6 +68,9 @@ public: nscoord GetEffectiveMinColWidth(); void SetEffectiveMinColWidth(nscoord aMinColWidth); + nscoord GetAdjustedMinColWidth(); + void SetAdjustedMinColWidth(nscoord aMinColWidth); + PRInt32 GetWidthSource(); void SetWidthSource(PRInt32 aMinColWidth); @@ -86,12 +89,14 @@ protected: /** the number of columns that the attributes of this column extend to */ PRInt32 mRepeat; - nscoord mMaxColWidth; - nscoord mMinColWidth; + nscoord mMaxColWidth; + nscoord mMinColWidth; nscoord mMaxEffectiveColWidth; nscoord mMinEffectiveColWidth; + nscoord mMinAdjustedColWidth; + PRInt32 mWidthSource; }; @@ -136,8 +141,14 @@ inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth) inline nscoord nsTableColFrame::GetEffectiveMinColWidth() { return mMinEffectiveColWidth; } -inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth) -{ mMinEffectiveColWidth = aMinColWidth; } +inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinEffectiveColWidth) +{ mMinEffectiveColWidth = aMinEffectiveColWidth; } + +inline nscoord nsTableColFrame::GetAdjustedMinColWidth() +{ return mMinAdjustedColWidth; } + +inline void nsTableColFrame::SetAdjustedMinColWidth(nscoord aMinAdjustedColWidth) +{ mMinAdjustedColWidth = aMinAdjustedColWidth; } inline PRInt32 nsTableColFrame::GetWidthSource() { return mWidthSource; } diff --git a/layout/html/table/src/nsTableOuterFrame.cpp b/layout/html/table/src/nsTableOuterFrame.cpp index 60bf1c640c1..0226c043a5e 100644 --- a/layout/html/table/src/nsTableOuterFrame.cpp +++ b/layout/html/table/src/nsTableOuterFrame.cpp @@ -393,7 +393,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext, // Initialize our local reflow state OuterTableReflowState state(&aPresContext, aReflowState); - if (eReflowReason_Incremental == aReflowState.reason) { IncrementalReflow(&aPresContext, state, aDesiredSize, aReflowState, aStatus); diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index 987e1444227..42bb98d7c2d 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext); #ifdef NS_DEBUG -static PRBool gsDebug = PR_FALSE; +static PRBool gsDebug = PR_TRUE; static PRBool gsDebugCLD = PR_FALSE; #else static const PRBool gsDebug = PR_FALSE; @@ -184,13 +184,13 @@ PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyl //availWidth = mMinTableWidth; // bump it up to the min // Step 3 - assign the width of all proportional-width columns in the remaining space - if (PR_TRUE==gsDebug) + //if (PR_TRUE==gsDebug) { printf ("BalanceColumnWidths with aMaxWidth = %d, availWidth = %d\n", aMaxWidth, availWidth); printf ("\t\t specifiedTW = %d, min/maxTW = %d %d\n", specifiedTableWidth, mMinTableWidth, mMaxTableWidth); printf ("\t\t reflow reason = %d\n", aReflowState.reason); } - if (PR_TRUE==gsDebug) + //if (PR_TRUE==gsDebug) { printf("\n%p: BEGIN BALANCE COLUMN WIDTHS\n", mTableFrame); for (PRInt32 i=0; iGetRowCount(); + PRInt32 colIndex, rowIndex; // for every column, determine it's min and max width, and keep track of the table width - for (PRInt32 colIndex = 0; colIndexGetCellAt(rowIndex, colIndex); if (nsnull==cellFrame) @@ -426,6 +427,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() colFrame->SetMaxColWidth(effectiveMaxColumnWidth); colFrame->SetEffectiveMinColWidth(effectiveMinColumnWidth); colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth); + // this is the default, the real adjustment happens below where we deal with colspans + colFrame->SetAdjustedMinColWidth(effectiveMinColumnWidth); if (PR_TRUE==haveColWidth) mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); else @@ -433,15 +436,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() if (gsDebug) printf ("col %d, set col width to = %d\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); - // add col[i] metrics to the running totals for the table min/max width - if (NS_UNCONSTRAINEDSIZE!=mMinTableWidth) - mMinTableWidth += effectiveMinColumnWidth + colInset; - if (mMinTableWidth<0) - mMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow - if (NS_UNCONSTRAINEDSIZE!=mMaxTableWidth) - mMaxTableWidth += effectiveMaxColumnWidth + colInset; - if (mMaxTableWidth<0) - mMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow if (PR_TRUE==hasColsAttribute) { minColWidthArray[colIndex] = minColWidth; @@ -479,11 +473,36 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() if (nsnull==nextColFrame) break; spanInfo->effectiveMaxWidthOfSpannedCols += nextColFrame->GetEffectiveMaxColWidth(); + spanInfo->effectiveMinWidthOfSpannedCols += nextColFrame->GetEffectiveMinColWidth(); } - if (gsDebug) printf("effective max total = %d\n", spanInfo->effectiveMaxWidthOfSpannedCols); + if (gsDebug) printf("effective min total = %d, max total = %d\n", + spanInfo->effectiveMinWidthOfSpannedCols, spanInfo->effectiveMaxWidthOfSpannedCols); } nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex); nscoord colMinWidth = colFrame->GetMinColWidth(); + + + // compute the spanning cell's contribution to the column min width + // this is the "adjusted" column width, used in SetTableToMinWidth + nscoord spanCellMinWidth; + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) + { + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); + if (gsDebug==PR_TRUE) + printf ("spanCellMinWidth portion = %d \n", spanCellMinWidth); + if (colMinWidth < spanCellMinWidth) + colFrame->SetAdjustedMinColWidth(spanCellMinWidth); // set the new min width for the col + } + else + { + if (colMinWidth < spanCellMinWidth) + { + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + colFrame->SetAdjustedMinColWidth(spanCellMinWidth); + } + } + // compute the spanning cell's contribution to the column max width nscoord colMaxWidth = colFrame->GetMaxColWidth(); nscoord spanCellMaxWidth; @@ -498,11 +517,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() // make sure we're at least as big as our min spanCellMaxWidth = PR_MAX(spanCellMaxWidth, colMinWidth); colFrame->SetMaxColWidth(spanCellMaxWidth); // set the new max width for the col - //mMaxTableWidth += spanCellMaxWidth-colMaxWidth; // add in the col max width delta mTableFrame->SetColumnWidth(colIndex, spanCellMaxWidth); // set the column to the new desired max width if (gsDebug==PR_TRUE) { - printf ("set mMaxTableWidth to %d\n", mMaxTableWidth); printf ("for spanning cell into col %d with remaining span=%d, old max = %d, new max = %d\n", colIndex, spanInfo->span, colMaxWidth, spanCellMaxWidth); } @@ -531,8 +548,10 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() } } + // now set the min and max table widths + SetMinAndMaxTableWidths(); - // second, handle the COLS attribute (equal column widths) + // then, handle the COLS attribute (equal column widths) // if there is a COLS attribute, fix up mMinTableWidth and mMaxTableWidth if (PR_TRUE==hasColsAttribute) { @@ -600,6 +619,53 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() return PR_TRUE; } +void BasicTableLayoutStrategy::SetMinAndMaxTableWidths() +{ + PRInt32 colIndex, rowIndex; + PRInt32 numRows = mTableFrame->GetRowCount(); + nscoord colInset = mTableFrame->GetCellSpacing(); + for (rowIndex = 0; rowIndexGetCellAt(rowIndex, colIndex); + rowMinWidth += colInset; + rowMaxWidth += colInset; + if (nsnull==cellFrame) + { // there is no cell in this row that corresponds to this column + continue; + } + if (colIndex!=cellFrame->GetColIndex()) { + // For cells that span cols, we figured in the cell the first time we saw it + continue; + } + nsSize cellMinSize = cellFrame->GetPass1MaxElementSize(); + nsSize cellMaxSize = cellFrame->GetPass1DesiredSize(); + //PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame); + if (NS_UNCONSTRAINEDSIZE!=rowMinWidth) + rowMinWidth += cellMinSize.width; + if (NS_UNCONSTRAINEDSIZE!=rowMaxWidth) + rowMaxWidth += cellMaxSize.width; + } + printf(" rowMinWidth=%d, rowMaxWidth=%d\n", rowMinWidth, rowMaxWidth); + // the largest row widths are the table widths + mMinTableWidth = PR_MAX(mMinTableWidth, rowMinWidth); + mMaxTableWidth = PR_MAX(mMaxTableWidth, rowMaxWidth); + } + // verify max of min row widths vs. sum of adjusted column min widths. bigger one wins + nscoord sumOfAdjustedColMinWidths=colInset; + for (colIndex = 0; colIndexGetColumnFrame(colIndex, colFrame); + sumOfAdjustedColMinWidths += colFrame->GetAdjustedMinColWidth() + colInset; + } + mMinTableWidth = PR_MAX(mMinTableWidth, sumOfAdjustedColMinWidths); + printf("minTW=%d, maxTW=%d with DMCW=%d\n", mMinTableWidth, mMaxTableWidth, sumOfAdjustedColMinWidths); +} + // take the fixed space spanned by the columns in aColSpanList // and distribute it proportionately (based on desired width) void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList) @@ -709,8 +775,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() PRInt32 numRows = mTableFrame->GetRowCount(); for (PRInt32 colIndex = 0; colIndexGetColFrame(colIndex); @@ -721,11 +786,11 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); if (PR_FALSE==IsFixedWidth(colPosition)) { - minColWidth = colFrame->GetMinColWidth(); - mTableFrame->SetColumnWidth(colIndex, minColWidth); + minAdjustedColWidth = colFrame->GetAdjustedMinColWidth(); + mTableFrame->SetColumnWidth(colIndex, minAdjustedColWidth); if (PR_TRUE==hasColsAttribute) { - minColWidthArray[colIndex] = minColWidth; + minColWidthArray[colIndex] = minAdjustedColWidth; } } if (gsDebug==PR_TRUE) @@ -739,7 +804,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth() PRInt32 numColsEffected = mNumCols; if (NS_STYLE_TABLE_COLS_ALL!=mCols) numColsEffected = mCols; - PRInt32 maxOfEffectedColWidths=0; + nscoord maxOfEffectedColWidths=0; PRInt32 effectedColIndex; // XXX need to fix this and all similar code if any fixed-width columns intersect COLS for (effectedColIndex=0; effectedColIndexeffectiveMinWidthOfSpannedCols) + PRBool needsExtraMinWidth = PR_FALSE; + /* + if (spanInfo->effectiveMinWidthOfSpannedColscellMinWidth) + needsExtraMinWidth = PR_TRUE; + */ + if (PR_TRUE==needsExtraMinWidth) { - spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / - (spanInfo->effectiveMinWidthOfSpannedCols); - if (gsDebug==PR_TRUE) - printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); - if (minColWidth < spanCellMinWidth) + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) { - minColWidth = spanCellMinWidth; // set the new min width for the col - if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - // if the new min width is greater than the desired width, bump up the desired width - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" and maxColWidth = %d\n", maxColWidth); - } - } - else - { - spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; - if (minColWidth < spanCellMinWidth) - { - minColWidth = spanCellMinWidth; + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); if (gsDebug==PR_TRUE) + printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; // set the new min width for the col + if (gsDebug==PR_TRUE) printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", colIndex, spanInfo->span, minColWidth); - // if the new min width is greater than the desired width, bump up the desired width - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) + // if the new min width is greater than the desired width, bump up the desired width + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) printf (" and maxColWidth = %d\n", maxColWidth); + } + } + else + { + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + // if the new min width is greater than the desired width, bump up the desired width + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" and maxColWidth = %d\n", maxColWidth); + } } } @@ -1319,35 +1392,43 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( const nsReflowState& { // compute the spanning cell's contribution to the column min width nscoord spanCellMinWidth; - if (0!=spanInfo->effectiveMinWidthOfSpannedCols) + PRBool needsExtraMinWidth = PR_FALSE; + /* + if (spanInfo->effectiveMinWidthOfSpannedColscellMinWidth) + needsExtraMinWidth = PR_TRUE; + */ + if (PR_TRUE==needsExtraMinWidth) { - spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / - (spanInfo->effectiveMinWidthOfSpannedCols); - if (gsDebug==PR_TRUE) - printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); - if (minColWidth < spanCellMinWidth) + if (0!=spanInfo->effectiveMinWidthOfSpannedCols) { - minColWidth = spanCellMinWidth; // set the new min width for the col + spanCellMinWidth = (spanInfo->cellMinWidth * colFrame->GetEffectiveMinColWidth()) / + (spanInfo->effectiveMinWidthOfSpannedCols); if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" maxColWidth = %d\n", maxColWidth); + printf (" spanlist min: %d of %d\n", spanCellMinWidth, spanInfo->effectiveMaxWidthOfSpannedCols); + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; // set the new min width for the col + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" maxColWidth = %d\n", maxColWidth); + } } - } - else - { - spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; - if (minColWidth < spanCellMinWidth) + else { - minColWidth = spanCellMinWidth; - if (gsDebug==PR_TRUE) - printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", - colIndex, spanInfo->span, minColWidth); - maxColWidth = PR_MAX(maxColWidth, minColWidth); - if (gsDebug) - printf (" maxColWidth = %d\n", maxColWidth); + spanCellMinWidth = spanInfo->cellMinWidth/spanInfo->initialColSpan; + if (minColWidth < spanCellMinWidth) + { + minColWidth = spanCellMinWidth; + if (gsDebug==PR_TRUE) + printf (" for spanning cell into col %d with remaining span=%d, new min = %d\n", + colIndex, spanInfo->span, minColWidth); + maxColWidth = PR_MAX(maxColWidth, minColWidth); + if (gsDebug) + printf (" maxColWidth = %d\n", maxColWidth); + } } } diff --git a/layout/tables/BasicTableLayoutStrategy.h b/layout/tables/BasicTableLayoutStrategy.h index 83bab50e64f..eed7df42289 100644 --- a/layout/tables/BasicTableLayoutStrategy.h +++ b/layout/tables/BasicTableLayoutStrategy.h @@ -90,6 +90,8 @@ public: */ virtual PRBool AssignPreliminaryColumnWidths(); + virtual void SetMinAndMaxTableWidths(); + /** assign widths for each column that has proportional width inside a table that * has auto width (width set by the content and available space.) * Sets mColumnWidths as a side effect. diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp index e90fd2c36a6..f6e9faad98b 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -42,6 +42,7 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) mMinColWidth = 0; mMaxEffectiveColWidth = 0; mMinEffectiveColWidth = 0; + mMinAdjustedColWidth = 0; mWidthSource = eWIDTH_SOURCE_NONE; } diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index ffe92282e4b..fda51866ddb 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -68,6 +68,9 @@ public: nscoord GetEffectiveMinColWidth(); void SetEffectiveMinColWidth(nscoord aMinColWidth); + nscoord GetAdjustedMinColWidth(); + void SetAdjustedMinColWidth(nscoord aMinColWidth); + PRInt32 GetWidthSource(); void SetWidthSource(PRInt32 aMinColWidth); @@ -86,12 +89,14 @@ protected: /** the number of columns that the attributes of this column extend to */ PRInt32 mRepeat; - nscoord mMaxColWidth; - nscoord mMinColWidth; + nscoord mMaxColWidth; + nscoord mMinColWidth; nscoord mMaxEffectiveColWidth; nscoord mMinEffectiveColWidth; + nscoord mMinAdjustedColWidth; + PRInt32 mWidthSource; }; @@ -136,8 +141,14 @@ inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth) inline nscoord nsTableColFrame::GetEffectiveMinColWidth() { return mMinEffectiveColWidth; } -inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth) -{ mMinEffectiveColWidth = aMinColWidth; } +inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinEffectiveColWidth) +{ mMinEffectiveColWidth = aMinEffectiveColWidth; } + +inline nscoord nsTableColFrame::GetAdjustedMinColWidth() +{ return mMinAdjustedColWidth; } + +inline void nsTableColFrame::SetAdjustedMinColWidth(nscoord aMinAdjustedColWidth) +{ mMinAdjustedColWidth = aMinAdjustedColWidth; } inline PRInt32 nsTableColFrame::GetWidthSource() { return mWidthSource; } diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 60bf1c640c1..0226c043a5e 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -393,7 +393,6 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext& aPresContext, // Initialize our local reflow state OuterTableReflowState state(&aPresContext, aReflowState); - if (eReflowReason_Incremental == aReflowState.reason) { IncrementalReflow(&aPresContext, state, aDesiredSize, aReflowState, aStatus);