major hackage to the table data structures. slimmer, simpler, faster
this work exposed a few bugs and slow spots, which have been fixed for the aol page, I added some additional backwards compatibility code to proportionately distribute width when a fixed-width cell has colspans
This commit is contained in:
@@ -19,16 +19,13 @@
|
||||
#include "BasicTableLayoutStrategy.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsColLayoutData.h"
|
||||
#include "nsCellLayoutData.h"
|
||||
#include "nsTableCol.h"
|
||||
#include "nsTableCellFrame.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIPtr.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
|
||||
NS_DEF_PTR(nsTableCol);
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
|
||||
|
||||
@@ -64,6 +61,23 @@ struct ProportionalColumnLayoutStruct
|
||||
};
|
||||
|
||||
|
||||
/* ---------- ColSpanStruct ---------- */
|
||||
struct ColSpanStruct
|
||||
{
|
||||
PRInt32 colIndex;
|
||||
PRInt32 colSpan;
|
||||
nscoord width;
|
||||
|
||||
ColSpanStruct(PRInt32 aSpan, PRInt32 aIndex, nscoord aWidth)
|
||||
{
|
||||
colSpan = aSpan;
|
||||
colIndex = aIndex;
|
||||
width = aWidth;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* ---------- BasicTableLayoutStrategy ---------- */
|
||||
|
||||
@@ -228,7 +242,9 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
|
||||
if (gsDebug==PR_TRUE) printf (" AssignFixedColumnWidths\n");
|
||||
nsVoidArray *spanList=nsnull;
|
||||
|
||||
nsVoidArray *colSpanList=nsnull;
|
||||
nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
|
||||
|
||||
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
|
||||
|
||||
@@ -240,26 +256,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
maxColWidthArray = new PRInt32[mNumCols];
|
||||
}
|
||||
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
|
||||
// for every column, determine it's min and max width, and keep track of the table width
|
||||
for (PRInt32 colIndex = 0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
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");
|
||||
|
||||
// need to track min/max column width for setting min/max table widths
|
||||
// QQQ: Eventually, this will be cached in col frame
|
||||
// We'll just ask the column frame to compute this, and it'll use cached info if available
|
||||
PRInt32 minColWidth = 0;
|
||||
PRInt32 maxColWidth = 0;
|
||||
nsVoidArray *cells = colData->GetCells();
|
||||
PRInt32 numCells = cells->Count();
|
||||
if (gsDebug==PR_TRUE) printf (" for column %d numCells = %d\n", colIndex, numCells);
|
||||
|
||||
// Get column information
|
||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
||||
|
||||
// Get the columns's style
|
||||
nsIStyleContextPtr colSC;
|
||||
colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
|
||||
const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
|
||||
|
||||
// Get column width if it has one
|
||||
PRBool haveColWidth = PR_FALSE;
|
||||
@@ -268,7 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
case eStyleUnit_Coord:
|
||||
haveColWidth = PR_TRUE;
|
||||
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
|
||||
mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth); //QQQ add in margins?
|
||||
mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -303,38 +317,49 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
}
|
||||
}
|
||||
|
||||
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
|
||||
PRInt32 firstRowIndex = -1;
|
||||
for (PRInt32 rowIndex = 0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
|
||||
if (nsnull == data) {
|
||||
// For cells that span rows there's only cell layout data for the first row
|
||||
nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull==cellFrame)
|
||||
{ // there is no cell in this row that corresponds to this column
|
||||
continue;
|
||||
}
|
||||
if (-1==firstRowIndex)
|
||||
firstRowIndex = rowIndex;
|
||||
if (rowIndex!=cellFrame->GetRowIndex()) {
|
||||
// For cells that span rows, we only figure it in once
|
||||
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
|
||||
continue;
|
||||
}
|
||||
if (colIndex!=cellFrame->GetColIndex()) {
|
||||
// For cells that span rows, we only figure it in once
|
||||
NS_ASSERTION(1 != cellFrame->GetColSpan(), "col index does not match row span"); // sanity check
|
||||
continue;
|
||||
}
|
||||
|
||||
nsMargin margin;
|
||||
nsresult result = data->GetMargin(margin);
|
||||
|
||||
nsSize * cellMinSize = data->GetMaxElementSize();
|
||||
nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
|
||||
NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
|
||||
PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
|
||||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
|
||||
PRInt32 colSpan = cellFrame->GetColSpan();
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d, margins %d %d\n",
|
||||
cellIndex, colSpan, cellMinSize->width, cellMinSize->height,
|
||||
cellDesiredSize->width, cellDesiredSize->height,
|
||||
margin.left, margin.right);
|
||||
printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n",
|
||||
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
|
||||
cellDesiredSize.width, cellDesiredSize.height);
|
||||
|
||||
switch (colPosition->mWidth.GetUnit()) {
|
||||
switch (colPosition->mWidth.GetUnit())
|
||||
{
|
||||
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 = PR_MAX(cellMinSize->width, colPosition->mWidth.GetCoordValue());
|
||||
if (mTableFrame->GetColumnWidth(colIndex) < widthForThisCell)
|
||||
nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue());
|
||||
widthForThisCell = widthForThisCell/colSpan;
|
||||
nscoord widthFromCol = mTableFrame->GetColumnWidth(colIndex);
|
||||
if (widthFromCol < widthForThisCell)
|
||||
{
|
||||
if (gsDebug) printf (" setting fixed width to %d\n",widthForThisCell);
|
||||
mTableFrame->SetColumnWidth(colIndex, widthForThisCell); //QQQ add in margins?
|
||||
mTableFrame->SetColumnWidth(colIndex, widthForThisCell);
|
||||
maxColWidth = widthForThisCell;
|
||||
}
|
||||
}
|
||||
@@ -347,24 +372,24 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
|
||||
// regardless of the width specification, keep track of the
|
||||
// min/max column widths
|
||||
nscoord cellMinWidth = cellMinSize->width/colSpan;
|
||||
nscoord cellDesiredWidth = cellDesiredSize->width/colSpan;
|
||||
|
||||
if (aMaxWidth!=cellDesiredSize->width)
|
||||
{
|
||||
if (NS_UNCONSTRAINEDSIZE!=cellMinWidth)
|
||||
cellMinWidth += margin.left + margin.right;
|
||||
if (NS_UNCONSTRAINEDSIZE!=cellDesiredWidth)
|
||||
cellDesiredWidth += margin.left + margin.right;
|
||||
}
|
||||
|
||||
nscoord cellMinWidth = cellMinSize.width/colSpan;
|
||||
nscoord cellDesiredWidth = cellDesiredSize.width/colSpan;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
if (maxColWidth < cellDesiredWidth)
|
||||
maxColWidth = cellDesiredWidth;
|
||||
// effectiveColumnWidth is the width as if no cells with colspans existed
|
||||
if ((1==colSpan) && (effectiveColumnWidths[colIndex] < maxColWidth))
|
||||
effectiveColumnWidths[colIndex] = cellDesiredWidth;
|
||||
if (1<colSpan)
|
||||
{
|
||||
// add the cell to our list of spanners
|
||||
// add the column to our list of post-process columns
|
||||
ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, cellDesiredSize.width);
|
||||
if (nsnull==colSpanList)
|
||||
colSpanList = new nsVoidArray();
|
||||
colSpanList->AppendElement(colSpanInfo);
|
||||
|
||||
// add the cell to our list of spanning cells
|
||||
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
|
||||
if (nsnull==spanList)
|
||||
spanList = new nsVoidArray();
|
||||
@@ -372,26 +397,30 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
}
|
||||
if (gsDebug) {
|
||||
printf (" after cell %d, minColWidth = %d and maxColWidth = %d\n",
|
||||
cellIndex, minColWidth, maxColWidth);
|
||||
rowIndex, minColWidth, maxColWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// do all the global bookkeeping, factoring in margins
|
||||
nsTableCellFrame * firstCellInColumn = mTableFrame->GetCellAt(firstRowIndex, colIndex);
|
||||
nsMargin colMargin;
|
||||
firstCellInColumn->GetMargin(colMargin);
|
||||
nscoord colInset = colMargin.left + colMargin.right;
|
||||
// keep a running total of the amount of space taken up by all fixed-width columns
|
||||
if (PR_TRUE==haveColWidth)
|
||||
aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex);
|
||||
aTotalFixedWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
|
||||
|
||||
if (gsDebug) {
|
||||
printf (" after col %d, aTotalFixedWidth = %d\n",
|
||||
colIndex, aTotalFixedWidth);
|
||||
}
|
||||
|
||||
// add col[i] metrics to the running totals for the table min/max width
|
||||
if (NS_UNCONSTRAINEDSIZE!=aMinTableWidth)
|
||||
aMinTableWidth += minColWidth; // SEC: insets!
|
||||
aMinTableWidth += minColWidth + colInset;
|
||||
if (aMinTableWidth<=0)
|
||||
aMinTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
|
||||
if (NS_UNCONSTRAINEDSIZE!=aMaxTableWidth)
|
||||
aMaxTableWidth += maxColWidth; // SEC: insets!
|
||||
aMaxTableWidth += maxColWidth + colInset;
|
||||
if (aMaxTableWidth<=0)
|
||||
aMaxTableWidth = NS_UNCONSTRAINEDSIZE; // handle overflow
|
||||
if (PR_TRUE==hasColsAttribute)
|
||||
@@ -441,15 +470,59 @@ PRBool BasicTableLayoutStrategy::AssignFixedColumnWidths(nsIPresContext* aPresCo
|
||||
delete [] minColWidthArray;
|
||||
delete [] maxColWidthArray;
|
||||
}
|
||||
if (nsnull!=colSpanList)
|
||||
DistributeFixedSpace(colSpanList, effectiveColumnWidths);
|
||||
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
|
||||
if (nsnull!=effectiveColumnWidths)
|
||||
delete [] effectiveColumnWidths;
|
||||
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, aMinTableWidth, aMaxTableWidth);
|
||||
|
||||
if (nsnull!=spanList)
|
||||
delete spanList;
|
||||
if (nsnull!=colSpanList)
|
||||
delete colSpanList;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// take the fixed space spanned by the columns in aColSpanList
|
||||
// and distribute it proportionately (based on desired width)
|
||||
void BasicTableLayoutStrategy::DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths)
|
||||
{
|
||||
nscoord excess = 0;
|
||||
if (PR_TRUE==gsDebug) printf ("DistributeFixedSpace:\n");
|
||||
// for all fixed-width columns, determine the amount of the specified width each column spanned recieves
|
||||
PRInt32 numSpanningCells = aColSpanList->Count();
|
||||
for (PRInt32 nextSpanningCell=0; nextSpanningCell<numSpanningCells; nextSpanningCell++)
|
||||
{ // proportionately distributed extra space, based on the column's fixed width
|
||||
ColSpanStruct * colInfo = (ColSpanStruct *)aColSpanList->ElementAt(nextSpanningCell);
|
||||
PRInt32 colIndex = colInfo->colIndex;
|
||||
PRInt32 colSpan = colInfo->colSpan;
|
||||
nscoord totalColWidth = colInfo->width;
|
||||
|
||||
// 1. get the sum of the effective widths of the columns in the span
|
||||
nscoord totalEffectiveWidth=0;
|
||||
PRInt32 i;
|
||||
for (i = 0; i<colSpan; i++)
|
||||
{
|
||||
totalEffectiveWidth += aColWidths[colIndex+i];
|
||||
}
|
||||
|
||||
// 2. next, compute the proportion to be added to each column, and add it
|
||||
for (i = 0; i<colSpan; i++)
|
||||
{
|
||||
float percent;
|
||||
percent = ((float)(aColWidths[colIndex+i]))/((float)totalEffectiveWidth);
|
||||
nscoord colWidth = (nscoord)(totalColWidth*percent);
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" assigning fixed col width for spanning cells: column %d set to %d\n",
|
||||
colIndex+i, colWidth);
|
||||
mTableFrame->SetColumnWidth(colIndex+i, colWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool BasicTableLayoutStrategy::BalanceProportionalColumns(nsIPresContext* aPresContext,
|
||||
const nsReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
@@ -529,35 +602,37 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
|
||||
minColWidthArray = new PRInt32[mNumCols];
|
||||
}
|
||||
|
||||
nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
|
||||
PRInt32 numCols = columnLayoutData->Count();
|
||||
for (PRInt32 colIndex = 0; colIndex<numCols; colIndex++)
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
for (PRInt32 colIndex = 0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex));
|
||||
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 column frame to ask this question
|
||||
const nsStylePosition* colPosition = nsnull;
|
||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
||||
|
||||
// Get the columns's style
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
|
||||
if (PR_FALSE==IsFixedWidth(colPosition))
|
||||
{
|
||||
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
|
||||
{ // this col has proportional width, so determine its width requirements
|
||||
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
|
||||
if (nsnull==data)
|
||||
{ // For cells that span rows there's only cell layout data for the first row
|
||||
for (PRInt32 rowIndex = 0; rowIndex<numRows; rowIndex++)
|
||||
{ // this col has non-fixed width, so determine its width requirements
|
||||
nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull==cellFrame)
|
||||
{ // there is no cell in this row that corresponds to this column
|
||||
continue;
|
||||
}
|
||||
nsMargin margin;
|
||||
data->GetMargin(margin);
|
||||
nsSize * cellMinSize = data->GetMaxElementSize();
|
||||
NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
|
||||
nscoord cellMinWidth = cellMinSize->width; // do we need to take into account colSpan here?
|
||||
cellMinWidth += margin.left + margin.right;
|
||||
if (rowIndex!=cellFrame->GetRowIndex()) {
|
||||
// For cells that span rows, we only figure it in once
|
||||
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
|
||||
continue;
|
||||
}
|
||||
|
||||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
PRInt32 colSpan = cellFrame->GetColSpan();
|
||||
nscoord cellMinWidth = cellMinSize.width/colSpan;
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
}
|
||||
@@ -624,32 +699,42 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
nscoord tableWidth=0; // the width of the table as a result of setting column widths
|
||||
nscoord widthOfFixedTableColumns=0; // the sum of the width of all fixed-width columns
|
||||
// tableWidth - widthOfFixedTableColumns is the width of columns computed in this method
|
||||
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();
|
||||
nscoord * effectiveColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
|
||||
for (PRInt32 colIndex = 0; colIndex<numCols; colIndex++)
|
||||
nscoord * effectiveColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveColumnWidths, 0, mNumCols*sizeof(PRInt32));
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
|
||||
for (PRInt32 colIndex = 0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
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));
|
||||
nsVoidArray *cells = colData->GetCells();
|
||||
PRInt32 numCells = cells->Count();
|
||||
|
||||
// Get the columns's style
|
||||
nsTableColFrame *colFrame = colData->GetColFrame();
|
||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
||||
nsIStyleContextPtr colSC;
|
||||
colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
|
||||
const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
|
||||
if (gsDebug) printf("col %d has frame %p with style %p and pos %p\n",
|
||||
colIndex, colFrame, (nsIStyleContext *)colSC, colPosition);
|
||||
PRInt32 rowIndex;
|
||||
PRInt32 firstRowIndex = -1;
|
||||
nsTableCellFrame * firstCellInColumn;
|
||||
for (rowIndex=0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
firstCellInColumn = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull!=firstCellInColumn)
|
||||
break;
|
||||
}
|
||||
nsMargin colMargin;
|
||||
nscoord colInset = 0;
|
||||
if (nsnull!=firstCellInColumn)
|
||||
{
|
||||
firstCellInColumn->GetMargin(colMargin);
|
||||
colInset = colMargin.left + colMargin.right;
|
||||
}
|
||||
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
|
||||
if (PR_FALSE==IsFixedWidth(colPosition))
|
||||
{
|
||||
// first, deal with any cells that span into this column from a pervious column
|
||||
@@ -676,33 +761,33 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
}
|
||||
}
|
||||
|
||||
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
|
||||
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
|
||||
{ // this col has proportional width, so determine its width requirements
|
||||
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
|
||||
if (nsnull == data) {
|
||||
// For cells that span columns there's only cell layout data for the first column
|
||||
nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull==cellFrame)
|
||||
{ // there is no cell in this row that corresponds to this column
|
||||
continue;
|
||||
}
|
||||
if (-1==firstRowIndex)
|
||||
firstRowIndex = rowIndex;
|
||||
if (rowIndex!=cellFrame->GetRowIndex()) {
|
||||
// For cells that span rows, we only figure it in once
|
||||
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
|
||||
continue;
|
||||
}
|
||||
|
||||
PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
|
||||
PRInt32 colSpan = cellFrame->GetColSpan();
|
||||
// distribute a portion of the spanning cell's min and max width to this column
|
||||
nsSize * cellMinSize = data->GetMaxElementSize();
|
||||
NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
|
||||
nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
|
||||
NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
|
||||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
|
||||
|
||||
nsMargin margin;
|
||||
nsresult result = data->GetMargin(margin);
|
||||
nscoord marginWidth = margin.left + margin.right;
|
||||
PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
|
||||
PRInt32 cellMinWidth = cellMinSize.width/colSpan;
|
||||
// first get the desired size info from reflow pass 1
|
||||
PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
|
||||
PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
|
||||
// then get the desired size info factoring in the cell style attributes
|
||||
nscoord specifiedCellWidth=-1;
|
||||
nsIStyleContextPtr cellSC;
|
||||
data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
|
||||
const nsStylePosition* cellPosition = (const nsStylePosition*)
|
||||
cellSC->GetStyleData(eStyleStruct_Position);
|
||||
const nsStylePosition* cellPosition;
|
||||
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
|
||||
switch (cellPosition->mWidth.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
|
||||
@@ -730,17 +815,17 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
}
|
||||
if (-1!=specifiedCellWidth)
|
||||
{
|
||||
if (specifiedCellWidth>cellMinWidth)
|
||||
if (specifiedCellWidth/colSpan>cellMinWidth)
|
||||
{
|
||||
if (gsDebug) printf("setting cellDesiredWidth from %d to %d\n",
|
||||
cellDesiredWidth, specifiedCellWidth);
|
||||
cellDesiredWidth = specifiedCellWidth; // TODO: some math needed here for colspans
|
||||
cellDesiredWidth, specifiedCellWidth/colSpan);
|
||||
cellDesiredWidth = specifiedCellWidth/colSpan; // TODO: some math needed here for colspans
|
||||
}
|
||||
}
|
||||
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
|
||||
cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
|
||||
rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
if (maxColWidth < cellDesiredWidth)
|
||||
@@ -750,10 +835,10 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
effectiveColumnWidths[colIndex] = cellDesiredWidth;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
|
||||
cellIndex, minColWidth, maxColWidth,
|
||||
rowIndex, minColWidth, maxColWidth,
|
||||
colIndex, effectiveColumnWidths[colIndex]);
|
||||
if (1<colSpan)
|
||||
{ // add the cell to our list of spanners
|
||||
if ((1<colSpan) && (cellFrame->GetColIndex()==colIndex))
|
||||
{ // add this cell to span list iff we are currently processing the column the cell starts in
|
||||
SpanInfo *spanInfo = new SpanInfo(colSpan-1, cellMinWidth, cellDesiredWidth);
|
||||
if (nsnull==spanList)
|
||||
spanList = new nsVoidArray();
|
||||
@@ -863,7 +948,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
}
|
||||
if (-1==percentage)
|
||||
{
|
||||
percentage = 100/numCols;
|
||||
percentage = 100/mNumCols;
|
||||
// base the % on the remaining available width
|
||||
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
|
||||
if (gsDebug==PR_TRUE)
|
||||
@@ -879,7 +964,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
}
|
||||
}
|
||||
}
|
||||
tableWidth += mTableFrame->GetColumnWidth(colIndex);
|
||||
else
|
||||
{ // need to maintain this so we know how much we have left over at the end
|
||||
widthOfFixedTableColumns += mTableFrame->GetColumnWidth(colIndex) + colInset;
|
||||
}
|
||||
tableWidth += mTableFrame->GetColumnWidth(colIndex) + colInset;
|
||||
}
|
||||
|
||||
/* --- post-process if necessary --- */
|
||||
@@ -938,9 +1027,9 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
// 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 ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > tableWidth))
|
||||
if ((PR_FALSE==aTableIsAutoWidth) && (aAvailWidth > (tableWidth-widthOfFixedTableColumns)))
|
||||
{
|
||||
DistributeExcessSpace(aAvailWidth, tableWidth, effectiveColumnWidths);
|
||||
DistributeExcessSpace(aAvailWidth, tableWidth, widthOfFixedTableColumns, effectiveColumnWidths);
|
||||
}
|
||||
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
|
||||
if (nsnull!=effectiveColumnWidths)
|
||||
@@ -952,24 +1041,27 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
|
||||
|
||||
// take the extra space in the table and distribute it proportionately (based on desired width)
|
||||
// give extra space to auto-width cells first, or if there are none to all cells
|
||||
void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
|
||||
nscoord aComputedTableWidth,
|
||||
void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
|
||||
nscoord aTableWidth,
|
||||
nscoord aWidthOfFixedTableColumns,
|
||||
nscoord *aColWidths)
|
||||
{
|
||||
nscoord excess = 0;
|
||||
if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d\n",
|
||||
aTableFixedWidth, aComputedTableWidth);
|
||||
if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d, woftc=%d\n",
|
||||
aAvailWidth, aTableWidth, aWidthOfFixedTableColumns);
|
||||
// if there are auto-sized columns, give them the extra space
|
||||
// the trick here is to do the math excluding non-auto width columns
|
||||
PRInt32 numAutoColumns=0;
|
||||
PRInt32 *autoColumns=nsnull;
|
||||
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
|
||||
if (0!=numAutoColumns)
|
||||
{
|
||||
nscoord computedTableWidth = aTableWidth - aWidthOfFixedTableColumns;
|
||||
// there's at least one auto-width column, so give it (them) the extra space
|
||||
// proportionately distributed extra space, based on the column's desired size
|
||||
nscoord totalEffectiveWidthOfAutoColumns = 0;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
|
||||
printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n", aAvailWidth, excess);
|
||||
// 1. first, get the total width of the auto columns
|
||||
PRInt32 i;
|
||||
for (i = 0; i<numAutoColumns; i++)
|
||||
@@ -979,12 +1071,12 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
|
||||
else
|
||||
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
|
||||
}
|
||||
excess = aTableFixedWidth - aComputedTableWidth;
|
||||
excess = aAvailWidth - computedTableWidth;
|
||||
// 2. next, compute the proportion to be added to each column, and add it
|
||||
for (i = 0; i<numAutoColumns; i++)
|
||||
{
|
||||
PRInt32 colIndex = autoColumns[i];
|
||||
nscoord oldColWidth = aColWidths[colIndex];
|
||||
nscoord oldColWidth = mTableFrame->GetColumnWidth(colIndex);//aColWidths[colIndex];
|
||||
float percent;
|
||||
if (0!=totalEffectiveWidthOfAutoColumns)
|
||||
percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
|
||||
@@ -1002,25 +1094,25 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
|
||||
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
|
||||
else
|
||||
{
|
||||
excess = aTableFixedWidth - aComputedTableWidth;
|
||||
nscoord excessPerColumn = excess/mNumCols;
|
||||
excess = aAvailWidth - (aTableWidth-aWidthOfFixedTableColumns);
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
|
||||
printf(" aAvailWidth specified as %d, expanding columns by excess = %d\n",
|
||||
aAvailWidth, excess);
|
||||
for (PRInt32 colIndex = 0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
nscoord oldColWidth = aColWidths[colIndex];
|
||||
nscoord oldColWidth=0;// = aColWidths[colIndex];
|
||||
if (0==oldColWidth)
|
||||
oldColWidth = mTableFrame->GetColumnWidth(colIndex);
|
||||
float percent;
|
||||
if (0!=aComputedTableWidth)
|
||||
percent = (float)oldColWidth/(float)aComputedTableWidth;
|
||||
if (0!=aTableWidth)
|
||||
percent = (float)oldColWidth/(float)aTableWidth;
|
||||
else
|
||||
percent = (float)1/(float)mNumCols;
|
||||
nscoord excessForThisColumn = (nscoord)(excess*percent);
|
||||
nscoord colWidth = excessForThisColumn+oldColWidth;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" distribute excess to all columns: column %d was %d, now set to %d\n",
|
||||
colIndex, aColWidths[colIndex], colWidth);
|
||||
printf(" distribute excess to all columns: column %d was %d, now set to %d from % = %f\n",
|
||||
colIndex, oldColWidth, colWidth, percent);
|
||||
mTableFrame->SetColumnWidth(colIndex, colWidth);
|
||||
}
|
||||
}
|
||||
@@ -1051,29 +1143,40 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
// proportional-width columns are equal (if any are anything other than 1)
|
||||
PRBool atLeastOneAutoWidthColumn = PR_FALSE; // true if at least one column is auto-width, requiring us to post-process
|
||||
nsVoidArray *spanList=nsnull; // a list of the cells that span columns
|
||||
nsVoidArray *columnLayoutData = mTableFrame->GetColumnLayoutData();
|
||||
PRInt32 numCols = columnLayoutData->Count();
|
||||
nscoord * effectiveMaxColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveMaxColumnWidths, 0, numCols*sizeof(PRInt32));
|
||||
nscoord * effectiveMinColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveMinColumnWidths, 0, numCols*sizeof(PRInt32));
|
||||
for (PRInt32 colIndex = 0; colIndex<numCols; colIndex++)
|
||||
nscoord * effectiveMaxColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveMaxColumnWidths, 0, mNumCols*sizeof(PRInt32));
|
||||
nscoord * effectiveMinColumnWidths = new nscoord[mNumCols]; // used for Nav4 compatible table fluffing
|
||||
nsCRT::memset (effectiveMinColumnWidths, 0, mNumCols*sizeof(PRInt32));
|
||||
PRInt32 numRows = mTableFrame->GetRowCount();
|
||||
|
||||
for (PRInt32 colIndex = 0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
if (gsDebug==PR_TRUE) printf (" for col %d\n", colIndex);
|
||||
nscoord minColWidth = 0;
|
||||
nscoord maxColWidth = 0;
|
||||
|
||||
// Get column information
|
||||
nsColLayoutData * colData = (nsColLayoutData *)(columnLayoutData->ElementAt(colIndex));
|
||||
nsVoidArray *cells = colData->GetCells();
|
||||
PRInt32 numCells = cells->Count();
|
||||
|
||||
// Get the columns's style
|
||||
nsTableColFrame *colFrame = colData->GetColFrame();
|
||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
||||
nsIStyleContextPtr colSC;
|
||||
colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
|
||||
const nsStylePosition* colPosition = (const nsStylePosition*) colSC->GetStyleData(eStyleStruct_Position);
|
||||
// Get the columns's style and margins
|
||||
PRInt32 rowIndex;
|
||||
PRInt32 firstRowIndex = -1;
|
||||
nsTableCellFrame * firstCellInColumn;
|
||||
for (rowIndex=0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
firstCellInColumn = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull!=firstCellInColumn)
|
||||
break;
|
||||
}
|
||||
nsMargin colMargin;
|
||||
nscoord colInset = 0;
|
||||
if (nsnull!=firstCellInColumn)
|
||||
{
|
||||
firstCellInColumn->GetMargin(colMargin);
|
||||
colInset = colMargin.left + colMargin.right;
|
||||
}
|
||||
const nsStylePosition* colPosition;
|
||||
colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition);
|
||||
|
||||
if (PR_FALSE==IsFixedWidth(colPosition))
|
||||
{
|
||||
@@ -1100,33 +1203,30 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
|
||||
{ // this col has proportional width, so determine its width requirements
|
||||
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
|
||||
if (nsnull == data) {
|
||||
// For cells that span rows there's only cell layout data for the first row
|
||||
for (rowIndex = 0; rowIndex<numRows; rowIndex++)
|
||||
{
|
||||
nsTableCellFrame * cellFrame = mTableFrame->GetCellAt(rowIndex, colIndex);
|
||||
if (nsnull==cellFrame)
|
||||
{ // there is no cell in this row that corresponds to this column
|
||||
continue;
|
||||
}
|
||||
if (rowIndex!=cellFrame->GetRowIndex()) {
|
||||
// For cells that span rows, we only figure it in once
|
||||
NS_ASSERTION(1 != cellFrame->GetRowSpan(), "row index does not match row span"); // sanity check
|
||||
continue;
|
||||
}
|
||||
|
||||
PRInt32 colSpan = data->GetCellFrame()->GetColSpan();
|
||||
nsSize * cellMinSize = data->GetMaxElementSize();
|
||||
NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
|
||||
nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();
|
||||
NS_ASSERTION(nsnull != cellDesiredSize, "bad cellDesiredSize");
|
||||
PRInt32 colSpan = cellFrame->GetColSpan();
|
||||
nsSize cellMinSize = cellFrame->GetPass1MaxElementSize();
|
||||
nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize();
|
||||
|
||||
nsMargin margin;
|
||||
nsresult result = data->GetMargin(margin);
|
||||
nscoord marginWidth = margin.left + margin.right;
|
||||
|
||||
PRInt32 cellMinWidth = cellMinSize->width/colSpan + marginWidth;
|
||||
PRInt32 cellMinWidth = cellMinSize.width/colSpan;
|
||||
// first get the desired size info from reflow pass 1
|
||||
PRInt32 cellDesiredWidth = cellDesiredSize->width/colSpan + marginWidth;
|
||||
PRInt32 cellDesiredWidth = cellDesiredSize.width/colSpan;
|
||||
// then get the desired size info factoring in the cell style attributes
|
||||
nscoord specifiedCellWidth=-1;
|
||||
nsIStyleContextPtr cellSC;
|
||||
data->GetCellFrame()->GetStyleContext(aPresContext, cellSC.AssignRef());
|
||||
const nsStylePosition* cellPosition = (const nsStylePosition*)
|
||||
cellSC->GetStyleData(eStyleStruct_Position);
|
||||
const nsStylePosition* cellPosition;
|
||||
cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition);
|
||||
switch (cellPosition->mWidth.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
specifiedCellWidth = cellPosition->mWidth.GetCoordValue();
|
||||
@@ -1164,7 +1264,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
|
||||
if (PR_TRUE==gsDebug)
|
||||
printf("factoring in cell %d with colSpan=%d\n factoring in min=%d and desired=%d\n",
|
||||
cellIndex, colSpan, cellMinWidth, cellDesiredWidth);
|
||||
rowIndex, colSpan, cellMinWidth, cellDesiredWidth);
|
||||
// remember the widest min cell width
|
||||
if (minColWidth < cellMinWidth)
|
||||
minColWidth = cellMinWidth;
|
||||
@@ -1179,7 +1279,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
|
||||
cellIndex, minColWidth, maxColWidth,
|
||||
rowIndex, minColWidth, maxColWidth,
|
||||
colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
|
||||
if (1<colSpan)
|
||||
{
|
||||
@@ -1236,7 +1336,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
printf (" 4 (0): col %d set to min width = %d because style set proportionalWidth=0\n",
|
||||
colIndex, mTableFrame->GetColumnWidth(colIndex));
|
||||
}
|
||||
else if (1==numCols)
|
||||
else if (1==mNumCols)
|
||||
{ // there is only one column, and we know that it's desired width doesn't fit
|
||||
// so the column 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);
|
||||
@@ -1300,7 +1400,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
|
||||
}
|
||||
if (-1==percentage)
|
||||
{
|
||||
percentage = 100/numCols;
|
||||
percentage = 100/mNumCols;
|
||||
// base the % on the remaining available width
|
||||
mTableFrame->SetColumnWidth(colIndex, (percentage*aAvailWidth)/100);
|
||||
if (gsDebug==PR_TRUE)
|
||||
@@ -1417,16 +1517,52 @@ void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidt
|
||||
else
|
||||
percent = ((float)1)/((float)numAutoColumns);
|
||||
nscoord colWidth = (nscoord)(availWidth*percent);
|
||||
if (colWidth<aMinColWidths[colIndex])
|
||||
{
|
||||
availWidth -= (aMinColWidths[colIndex]-colWidth);
|
||||
colWidth=aMinColWidths[colIndex];
|
||||
}
|
||||
if (gsDebug==PR_TRUE)
|
||||
printf(" distribute width to auto columns: column %d was %d, now set to %d\n",
|
||||
colIndex, aMaxColWidths[colIndex], colWidth);
|
||||
mTableFrame->SetColumnWidth(colIndex, colWidth);
|
||||
}
|
||||
EnsureCellMinWidths(aMinColWidths);
|
||||
}
|
||||
}
|
||||
|
||||
void BasicTableLayoutStrategy::EnsureCellMinWidths(nscoord *aMinColWidths)
|
||||
{
|
||||
PRBool atLeastOne = PR_TRUE;
|
||||
while (PR_TRUE==atLeastOne)
|
||||
{
|
||||
atLeastOne=PR_FALSE;
|
||||
PRInt32 colIndex;
|
||||
nscoord addedWidth = 0;
|
||||
// first, bump up cells that are below their min to their min width
|
||||
for (colIndex=0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
|
||||
if (colWidth<aMinColWidths[colIndex])
|
||||
{
|
||||
addedWidth += (aMinColWidths[colIndex]-colWidth);
|
||||
mTableFrame->SetColumnWidth(colIndex, aMinColWidths[colIndex]);
|
||||
atLeastOne=PR_TRUE;
|
||||
}
|
||||
}
|
||||
// second, remove the added space from cells that can afford to slim down
|
||||
//QQQ boy is this slow! there has to be a faster way that is still guaranteed to be accurate...
|
||||
while ((addedWidth>0))
|
||||
{ // while we still have some extra space, and last time we were able to take some off...
|
||||
for (colIndex=0; colIndex<mNumCols; colIndex++)
|
||||
{
|
||||
nscoord colWidth = mTableFrame->GetColumnWidth(colIndex);
|
||||
if (colWidth>aMinColWidths[colIndex])
|
||||
{
|
||||
mTableFrame->SetColumnWidth(colIndex, colWidth-1);
|
||||
addedWidth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0<addedWidth)
|
||||
{ // all our cells are at their min width, so no use doing anything else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user