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