From a4a065bae0427ca431ffcef427b01aa097d22ebd Mon Sep 17 00:00:00 2001 From: buster Date: Fri, 29 May 1998 22:08:19 +0000 Subject: [PATCH] some proportional column balancing now works the COLS attribute is supported via proportional column balancing. git-svn-id: svn://10.0.0.236/trunk@2648 18797224-902f-48f8-a5cc-f745e15eee43 --- .../table/src/BasicTableLayoutStrategy.cpp | 401 ++++++++++++------ .../html/table/src/BasicTableLayoutStrategy.h | 11 +- .../layout/html/table/src/nsColLayoutData.cpp | 13 +- .../layout/html/table/src/nsColLayoutData.h | 6 + .../html/table/src/nsITableLayoutStrategy.h | 93 ---- mozilla/layout/html/table/src/nsTableCol.cpp | 24 +- .../layout/html/table/src/nsTableColFrame.h | 49 +++ .../html/table/src/nsTableColGroupFrame.cpp | 80 ++-- .../layout/html/table/src/nsTableFrame.cpp | 39 +- mozilla/layout/html/table/src/nsTableFrame.h | 7 +- .../tables/BasicTableLayoutStrategy.cpp | 401 ++++++++++++------ .../layout/tables/BasicTableLayoutStrategy.h | 11 +- .../layout/tables/nsITableLayoutStrategy.h | 93 ---- mozilla/layout/tables/nsTableColFrame.h | 49 +++ .../layout/tables/nsTableColGroupFrame.cpp | 80 ++-- mozilla/layout/tables/nsTableFrame.cpp | 39 +- mozilla/layout/tables/nsTableFrame.h | 7 +- 17 files changed, 769 insertions(+), 634 deletions(-) create mode 100644 mozilla/layout/html/table/src/nsTableColFrame.h create mode 100644 mozilla/layout/tables/nsTableColFrame.h diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index da174e2274b..aed862b7993 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -19,6 +19,7 @@ #include #include "BasicTableLayoutStrategy.h" #include "nsTableFrame.h" +#include "nsTableColFrame.h" #include "nsColLayoutData.h" #include "nsCellLayoutData.h" #include "nsTableCol.h" @@ -42,12 +43,39 @@ static const PRBool gsDebugCLD = PR_FALSE; static const PRBool gsTiming = PR_FALSE; #endif +/* ---------- ProportionalColumnLayoutStruct ---------- */ +// TODO: make public so other subclasses can use it + +/** useful info about a column for layout */ +struct ProportionalColumnLayoutStruct +{ + ProportionalColumnLayoutStruct(PRInt32 aColIndex, + nscoord aMinColWidth, + nscoord aMaxColWidth, + PRInt32 aProportion) + { + mColIndex = aColIndex; + mMinColWidth = aMinColWidth; + mMaxColWidth = aMaxColWidth; + mProportion = aProportion; + }; + + PRInt32 mColIndex; + nscoord mMinColWidth; + nscoord mMaxColWidth; + PRInt32 mProportion; +}; + + + +/* ---------- BasicTableLayoutStrategy ---------- */ + /* return true if the style indicates that the width is proportional * for the purposes of column width determination */ -PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosition) +PRBool BasicTableLayoutStrategy::IsFixedWidth(nsStylePosition* aStylePosition) { - PRBool result = PR_FALSE; // assume that it is not + PRBool result = PR_FALSE; // assume that it is not fixed width PRInt32 unitType; if (nsnull == aStylePosition) { unitType = eStyleUnit_Auto; @@ -58,12 +86,11 @@ PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosi switch (unitType) { case eStyleUnit_Coord: - break; + result = PR_TRUE; case eStyleUnit_Auto: case eStyleUnit_Proportional: case eStyleUnit_Percent: - result = PR_TRUE; break; // TODO @@ -71,7 +98,7 @@ PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosi break; default: - NS_ASSERTION(PR_FALSE, "illegal style type in IsProportionalWidth"); + NS_ASSERTION(PR_FALSE, "illegal style type in IsFixedWidth"); break; } return result; @@ -263,6 +290,8 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData(); nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex)); NS_ASSERTION(nsnull != colData, "bad column data"); + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); nsTableColPtr col = colData->GetCol(); // col: ADDREF++ NS_ASSERTION(col.IsNotNull(), "bad col"); @@ -273,35 +302,25 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo PRInt32 numCells = cells->Count(); if (gsDebug==PR_TRUE) printf (" for column %d numCells = %d\n", colIndex, numCells); -#if XXX_need_access_to_column_frame_help // Get the columns's style nsIStyleContextPtr colSC; colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); - nsStylePosition* colPosition = (nsStylePosition*) - colSC->GetData(eStyleStruct_Position); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); // Get column width if it has one PRBool haveColWidth = PR_FALSE; - nscoord colWidth; + nscoord specifiedFixedColWidth=0; switch (colPosition->mWidth.GetUnit()) { - default: - case eStyleUnit_Auto: - case eStyleUnit_Inherit: - break; + case eStyleUnit_Coord: + haveColWidth = PR_TRUE; + specifiedFixedColWidth = colPosition->mWidth.GetCoordValue(); + break; - case eStyleUnit_Coord: - haveColWidth = PR_TRUE; - colWidth = colPosition->mWidth.GetCoordValue; - break; - - case eStyleUnit_Percent: - case eStyleUnit_Proportional: - //XXX haveColWidth = PR_TRUE; - //XXX colWidth = colPosition->mWidthPCT * something; - break; + default: + break; } -#endif + // TODO - use specifiedFixedColWidth to influence the width when both col span and fixed col width are given /* Scan the column, simulatneously assigning fixed column widths * and computing the min/max column widths */ @@ -388,34 +407,27 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo } } -#if XXX_need_access_to_column_frame_help + // TODO - use cellWidth found above to influence the cell width here switch (colPosition->mWidth.GetUnit()) { - default: - case eStyleUnit_Auto: - case eStyleUnit_Inherit: - break; - - case eStyleUnit_Coord: - { - // This col has a fixed width, so set the cell's width to the - // larger of (specified width, largest max_element_size of the - // cells in the column) - PRInt32 widthForThisCell = max(cellMinSize->width, colPosition->mWidth.GetCoordValue()); - if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell) + case eStyleUnit_Coord: { - if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell); - mTableFrame->SetColumnWidth(colIndex, widthForThisCell); - maxColWidth = widthForThisCell; + // This col has a fixed width, so set the cell's width to the + // larger of (specified width, largest max_element_size of the + // cells in the column) + PRInt32 widthForThisCell = PR_MAX(cellMinSize->width, colPosition->mWidth.GetCoordValue()); + if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell) + { + if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell); + mTableFrame->SetColumnWidth(colIndex, widthForThisCell); + maxColWidth = widthForThisCell; + } } - } - break; + break; + + default: + break; - case NS_STYLE_POSITION_VALUE_PCT: - case NS_STYLE_POSITION_VALUE_PROPORTIONAL: - // XXX write me when pct/proportional are supported - break; } -#endif // regardless of the width specification, keep track of the // min/max column widths @@ -443,20 +455,18 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo } } -#if 0 // if the col is fixed-width, expand the col to the specified // fixed width if necessary - if (colStyle->fixedWidth > mTableFrame->GetColumnWidth(colIndex)) - mTableFrame->SetColumnWidth(colIndex, colStyle->fixedWidth); + if (PR_TRUE==haveColWidth && specifiedFixedColWidth > mTableFrame->GetColumnWidth(colIndex)) + mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); // keep a running total of the amount of space taken up by all // fixed-width columns - aTotalFixedWidth += mTableFrame->GetColumnWidths(colIndex); + aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex); if (gsDebug) { printf (" after col %d, aTotalFixedWidth = %d\n", colIndex, aTotalFixedWidth); } -#endif // add col[i] metrics to the running totals for the table min/max width if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth) @@ -478,10 +488,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth, + nscoord aAvailWidth, + nscoord aMaxWidth, + nscoord aMinTableWidth, + nscoord aMaxTableWidth, nscoord aTableFixedWidth) { PRBool result = PR_TRUE; @@ -491,7 +501,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre if (NS_UNCONSTRAINEDSIZE==aMaxWidth) { // the max width of the table fits comfortably in the available space if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } else if (aMinTableWidth > aMaxWidth) { // the table doesn't fit in the available space @@ -501,7 +511,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre else if (aMaxTableWidth <= aMaxWidth) { // the max width of the table fits comfortably in the available space if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } else { // the table fits somewhere between its min and desired size @@ -511,9 +521,9 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre } } else - { + { // tables with fixed-width have their own rules if (aTableFixedWidth= its max width, so give each column its max requested size if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } } return result; @@ -550,7 +560,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte // XXX need column frame to ask this question nsStylePosition* colPosition = nsnull; - if (PR_TRUE==IsProportionalWidth(colPosition)) + if (PR_FALSE==IsFixedWidth(colPosition)) { for (PRInt32 cellIndex = 0; cellIndexGetColumnLayoutData(); PRInt32 numCols = columnLayoutData->Count(); for (PRInt32 colIndex = 0; colIndexElementAt(colIndex)); nsTableColPtr col = colData->GetCol(); // col: ADDREF++ nsVoidArray *cells = colData->GetCells(); - PRInt32 minColWidth = 0; - PRInt32 maxColWidth = 0; PRInt32 numCells = cells->Count(); - if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); - // XXX Need columnFrame to ask the style question - nsStylePosition* colPosition = nsnull; + // Get the columns's style + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + nsIStyleContextPtr colSC; + colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); - if (PR_TRUE==IsProportionalWidth(colPosition)) + if (PR_FALSE==IsFixedWidth(colPosition)) { numProportionalColumns++; // first, deal with any cells that span into this column from a pervious column @@ -683,60 +701,115 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo if (gsDebug==PR_TRUE) { printf (" for determining width of col %d %s:\n", - colIndex, IsProportionalWidth(colPosition)? "(P)":"(A)"); + colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)"); printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth); printf (" aAvailWidth = %d\n", aAvailWidth); } + // Get column width if it has one + nscoord specifiedProportion = -1; + float specifiedPercentageColWidth = -1.0f; + PRBool isAutoWidth = PR_FALSE; + switch (colPosition->mWidth.GetUnit()) { + case eStyleUnit_Percent: + specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue(); + break; + case eStyleUnit_Proportional: + specifiedProportion = colPosition->mWidth.GetIntValue(); + break; + case eStyleUnit_Auto: + isAutoWidth = PR_TRUE; + break; + default: + break; + } -#if XXX_bug_kipp_about_this - if (0==colStyle->proportionalWidth) + /* set the column width, knowing that the table fits in the available space */ + if (0==specifiedProportion || 0.0==specifiedPercentageColWidth) { // col width is specified to be the minimum mTableFrame->SetColumnWidth(colIndex, minColWidth); if (gsDebug==PR_TRUE) printf (" 3 (0): col %d set to min width = %d because style set proportionalWidth=0\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); } - else // BUG? else? other code below has the else -#endif - if (PR_TRUE==IsAutoWidth(colPosition)) - { // give each remaining column it's desired width + else if (PR_TRUE==isAutoWidth) + { // col width is determined by the cells' content, + // so give each remaining column it's desired width (because we know we fit.) // if there is width left over, we'll factor that in after this loop is complete mTableFrame->SetColumnWidth(colIndex, maxColWidth); if (gsDebug==PR_TRUE) printf (" 3a: col %d with availWidth %d, set to width = %d\n", colIndex, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); } + else if (0!=specifiedProportion) + { // we need to save these and do them after all other columns have been calculated + /* the calculation will be: + sum up n, the total number of slices for the columns with proportional width + compute the table "required" width, fixed-width + percentage-width + + the sum of the proportional column's max widths (especially because in this routine I know the table fits) + compute the remaining width: the required width - the used width (fixed + percentage) + compute the width per slice + set the width of each proportional-width column to it's number of slices * width per slice + */ + mTableFrame->SetColumnWidth(colIndex, 0); // set the column width to 0, since it isn't computed yet + if (nsnull==proportionalColumnsList) + proportionalColumnsList = new nsVoidArray(); + ProportionalColumnLayoutStruct * info = + new ProportionalColumnLayoutStruct(colIndex, minColWidth, maxColWidth, specifiedProportion); + proportionalColumnsList->AppendElement(info); + totalSlices += specifiedProportion; + } else - { // give each remaining column an equal percentage of the remaining space + { // give each remaining column a percentage of the remaining space PRInt32 percentage = -1; if (NS_UNCONSTRAINEDSIZE==aAvailWidth) - { + { // since the "remaining space" is infinite, give the column it's max requested size mTableFrame->SetColumnWidth(colIndex, maxColWidth); } else { -#if XXX_bug_kipp_about_this - percentage = colStyle->proportionalWidth; + if (-1.0f != specifiedPercentageColWidth) + percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors? if (-1==percentage) -#endif percentage = 100/numCols; - mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100); + // base the % on the total max width + mTableFrame->SetColumnWidth(colIndex, (percentage*aMaxWidth)/100); // if the column was computed to be too small, enlarge the column if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) mTableFrame->SetColumnWidth(colIndex, minColWidth); } if (gsDebug==PR_TRUE) - printf (" 3b: col %d given %d percent of availWidth %d, set to width = %d\n", - colIndex, percentage, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); + printf (" 3b: col %d given %d percent of aMaxWidth %d, set to width = %d\n", + colIndex, percentage, aMaxWidth, mTableFrame->GetColumnWidth(colIndex)); } } tableWidth += mTableFrame->GetColumnWidth(colIndex); } - // post-process if necessary + /* --- post-process if necessary --- */ + // first, assign a width to proportional-width columns + if (nsnull!=proportionalColumnsList) + { + // first, figure out the amount of space per slice + nscoord widthRemaining = aMaxWidth - tableWidth; + nscoord widthPerSlice = widthRemaining/totalSlices; + PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count(); + for (PRInt32 i=0; iElementAt(i)); + nscoord computedColWidth = info->mProportion*widthPerSlice; + mTableFrame->SetColumnWidth(info->mColIndex, computedColWidth); + if (gsDebug==PR_TRUE) + printf (" 3c: col %d given %d proportion of remaining space %d, set to width = %d\n", + info->mColIndex, info->mProportion, widthRemaining, computedColWidth); + tableWidth += computedColWidth; + delete info; + } + delete proportionalColumnsList; + } - // if the specified width of the table is greater than the table's computed width, expand the + // next, if the specified width of the table is greater than the table's computed width, expand the // table's computed width to match the specified width, giving the extra space to proportionately-sized // columns if possible. if (aTableFixedWidth > tableWidth) @@ -750,7 +823,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex); mTableFrame->SetColumnWidth(colIndex, colWidth); @@ -788,31 +861,33 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre #endif PRBool result = PR_TRUE; - PRBool equalWidthColumns=PR_FALSE; // TODO: compute this via style system - PRInt32 maxOfAllMinColWidths = 0; - nsVoidArray *spanList=nsnull; + PRInt32 maxOfAllMinColWidths = 0; // for the case where we have equal column widths, this is the smallest a column can be + nscoord tableWidth=0; // the width of the table as a result of setting column widths + nscoord numProportionalColumns = 0; // the total number of proportional-width columns + PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request + nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width + nsVoidArray *spanList=nsnull; // a list of the cells that span columns nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData(); PRInt32 numCols = columnLayoutData->Count(); for (PRInt32 colIndex = 0; colIndexElementAt(colIndex)); - nsTableColPtr col = colData->GetCol(); // col: ADDREF++ - -#if XXX_bug_kipp_about_this - // XXX BUG: mStyleContext is for the table frame not for the column. - nsStyleMolecule* colStyle = - (nsStyleMolecule*)mStyleContext->GetData(eStyleStruct_Molecule); -#else - nsStylePosition* colPosition = nsnull; -#endif - - nsVoidArray *cells = colData->GetCells(); + if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); PRInt32 minColWidth = 0; PRInt32 maxColWidth = 0; + // Get column information + nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex)); + nsTableColPtr col = colData->GetCol(); // col: ADDREF++ + nsVoidArray *cells = colData->GetCells(); PRInt32 numCells = cells->Count(); - if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); - if (PR_TRUE==IsProportionalWidth(colPosition)) + // Get the columns's style + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + nsIStyleContextPtr colSC; + colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); + + if (PR_FALSE==IsFixedWidth(colPosition)) { // first, deal with any cells that span into this column from a pervious column if (nsnull!=spanList) @@ -873,31 +948,45 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre if (gsDebug==PR_TRUE) { printf (" for determining width of col %d %s:\n", - colIndex, IsProportionalWidth(colPosition)? "(P)":"(A)"); + colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)"); printf (" minTableWidth = %d and maxTableWidth = %d\n", aMinTableWidth, aMaxTableWidth); printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth); printf (" aAvailWidth = %d\n", aAvailWidth); } - // this col has proportional width, so set its width based on the table width + // Get column width if it has one + nscoord specifiedProportion = -1; + float specifiedPercentageColWidth = -1.0f; + PRBool isAutoWidth = PR_FALSE; + switch (colPosition->mWidth.GetUnit()) { + case eStyleUnit_Percent: + specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue(); + break; + case eStyleUnit_Proportional: + specifiedProportion = colPosition->mWidth.GetIntValue(); + break; + case eStyleUnit_Auto: + isAutoWidth = PR_TRUE; + break; + default: + break; + } + // the table fits in the space somewhere between its min and max size // so dole out the available space appropriately -#if XXX_bug_kipp_about_this - if (0==colStyle->proportionalWidth) + if (0==specifiedProportion || 0.0==specifiedPercentageColWidth) { // col width is specified to be the minimum mTableFrame->SetColumnWidth(colIndex, minColWidth); if (gsDebug==PR_TRUE) printf (" 4 (0): col %d set to min width = %d because style set proportionalWidth=0\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); } - else -#endif - if (1==numCols) + else if (1==numCols) { // there is only one column, so it should be as wide as the available space allows it to be if (gsDebug==PR_TRUE) printf (" 4 one-column: col %d set to width = %d\n", colIndex, aAvailWidth); mTableFrame->SetColumnWidth(colIndex, aAvailWidth); } - else if (IsAutoWidth(colPosition)) + else if (PR_TRUE==isAutoWidth) { // column's width is determined by its content PRUint32 W = aMaxWidth - aMinTableWidth; PRUint32 D = aMaxTableWidth - aMinTableWidth; @@ -910,34 +999,81 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre printf (" 4 auto-width: col %d W=%d D=%d d=%d, set to width = %d\n", colIndex, W, D, d, mTableFrame->GetColumnWidth(colIndex)); } + else if (0!=specifiedProportion) + { // we need to save these and do them after all other columns have been calculated + /* the calculation will be: + sum up n, the total number of slices for the columns with proportional width + compute the table "required" width, fixed-width + percentage-width + + the sum of the proportional column's max widths (especially because in this routine I know the table fits) + compute the remaining width: the required width - the used width (fixed + percentage) + compute the width per slice + set the width of each proportional-width column to it's number of slices * width per slice + */ + mTableFrame->SetColumnWidth(colIndex, 0); // set the column width to 0, since it isn't computed yet + if (nsnull==proportionalColumnsList) + proportionalColumnsList = new nsVoidArray(); + ProportionalColumnLayoutStruct * info = + new ProportionalColumnLayoutStruct(colIndex, minColWidth, maxColWidth, specifiedProportion); + proportionalColumnsList->AppendElement(info); + totalSlices += specifiedProportion; + } else - { // give each remaining column an equal percentage of the remaining space -#if XXX_bug_kipp_about_this - PRInt32 percentage = colStyle->proportionalWidth; - if (-1==percentage) -#endif - PRInt32 percentage = 100/numCols; - mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100); - // if the column was computed to be too small, enlarge the column - if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) + { // give each remaining column a percentage of the remaining space + PRInt32 percentage = -1; + if (NS_UNCONSTRAINEDSIZE==aAvailWidth) + { // since the "remaining space" is infinite, give the column it's max requested size + mTableFrame->SetColumnWidth(colIndex, maxColWidth); + } + else { - mTableFrame->SetColumnWidth(colIndex, minColWidth); - if (maxOfAllMinColWidths < minColWidth) - maxOfAllMinColWidths = minColWidth; + if (-1.0f != specifiedPercentageColWidth) + percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors? + if (-1==percentage) + percentage = 100/numCols; + // base the % on the total max width + mTableFrame->SetColumnWidth(colIndex, (percentage*aMaxWidth)/100); + // if the column was computed to be too small, enlarge the column + if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) + { + mTableFrame->SetColumnWidth(colIndex, minColWidth); + if (maxOfAllMinColWidths < minColWidth) + maxOfAllMinColWidths = minColWidth; + } } if (gsDebug==PR_TRUE) { - printf (" 4 equal width: col %d given %d percent of availWidth %d, set to width = %d\n", - colIndex, percentage, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); + printf (" 4b: col %d given %d percent of maxWidth %d, set to width = %d\n", + colIndex, percentage, aMaxWidth, mTableFrame->GetColumnWidth(colIndex)); if (0!=maxOfAllMinColWidths) printf(" and setting maxOfAllMins to %d\n", maxOfAllMinColWidths); } } } } + /* --- post-process if necessary --- */ + // first, assign a width to proportional-width columns + if (nsnull!=proportionalColumnsList) + { + // first, figure out the amount of space per slice + nscoord widthRemaining = aMaxWidth - tableWidth; + nscoord widthPerSlice = widthRemaining/totalSlices; + PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count(); + for (PRInt32 i=0; iElementAt(i)); + nscoord computedColWidth = info->mProportion*widthPerSlice; + mTableFrame->SetColumnWidth(info->mColIndex, computedColWidth); + if (gsDebug==PR_TRUE) + printf (" 3c: col %d given %d proportion of remaining space %d, set to width = %d\n", + info->mColIndex, info->mProportion, widthRemaining, computedColWidth); + tableWidth += computedColWidth; + delete info; + } + delete proportionalColumnsList; + } - // post-process if necessary - + /* // if columns have equal width, and some column's content couldn't squeeze into the computed size, // then expand every column to the min size of the column with the largest min size if (equalWidthColumns && 0!=maxOfAllMinColWidths) @@ -946,6 +1082,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre for (PRInt32 colIndex = 0; colIndexSetColumnWidth(colIndex, maxOfAllMinColWidths); } + */ if (nsnull!=spanList) delete spanList; diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h index 9b0cee6b530..2c2ad55cb08 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h @@ -124,13 +124,15 @@ public: * * @param aPresContext the presentation context * @param aAvailWidth the remaining amount of horizontal space available + * @param aMaxWidth the total amount of horizontal space available * @param aTableFixedWidth the specified width of the table. If there is none, * this param is 0 * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error */ virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, + nscoord aAvailWidth, + nscoord aMaxWidth, nscoord aTableFixedWidth); /** assign widths for each column that has proportional width inside a table that @@ -155,10 +157,11 @@ public: PRInt32 aMinTableWidth, PRInt32 aMaxTableWidth); - /** return true if the style indicates that the width is proportional - * for the purposes of column width determination + /** return true if the style indicates that the width is a specific width + * for the purposes of column width determination. + * return false if the width changes based on content, parent size, etc. */ - virtual PRBool IsProportionalWidth(nsStylePosition* aStylePosition); + virtual PRBool IsFixedWidth(nsStylePosition* aStylePosition); virtual PRBool IsAutoWidth(nsStylePosition* aStylePosition); diff --git a/mozilla/layout/html/table/src/nsColLayoutData.cpp b/mozilla/layout/html/table/src/nsColLayoutData.cpp index 57af73713ae..2b972868176 100644 --- a/mozilla/layout/html/table/src/nsColLayoutData.cpp +++ b/mozilla/layout/html/table/src/nsColLayoutData.cpp @@ -24,6 +24,7 @@ nsColLayoutData::nsColLayoutData(nsTableCol *aCol) { mCol = aCol; mCells = new nsVoidArray(); + mColFrame = nsnull; } nsColLayoutData::~nsColLayoutData() @@ -55,7 +56,17 @@ void nsColLayoutData::SetCol(nsTableCol * aCol) NS_IF_RELEASE(mCol); mCol = aCol; } -}; +} + +nsTableColFrame * nsColLayoutData::GetColFrame() +{ + return mColFrame; +} + +void nsColLayoutData::SetColFrame(nsTableColFrame *aColFrame) +{ + mColFrame = aColFrame; +} nsCellLayoutData* nsColLayoutData::ElementAt(PRInt32 aIndex) const diff --git a/mozilla/layout/html/table/src/nsColLayoutData.h b/mozilla/layout/html/table/src/nsColLayoutData.h index edfe9491ba4..e4ca160430b 100644 --- a/mozilla/layout/html/table/src/nsColLayoutData.h +++ b/mozilla/layout/html/table/src/nsColLayoutData.h @@ -26,6 +26,7 @@ class nsVoidArray; class nsCellLayoutData; class nsTableFrame; +class nsTableColFrame; /** Simple data class that represents in-process reflow information about a column. @@ -42,6 +43,10 @@ public: void SetCol(nsTableCol * aCol); + nsTableColFrame *GetColFrame(); + + void SetColFrame(nsTableColFrame *aColFrame); + nsVoidArray * GetCells(); PRInt32 Count() const; @@ -67,6 +72,7 @@ public: private: nsTableCol *mCol; + nsTableColFrame *mColFrame; nsVoidArray *mCells; }; diff --git a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h index 4a6c2484036..7d5d39ff619 100644 --- a/mozilla/layout/html/table/src/nsITableLayoutStrategy.h +++ b/mozilla/layout/html/table/src/nsITableLayoutStrategy.h @@ -44,99 +44,6 @@ public: PRInt32 &aMinTableWidth, PRInt32 &aMaxTableWidth, nsSize* aMaxElementSize)=0; - - /** assign widths for each column that has fixed width. - * Computes the minimum and maximum table widths. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aMaxWidth the maximum width of the table - * @param aNumCols the total number of columns in the table - * @param aTableStyle the resolved style for the table - * @param aTotalFixedWidth out param, the sum of the fixed width columns - * @param aMinTableWidth out param, the min possible table width - * @param aMaxTableWidth out param, the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - * - * TODO: should be renamed to "AssignKnownWidthInformation - */ - virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext, - PRInt32 aMaxWidth, - PRInt32 aNumCols, - PRInt32 & aTotalFixedWidth, - PRInt32 & aMinTableWidth, - PRInt32 & aMaxTableWidth)=0; - - - - /** 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. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * @param aMaxWidth the total amount of horizontal space available - * @param aMinTableWidth the min possible table width - * @param aMaxTableWidth the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth, - nscoord aTableFixedWidth)=0; - - /** assign the minimum allowed width for each column that has proportional width. - * Typically called when the min table width doesn't fit in the available space. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext)=0; - - /** assign the maximum allowed width for each column that has proportional width. - * Typically called when the desired max table width fits in the available space. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - nscoord aTableFixedWidth)=0; - - /** assign widths for each column that has proportional width inside a table that - * has auto width (width set by the content and available space) according to the - * HTML 4 specification. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * @param aMaxWidth the total amount of horizontal space available - * @param aMinTableWidth the min possible table width - * @param aMaxTableWidth the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - * - * TODO: rename this method to reflect that it is a Nav4 compatibility method - */ - virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth)=0; - - }; #endif diff --git a/mozilla/layout/html/table/src/nsTableCol.cpp b/mozilla/layout/html/table/src/nsTableCol.cpp index ca2fdde9a9f..1d29b5ad50a 100644 --- a/mozilla/layout/html/table/src/nsTableCol.cpp +++ b/mozilla/layout/html/table/src/nsTableCol.cpp @@ -16,6 +16,7 @@ * Reserved. */ #include "nsTableCol.h" +#include "nsTableColFrame.h" #include "nsTableColGroup.h" #include "nsTablePart.h" #include "nsHTMLParts.h" @@ -35,29 +36,6 @@ static const PRBool gsDebug = PR_FALSE; static const PRBool gsNoisyRefs = PR_FALSE; #endif -class nsTableColFrame : public nsFrame { -public: - static nsresult NewFrame(nsIFrame** aInstancePtrResult, - nsIContent* aContent, - nsIFrame* aParent); - - NS_IMETHOD Paint(nsIPresContext& aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect); - - NS_IMETHOD Reflow(nsIPresContext* aPresContext, - nsReflowMetrics& aDesiredSize, - const nsReflowState& aReflowState, - nsReflowStatus& aStatus); - -protected: - - nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame); - - ~nsTableColFrame(); - -}; - nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame) diff --git a/mozilla/layout/html/table/src/nsTableColFrame.h b/mozilla/layout/html/table/src/nsTableColFrame.h new file mode 100644 index 00000000000..80e0c761a4a --- /dev/null +++ b/mozilla/layout/html/table/src/nsTableColFrame.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef nsTableColFrame_h__ +#define nsTableColFrame_h__ + +#include "nscore.h" +#include "nsContainerFrame.h" + + +class nsTableColFrame : public nsFrame { +public: + static nsresult NewFrame(nsIFrame** aInstancePtrResult, + nsIContent* aContent, + nsIFrame* aParent); + + NS_IMETHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsReflowMetrics& aDesiredSize, + const nsReflowState& aReflowState, + nsReflowStatus& aStatus); + +protected: + + nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + ~nsTableColFrame(); + +}; + +#endif + diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index 4a1b85720c5..1b36a298cec 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -135,48 +135,52 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre result = table->GetAttribute(nsHTMLAtoms::cols, value); // if COLS is set, then map it into the COL frames - // chicken and egg problem here. I don't have any children yet, so I - // don't know how many columns there are, so I can't do this! - // I need to just set some state, and let the individual columns query up into me - // in their own hooks - PRInt32 numCols; - if (result == eContentAttr_NoValue) - ChildCount(numCols); - else if (result == eContentAttr_HasValue) + if (eContentAttr_NotThere != result) { - nsHTMLUnit unit = value.GetUnit(); - if (eHTMLUnit_Empty==unit) + PRInt32 numCols=0; + if (eContentAttr_NoValue == result) ChildCount(numCols); - else - numCols = value.GetIntValue(); - } + else if (eContentAttr_HasValue == result) + { + nsHTMLUnit unit = value.GetUnit(); + if (eHTMLUnit_Empty==unit) + ChildCount(numCols); + else + numCols = value.GetIntValue(); + } - PRInt32 colIndex=0; - nsIFrame *colFrame; - FirstChild(colFrame); - for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); - nsStyleCoord width (1, eStyleUnit_Proportional); - colPosition->mWidth = width; - colFrame->GetNextSibling(colFrame); - } - // if there are more columns, there width is set to "minimum" - PRInt32 numChildFrames; - ChildCount(numChildFrames); - for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); - nsStyleCoord width (0, eStyleUnit_Integer); - colPosition->mWidth = width; - colFrame->GetNextSibling(colFrame); - } + PRInt32 colIndex=0; + nsIFrame *colFrame=nsnull; + nsIStyleContext *colStyleContext; + for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + nsStyleCoord width (1, eStyleUnit_Proportional); + colPosition->mWidth = width; + colFrame->GetStyleContext(aPresContext, colStyleContext); + colStyleContext->RecalcAutomaticData(aPresContext); + } + // if there are more columns, there width is set to "minimum" + PRInt32 numChildFrames; + ChildCount(numChildFrames); + for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + nsStyleCoord width (0, eStyleUnit_Integer); + colPosition->mWidth = width; + colFrame->GetStyleContext(aPresContext, colStyleContext); + colStyleContext->RecalcAutomaticData(aPresContext); + } - mStyleContext->RecalcAutomaticData(aPresContext); + mStyleContext->RecalcAutomaticData(aPresContext); + } return NS_OK; } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 301cf4dd80a..d3d73600a71 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -630,40 +630,6 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, mLastContentIsComplete = PR_TRUE; const PRInt32 contentType = ((nsTableContent *)(nsIContent*)kid)->GetType(); - /* - if (contentType==nsITableContent::kTableColGroupType) - { - // Resolve style - nsIStyleContextPtr kidStyleContext = - aPresContext->ResolveStyleContextFor(kid, this); - NS_ASSERTION(kidStyleContext.IsNotNull(), "null style context for kid"); - - // SEC: TODO: when content is appended or deleted, be sure to clear out the frame hierarchy!!!! - - // get next frame, creating one if needed - nsIFrame* kidFrame=nsnull; - if (nsnull!=prevKidFrame) - prevKidFrame->GetNextSibling(kidFrame); // no need to check for an error, just see if it returned null... - else - ChildAt(0, kidFrame); - - // if this is the first time, allocate the frame - if (nsnull==kidFrame) - { - nsIContentDelegate* kidDel; - kidDel = kid->GetDelegate(aPresContext); - nsresult rv = kidDel->CreateFrame(aPresContext, kid, - this, kidStyleContext, kidFrame); - NS_RELEASE(kidDel); - } - - // reflow the column group - nsReflowState kidReflowState(eReflowReason_Resize, availSize); - result = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState); - kidFrame->SetRect(0,0,0,0); - } - else */ - //if (contentType==nsITableContent::kTableRowGroupType) if (contentType!=nsITableContent::kTableCaptionType) { // Resolve style @@ -1983,6 +1949,7 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC nsTablePart * tablePart = (nsTablePart *)mContent; PRInt32 cols = tablePart->GetMaxColumns(); PRInt32 tableKidCount = tablePart->ChildCount(); + nsIFrame * colGroupFrame = mFirstChild; for (PRInt32 i=0; iChildAt(i); @@ -1996,6 +1963,9 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC nsTableColPtr col = (nsTableCol *)tableKid->ChildAt(j); NS_ASSERTION(col.IsNotNull(), "bad content"); nsColLayoutData *colData = new nsColLayoutData(col); + nsTableColFrame *colFrame=nsnull; + colGroupFrame->ChildAt(j, (nsIFrame *&)colFrame); + colData->SetColFrame(colFrame); mColumnLayoutData->AppendElement((void *)colData); } } @@ -2004,6 +1974,7 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC { break; } + ChildAt(i, colGroupFrame); // can't use colGroupFrame->GetNextSibling because it hasn't been set yet } } diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index c29f38d78c4..12aca89da5c 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -129,15 +129,14 @@ public: * DEBUG METHOD * */ - void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const; /** return the width of the column at aColIndex */ - PRInt32 GetColumnWidth(PRInt32 aColIndex); + virtual PRInt32 GetColumnWidth(PRInt32 aColIndex); /** set the width of the column at aColIndex to aWidth */ - void SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth); - + virtual void SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth); /** * Calculate Layout Information diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index da174e2274b..aed862b7993 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -19,6 +19,7 @@ #include #include "BasicTableLayoutStrategy.h" #include "nsTableFrame.h" +#include "nsTableColFrame.h" #include "nsColLayoutData.h" #include "nsCellLayoutData.h" #include "nsTableCol.h" @@ -42,12 +43,39 @@ static const PRBool gsDebugCLD = PR_FALSE; static const PRBool gsTiming = PR_FALSE; #endif +/* ---------- ProportionalColumnLayoutStruct ---------- */ +// TODO: make public so other subclasses can use it + +/** useful info about a column for layout */ +struct ProportionalColumnLayoutStruct +{ + ProportionalColumnLayoutStruct(PRInt32 aColIndex, + nscoord aMinColWidth, + nscoord aMaxColWidth, + PRInt32 aProportion) + { + mColIndex = aColIndex; + mMinColWidth = aMinColWidth; + mMaxColWidth = aMaxColWidth; + mProportion = aProportion; + }; + + PRInt32 mColIndex; + nscoord mMinColWidth; + nscoord mMaxColWidth; + PRInt32 mProportion; +}; + + + +/* ---------- BasicTableLayoutStrategy ---------- */ + /* return true if the style indicates that the width is proportional * for the purposes of column width determination */ -PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosition) +PRBool BasicTableLayoutStrategy::IsFixedWidth(nsStylePosition* aStylePosition) { - PRBool result = PR_FALSE; // assume that it is not + PRBool result = PR_FALSE; // assume that it is not fixed width PRInt32 unitType; if (nsnull == aStylePosition) { unitType = eStyleUnit_Auto; @@ -58,12 +86,11 @@ PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosi switch (unitType) { case eStyleUnit_Coord: - break; + result = PR_TRUE; case eStyleUnit_Auto: case eStyleUnit_Proportional: case eStyleUnit_Percent: - result = PR_TRUE; break; // TODO @@ -71,7 +98,7 @@ PRBool BasicTableLayoutStrategy::IsProportionalWidth(nsStylePosition* aStylePosi break; default: - NS_ASSERTION(PR_FALSE, "illegal style type in IsProportionalWidth"); + NS_ASSERTION(PR_FALSE, "illegal style type in IsFixedWidth"); break; } return result; @@ -263,6 +290,8 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData(); nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex)); NS_ASSERTION(nsnull != colData, "bad column data"); + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); nsTableColPtr col = colData->GetCol(); // col: ADDREF++ NS_ASSERTION(col.IsNotNull(), "bad col"); @@ -273,35 +302,25 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo PRInt32 numCells = cells->Count(); if (gsDebug==PR_TRUE) printf (" for column %d numCells = %d\n", colIndex, numCells); -#if XXX_need_access_to_column_frame_help // Get the columns's style nsIStyleContextPtr colSC; colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); - nsStylePosition* colPosition = (nsStylePosition*) - colSC->GetData(eStyleStruct_Position); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); // Get column width if it has one PRBool haveColWidth = PR_FALSE; - nscoord colWidth; + nscoord specifiedFixedColWidth=0; switch (colPosition->mWidth.GetUnit()) { - default: - case eStyleUnit_Auto: - case eStyleUnit_Inherit: - break; + case eStyleUnit_Coord: + haveColWidth = PR_TRUE; + specifiedFixedColWidth = colPosition->mWidth.GetCoordValue(); + break; - case eStyleUnit_Coord: - haveColWidth = PR_TRUE; - colWidth = colPosition->mWidth.GetCoordValue; - break; - - case eStyleUnit_Percent: - case eStyleUnit_Proportional: - //XXX haveColWidth = PR_TRUE; - //XXX colWidth = colPosition->mWidthPCT * something; - break; + default: + break; } -#endif + // TODO - use specifiedFixedColWidth to influence the width when both col span and fixed col width are given /* Scan the column, simulatneously assigning fixed column widths * and computing the min/max column widths */ @@ -388,34 +407,27 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo } } -#if XXX_need_access_to_column_frame_help + // TODO - use cellWidth found above to influence the cell width here switch (colPosition->mWidth.GetUnit()) { - default: - case eStyleUnit_Auto: - case eStyleUnit_Inherit: - break; - - case eStyleUnit_Coord: - { - // This col has a fixed width, so set the cell's width to the - // larger of (specified width, largest max_element_size of the - // cells in the column) - PRInt32 widthForThisCell = max(cellMinSize->width, colPosition->mWidth.GetCoordValue()); - if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell) + case eStyleUnit_Coord: { - if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell); - mTableFrame->SetColumnWidth(colIndex, widthForThisCell); - maxColWidth = widthForThisCell; + // This col has a fixed width, so set the cell's width to the + // larger of (specified width, largest max_element_size of the + // cells in the column) + PRInt32 widthForThisCell = PR_MAX(cellMinSize->width, colPosition->mWidth.GetCoordValue()); + if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell) + { + if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell); + mTableFrame->SetColumnWidth(colIndex, widthForThisCell); + maxColWidth = widthForThisCell; + } } - } - break; + break; + + default: + break; - case NS_STYLE_POSITION_VALUE_PCT: - case NS_STYLE_POSITION_VALUE_PROPORTIONAL: - // XXX write me when pct/proportional are supported - break; } -#endif // regardless of the width specification, keep track of the // min/max column widths @@ -443,20 +455,18 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo } } -#if 0 // if the col is fixed-width, expand the col to the specified // fixed width if necessary - if (colStyle->fixedWidth > mTableFrame->GetColumnWidth(colIndex)) - mTableFrame->SetColumnWidth(colIndex, colStyle->fixedWidth); + if (PR_TRUE==haveColWidth && specifiedFixedColWidth > mTableFrame->GetColumnWidth(colIndex)) + mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); // keep a running total of the amount of space taken up by all // fixed-width columns - aTotalFixedWidth += mTableFrame->GetColumnWidths(colIndex); + aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex); if (gsDebug) { printf (" after col %d, aTotalFixedWidth = %d\n", colIndex, aTotalFixedWidth); } -#endif // add col[i] metrics to the running totals for the table min/max width if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth) @@ -478,10 +488,10 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth, + nscoord aAvailWidth, + nscoord aMaxWidth, + nscoord aMinTableWidth, + nscoord aMaxTableWidth, nscoord aTableFixedWidth) { PRBool result = PR_TRUE; @@ -491,7 +501,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre if (NS_UNCONSTRAINEDSIZE==aMaxWidth) { // the max width of the table fits comfortably in the available space if (gsDebug) printf (" * table laying out in NS_UNCONSTRAINEDSIZE, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } else if (aMinTableWidth > aMaxWidth) { // the table doesn't fit in the available space @@ -501,7 +511,7 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre else if (aMaxTableWidth <= aMaxWidth) { // the max width of the table fits comfortably in the available space if (gsDebug) printf (" * table desired size fits, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } else { // the table fits somewhere between its min and desired size @@ -511,9 +521,9 @@ PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPre } } else - { + { // tables with fixed-width have their own rules if (aTableFixedWidth= its max width, so give each column its max requested size if (gsDebug) printf (" * specified width table > maxTableWidth, calling BalanceColumnsTableFits\n"); - result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aTableFixedWidth); + result = BalanceColumnsTableFits(aPresContext, aAvailWidth, aMaxWidth, aTableFixedWidth); } } return result; @@ -550,7 +560,7 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte // XXX need column frame to ask this question nsStylePosition* colPosition = nsnull; - if (PR_TRUE==IsProportionalWidth(colPosition)) + if (PR_FALSE==IsFixedWidth(colPosition)) { for (PRInt32 cellIndex = 0; cellIndexGetColumnLayoutData(); PRInt32 numCols = columnLayoutData->Count(); for (PRInt32 colIndex = 0; colIndexElementAt(colIndex)); nsTableColPtr col = colData->GetCol(); // col: ADDREF++ nsVoidArray *cells = colData->GetCells(); - PRInt32 minColWidth = 0; - PRInt32 maxColWidth = 0; PRInt32 numCells = cells->Count(); - if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); - // XXX Need columnFrame to ask the style question - nsStylePosition* colPosition = nsnull; + // Get the columns's style + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + nsIStyleContextPtr colSC; + colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); - if (PR_TRUE==IsProportionalWidth(colPosition)) + if (PR_FALSE==IsFixedWidth(colPosition)) { numProportionalColumns++; // first, deal with any cells that span into this column from a pervious column @@ -683,60 +701,115 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo if (gsDebug==PR_TRUE) { printf (" for determining width of col %d %s:\n", - colIndex, IsProportionalWidth(colPosition)? "(P)":"(A)"); + colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)"); printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth); printf (" aAvailWidth = %d\n", aAvailWidth); } + // Get column width if it has one + nscoord specifiedProportion = -1; + float specifiedPercentageColWidth = -1.0f; + PRBool isAutoWidth = PR_FALSE; + switch (colPosition->mWidth.GetUnit()) { + case eStyleUnit_Percent: + specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue(); + break; + case eStyleUnit_Proportional: + specifiedProportion = colPosition->mWidth.GetIntValue(); + break; + case eStyleUnit_Auto: + isAutoWidth = PR_TRUE; + break; + default: + break; + } -#if XXX_bug_kipp_about_this - if (0==colStyle->proportionalWidth) + /* set the column width, knowing that the table fits in the available space */ + if (0==specifiedProportion || 0.0==specifiedPercentageColWidth) { // col width is specified to be the minimum mTableFrame->SetColumnWidth(colIndex, minColWidth); if (gsDebug==PR_TRUE) printf (" 3 (0): col %d set to min width = %d because style set proportionalWidth=0\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); } - else // BUG? else? other code below has the else -#endif - if (PR_TRUE==IsAutoWidth(colPosition)) - { // give each remaining column it's desired width + else if (PR_TRUE==isAutoWidth) + { // col width is determined by the cells' content, + // so give each remaining column it's desired width (because we know we fit.) // if there is width left over, we'll factor that in after this loop is complete mTableFrame->SetColumnWidth(colIndex, maxColWidth); if (gsDebug==PR_TRUE) printf (" 3a: col %d with availWidth %d, set to width = %d\n", colIndex, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); } + else if (0!=specifiedProportion) + { // we need to save these and do them after all other columns have been calculated + /* the calculation will be: + sum up n, the total number of slices for the columns with proportional width + compute the table "required" width, fixed-width + percentage-width + + the sum of the proportional column's max widths (especially because in this routine I know the table fits) + compute the remaining width: the required width - the used width (fixed + percentage) + compute the width per slice + set the width of each proportional-width column to it's number of slices * width per slice + */ + mTableFrame->SetColumnWidth(colIndex, 0); // set the column width to 0, since it isn't computed yet + if (nsnull==proportionalColumnsList) + proportionalColumnsList = new nsVoidArray(); + ProportionalColumnLayoutStruct * info = + new ProportionalColumnLayoutStruct(colIndex, minColWidth, maxColWidth, specifiedProportion); + proportionalColumnsList->AppendElement(info); + totalSlices += specifiedProportion; + } else - { // give each remaining column an equal percentage of the remaining space + { // give each remaining column a percentage of the remaining space PRInt32 percentage = -1; if (NS_UNCONSTRAINEDSIZE==aAvailWidth) - { + { // since the "remaining space" is infinite, give the column it's max requested size mTableFrame->SetColumnWidth(colIndex, maxColWidth); } else { -#if XXX_bug_kipp_about_this - percentage = colStyle->proportionalWidth; + if (-1.0f != specifiedPercentageColWidth) + percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors? if (-1==percentage) -#endif percentage = 100/numCols; - mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100); + // base the % on the total max width + mTableFrame->SetColumnWidth(colIndex, (percentage*aMaxWidth)/100); // if the column was computed to be too small, enlarge the column if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) mTableFrame->SetColumnWidth(colIndex, minColWidth); } if (gsDebug==PR_TRUE) - printf (" 3b: col %d given %d percent of availWidth %d, set to width = %d\n", - colIndex, percentage, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); + printf (" 3b: col %d given %d percent of aMaxWidth %d, set to width = %d\n", + colIndex, percentage, aMaxWidth, mTableFrame->GetColumnWidth(colIndex)); } } tableWidth += mTableFrame->GetColumnWidth(colIndex); } - // post-process if necessary + /* --- post-process if necessary --- */ + // first, assign a width to proportional-width columns + if (nsnull!=proportionalColumnsList) + { + // first, figure out the amount of space per slice + nscoord widthRemaining = aMaxWidth - tableWidth; + nscoord widthPerSlice = widthRemaining/totalSlices; + PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count(); + for (PRInt32 i=0; iElementAt(i)); + nscoord computedColWidth = info->mProportion*widthPerSlice; + mTableFrame->SetColumnWidth(info->mColIndex, computedColWidth); + if (gsDebug==PR_TRUE) + printf (" 3c: col %d given %d proportion of remaining space %d, set to width = %d\n", + info->mColIndex, info->mProportion, widthRemaining, computedColWidth); + tableWidth += computedColWidth; + delete info; + } + delete proportionalColumnsList; + } - // if the specified width of the table is greater than the table's computed width, expand the + // next, if the specified width of the table is greater than the table's computed width, expand the // table's computed width to match the specified width, giving the extra space to proportionately-sized // columns if possible. if (aTableFixedWidth > tableWidth) @@ -750,7 +823,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo for (PRInt32 colIndex = 0; colIndexGetColumnWidth(colIndex); mTableFrame->SetColumnWidth(colIndex, colWidth); @@ -788,31 +861,33 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre #endif PRBool result = PR_TRUE; - PRBool equalWidthColumns=PR_FALSE; // TODO: compute this via style system - PRInt32 maxOfAllMinColWidths = 0; - nsVoidArray *spanList=nsnull; + PRInt32 maxOfAllMinColWidths = 0; // for the case where we have equal column widths, this is the smallest a column can be + nscoord tableWidth=0; // the width of the table as a result of setting column widths + nscoord numProportionalColumns = 0; // the total number of proportional-width columns + PRInt32 totalSlices=0; // the total number of slices the proportional-width columns request + nsVoidArray *proportionalColumnsList=nsnull; // a list of the columns that are proportional-width + nsVoidArray *spanList=nsnull; // a list of the cells that span columns nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData(); PRInt32 numCols = columnLayoutData->Count(); for (PRInt32 colIndex = 0; colIndexElementAt(colIndex)); - nsTableColPtr col = colData->GetCol(); // col: ADDREF++ - -#if XXX_bug_kipp_about_this - // XXX BUG: mStyleContext is for the table frame not for the column. - nsStyleMolecule* colStyle = - (nsStyleMolecule*)mStyleContext->GetData(eStyleStruct_Molecule); -#else - nsStylePosition* colPosition = nsnull; -#endif - - nsVoidArray *cells = colData->GetCells(); + if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); PRInt32 minColWidth = 0; PRInt32 maxColWidth = 0; + // Get column information + nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex)); + nsTableColPtr col = colData->GetCol(); // col: ADDREF++ + nsVoidArray *cells = colData->GetCells(); PRInt32 numCells = cells->Count(); - if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex); - if (PR_TRUE==IsProportionalWidth(colPosition)) + // Get the columns's style + nsTableColFrame *colFrame = colData->GetColFrame(); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + nsIStyleContextPtr colSC; + colFrame->GetStyleContext(aPresContext, colSC.AssignRef()); + nsStylePosition* colPosition = (nsStylePosition*) colSC->GetData(eStyleStruct_Position); + + if (PR_FALSE==IsFixedWidth(colPosition)) { // first, deal with any cells that span into this column from a pervious column if (nsnull!=spanList) @@ -873,31 +948,45 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre if (gsDebug==PR_TRUE) { printf (" for determining width of col %d %s:\n", - colIndex, IsProportionalWidth(colPosition)? "(P)":"(A)"); + colIndex, !IsFixedWidth(colPosition)? "(P)":"(A)"); printf (" minTableWidth = %d and maxTableWidth = %d\n", aMinTableWidth, aMaxTableWidth); printf (" minColWidth = %d and maxColWidth = %d\n", minColWidth, maxColWidth); printf (" aAvailWidth = %d\n", aAvailWidth); } - // this col has proportional width, so set its width based on the table width + // Get column width if it has one + nscoord specifiedProportion = -1; + float specifiedPercentageColWidth = -1.0f; + PRBool isAutoWidth = PR_FALSE; + switch (colPosition->mWidth.GetUnit()) { + case eStyleUnit_Percent: + specifiedPercentageColWidth = colPosition->mWidth.GetPercentValue(); + break; + case eStyleUnit_Proportional: + specifiedProportion = colPosition->mWidth.GetIntValue(); + break; + case eStyleUnit_Auto: + isAutoWidth = PR_TRUE; + break; + default: + break; + } + // the table fits in the space somewhere between its min and max size // so dole out the available space appropriately -#if XXX_bug_kipp_about_this - if (0==colStyle->proportionalWidth) + if (0==specifiedProportion || 0.0==specifiedPercentageColWidth) { // col width is specified to be the minimum mTableFrame->SetColumnWidth(colIndex, minColWidth); if (gsDebug==PR_TRUE) printf (" 4 (0): col %d set to min width = %d because style set proportionalWidth=0\n", colIndex, mTableFrame->GetColumnWidth(colIndex)); } - else -#endif - if (1==numCols) + else if (1==numCols) { // there is only one column, so it should be as wide as the available space allows it to be if (gsDebug==PR_TRUE) printf (" 4 one-column: col %d set to width = %d\n", colIndex, aAvailWidth); mTableFrame->SetColumnWidth(colIndex, aAvailWidth); } - else if (IsAutoWidth(colPosition)) + else if (PR_TRUE==isAutoWidth) { // column's width is determined by its content PRUint32 W = aMaxWidth - aMinTableWidth; PRUint32 D = aMaxTableWidth - aMinTableWidth; @@ -910,34 +999,81 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre printf (" 4 auto-width: col %d W=%d D=%d d=%d, set to width = %d\n", colIndex, W, D, d, mTableFrame->GetColumnWidth(colIndex)); } + else if (0!=specifiedProportion) + { // we need to save these and do them after all other columns have been calculated + /* the calculation will be: + sum up n, the total number of slices for the columns with proportional width + compute the table "required" width, fixed-width + percentage-width + + the sum of the proportional column's max widths (especially because in this routine I know the table fits) + compute the remaining width: the required width - the used width (fixed + percentage) + compute the width per slice + set the width of each proportional-width column to it's number of slices * width per slice + */ + mTableFrame->SetColumnWidth(colIndex, 0); // set the column width to 0, since it isn't computed yet + if (nsnull==proportionalColumnsList) + proportionalColumnsList = new nsVoidArray(); + ProportionalColumnLayoutStruct * info = + new ProportionalColumnLayoutStruct(colIndex, minColWidth, maxColWidth, specifiedProportion); + proportionalColumnsList->AppendElement(info); + totalSlices += specifiedProportion; + } else - { // give each remaining column an equal percentage of the remaining space -#if XXX_bug_kipp_about_this - PRInt32 percentage = colStyle->proportionalWidth; - if (-1==percentage) -#endif - PRInt32 percentage = 100/numCols; - mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100); - // if the column was computed to be too small, enlarge the column - if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) + { // give each remaining column a percentage of the remaining space + PRInt32 percentage = -1; + if (NS_UNCONSTRAINEDSIZE==aAvailWidth) + { // since the "remaining space" is infinite, give the column it's max requested size + mTableFrame->SetColumnWidth(colIndex, maxColWidth); + } + else { - mTableFrame->SetColumnWidth(colIndex, minColWidth); - if (maxOfAllMinColWidths < minColWidth) - maxOfAllMinColWidths = minColWidth; + if (-1.0f != specifiedPercentageColWidth) + percentage = (PRInt32)(specifiedPercentageColWidth*100.0f); // TODO: rounding errors? + if (-1==percentage) + percentage = 100/numCols; + // base the % on the total max width + mTableFrame->SetColumnWidth(colIndex, (percentage*aMaxWidth)/100); + // if the column was computed to be too small, enlarge the column + if (mTableFrame->GetColumnWidth(colIndex) <= minColWidth) + { + mTableFrame->SetColumnWidth(colIndex, minColWidth); + if (maxOfAllMinColWidths < minColWidth) + maxOfAllMinColWidths = minColWidth; + } } if (gsDebug==PR_TRUE) { - printf (" 4 equal width: col %d given %d percent of availWidth %d, set to width = %d\n", - colIndex, percentage, aAvailWidth, mTableFrame->GetColumnWidth(colIndex)); + printf (" 4b: col %d given %d percent of maxWidth %d, set to width = %d\n", + colIndex, percentage, aMaxWidth, mTableFrame->GetColumnWidth(colIndex)); if (0!=maxOfAllMinColWidths) printf(" and setting maxOfAllMins to %d\n", maxOfAllMinColWidths); } } } } + /* --- post-process if necessary --- */ + // first, assign a width to proportional-width columns + if (nsnull!=proportionalColumnsList) + { + // first, figure out the amount of space per slice + nscoord widthRemaining = aMaxWidth - tableWidth; + nscoord widthPerSlice = widthRemaining/totalSlices; + PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count(); + for (PRInt32 i=0; iElementAt(i)); + nscoord computedColWidth = info->mProportion*widthPerSlice; + mTableFrame->SetColumnWidth(info->mColIndex, computedColWidth); + if (gsDebug==PR_TRUE) + printf (" 3c: col %d given %d proportion of remaining space %d, set to width = %d\n", + info->mColIndex, info->mProportion, widthRemaining, computedColWidth); + tableWidth += computedColWidth; + delete info; + } + delete proportionalColumnsList; + } - // post-process if necessary - + /* // if columns have equal width, and some column's content couldn't squeeze into the computed size, // then expand every column to the min size of the column with the largest min size if (equalWidthColumns && 0!=maxOfAllMinColWidths) @@ -946,6 +1082,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre for (PRInt32 colIndex = 0; colIndexSetColumnWidth(colIndex, maxOfAllMinColWidths); } + */ if (nsnull!=spanList) delete spanList; diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h index 9b0cee6b530..2c2ad55cb08 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.h +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h @@ -124,13 +124,15 @@ public: * * @param aPresContext the presentation context * @param aAvailWidth the remaining amount of horizontal space available + * @param aMaxWidth the total amount of horizontal space available * @param aTableFixedWidth the specified width of the table. If there is none, * this param is 0 * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error */ virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, + nscoord aAvailWidth, + nscoord aMaxWidth, nscoord aTableFixedWidth); /** assign widths for each column that has proportional width inside a table that @@ -155,10 +157,11 @@ public: PRInt32 aMinTableWidth, PRInt32 aMaxTableWidth); - /** return true if the style indicates that the width is proportional - * for the purposes of column width determination + /** return true if the style indicates that the width is a specific width + * for the purposes of column width determination. + * return false if the width changes based on content, parent size, etc. */ - virtual PRBool IsProportionalWidth(nsStylePosition* aStylePosition); + virtual PRBool IsFixedWidth(nsStylePosition* aStylePosition); virtual PRBool IsAutoWidth(nsStylePosition* aStylePosition); diff --git a/mozilla/layout/tables/nsITableLayoutStrategy.h b/mozilla/layout/tables/nsITableLayoutStrategy.h index 4a6c2484036..7d5d39ff619 100644 --- a/mozilla/layout/tables/nsITableLayoutStrategy.h +++ b/mozilla/layout/tables/nsITableLayoutStrategy.h @@ -44,99 +44,6 @@ public: PRInt32 &aMinTableWidth, PRInt32 &aMaxTableWidth, nsSize* aMaxElementSize)=0; - - /** assign widths for each column that has fixed width. - * Computes the minimum and maximum table widths. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aMaxWidth the maximum width of the table - * @param aNumCols the total number of columns in the table - * @param aTableStyle the resolved style for the table - * @param aTotalFixedWidth out param, the sum of the fixed width columns - * @param aMinTableWidth out param, the min possible table width - * @param aMaxTableWidth out param, the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - * - * TODO: should be renamed to "AssignKnownWidthInformation - */ - virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext, - PRInt32 aMaxWidth, - PRInt32 aNumCols, - PRInt32 & aTotalFixedWidth, - PRInt32 & aMinTableWidth, - PRInt32 & aMaxTableWidth)=0; - - - - /** 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. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * @param aMaxWidth the total amount of horizontal space available - * @param aMinTableWidth the min possible table width - * @param aMaxTableWidth the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth, - nscoord aTableFixedWidth)=0; - - /** assign the minimum allowed width for each column that has proportional width. - * Typically called when the min table width doesn't fit in the available space. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext)=0; - - /** assign the maximum allowed width for each column that has proportional width. - * Typically called when the desired max table width fits in the available space. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - */ - virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - nscoord aTableFixedWidth)=0; - - /** assign widths for each column that has proportional width inside a table that - * has auto width (width set by the content and available space) according to the - * HTML 4 specification. - * Sets mColumnWidths as a side effect. - * - * @param aPresContext the presentation context - * @param aTableStyle the resolved style for the table - * @param aAvailWidth the remaining amount of horizontal space available - * @param aMaxWidth the total amount of horizontal space available - * @param aMinTableWidth the min possible table width - * @param aMaxTableWidth the max table width - * - * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error - * - * TODO: rename this method to reflect that it is a Nav4 compatibility method - */ - virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext, - PRInt32 aAvailWidth, - PRInt32 aMaxWidth, - PRInt32 aMinTableWidth, - PRInt32 aMaxTableWidth)=0; - - }; #endif diff --git a/mozilla/layout/tables/nsTableColFrame.h b/mozilla/layout/tables/nsTableColFrame.h new file mode 100644 index 00000000000..80e0c761a4a --- /dev/null +++ b/mozilla/layout/tables/nsTableColFrame.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ +#ifndef nsTableColFrame_h__ +#define nsTableColFrame_h__ + +#include "nscore.h" +#include "nsContainerFrame.h" + + +class nsTableColFrame : public nsFrame { +public: + static nsresult NewFrame(nsIFrame** aInstancePtrResult, + nsIContent* aContent, + nsIFrame* aParent); + + NS_IMETHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsReflowMetrics& aDesiredSize, + const nsReflowState& aReflowState, + nsReflowStatus& aStatus); + +protected: + + nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + ~nsTableColFrame(); + +}; + +#endif + diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index 4a1b85720c5..1b36a298cec 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -135,48 +135,52 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre result = table->GetAttribute(nsHTMLAtoms::cols, value); // if COLS is set, then map it into the COL frames - // chicken and egg problem here. I don't have any children yet, so I - // don't know how many columns there are, so I can't do this! - // I need to just set some state, and let the individual columns query up into me - // in their own hooks - PRInt32 numCols; - if (result == eContentAttr_NoValue) - ChildCount(numCols); - else if (result == eContentAttr_HasValue) + if (eContentAttr_NotThere != result) { - nsHTMLUnit unit = value.GetUnit(); - if (eHTMLUnit_Empty==unit) + PRInt32 numCols=0; + if (eContentAttr_NoValue == result) ChildCount(numCols); - else - numCols = value.GetIntValue(); - } + else if (eContentAttr_HasValue == result) + { + nsHTMLUnit unit = value.GetUnit(); + if (eHTMLUnit_Empty==unit) + ChildCount(numCols); + else + numCols = value.GetIntValue(); + } - PRInt32 colIndex=0; - nsIFrame *colFrame; - FirstChild(colFrame); - for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); - nsStyleCoord width (1, eStyleUnit_Proportional); - colPosition->mWidth = width; - colFrame->GetNextSibling(colFrame); - } - // if there are more columns, there width is set to "minimum" - PRInt32 numChildFrames; - ChildCount(numChildFrames); - for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); - nsStyleCoord width (0, eStyleUnit_Integer); - colPosition->mWidth = width; - colFrame->GetNextSibling(colFrame); - } + PRInt32 colIndex=0; + nsIFrame *colFrame=nsnull; + nsIStyleContext *colStyleContext; + for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + nsStyleCoord width (1, eStyleUnit_Proportional); + colPosition->mWidth = width; + colFrame->GetStyleContext(aPresContext, colStyleContext); + colStyleContext->RecalcAutomaticData(aPresContext); + } + // if there are more columns, there width is set to "minimum" + PRInt32 numChildFrames; + ChildCount(numChildFrames); + for (; colIndexGetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + nsStyleCoord width (0, eStyleUnit_Integer); + colPosition->mWidth = width; + colFrame->GetStyleContext(aPresContext, colStyleContext); + colStyleContext->RecalcAutomaticData(aPresContext); + } - mStyleContext->RecalcAutomaticData(aPresContext); + mStyleContext->RecalcAutomaticData(aPresContext); + } return NS_OK; } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 301cf4dd80a..d3d73600a71 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -630,40 +630,6 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext, mLastContentIsComplete = PR_TRUE; const PRInt32 contentType = ((nsTableContent *)(nsIContent*)kid)->GetType(); - /* - if (contentType==nsITableContent::kTableColGroupType) - { - // Resolve style - nsIStyleContextPtr kidStyleContext = - aPresContext->ResolveStyleContextFor(kid, this); - NS_ASSERTION(kidStyleContext.IsNotNull(), "null style context for kid"); - - // SEC: TODO: when content is appended or deleted, be sure to clear out the frame hierarchy!!!! - - // get next frame, creating one if needed - nsIFrame* kidFrame=nsnull; - if (nsnull!=prevKidFrame) - prevKidFrame->GetNextSibling(kidFrame); // no need to check for an error, just see if it returned null... - else - ChildAt(0, kidFrame); - - // if this is the first time, allocate the frame - if (nsnull==kidFrame) - { - nsIContentDelegate* kidDel; - kidDel = kid->GetDelegate(aPresContext); - nsresult rv = kidDel->CreateFrame(aPresContext, kid, - this, kidStyleContext, kidFrame); - NS_RELEASE(kidDel); - } - - // reflow the column group - nsReflowState kidReflowState(eReflowReason_Resize, availSize); - result = ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState); - kidFrame->SetRect(0,0,0,0); - } - else */ - //if (contentType==nsITableContent::kTableRowGroupType) if (contentType!=nsITableContent::kTableCaptionType) { // Resolve style @@ -1983,6 +1949,7 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC nsTablePart * tablePart = (nsTablePart *)mContent; PRInt32 cols = tablePart->GetMaxColumns(); PRInt32 tableKidCount = tablePart->ChildCount(); + nsIFrame * colGroupFrame = mFirstChild; for (PRInt32 i=0; iChildAt(i); @@ -1996,6 +1963,9 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC nsTableColPtr col = (nsTableCol *)tableKid->ChildAt(j); NS_ASSERTION(col.IsNotNull(), "bad content"); nsColLayoutData *colData = new nsColLayoutData(col); + nsTableColFrame *colFrame=nsnull; + colGroupFrame->ChildAt(j, (nsIFrame *&)colFrame); + colData->SetColFrame(colFrame); mColumnLayoutData->AppendElement((void *)colData); } } @@ -2004,6 +1974,7 @@ PRBool nsTableFrame::SetCellLayoutData(nsCellLayoutData * aData, nsTableCell *aC { break; } + ChildAt(i, colGroupFrame); // can't use colGroupFrame->GetNextSibling because it hasn't been set yet } } diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index c29f38d78c4..12aca89da5c 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -129,15 +129,14 @@ public: * DEBUG METHOD * */ - void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void ListColumnLayoutData(FILE* out = stdout, PRInt32 aIndent = 0) const; /** return the width of the column at aColIndex */ - PRInt32 GetColumnWidth(PRInt32 aColIndex); + virtual PRInt32 GetColumnWidth(PRInt32 aColIndex); /** set the width of the column at aColIndex to aWidth */ - void SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth); - + virtual void SetColumnWidth(PRInt32 aColIndex, PRInt32 aWidth); /** * Calculate Layout Information