bug 60816 use correct cell when rowspan and colspan overlap. Fix pixel rounding errors. sr=attiansi, r=alexsavulov

This commit is contained in:
karnaze%netscape.com 2001-10-26 02:30:38 +00:00
Родитель 84c24158b4
Коммит 08cb1a9a29
12 изменённых файлов: 190 добавлений и 54 удалений

Просмотреть файл

@ -130,7 +130,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex
mTableFrame->SetHasPctCol(PR_FALSE);
nscoord boxWidth = mTableFrame->CalcBorderBoxWidth(aReflowState);
nscoord boxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
PRBool hasPctCol = AssignNonPctColumnWidths(aPresContext, boxWidth, aReflowState, p2t);
mTableFrame->SetHasPctCol(hasPctCol);
@ -224,7 +224,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
aReflowState.mComputedBorderPadding.right;
// determine if the table is auto/fixed and get the fixed width if available
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aReflowState);
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
if (NS_UNCONSTRAINEDSIZE == maxWidth) {
maxWidth = PR_MIN(maxWidth, aReflowState.availableWidth);
if (NS_UNCONSTRAINEDSIZE == maxWidth) {
@ -488,7 +488,8 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
: ((float)oldWidth) / ((float)divisor);
nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)aAllocAmount) * percent), aPixelToTwips);
if (addition > (aAllocAmount - totalAllocated)) {
mTableFrame->SetColumnWidth(colX, oldWidth + (aAllocAmount - totalAllocated));
addition = nsTableFrame::RoundToPixel(aAllocAmount - totalAllocated, aPixelToTwips);
mTableFrame->SetColumnWidth(colX, oldWidth + addition);
break;
}
mTableFrame->SetColumnWidth(colX, oldWidth + addition);
@ -1416,7 +1417,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
// if the percent total went over 100%, adjustments need to be made to right most cols
if (colPctTotal > 100) {
ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis));
ReduceOverSpecifiedPctCols(nsTableFrame::RoundToPixel(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis), aPixelToTwips));
colPctTotal = 100;
}
@ -1592,7 +1593,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
delete [] rowIndices;
// if the percent total went over 100%, adjustments need to be made to right most cols
if (colPctTotal > 100) {
ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis));
ReduceOverSpecifiedPctCols(nsTableFrame::RoundToPixel(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis), aPixelToTwips));
}
// adjust the basis to include table border, padding and cell spacing

Просмотреть файл

@ -219,6 +219,7 @@ FixedTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
// if there was too much allocated due to rounding, remove it from the last col
if ((colX == lastColAllocated) && (overAllocation != 0)) {
colWidths[colX] -= overAllocation;
colWidths[colX] = nsTableFrame::RoundToPixel(colWidths[colX], aPixelToTwips);
totalColWidth -= colWidths[colX] - PR_MAX(0, colWidths[colX]);
colWidths[colX] = PR_MAX(0, colWidths[colX]);
}

Просмотреть файл

