зеркало из https://github.com/mozilla/pjs.git
bug 60816 use correct cell when rowspan and colspan overlap. Fix pixel rounding errors. sr=attiansi, r=alexsavulov
This commit is contained in:
Родитель
84c24158b4
Коммит
08cb1a9a29
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче