diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index c585bbc8baf..d76383ed13b 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -135,10 +135,10 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
- PRInt32 aMaxWidth,
- PRInt32 &aTotalFixedWidth,
- PRInt32 &aMinTableWidth,
- PRInt32 &aMaxTableWidth,
+ nscoord aMaxWidth,
+ nscoord &aTotalFixedWidth,
+ nscoord &aMinTableWidth,
+ nscoord &aMaxTableWidth,
nsSize* aMaxElementSize)
{
PRBool result = PR_TRUE;
@@ -615,14 +615,14 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
#endif
- PRBool result = PR_TRUE;
+ PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
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();
- PRInt32 * effectiveColumnWidths = new PRInt32[numCols]; // used for Nav4 compatible table fluffing
+ nscoord * effectiveColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
for (PRInt32 colIndex = 0; colIndexAppendElement (spanInfo);
+ spanList->AppendElement(spanInfo);
}
}
@@ -887,7 +887,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
nscoord widthPerSlice = widthRemaining/totalSlices;
PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count();
for (PRInt32 i=0; iElementAt(i));
nscoord computedColWidth = info->mProportion*widthPerSlice;
@@ -896,11 +896,12 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2: col %d given %d proportion of remaining space %d, set to width = %d\n",
info->mColIndex, info->mProportion, widthRemaining, computedColWidth);
tableWidth += computedColWidth;
+ effectiveColumnWidths[info->mColIndex] = computedColWidth;
delete info;
}
}
else
- {
+ { // we're in an unconstrained situation, so give each column the max of the max column widths
PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count();
PRInt32 maxOfMaxColWidths = 0;
PRInt32 i;
@@ -920,6 +921,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2 (unconstrained!): col %d set to width = %d\n",
info->mColIndex, maxOfMaxColWidths);
tableWidth += maxOfMaxColWidths;
+ effectiveColumnWidths[info->mColIndex] = maxOfMaxColWidths;
delete info;
}
}
@@ -929,9 +931,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 (aTableFixedWidth > tableWidth)
+ if (aAvailWidth > tableWidth)
{
- DistributeExcessSpace(aTableFixedWidth, tableWidth, numCols, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, effectiveColumnWidths);
}
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
if (nsnull!=effectiveColumnWidths)
@@ -941,14 +943,15 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
return result;
}
+// 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,
- PRInt32 aNumCols,
- PRInt32 *aColWidths)
+ nscoord *aColWidths)
{
- nscoord excess = aTableFixedWidth - aComputedTableWidth;
- if (gsDebug) printf ("fixed width %d > computed table width %d, excess = %d\n",
- aTableFixedWidth, aComputedTableWidth, excess);
+ nscoord excess = 0;
+ if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d\n",
+ aTableFixedWidth, aComputedTableWidth);
// if there are auto-sized columns, give them the extra space
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
@@ -969,14 +972,15 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
+ excess = aTableFixedWidth - totalEffectiveWidthOfAutoColumns;
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(autoColumns[i]);
+ nscoord oldColWidth = aColWidths[colIndex];
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
- percent = ((float)(aColWidths[autoColumns[i]]))/((float)totalEffectiveWidthOfAutoColumns);
+ percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
else
percent = ((float)1)/((float)numAutoColumns);
nscoord excessForThisColumn = (nscoord)(excess*percent);
@@ -991,10 +995,11 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- nscoord excessPerColumn = excess/aNumCols;
+ excess = aTableFixedWidth - aComputedTableWidth;
+ nscoord excessPerColumn = excess/mNumCols;
if (gsDebug==PR_TRUE)
printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
- for (PRInt32 colIndex = 0; colIndexGetColumnLayoutData();
PRInt32 numCols = columnLayoutData->Count();
- PRInt32 * effectiveColumnWidths = new PRInt32[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
+ 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; colIndexElementAt(colIndex));
nsVoidArray *cells = colData->GetCells();
@@ -1149,17 +1158,22 @@ 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);
+ // remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
+ // effectiveMinColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMinColumnWidths[colIndex] < minColWidth))
+ effectiveMinColumnWidths[colIndex] = cellMinWidth;
+ // remember the max desired cell width
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;
+ // effectiveMaxColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMaxColumnWidths[colIndex] < maxColWidth))
+ effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
- printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
+ printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
cellIndex, minColWidth, maxColWidth,
- colIndex, effectiveColumnWidths[colIndex]);
+ colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
if (1GetColumnWidth(colIndex), aAvailWidth);
}
else if (PR_TRUE==isAutoWidth)
- { // column's width is determined by its content
- PRUint32 W = aMaxWidth - aMinTableWidth;
- PRUint32 D = aMaxTableWidth - aMinTableWidth;
- if (0==D) // fixed-size table
- D=1;
- // XXX really need to use effectiveColumnWidths[colIndex] here
- PRUint32 d = maxColWidth - minColWidth; // XXX: if this is 0, set to minColWidth?
- PRInt32 width = (d*W)/D;
- mTableFrame->SetColumnWidth(colIndex, minColWidth + width);
- if (gsDebug==PR_TRUE)
- printf (" 4 auto-width: col %d W=%d D=%d d=%d, set to width = %d\n",
- colIndex, W, D, d, mTableFrame->GetColumnWidth(colIndex));
+ { // column's width is determined by its content, done in post-processing
+ mTableFrame->SetColumnWidth(colIndex, 0); // set to 0 width for now
+ atLeastOneAutoWidthColumn = PR_TRUE;
}
else if (-1!=specifiedProportionColumnWidth)
{ // we need to save these and do them after all other columns have been calculated
@@ -1309,7 +1317,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
/* --- post-process if necessary --- */
- // first, assign a width to proportional-width columns
+ if (PR_TRUE==atLeastOneAutoWidthColumn)
+ { // proportionately distribute the remaining space to autowidth columns
+ DistributeRemainingSpace(aMaxWidth, tableWidth, effectiveMinColumnWidths, effectiveMaxColumnWidths);
+ }
+ // second, assign a width to proportional-width columns
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
@@ -1339,14 +1351,76 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
delete proportionalColumnsList;
}
-
+
+ // clean up
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
+ if (nsnull!=effectiveMinColumnWidths)
+ delete [] effectiveMinColumnWidths;
+ if (nsnull!=effectiveMaxColumnWidths)
+ delete [] effectiveMaxColumnWidths;
if (nsnull!=spanList)
delete spanList;
return result;
}
+//XXX: make sure aTFW takes into account fixed width cells already assigned
+// take the remaining space in the table and distribute it proportionately
+// to the auto-width cells in the table (based on desired width)
+void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidth,
+ nscoord aComputedTableWidth,
+ nscoord *aMinColWidths,
+ nscoord *aMaxColWidths)
+{
+ if (PR_TRUE==gsDebug)
+ printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
+ aTableFixedWidth, aComputedTableWidth);
+ // if there are auto-sized columns, give them the extra space
+ PRInt32 numAutoColumns=0;
+ PRInt32 *autoColumns=nsnull;
+ // availWidth is the difference between the total available width and the
+ // amount of space already assigned, assuming auto col widths were assigned 0.
+ nscoord availWidth = aTableFixedWidth - aComputedTableWidth;
+ mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
+ if (0!=numAutoColumns)
+ {
+ // 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;
+ // 1. first, get the total width of the auto columns
+ PRInt32 i;
+ for (i = 0; iGetColumnWidth(autoColumns[i]);
+ }
+ if (gsDebug==PR_TRUE)
+ printf(" aTableFixedWidth specified as %d, availWidth is = %d\n",
+ aTableFixedWidth, availWidth);
+
+ // 2. next, compute the proportion to be added to each column, and add it
+ for (i = 0; iSetColumnWidth(colIndex, colWidth);
+ }
+ }
+}
+
diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
index bb272fab46e..05e843b88af 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h
@@ -169,14 +169,27 @@ public:
* @param aTableFixedWidth the specified width of the table. If there is none,
* this param is 0
* @param aComputedTableWidth the width of the table before this final step.
- * @param aNumCols the number of columns in the table
*
* @return void
*/
virtual void DistributeExcessSpace(nscoord aTableFixedWidth,
nscoord aComputedTableWidth,
- PRInt32 aNumCols,
- PRInt32 *aColWidths);
+ nscoord *aColWidths);
+
+ /** starting with a partially balanced table, compute the amount
+ * of space to remove from each column to completely balance the table.
+ * set the column widths in mTableFrame based on these computations.
+ *
+ * @param aTableFixedWidth the specified width of the table. If there is none,
+ * this param is 0
+ * @param aComputedTableWidth the width of the table before this final step.
+ *
+ * @return void
+ */
+ virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
+ nscoord aComputedTableWidth,
+ nscoord *aMinColWidths,
+ nscoord *aMaxColWidths);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
diff --git a/mozilla/layout/html/table/src/nsCellMap.h b/mozilla/layout/html/table/src/nsCellMap.h
index 6d5d4d3fce2..15f9e6c441a 100644
--- a/mozilla/layout/html/table/src/nsCellMap.h
+++ b/mozilla/layout/html/table/src/nsCellMap.h
@@ -38,7 +38,7 @@ class nsCellMap
{
protected:
/** storage for CellData pointers */
- PRInt32 *mCells;
+ PRInt32 *mCells; ///XXX CellData *?
/** the number of rows */
int mRowCount; // in java, we could just do fCellMap.length;
diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
index 72ffeafca3e..00676145a18 100644
--- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp
@@ -268,10 +268,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
CreatePsuedoFrame(aPresContext);
}
- // reduce available space by insets
-
+ // reduce available space by insets, if we're in a constrained situation
if (NS_UNCONSTRAINEDSIZE!=availSize.width)
- availSize.width -= leftInset+rightInset+margin.left+margin.right;
+ availSize.width -= leftInset+rightInset;
if (NS_UNCONSTRAINEDSIZE!=availSize.height)
availSize.height -= topInset+bottomInset+margin.top+margin.bottom;
@@ -305,9 +304,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
}
SetFirstContentOffset(mFirstChild);
- //if (gsDebug) printf("CELL: set first content offset to %d\n", GetFirstContentOffset()); //@@@
SetLastContentOffset(mFirstChild);
- //if (gsDebug) printf("CELL: set last content offset to %d\n", GetLastContentOffset()); //@@@
// Place the child
mFirstChild->SetRect(nsRect(leftInset, topInset,
@@ -332,13 +329,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
printf(" %p cellFrame height set to %d from kidSize=%d and insets %d,%d\n",
this, cellHeight, kidSize.height, topInset, bottomInset);
// next determine the cell's width
- nscoord cellWidth = kidSize.width; // at this point, we've factored in the cell's style attributes
- // if we're really in a constrained situation, factor in insets
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.width)
- {
- NS_ASSERTION(NS_UNCONSTRAINEDSIZE!=cellWidth, "child says it has unconstrained width in a constrained case");
- cellWidth += leftInset + rightInset;
- }
+ nscoord cellWidth = kidSize.width; // at this point, we've factored in the cell's style attributes
+ cellWidth += leftInset + rightInset; // factor in insets
// Nav4 hack for 0 width cells. If the cell has any content, it must have a desired width of at least 1
/*
@@ -370,10 +362,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (nsnull!=aDesiredSize.maxElementSize)
{
*aDesiredSize.maxElementSize = *pMaxElementSize;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.height)
- aDesiredSize.maxElementSize->height += topInset + bottomInset;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.width)
- aDesiredSize.maxElementSize->width += leftInset + rightInset;
+ aDesiredSize.maxElementSize->height += topInset + bottomInset;
+ aDesiredSize.maxElementSize->width += leftInset + rightInset;
}
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h
index 106f64415da..654920edc84 100644
--- a/mozilla/layout/html/table/src/nsTableFrame.h
+++ b/mozilla/layout/html/table/src/nsTableFrame.h
@@ -29,7 +29,6 @@ class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
class nsTableRowFrame;
-class CellData;
class nsITableLayoutStrategy;
class nsHTMLValue;
class ColumnInfoCache;
@@ -43,6 +42,31 @@ struct nsStyleSpacing;
extern const nsIID kTableFrameCID;
+/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
+ * if mCell is null then mRealCell will be the rowspan/colspan source
+ * in addition, if fOverlap is non-null then it will point to the
+ * other cell that overlaps this position
+ * @see nsCellMap
+ * @see nsTableFrame::BuildCellMap
+ * @see nsTableFrame::GrowCellMap
+ * @see nsTableFrame::BuildCellIntoMap
+ *
+ */
+class CellData
+{
+public:
+ nsTableCellFrame *mCell;
+ CellData *mRealCell;
+ CellData *mOverlap;
+
+ CellData();
+
+ ~CellData();
+};
+
+
+/* ============================================================================ */
+
/** nsTableFrame maps the inner portion of a table (everything except captions.)
* Used as a pseudo-frame within nsTableOuterFrame,
* it may also be used stand-alone as the top-level frame.
diff --git a/mozilla/layout/html/table/src/nsTablePart.h b/mozilla/layout/html/table/src/nsTablePart.h
index 3ba28a8ea9c..479c4def322 100644
--- a/mozilla/layout/html/table/src/nsTablePart.h
+++ b/mozilla/layout/html/table/src/nsTablePart.h
@@ -23,35 +23,11 @@
#include "nsHTMLContainer.h"
// forward declarations
-class nsTableCellFrame;
-class nsCellMap;
class nsTableRowGroup;
class nsTableColGroup;
class nsTableCol;
class nsTableCaption;
-/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
- * if mCell is null then mRealCell will be the rowspan/colspan source
- * in addition, if fOverlap is non-null then it will point to the
- * other cell that overlaps this position
- * @see nsCellMap
- * @see nsTableFrame::BuildCellMap
- * @see nsTableFrame::GrowCellMap
- * @see nsTableFrame::BuildCellIntoMap
- *
- */
-class CellData
-{
-public:
- nsTableCellFrame *mCell;
- CellData *mRealCell;
- CellData *mOverlap;
-
- CellData();
-
- ~CellData();
-};
-
/**
* Table Content Model.
* We build a full rationalized content model, so the structure of a table
@@ -118,7 +94,6 @@ public:
protected:
/** destructor
- * deletes mCellMap, if allocated.
*/
virtual ~nsTablePart();
diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
index cc6d9cf6997..80897b6f69b 100644
--- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp
+++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp
@@ -405,16 +405,12 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
{
kidAvailSize.height -= kidMargin.top + kidMargin.bottom;
}
- // Subtract off for left and right margin
- // XXX Why bother doing this if we always set the available width
- // based on the column width below?
- if (PR_FALSE == aState.unconstrainedWidth) {
- kidAvailSize.width -= kidMargin.left + kidMargin.right;
- }
+
+ // left and right margins already taken into account by table layout strategy
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
- nscoord x = kidMargin.left;
+ nscoord x = 0;
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
for (PRInt32 colIndex=0; colIndexGetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellStartingCol+numColSpan);
+ }
kidAvailSize.width = availWidth;
if (availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth())
{
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index c585bbc8baf..d76383ed13b 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -135,10 +135,10 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
PRBool BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
- PRInt32 aMaxWidth,
- PRInt32 &aTotalFixedWidth,
- PRInt32 &aMinTableWidth,
- PRInt32 &aMaxTableWidth,
+ nscoord aMaxWidth,
+ nscoord &aTotalFixedWidth,
+ nscoord &aMinTableWidth,
+ nscoord &aMaxTableWidth,
nsSize* aMaxElementSize)
{
PRBool result = PR_TRUE;
@@ -615,14 +615,14 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!");
#endif
- PRBool result = PR_TRUE;
+ PRBool result = PR_TRUE;
nscoord tableWidth=0; // the width of the table as a result of setting column widths
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();
- PRInt32 * effectiveColumnWidths = new PRInt32[numCols]; // used for Nav4 compatible table fluffing
+ nscoord * effectiveColumnWidths = new nscoord[numCols]; // used for Nav4 compatible table fluffing
nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
for (PRInt32 colIndex = 0; colIndexAppendElement (spanInfo);
+ spanList->AppendElement(spanInfo);
}
}
@@ -887,7 +887,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
nscoord widthPerSlice = widthRemaining/totalSlices;
PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count();
for (PRInt32 i=0; iElementAt(i));
nscoord computedColWidth = info->mProportion*widthPerSlice;
@@ -896,11 +896,12 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2: col %d given %d proportion of remaining space %d, set to width = %d\n",
info->mColIndex, info->mProportion, widthRemaining, computedColWidth);
tableWidth += computedColWidth;
+ effectiveColumnWidths[info->mColIndex] = computedColWidth;
delete info;
}
}
else
- {
+ { // we're in an unconstrained situation, so give each column the max of the max column widths
PRInt32 numSpecifiedProportionalColumns = proportionalColumnsList->Count();
PRInt32 maxOfMaxColWidths = 0;
PRInt32 i;
@@ -920,6 +921,7 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
printf (" 3 proportional step 2 (unconstrained!): col %d set to width = %d\n",
info->mColIndex, maxOfMaxColWidths);
tableWidth += maxOfMaxColWidths;
+ effectiveColumnWidths[info->mColIndex] = maxOfMaxColWidths;
delete info;
}
}
@@ -929,9 +931,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 (aTableFixedWidth > tableWidth)
+ if (aAvailWidth > tableWidth)
{
- DistributeExcessSpace(aTableFixedWidth, tableWidth, numCols, effectiveColumnWidths);
+ DistributeExcessSpace(aAvailWidth, tableWidth, effectiveColumnWidths);
}
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
if (nsnull!=effectiveColumnWidths)
@@ -941,14 +943,15 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsTableFits(nsIPresContext* aPresCo
return result;
}
+// 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,
- PRInt32 aNumCols,
- PRInt32 *aColWidths)
+ nscoord *aColWidths)
{
- nscoord excess = aTableFixedWidth - aComputedTableWidth;
- if (gsDebug) printf ("fixed width %d > computed table width %d, excess = %d\n",
- aTableFixedWidth, aComputedTableWidth, excess);
+ nscoord excess = 0;
+ if (PR_TRUE==gsDebug) printf ("DistributeExcessSpace: fixed width %d > computed table width %d\n",
+ aTableFixedWidth, aComputedTableWidth);
// if there are auto-sized columns, give them the extra space
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
@@ -969,14 +972,15 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
else
totalEffectiveWidthOfAutoColumns += mTableFrame->GetColumnWidth(autoColumns[i]);
}
+ excess = aTableFixedWidth - totalEffectiveWidthOfAutoColumns;
// 2. next, compute the proportion to be added to each column, and add it
for (i = 0; iGetColumnWidth(autoColumns[i]);
+ nscoord oldColWidth = aColWidths[colIndex];
float percent;
if (0!=totalEffectiveWidthOfAutoColumns)
- percent = ((float)(aColWidths[autoColumns[i]]))/((float)totalEffectiveWidthOfAutoColumns);
+ percent = ((float)(aColWidths[colIndex]))/((float)totalEffectiveWidthOfAutoColumns);
else
percent = ((float)1)/((float)numAutoColumns);
nscoord excessForThisColumn = (nscoord)(excess*percent);
@@ -991,10 +995,11 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aTableFixedWidth,
// (they must be all fixed and percentage-width columns, or we would have gone into the block above)
else
{
- nscoord excessPerColumn = excess/aNumCols;
+ excess = aTableFixedWidth - aComputedTableWidth;
+ nscoord excessPerColumn = excess/mNumCols;
if (gsDebug==PR_TRUE)
printf(" aTableFixedWidth specified as %d, expanding columns by excess = %d\n", aTableFixedWidth, excess);
- for (PRInt32 colIndex = 0; colIndexGetColumnLayoutData();
PRInt32 numCols = columnLayoutData->Count();
- PRInt32 * effectiveColumnWidths = new PRInt32[numCols]; // used for Nav4 compatible table fluffing
- nsCRT::memset (effectiveColumnWidths, 0, numCols*sizeof(PRInt32));
+ 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; colIndexElementAt(colIndex));
nsVoidArray *cells = colData->GetCells();
@@ -1149,17 +1158,22 @@ 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);
+ // remember the widest min cell width
if (minColWidth < cellMinWidth)
minColWidth = cellMinWidth;
+ // effectiveMinColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMinColumnWidths[colIndex] < minColWidth))
+ effectiveMinColumnWidths[colIndex] = cellMinWidth;
+ // remember the max desired cell width
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;
+ // effectiveMaxColumnWidth is the width as if no cells with colspans existed
+ if ((1==colSpan) && (effectiveMaxColumnWidths[colIndex] < maxColWidth))
+ effectiveMaxColumnWidths[colIndex] = cellDesiredWidth;
if (gsDebug==PR_TRUE)
- printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d\n",
+ printf (" after cell %d, minColWidth=%d maxColWidth=%d effColWidth[%d]=%d,%d\n",
cellIndex, minColWidth, maxColWidth,
- colIndex, effectiveColumnWidths[colIndex]);
+ colIndex, effectiveMaxColumnWidths[colIndex], effectiveMaxColumnWidths[colIndex]);
if (1GetColumnWidth(colIndex), aAvailWidth);
}
else if (PR_TRUE==isAutoWidth)
- { // column's width is determined by its content
- PRUint32 W = aMaxWidth - aMinTableWidth;
- PRUint32 D = aMaxTableWidth - aMinTableWidth;
- if (0==D) // fixed-size table
- D=1;
- // XXX really need to use effectiveColumnWidths[colIndex] here
- PRUint32 d = maxColWidth - minColWidth; // XXX: if this is 0, set to minColWidth?
- PRInt32 width = (d*W)/D;
- mTableFrame->SetColumnWidth(colIndex, minColWidth + width);
- if (gsDebug==PR_TRUE)
- printf (" 4 auto-width: col %d W=%d D=%d d=%d, set to width = %d\n",
- colIndex, W, D, d, mTableFrame->GetColumnWidth(colIndex));
+ { // column's width is determined by its content, done in post-processing
+ mTableFrame->SetColumnWidth(colIndex, 0); // set to 0 width for now
+ atLeastOneAutoWidthColumn = PR_TRUE;
}
else if (-1!=specifiedProportionColumnWidth)
{ // we need to save these and do them after all other columns have been calculated
@@ -1309,7 +1317,11 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
}
/* --- post-process if necessary --- */
- // first, assign a width to proportional-width columns
+ if (PR_TRUE==atLeastOneAutoWidthColumn)
+ { // proportionately distribute the remaining space to autowidth columns
+ DistributeRemainingSpace(aMaxWidth, tableWidth, effectiveMinColumnWidths, effectiveMaxColumnWidths);
+ }
+ // second, assign a width to proportional-width columns
if (nsnull!=proportionalColumnsList)
{
// first, figure out the amount of space per slice
@@ -1339,14 +1351,76 @@ PRBool BasicTableLayoutStrategy::BalanceColumnsConstrained( nsIPresContext* aPre
}
delete proportionalColumnsList;
}
-
+
+ // clean up
// today we always allocate effectiveColumnWidths, but tomorrow we might be smarter, so leave the check in
- if (nsnull!=effectiveColumnWidths)
- delete [] effectiveColumnWidths;
+ if (nsnull!=effectiveMinColumnWidths)
+ delete [] effectiveMinColumnWidths;
+ if (nsnull!=effectiveMaxColumnWidths)
+ delete [] effectiveMaxColumnWidths;
if (nsnull!=spanList)
delete spanList;
return result;
}
+//XXX: make sure aTFW takes into account fixed width cells already assigned
+// take the remaining space in the table and distribute it proportionately
+// to the auto-width cells in the table (based on desired width)
+void BasicTableLayoutStrategy::DistributeRemainingSpace(nscoord aTableFixedWidth,
+ nscoord aComputedTableWidth,
+ nscoord *aMinColWidths,
+ nscoord *aMaxColWidths)
+{
+ if (PR_TRUE==gsDebug)
+ printf ("DistributeRemainingSpace: fixed width %d > computed table width %d\n",
+ aTableFixedWidth, aComputedTableWidth);
+ // if there are auto-sized columns, give them the extra space
+ PRInt32 numAutoColumns=0;
+ PRInt32 *autoColumns=nsnull;
+ // availWidth is the difference between the total available width and the
+ // amount of space already assigned, assuming auto col widths were assigned 0.
+ nscoord availWidth = aTableFixedWidth - aComputedTableWidth;
+ mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
+ if (0!=numAutoColumns)
+ {
+ // 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;
+ // 1. first, get the total width of the auto columns
+ PRInt32 i;
+ for (i = 0; iGetColumnWidth(autoColumns[i]);
+ }
+ if (gsDebug==PR_TRUE)
+ printf(" aTableFixedWidth specified as %d, availWidth is = %d\n",
+ aTableFixedWidth, availWidth);
+
+ // 2. next, compute the proportion to be added to each column, and add it
+ for (i = 0; iSetColumnWidth(colIndex, colWidth);
+ }
+ }
+}
+
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h
index bb272fab46e..05e843b88af 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.h
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h
@@ -169,14 +169,27 @@ public:
* @param aTableFixedWidth the specified width of the table. If there is none,
* this param is 0
* @param aComputedTableWidth the width of the table before this final step.
- * @param aNumCols the number of columns in the table
*
* @return void
*/
virtual void DistributeExcessSpace(nscoord aTableFixedWidth,
nscoord aComputedTableWidth,
- PRInt32 aNumCols,
- PRInt32 *aColWidths);
+ nscoord *aColWidths);
+
+ /** starting with a partially balanced table, compute the amount
+ * of space to remove from each column to completely balance the table.
+ * set the column widths in mTableFrame based on these computations.
+ *
+ * @param aTableFixedWidth the specified width of the table. If there is none,
+ * this param is 0
+ * @param aComputedTableWidth the width of the table before this final step.
+ *
+ * @return void
+ */
+ virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
+ nscoord aComputedTableWidth,
+ nscoord *aMinColWidths,
+ nscoord *aMaxColWidths);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
diff --git a/mozilla/layout/tables/nsCellMap.h b/mozilla/layout/tables/nsCellMap.h
index 6d5d4d3fce2..15f9e6c441a 100644
--- a/mozilla/layout/tables/nsCellMap.h
+++ b/mozilla/layout/tables/nsCellMap.h
@@ -38,7 +38,7 @@ class nsCellMap
{
protected:
/** storage for CellData pointers */
- PRInt32 *mCells;
+ PRInt32 *mCells; ///XXX CellData *?
/** the number of rows */
int mRowCount; // in java, we could just do fCellMap.length;
diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp
index 72ffeafca3e..00676145a18 100644
--- a/mozilla/layout/tables/nsTableCellFrame.cpp
+++ b/mozilla/layout/tables/nsTableCellFrame.cpp
@@ -268,10 +268,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
CreatePsuedoFrame(aPresContext);
}
- // reduce available space by insets
-
+ // reduce available space by insets, if we're in a constrained situation
if (NS_UNCONSTRAINEDSIZE!=availSize.width)
- availSize.width -= leftInset+rightInset+margin.left+margin.right;
+ availSize.width -= leftInset+rightInset;
if (NS_UNCONSTRAINEDSIZE!=availSize.height)
availSize.height -= topInset+bottomInset+margin.top+margin.bottom;
@@ -305,9 +304,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
}
SetFirstContentOffset(mFirstChild);
- //if (gsDebug) printf("CELL: set first content offset to %d\n", GetFirstContentOffset()); //@@@
SetLastContentOffset(mFirstChild);
- //if (gsDebug) printf("CELL: set last content offset to %d\n", GetLastContentOffset()); //@@@
// Place the child
mFirstChild->SetRect(nsRect(leftInset, topInset,
@@ -332,13 +329,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
printf(" %p cellFrame height set to %d from kidSize=%d and insets %d,%d\n",
this, cellHeight, kidSize.height, topInset, bottomInset);
// next determine the cell's width
- nscoord cellWidth = kidSize.width; // at this point, we've factored in the cell's style attributes
- // if we're really in a constrained situation, factor in insets
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.width)
- {
- NS_ASSERTION(NS_UNCONSTRAINEDSIZE!=cellWidth, "child says it has unconstrained width in a constrained case");
- cellWidth += leftInset + rightInset;
- }
+ nscoord cellWidth = kidSize.width; // at this point, we've factored in the cell's style attributes
+ cellWidth += leftInset + rightInset; // factor in insets
// Nav4 hack for 0 width cells. If the cell has any content, it must have a desired width of at least 1
/*
@@ -370,10 +362,8 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (nsnull!=aDesiredSize.maxElementSize)
{
*aDesiredSize.maxElementSize = *pMaxElementSize;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.height)
- aDesiredSize.maxElementSize->height += topInset + bottomInset;
- if (NS_UNCONSTRAINEDSIZE!=aReflowState.maxSize.width)
- aDesiredSize.maxElementSize->width += leftInset + rightInset;
+ aDesiredSize.maxElementSize->height += topInset + bottomInset;
+ aDesiredSize.maxElementSize->width += leftInset + rightInset;
}
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugNT)
diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h
index 106f64415da..654920edc84 100644
--- a/mozilla/layout/tables/nsTableFrame.h
+++ b/mozilla/layout/tables/nsTableFrame.h
@@ -29,7 +29,6 @@ class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
class nsTableRowFrame;
-class CellData;
class nsITableLayoutStrategy;
class nsHTMLValue;
class ColumnInfoCache;
@@ -43,6 +42,31 @@ struct nsStyleSpacing;
extern const nsIID kTableFrameCID;
+/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
+ * if mCell is null then mRealCell will be the rowspan/colspan source
+ * in addition, if fOverlap is non-null then it will point to the
+ * other cell that overlaps this position
+ * @see nsCellMap
+ * @see nsTableFrame::BuildCellMap
+ * @see nsTableFrame::GrowCellMap
+ * @see nsTableFrame::BuildCellIntoMap
+ *
+ */
+class CellData
+{
+public:
+ nsTableCellFrame *mCell;
+ CellData *mRealCell;
+ CellData *mOverlap;
+
+ CellData();
+
+ ~CellData();
+};
+
+
+/* ============================================================================ */
+
/** nsTableFrame maps the inner portion of a table (everything except captions.)
* Used as a pseudo-frame within nsTableOuterFrame,
* it may also be used stand-alone as the top-level frame.
diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp
index cc6d9cf6997..80897b6f69b 100644
--- a/mozilla/layout/tables/nsTableRowFrame.cpp
+++ b/mozilla/layout/tables/nsTableRowFrame.cpp
@@ -405,16 +405,12 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
{
kidAvailSize.height -= kidMargin.top + kidMargin.bottom;
}
- // Subtract off for left and right margin
- // XXX Why bother doing this if we always set the available width
- // based on the column width below?
- if (PR_FALSE == aState.unconstrainedWidth) {
- kidAvailSize.width -= kidMargin.left + kidMargin.right;
- }
+
+ // left and right margins already taken into account by table layout strategy
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
- nscoord x = kidMargin.left;
+ nscoord x = 0;
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
for (PRInt32 colIndex=0; colIndexGetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpanGetColumnWidth(cellStartingCol+numColSpan);
+ }
kidAvailSize.width = availWidth;
if (availWidth != ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth())
{