@ -1149,9 +1149,26 @@ PRInt32 nsCellMap::GetEffectiveColSpan(nsTableCellMap& aMap,
if (row) {
PRInt32 colX;
CellData* data;
for (colX = aColIndex + 1; colX < numColsInTable; colX++) {
PRInt32 maxCols = numColsInTable;
PRBool hitOverlap = PR_FALSE;
for (colX = aColIndex + 1; colX < maxCols; colX++) {
data = GetMapCellAt(aMap, aRowIndex, colX, PR_TRUE);
if (data) {
// for an overlapping situation get the colspan from the originating cell and
// use that as the max number of cols to iterate. Since this is rare, only
// pay the price of looking up the cell's colspan here.
if (!hitOverlap && data->IsOverlap()) {
CellData* origData = GetMapCellAt(aMap, aRowIndex, aColIndex, PR_TRUE);
if (origData->IsOrig()) {
nsTableCellFrame* cellFrame = origData->GetCellFrame();
if (cellFrame) {
// possible change the number of colums to iterate
maxCols = PR_MIN(aColIndex + cellFrame->GetColSpan(), maxCols);
if (colX >= maxCols)
break;
}
}
}
if (data->IsColSpan()) {
colSpan++;
if (data->IsZeroColSpan()) {

Просмотреть файл

@ -3922,7 +3922,8 @@ nsTableFrame::IsAutoHeight()
}
nscoord
nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
nsTableFrame::CalcBorderBoxWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aState)
{
nscoord width = aState.mComputedWidth;
@ -3940,6 +3941,12 @@ nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
}
width = PR_MAX(width, 0);
if (NS_UNCONSTRAINEDSIZE != width) {
float p2t;
aPresContext->GetPixelsToTwips(&p2t);
width = RoundToPixel(width, p2t);
}
return width;
}
@ -4028,7 +4035,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext,
if (HasPctCol() && aCalcPrefWidthIfAutoWithPctCol &&
(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
// for an auto table with a pct cell, use the strategy's CalcPctAdjTableWidth
nscoord availWidth = CalcBorderBoxWidth(aReflowState);
nscoord availWidth = CalcBorderBoxWidth(aPresContext, aReflowState);
availWidth = PR_MIN(availWidth, aReflowState.availableWidth);
if (mTableLayoutStrategy && IsAutoLayout()) {
float p2t;

Просмотреть файл

@ -628,7 +628,8 @@ public:
// calculate the computed width of aFrame including its border and padding given
// its reflow state.
nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
nscoord CalcBorderBoxWidth(nsIPresContext* aPresContex,
const nsHTMLReflowState& aReflowState);
// calculate the computed height of aFrame including its border and padding given
// its reflow state.

Просмотреть файл

@ -744,12 +744,15 @@ nsTableRowFrame::CalculateCellActualSize(nsIFrame* aCellFrame,
// Calculates the available width for the table cell based on the known
// column widths taking into account column spans and column spacing
nscoord
CalcCellAvailWidth(nsTableFrame& aTableFrame,
nsTableCellFrame& aCellFrame,
nscoord aCellSpacingX)
static void
CalcAvailWidth(nsTableFrame& aTableFrame,
nscoord aTableComputedWidth,
nsTableCellFrame& aCellFrame,
nscoord aCellSpacingX,
nscoord& aColAvailWidth,
nscoord& aCellAvailWidth)
{
nscoord cellWidth = 0;
aColAvailWidth = aCellAvailWidth = 0;
PRInt32 colIndex;
aCellFrame.GetColIndex(colIndex);
PRInt32 colspan = aTableFrame.GetEffectiveColSpan(aCellFrame);
@ -757,14 +760,29 @@ CalcCellAvailWidth(nsTableFrame& aTableFrame,
for (PRInt32 spanX = 0; spanX < colspan; spanX++) {
nscoord colWidth = aTableFrame.GetColumnWidth(colIndex + spanX);
if (colWidth > 0) {
cellWidth += colWidth;
aColAvailWidth += colWidth;
}
if ((spanX > 0) && (aTableFrame.GetNumCellsOriginatingInCol(colIndex + spanX) > 0)) {
cellWidth += aCellSpacingX;
aColAvailWidth += aCellSpacingX;
}
}
aCellAvailWidth = aColAvailWidth;
return cellWidth;
// for a cell with a colspan > 1, use its fix width (if set) as the avail width
if (aTableFrame.GetEffectiveColSpan(aCellFrame) > 1) {
// see if the cell has a style width specified
const nsStylePosition* cellPosition;
aCellFrame.GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
// need to add padding into fixed width
nsMargin padding(0,0,0,0);
if (NS_UNCONSTRAINEDSIZE != aTableComputedWidth) {
padding = nsTableFrame::GetPadding(nsSize(aTableComputedWidth, 0), &aCellFrame);
}
nscoord fixWidth = cellPosition->mWidth.GetCoordValue() + padding.left + padding.right;
aCellAvailWidth = PR_MIN(aColAvailWidth, fixWidth);
}
}
}
nscoord
@ -797,6 +815,21 @@ GetSpaceBetween(PRInt32 aPrevColIndex,
return space;
}
static nscoord
GetComputedWidth(const nsHTMLReflowState& aReflowState,
nsTableFrame& aTableFrame)
{
const nsHTMLReflowState* parentReflow = aReflowState.parentReflowState;
nscoord computedWidth = 0;
while (parentReflow) {
if (parentReflow->frame == &aTableFrame) {
computedWidth = parentReflow->mComputedWidth;
break;
}
parentReflow = parentReflow->parentReflowState;
}
return computedWidth;
}
// Called for a dirty or resize reflow. Reflows all the existing table cell
// frames unless aDirtyOnly is PR_TRUE in which case only reflow the dirty frames
@ -866,10 +899,11 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
cellSpacingX, iter.IsLeftToRight());
}
// Calculate the available width for the table cell using the known column widths
nscoord availWidth = CalcCellAvailWidth(*tableFrame, *cellFrame, cellSpacingX);
if (0 == availWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
nscoord availColWidth, availCellWidth;
CalcAvailWidth(*tableFrame, GetComputedWidth(aReflowState, *tableFrame),
*cellFrame, cellSpacingX, availColWidth, availCellWidth);
if (0 == availColWidth) availColWidth = NS_UNCONSTRAINEDSIZE;
if (0 == availCellWidth) availCellWidth = NS_UNCONSTRAINEDSIZE;
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
@ -882,12 +916,12 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
nsIFrame* kidNextInFlow;
kidFrame->GetNextInFlow(&kidNextInFlow);
nsSize cellDesiredSize = cellFrame->GetDesiredSize();
if ((availWidth != cellFrame->GetPriorAvailWidth()) ||
if ((availCellWidth != cellFrame->GetPriorAvailWidth()) ||
(cellDesiredSize.width > cellFrame->GetPriorAvailWidth()) ||
(eReflowReason_StyleChange == aReflowState.reason) ||
isPaginated) {
// Reflow the cell to fit the available width, height
nsSize kidAvailSize(availWidth, aReflowState.availableHeight);
nsSize kidAvailSize(availColWidth, aReflowState.availableHeight);
nsReflowReason reason = eReflowReason_Resize;
PRBool cellToWatch = PR_FALSE;
nsSize maxElementSize;
@ -905,7 +939,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
if (!tablePrevInFlow && isAutoLayout) {
// request the maximum width if availWidth is constrained
// XXX we could just do this always, but blocks have some problems
if (NS_UNCONSTRAINEDSIZE != availWidth) {
if (NS_UNCONSTRAINEDSIZE != availCellWidth) {
desiredSize.mFlags |= NS_REFLOW_CALC_MAX_WIDTH;
}
// request to get the max element size
@ -927,7 +961,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
x, 0, 0, status);
if (cellToWatch) {
nscoord maxWidth = (NS_UNCONSTRAINEDSIZE == availWidth)
nscoord maxWidth = (NS_UNCONSTRAINEDSIZE == availCellWidth)
? desiredSize.width : desiredSize.mMaximumWidth;
// save the max element width and max width
cellFrame->SetPass1MaxElementSize(desiredSize.width, *desiredSize.maxElementSize);
@ -963,7 +997,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
// takes into account the specified height (in the style), and any special
// logic needed for backwards compatibility
CalculateCellActualSize(kidFrame, desiredSize.width,
desiredSize.height, availWidth);
desiredSize.height, availCellWidth);
// height may have changed, adjust descent to absorb any excess difference
nscoord ascent = cellFrame->GetDesiredAscent();
@ -971,6 +1005,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
SetTallestCell(desiredSize.height, ascent, descent, tableFrame, cellFrame);
// Place the child
if (NS_UNCONSTRAINEDSIZE != availColWidth) {
desiredSize.width = PR_MAX(availCellWidth, availColWidth);
}
FinishReflowChild(kidFrame, aPresContext, desiredSize, x, 0, 0);
x += desiredSize.width;
}
@ -1104,7 +1142,9 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
PRInt32 cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
nscoord cellAvailWidth = CalcCellAvailWidth(aTableFrame, *cellFrame, cellSpacingX);
nscoord colAvailWidth, cellAvailWidth;
CalcAvailWidth(aTableFrame, GetComputedWidth(aReflowState, aTableFrame),
*cellFrame, cellSpacingX, colAvailWidth, cellAvailWidth);
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
@ -1203,6 +1243,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
}
// Now place the child
cellMet.width = colAvailWidth;
FinishReflowChild(aNextFrame, aPresContext, cellMet, cellOrigin.x, 0, 0);
// Notify the table if the cell width changed so it can decide whether to rebalance

Просмотреть файл

@ -130,7 +130,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex
mTableFrame->SetHasPctCol(PR_FALSE);
nscoord boxWidth = mTableFrame->CalcBorderBoxWidth(aReflowState);
nscoord boxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
PRBool hasPctCol = AssignNonPctColumnWidths(aPresContext, boxWidth, aReflowState, p2t);
mTableFrame->SetHasPctCol(hasPctCol);
@ -224,7 +224,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
aReflowState.mComputedBorderPadding.right;
// determine if the table is auto/fixed and get the fixed width if available
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aReflowState);
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
if (NS_UNCONSTRAINEDSIZE == maxWidth) {
maxWidth = PR_MIN(maxWidth, aReflowState.availableWidth);
if (NS_UNCONSTRAINEDSIZE == maxWidth) {
@ -488,7 +488,8 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
: ((float)oldWidth) / ((float)divisor);
nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)aAllocAmount) * percent), aPixelToTwips);
if (addition > (aAllocAmount - totalAllocated)) {
mTableFrame->SetColumnWidth(colX, oldWidth + (aAllocAmount - totalAllocated));
addition = nsTableFrame::RoundToPixel(aAllocAmount - totalAllocated, aPixelToTwips);
mTableFrame->SetColumnWidth(colX, oldWidth + addition);
break;
}
mTableFrame->SetColumnWidth(colX, oldWidth + addition);
@ -1416,7 +1417,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
// if the percent total went over 100%, adjustments need to be made to right most cols
if (colPctTotal > 100) {
ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis));
ReduceOverSpecifiedPctCols(nsTableFrame::RoundToPixel(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis), aPixelToTwips));
colPctTotal = 100;
}
@ -1592,7 +1593,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
delete [] rowIndices;
// if the percent total went over 100%, adjustments need to be made to right most cols
if (colPctTotal > 100) {
ReduceOverSpecifiedPctCols(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis));
ReduceOverSpecifiedPctCols(nsTableFrame::RoundToPixel(NSToCoordRound(((float)(colPctTotal - 100)) * 0.01f * (float)basis), aPixelToTwips));
}
// adjust the basis to include table border, padding and cell spacing

Просмотреть файл

@ -219,6 +219,7 @@ FixedTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
// if there was too much allocated due to rounding, remove it from the last col
if ((colX == lastColAllocated) && (overAllocation != 0)) {
colWidths[colX] -= overAllocation;
colWidths[colX] = nsTableFrame::RoundToPixel(colWidths[colX], aPixelToTwips);
totalColWidth -= colWidths[colX] - PR_MAX(0, colWidths[colX]);
colWidths[colX] = PR_MAX(0, colWidths[colX]);
}

Просмотреть файл

@ -1149,9 +1149,26 @@ PRInt32 nsCellMap::GetEffectiveColSpan(nsTableCellMap& aMap,
if (row) {
PRInt32 colX;
CellData* data;
for (colX = aColIndex + 1; colX < numColsInTable; colX++) {
PRInt32 maxCols = numColsInTable;
PRBool hitOverlap = PR_FALSE;
for (colX = aColIndex + 1; colX < maxCols; colX++) {
data = GetMapCellAt(aMap, aRowIndex, colX, PR_TRUE);
if (data) {
// for an overlapping situation get the colspan from the originating cell and
// use that as the max number of cols to iterate. Since this is rare, only
// pay the price of looking up the cell's colspan here.
if (!hitOverlap && data->IsOverlap()) {
CellData* origData = GetMapCellAt(aMap, aRowIndex, aColIndex, PR_TRUE);
if (origData->IsOrig()) {
nsTableCellFrame* cellFrame = origData->GetCellFrame();
if (cellFrame) {
// possible change the number of colums to iterate
maxCols = PR_MIN(aColIndex + cellFrame->GetColSpan(), maxCols);
if (colX >= maxCols)
break;
}
}
}
if (data->IsColSpan()) {
colSpan++;
if (data->IsZeroColSpan()) {

Просмотреть файл

@ -3922,7 +3922,8 @@ nsTableFrame::IsAutoHeight()
}
nscoord
nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
nsTableFrame::CalcBorderBoxWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aState)
{
nscoord width = aState.mComputedWidth;
@ -3940,6 +3941,12 @@ nsTableFrame::CalcBorderBoxWidth(const nsHTMLReflowState& aState)
}
width = PR_MAX(width, 0);
if (NS_UNCONSTRAINEDSIZE != width) {
float p2t;
aPresContext->GetPixelsToTwips(&p2t);
width = RoundToPixel(width, p2t);
}
return width;
}
@ -4028,7 +4035,7 @@ nsTableFrame::CalcMinAndPreferredWidths(nsIPresContext* aPresContext,
if (HasPctCol() && aCalcPrefWidthIfAutoWithPctCol &&
(NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
// for an auto table with a pct cell, use the strategy's CalcPctAdjTableWidth
nscoord availWidth = CalcBorderBoxWidth(aReflowState);
nscoord availWidth = CalcBorderBoxWidth(aPresContext, aReflowState);
availWidth = PR_MIN(availWidth, aReflowState.availableWidth);
if (mTableLayoutStrategy && IsAutoLayout()) {
float p2t;

Просмотреть файл

@ -628,7 +628,8 @@ public:
// calculate the computed width of aFrame including its border and padding given
// its reflow state.
nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
nscoord CalcBorderBoxWidth(nsIPresContext* aPresContex,
const nsHTMLReflowState& aReflowState);
// calculate the computed height of aFrame including its border and padding given
// its reflow state.

Просмотреть файл

@ -744,12 +744,15 @@ nsTableRowFrame::CalculateCellActualSize(nsIFrame* aCellFrame,
// Calculates the available width for the table cell based on the known
// column widths taking into account column spans and column spacing
nscoord
CalcCellAvailWidth(nsTableFrame& aTableFrame,
nsTableCellFrame& aCellFrame,
nscoord aCellSpacingX)
static void
CalcAvailWidth(nsTableFrame& aTableFrame,
nscoord aTableComputedWidth,
nsTableCellFrame& aCellFrame,
nscoord aCellSpacingX,
nscoord& aColAvailWidth,
nscoord& aCellAvailWidth)
{
nscoord cellWidth = 0;
aColAvailWidth = aCellAvailWidth = 0;
PRInt32 colIndex;
aCellFrame.GetColIndex(colIndex);
PRInt32 colspan = aTableFrame.GetEffectiveColSpan(aCellFrame);
@ -757,14 +760,29 @@ CalcCellAvailWidth(nsTableFrame& aTableFrame,
for (PRInt32 spanX = 0; spanX < colspan; spanX++) {
nscoord colWidth = aTableFrame.GetColumnWidth(colIndex + spanX);
if (colWidth > 0) {
cellWidth += colWidth;
aColAvailWidth += colWidth;
}
if ((spanX > 0) && (aTableFrame.GetNumCellsOriginatingInCol(colIndex + spanX) > 0)) {
cellWidth += aCellSpacingX;
aColAvailWidth += aCellSpacingX;
}
}
aCellAvailWidth = aColAvailWidth;
return cellWidth;
// for a cell with a colspan > 1, use its fix width (if set) as the avail width
if (aTableFrame.GetEffectiveColSpan(aCellFrame) > 1) {
// see if the cell has a style width specified
const nsStylePosition* cellPosition;
aCellFrame.GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
// need to add padding into fixed width
nsMargin padding(0,0,0,0);
if (NS_UNCONSTRAINEDSIZE != aTableComputedWidth) {
padding = nsTableFrame::GetPadding(nsSize(aTableComputedWidth, 0), &aCellFrame);
}
nscoord fixWidth = cellPosition->mWidth.GetCoordValue() + padding.left + padding.right;
aCellAvailWidth = PR_MIN(aColAvailWidth, fixWidth);
}
}
}
nscoord
@ -797,6 +815,21 @@ GetSpaceBetween(PRInt32 aPrevColIndex,
return space;
}
static nscoord
GetComputedWidth(const nsHTMLReflowState& aReflowState,
nsTableFrame& aTableFrame)
{
const nsHTMLReflowState* parentReflow = aReflowState.parentReflowState;
nscoord computedWidth = 0;
while (parentReflow) {
if (parentReflow->frame == &aTableFrame) {
computedWidth = parentReflow->mComputedWidth;
break;
}
parentReflow = parentReflow->parentReflowState;
}
return computedWidth;
}
// Called for a dirty or resize reflow. Reflows all the existing table cell
// frames unless aDirtyOnly is PR_TRUE in which case only reflow the dirty frames
@ -866,10 +899,11 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
cellSpacingX, iter.IsLeftToRight());
}
// Calculate the available width for the table cell using the known column widths
nscoord availWidth = CalcCellAvailWidth(*tableFrame, *cellFrame, cellSpacingX);
if (0 == availWidth) {
availWidth = NS_UNCONSTRAINEDSIZE;
}
nscoord availColWidth, availCellWidth;
CalcAvailWidth(*tableFrame, GetComputedWidth(aReflowState, *tableFrame),
*cellFrame, cellSpacingX, availColWidth, availCellWidth);
if (0 == availColWidth) availColWidth = NS_UNCONSTRAINEDSIZE;
if (0 == availCellWidth) availCellWidth = NS_UNCONSTRAINEDSIZE;
// remember the rightmost (ltr) or leftmost (rtl) column this cell spans into
prevColIndex = (iter.IsLeftToRight()) ? cellColIndex + (cellColSpan - 1) : cellColIndex;
@ -882,12 +916,12 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
nsIFrame* kidNextInFlow;
kidFrame->GetNextInFlow(&kidNextInFlow);
nsSize cellDesiredSize = cellFrame->GetDesiredSize();
if ((availWidth != cellFrame->GetPriorAvailWidth()) ||
if ((availCellWidth != cellFrame->GetPriorAvailWidth()) ||
(cellDesiredSize.width > cellFrame->GetPriorAvailWidth()) ||
(eReflowReason_StyleChange == aReflowState.reason) ||
isPaginated) {
// Reflow the cell to fit the available width, height
nsSize kidAvailSize(availWidth, aReflowState.availableHeight);
nsSize kidAvailSize(availColWidth, aReflowState.availableHeight);
nsReflowReason reason = eReflowReason_Resize;
PRBool cellToWatch = PR_FALSE;
nsSize maxElementSize;
@ -905,7 +939,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
if (!tablePrevInFlow && isAutoLayout) {
// request the maximum width if availWidth is constrained
// XXX we could just do this always, but blocks have some problems
if (NS_UNCONSTRAINEDSIZE != availWidth) {
if (NS_UNCONSTRAINEDSIZE != availCellWidth) {
desiredSize.mFlags |= NS_REFLOW_CALC_MAX_WIDTH;
}
// request to get the max element size
@ -927,7 +961,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
x, 0, 0, status);
if (cellToWatch) {
nscoord maxWidth = (NS_UNCONSTRAINEDSIZE == availWidth)
nscoord maxWidth = (NS_UNCONSTRAINEDSIZE == availCellWidth)
? desiredSize.width : desiredSize.mMaximumWidth;
// save the max element width and max width
cellFrame->SetPass1MaxElementSize(desiredSize.width, *desiredSize.maxElementSize);
@ -963,7 +997,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
// takes into account the specified height (in the style), and any special
// logic needed for backwards compatibility
CalculateCellActualSize(kidFrame, desiredSize.width,
desiredSize.height, availWidth);
desiredSize.height, availCellWidth);
// height may have changed, adjust descent to absorb any excess difference
nscoord ascent = cellFrame->GetDesiredAscent();
@ -971,6 +1005,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
SetTallestCell(desiredSize.height, ascent, descent, tableFrame, cellFrame);
// Place the child
if (NS_UNCONSTRAINEDSIZE != availColWidth) {
desiredSize.width = PR_MAX(availCellWidth, availColWidth);
}
FinishReflowChild(kidFrame, aPresContext, desiredSize, x, 0, 0);
x += desiredSize.width;
}
@ -1104,7 +1142,9 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
PRInt32 cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
nscoord cellAvailWidth = CalcCellAvailWidth(aTableFrame, *cellFrame, cellSpacingX);
nscoord colAvailWidth, cellAvailWidth;
CalcAvailWidth(aTableFrame, GetComputedWidth(aReflowState, aTableFrame),
*cellFrame, cellSpacingX, colAvailWidth, cellAvailWidth);
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
@ -1203,6 +1243,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
}
// Now place the child
cellMet.width = colAvailWidth;
FinishReflowChild(aNextFrame, aPresContext, cellMet, cellOrigin.x, 0, 0);
// Notify the table if the cell width changed so it can decide whether to rebalance