diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
index bfbfb36a841..8c386257bb2 100644
--- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp
@@ -253,6 +253,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
+ PRInt32 numProvisionalFixedColumns = 0; // used for assigning width from cell with colspan to columns that are spanned
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@@ -291,6 +292,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
{
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
+ if (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN==colFrame->GetWidthSource())
+ numProvisionalFixedColumns++;
}
/* Scan the column, simulatneously assigning column widths
@@ -341,7 +344,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
- if (PR_TRUE==haveColWidth)// && PR_TRUE==cellGrantingWidth)
+ if ((PR_TRUE==haveColWidth) &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
{
// This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
@@ -380,16 +384,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMinColumnWidth = cellMinWidth;
}
- //bookkeeping: is this the cell that gave the column it's fixed width attribute?
- // must be done after "haveColWidth && cellGrantingWidth" used above
- if (PR_TRUE==cellGrantingWidth && 1==colSpan)
- {
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
- if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
- cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
- }
-
if (1GetColumnFrame(i+colIndex, cf);
const nsStylePosition* colPos;
cf->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPos);
- if (colPos->mWidth.GetUnit() != eStyleUnit_Auto)
+ if (colPos->mWidth.GetUnit() != eStyleUnit_Auto &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=cf->GetWidthSource()))
{
okToAdd = PR_FALSE;
break;
@@ -412,20 +407,39 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
}
+ nscoord width = cellDesiredSize.width; // used below as the cell's "natural" width
+ if (PR_TRUE == haveColWidth)
+ width = colSpan*specifiedFixedColWidth;
+
if (PR_TRUE==okToAdd)
{
- ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, cellDesiredSize.width);
+ ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, width);
if (nsnull==colSpanList)
colSpanList = new nsVoidArray();
colSpanList->AppendElement(colSpanInfo);
}
- // add the cell to our list of spanning cells
- SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
+ if (PR_TRUE==cellGrantingWidth)
+ {
+ // add the cell to our list of spanning cells
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, width);
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
+ }
}
+
+ //bookkeeping: is this the cell that gave the column it's fixed width attribute?
+ // must be done after "haveColWidth && cellGrantingWidth" used above
+ if (PR_TRUE==cellGrantingWidth)
+ {
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
+ }
+
+ // book 'em, Danno
if (gsDebug) {
printf (" after cell %d, minColWidth = %d and maxColWidth = %d\n",
rowIndex, minColWidth, maxColWidth);
@@ -454,7 +468,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
// this is the default, the real adjustment happens below where we deal with colspans
colFrame->SetAdjustedMinColWidth(effectiveMinColumnWidth);
- if (PR_TRUE==haveColWidth)
+ if ((PR_TRUE==haveColWidth) &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
else
mTableFrame->SetColumnWidth(colIndex, effectiveMaxColumnWidth);
@@ -467,8 +482,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
maxColWidthArray[colIndex] = maxColWidth;
}
if (gsDebug==PR_TRUE)
- printf ("after col %d, minColWidth=%d effectiveMinColumnWidth=%d\n\tminTableWidth = %d and maxTableWidth = %d\n",
- colIndex, minColWidth, effectiveMinColumnWidth, mMinTableWidth, mMaxTableWidth);
+ printf ("after col %d, minColWidth=%d effectiveMinColumnWidth=%d\n\teffectiveMaxColumnWidth = %d\n",
+ colIndex, minColWidth, effectiveMinColumnWidth, effectiveMaxColumnWidth);
}
// now, post-process the computed values based on the table attributes
@@ -479,10 +494,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (nsnull!=spanList)
{
// we only want to do this if there are auto-cells involved
+ // or if we have columns that are provisionally fixed-width with colspans
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
- if (0==numAutoColumns)
+ if (0==numAutoColumns && 0==numProvisionalFixedColumns)
{ //table fully specified, so no need to do any extra work here
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
@@ -494,21 +510,21 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
}
else
- {
+ { // for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndexCount();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
- {
+ { // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
{
if (0==spanInfo->effectiveMaxWidthOfSpannedCols)
- {
+ { // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
for (PRInt32 span=0; spaninitialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
@@ -550,10 +566,13 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
- spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMaxColWidth()) /
- (spanInfo->effectiveMaxWidthOfSpannedCols);
+ float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
+ ((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
+ spanCellMaxWidth = (nscoord)(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
- printf ("spanCellMaxWidth portion = %d\n", spanCellMaxWidth);
+ printf ("spanCellMaxWidth portion = %d with percent = %f from effMaxColW=%d and sum=%d\n",
+ spanCellMaxWidth, percent, colFrame->GetEffectiveMaxColWidth(),
+ spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
@@ -1561,7 +1580,7 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
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 from % = %f\n",
+ printf(" distribute excess: column %d was %d, now %d from %=%f\n",
colIndex, oldColWidth, colWidth, percent);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
diff --git a/mozilla/layout/html/table/src/nsCellMap.cpp b/mozilla/layout/html/table/src/nsCellMap.cpp
index befaa3ddb40..daba16d32b5 100644
--- a/mozilla/layout/html/table/src/nsCellMap.cpp
+++ b/mozilla/layout/html/table/src/nsCellMap.cpp
@@ -35,6 +35,7 @@ nsCellMap::nsCellMap(int aRows, int aColumns)
{
mCells = nsnull;
mColFrames = nsnull;
+ mMinColSpans = nsnull;
Reset(aRows, aColumns);
}
@@ -57,10 +58,13 @@ nsCellMap::~nsCellMap()
}
delete [] mCells;
}
- if (nsnull!= mColFrames)
+ if (nsnull != mColFrames)
delete mColFrames;
+ if (nsnull != mMinColSpans)
+ delete [] mMinColSpans;
mCells = nsnull;
mColFrames = nsnull;
+ mMinColSpans = nsnull;
};
@@ -131,5 +135,32 @@ nsTableColFrame* nsCellMap::GetColumnFrame(PRInt32 aColIndex)
}
+void nsCellMap::SetMinColSpan(PRInt32 aColIndex, PRBool aColSpan)
+{
+ NS_ASSERTION(aColIndex=0, "bad aColSpan");
+
+ // initialize the data structure if not already done
+ if (nsnull==mMinColSpans)
+ {
+ mMinColSpans = new PRInt32[mColCount];
+ for (PRInt32 i=0; iGetRowCount()==1)
return 1;
PRInt32 colSpan = aCell->GetColSpan();
PRInt32 colCount = GetColCount();
if (colCount < (aColIndex + colSpan))
- return (colCount - aColIndex);
- return colSpan;
+ result = colCount - aColIndex;
+ else
+ {
+ result = colSpan;
+ // check for case where all cells in a column have a colspan
+ PRInt32 initialColIndex = aCell->GetColIndex();
+ PRInt32 minColSpanForCol = cellMap->GetMinColSpan(initialColIndex);
+ result -= (minColSpanForCol - 1); // minColSpanForCol is always at least 1
+ // and we want to treat default as 0 (no effect)
+ }
+
+ return result;
}
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
@@ -691,8 +702,6 @@ void nsTableFrame::BuildCellMap ()
PRInt32 colIndex = 0;
nsIFrame* cellFrame;
rowFrame->FirstChild(cellFrame);
- if (gsDebug==PR_TRUE)
- DumpCellMap();
while ((nsnull != cellFrame) && (colIndex < mColCount))
{
@@ -745,6 +754,26 @@ void nsTableFrame::BuildCellMap ()
}
if (gsDebug==PR_TRUE)
DumpCellMap ();
+ // iterate through the columns setting the min col span if necessary
+ // it would be more efficient if we could do this in the above loop
+ for (PRInt32 colIndex=0; colIndexGetCellFrameAt(rowIndex, colIndex);
+ if (nsnull!=cellFrame)
+ {
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ if (0==rowIndex)
+ minColSpan = colSpan;
+ else
+ minColSpan = PR_MIN(minColSpan, colSpan);
+ }
+ }
+ if (1!=minColSpan)
+ mCellMap->SetMinColSpan(colIndex, minColSpan);
+ }
}
/**
@@ -2529,27 +2558,31 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
{
- // get the column style and set the width attribute
- nsIStyleContext *colSC;
- colFrame->GetStyleContext(aPresContext, colSC);
- nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
- NS_RELEASE(colSC);
- // set the column width attribute
- if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ if ((1==colSpan) ||
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource()))
{
- nscoord width = cellPosition->mWidth.GetCoordValue();
- colPosition->mWidth.SetCoordValue(width/colSpan);
+ // get the column style and set the width attribute
+ nsIStyleContext *colSC;
+ colFrame->GetStyleContext(aPresContext, colSC);
+ nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
+ NS_RELEASE(colSC);
+ // set the column width attribute
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ {
+ nscoord width = cellPosition->mWidth.GetCoordValue();
+ colPosition->mWidth.SetCoordValue(width/colSpan);
+ }
+ else
+ {
+ float width = cellPosition->mWidth.GetPercentValue();
+ colPosition->mWidth.SetPercentValue(width/colSpan);
+ }
+ // set the column width-set-type
+ if (1==colSpan)
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
+ else
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
- else
- {
- float width = cellPosition->mWidth.GetPercentValue();
- colPosition->mWidth.SetPercentValue(width/colSpan);
- }
- // set the column width-set-type
- if (1==colSpan)
- colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
- else
- colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
}
}
diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
index bfbfb36a841..8c386257bb2 100644
--- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
+++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp
@@ -253,6 +253,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
nsVoidArray *spanList=nsnull;
nsVoidArray *colSpanList=nsnull;
+ PRInt32 numProvisionalFixedColumns = 0; // used for assigning width from cell with colspan to columns that are spanned
PRBool hasColsAttribute = (PRBool)(NS_STYLE_TABLE_COLS_NONE!=mCols);
@@ -291,6 +292,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
{
haveColWidth = PR_TRUE;
specifiedFixedColWidth = colPosition->mWidth.GetCoordValue();
+ if (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN==colFrame->GetWidthSource())
+ numProvisionalFixedColumns++;
}
/* Scan the column, simulatneously assigning column widths
@@ -341,7 +344,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
rowIndex, colSpan, cellMinSize.width, cellMinSize.height,
cellDesiredSize.width, cellDesiredSize.height);
- if (PR_TRUE==haveColWidth)// && PR_TRUE==cellGrantingWidth)
+ if ((PR_TRUE==haveColWidth) &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
{
// This col has a specified fixed width so set the min and max width to the larger of
// (specified width, largest max_element_size of the cells in the column)
@@ -380,16 +384,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
effectiveMinColumnWidth = cellMinWidth;
}
- //bookkeeping: is this the cell that gave the column it's fixed width attribute?
- // must be done after "haveColWidth && cellGrantingWidth" used above
- if (PR_TRUE==cellGrantingWidth && 1==colSpan)
- {
- const nsStylePosition* cellPosition;
- cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
- if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
- cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
- }
-
if (1GetColumnFrame(i+colIndex, cf);
const nsStylePosition* colPos;
cf->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPos);
- if (colPos->mWidth.GetUnit() != eStyleUnit_Auto)
+ if (colPos->mWidth.GetUnit() != eStyleUnit_Auto &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=cf->GetWidthSource()))
{
okToAdd = PR_FALSE;
break;
@@ -412,20 +407,39 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
}
+ nscoord width = cellDesiredSize.width; // used below as the cell's "natural" width
+ if (PR_TRUE == haveColWidth)
+ width = colSpan*specifiedFixedColWidth;
+
if (PR_TRUE==okToAdd)
{
- ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, cellDesiredSize.width);
+ ColSpanStruct *colSpanInfo = new ColSpanStruct(colSpan, colIndex, width);
if (nsnull==colSpanList)
colSpanList = new nsVoidArray();
colSpanList->AppendElement(colSpanInfo);
}
- // add the cell to our list of spanning cells
- SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, cellDesiredWidth);
- if (nsnull==spanList)
- spanList = new nsVoidArray();
- spanList->AppendElement(spanInfo);
+ if (PR_TRUE==cellGrantingWidth)
+ {
+ // add the cell to our list of spanning cells
+ SpanInfo *spanInfo = new SpanInfo(colIndex, colSpan, cellMinWidth, width);
+ if (nsnull==spanList)
+ spanList = new nsVoidArray();
+ spanList->AppendElement(spanInfo);
+ }
}
+
+ //bookkeeping: is this the cell that gave the column it's fixed width attribute?
+ // must be done after "haveColWidth && cellGrantingWidth" used above
+ if (PR_TRUE==cellGrantingWidth)
+ {
+ const nsStylePosition* cellPosition;
+ cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width
+ }
+
+ // book 'em, Danno
if (gsDebug) {
printf (" after cell %d, minColWidth = %d and maxColWidth = %d\n",
rowIndex, minColWidth, maxColWidth);
@@ -454,7 +468,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
colFrame->SetEffectiveMaxColWidth(effectiveMaxColumnWidth);
// this is the default, the real adjustment happens below where we deal with colspans
colFrame->SetAdjustedMinColWidth(effectiveMinColumnWidth);
- if (PR_TRUE==haveColWidth)
+ if ((PR_TRUE==haveColWidth) &&
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN!=colFrame->GetWidthSource()))
mTableFrame->SetColumnWidth(colIndex, specifiedFixedColWidth);
else
mTableFrame->SetColumnWidth(colIndex, effectiveMaxColumnWidth);
@@ -467,8 +482,8 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
maxColWidthArray[colIndex] = maxColWidth;
}
if (gsDebug==PR_TRUE)
- printf ("after col %d, minColWidth=%d effectiveMinColumnWidth=%d\n\tminTableWidth = %d and maxTableWidth = %d\n",
- colIndex, minColWidth, effectiveMinColumnWidth, mMinTableWidth, mMaxTableWidth);
+ printf ("after col %d, minColWidth=%d effectiveMinColumnWidth=%d\n\teffectiveMaxColumnWidth = %d\n",
+ colIndex, minColWidth, effectiveMinColumnWidth, effectiveMaxColumnWidth);
}
// now, post-process the computed values based on the table attributes
@@ -479,10 +494,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
if (nsnull!=spanList)
{
// we only want to do this if there are auto-cells involved
+ // or if we have columns that are provisionally fixed-width with colspans
PRInt32 numAutoColumns=0;
PRInt32 *autoColumns=nsnull;
mTableFrame->GetColumnsByType(eStyleUnit_Auto, numAutoColumns, autoColumns);
- if (0==numAutoColumns)
+ if (0==numAutoColumns && 0==numProvisionalFixedColumns)
{ //table fully specified, so no need to do any extra work here
PRInt32 spanCount = spanList->Count();
// go through the list backwards so we can delete easily
@@ -494,21 +510,21 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
}
}
else
- {
+ { // for every column, handle spanning cells that impact that column
for (PRInt32 colIndex=0; colIndexCount();
// go through the list backwards so we can delete easily
for (PRInt32 spanIndex=spanCount-1; 0<=spanIndex; spanIndex--)
- {
+ { // get each spanInfo struct and see if it impacts this column
SpanInfo *spanInfo = (SpanInfo *)(spanList->ElementAt(spanIndex));
// if the spanInfo is about a column before the current column, it effects
// the current column (otherwise it would have already been deleted.)
if (spanInfo->initialColIndex <= colIndex)
{
if (0==spanInfo->effectiveMaxWidthOfSpannedCols)
- {
+ { // if we have not yet computed effectiveMaxWidthOfSpannedCols, do it now
for (PRInt32 span=0; spaninitialColSpan; span++)
{
nsTableColFrame *nextColFrame = mTableFrame->GetColFrame(colIndex+span);
@@ -550,10 +566,13 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
nscoord spanCellMaxWidth;
if (0!=spanInfo->effectiveMaxWidthOfSpannedCols)
{
- spanCellMaxWidth = (spanInfo->cellDesiredWidth * colFrame->GetEffectiveMaxColWidth()) /
- (spanInfo->effectiveMaxWidthOfSpannedCols);
+ float percent = ((float)(colFrame->GetEffectiveMaxColWidth())) /
+ ((float)(spanInfo->effectiveMaxWidthOfSpannedCols));
+ spanCellMaxWidth = (nscoord)(((float)(spanInfo->cellDesiredWidth)) * percent);
if (gsDebug==PR_TRUE)
- printf ("spanCellMaxWidth portion = %d\n", spanCellMaxWidth);
+ printf ("spanCellMaxWidth portion = %d with percent = %f from effMaxColW=%d and sum=%d\n",
+ spanCellMaxWidth, percent, colFrame->GetEffectiveMaxColWidth(),
+ spanInfo->effectiveMaxWidthOfSpannedCols);
if (colMaxWidth < spanCellMaxWidth)
{
// make sure we're at least as big as our min
@@ -1561,7 +1580,7 @@ void BasicTableLayoutStrategy::DistributeExcessSpace(nscoord aAvailWidth,
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 from % = %f\n",
+ printf(" distribute excess: column %d was %d, now %d from %=%f\n",
colIndex, oldColWidth, colWidth, percent);
mTableFrame->SetColumnWidth(colIndex, colWidth);
}
diff --git a/mozilla/layout/tables/nsCellMap.cpp b/mozilla/layout/tables/nsCellMap.cpp
index befaa3ddb40..daba16d32b5 100644
--- a/mozilla/layout/tables/nsCellMap.cpp
+++ b/mozilla/layout/tables/nsCellMap.cpp
@@ -35,6 +35,7 @@ nsCellMap::nsCellMap(int aRows, int aColumns)
{
mCells = nsnull;
mColFrames = nsnull;
+ mMinColSpans = nsnull;
Reset(aRows, aColumns);
}
@@ -57,10 +58,13 @@ nsCellMap::~nsCellMap()
}
delete [] mCells;
}
- if (nsnull!= mColFrames)
+ if (nsnull != mColFrames)
delete mColFrames;
+ if (nsnull != mMinColSpans)
+ delete [] mMinColSpans;
mCells = nsnull;
mColFrames = nsnull;
+ mMinColSpans = nsnull;
};
@@ -131,5 +135,32 @@ nsTableColFrame* nsCellMap::GetColumnFrame(PRInt32 aColIndex)
}
+void nsCellMap::SetMinColSpan(PRInt32 aColIndex, PRBool aColSpan)
+{
+ NS_ASSERTION(aColIndex=0, "bad aColSpan");
+
+ // initialize the data structure if not already done
+ if (nsnull==mMinColSpans)
+ {
+ mMinColSpans = new PRInt32[mColCount];
+ for (PRInt32 i=0; iGetRowCount()==1)
return 1;
PRInt32 colSpan = aCell->GetColSpan();
PRInt32 colCount = GetColCount();
if (colCount < (aColIndex + colSpan))
- return (colCount - aColIndex);
- return colSpan;
+ result = colCount - aColIndex;
+ else
+ {
+ result = colSpan;
+ // check for case where all cells in a column have a colspan
+ PRInt32 initialColIndex = aCell->GetColIndex();
+ PRInt32 minColSpanForCol = cellMap->GetMinColSpan(initialColIndex);
+ result -= (minColSpanForCol - 1); // minColSpanForCol is always at least 1
+ // and we want to treat default as 0 (no effect)
+ }
+
+ return result;
}
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
@@ -691,8 +702,6 @@ void nsTableFrame::BuildCellMap ()
PRInt32 colIndex = 0;
nsIFrame* cellFrame;
rowFrame->FirstChild(cellFrame);
- if (gsDebug==PR_TRUE)
- DumpCellMap();
while ((nsnull != cellFrame) && (colIndex < mColCount))
{
@@ -745,6 +754,26 @@ void nsTableFrame::BuildCellMap ()
}
if (gsDebug==PR_TRUE)
DumpCellMap ();
+ // iterate through the columns setting the min col span if necessary
+ // it would be more efficient if we could do this in the above loop
+ for (PRInt32 colIndex=0; colIndexGetCellFrameAt(rowIndex, colIndex);
+ if (nsnull!=cellFrame)
+ {
+ PRInt32 colSpan = cellFrame->GetColSpan();
+ if (0==rowIndex)
+ minColSpan = colSpan;
+ else
+ minColSpan = PR_MIN(minColSpan, colSpan);
+ }
+ }
+ if (1!=minColSpan)
+ mCellMap->SetMinColSpan(colIndex, minColSpan);
+ }
}
/**
@@ -2529,27 +2558,31 @@ nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext,
GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
if (nsTableColFrame::eWIDTH_SOURCE_CELL != colFrame->GetWidthSource())
{
- // get the column style and set the width attribute
- nsIStyleContext *colSC;
- colFrame->GetStyleContext(aPresContext, colSC);
- nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
- NS_RELEASE(colSC);
- // set the column width attribute
- if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ if ((1==colSpan) ||
+ (nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN != colFrame->GetWidthSource()))
{
- nscoord width = cellPosition->mWidth.GetCoordValue();
- colPosition->mWidth.SetCoordValue(width/colSpan);
+ // get the column style and set the width attribute
+ nsIStyleContext *colSC;
+ colFrame->GetStyleContext(aPresContext, colSC);
+ nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
+ NS_RELEASE(colSC);
+ // set the column width attribute
+ if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
+ {
+ nscoord width = cellPosition->mWidth.GetCoordValue();
+ colPosition->mWidth.SetCoordValue(width/colSpan);
+ }
+ else
+ {
+ float width = cellPosition->mWidth.GetPercentValue();
+ colPosition->mWidth.SetPercentValue(width/colSpan);
+ }
+ // set the column width-set-type
+ if (1==colSpan)
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
+ else
+ colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
- else
- {
- float width = cellPosition->mWidth.GetPercentValue();
- colPosition->mWidth.SetPercentValue(width/colSpan);
- }
- // set the column width-set-type
- if (1==colSpan)
- colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL);
- else
- colFrame->SetWidthSource(nsTableColFrame::eWIDTH_SOURCE_CELL_WITH_SPAN);
}
}
}