From ba59a76950e4e09a458a778f8e5b1a5189db826a Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Fri, 1 Sep 2000 01:29:50 +0000 Subject: [PATCH] bug 27529 - round column allocations to even pixel value. bug 18955 - don't allocate a col based on desired content if there is a fixed value. r=peterl. git-svn-id: svn://10.0.0.236/trunk@77825 18797224-902f-48f8-a5cc-f745e15eee43 --- .../table/src/BasicTableLayoutStrategy.cpp | 117 ++++++++++-------- .../html/table/src/BasicTableLayoutStrategy.h | 18 ++- .../table/src/FixedTableLayoutStrategy.cpp | 13 +- .../html/table/src/FixedTableLayoutStrategy.h | 3 +- .../layout/html/table/src/nsTableFrame.cpp | 20 +++ mozilla/layout/html/table/src/nsTableFrame.h | 3 + .../tables/BasicTableLayoutStrategy.cpp | 117 ++++++++++-------- .../layout/tables/BasicTableLayoutStrategy.h | 18 ++- .../tables/FixedTableLayoutStrategy.cpp | 13 +- .../layout/tables/FixedTableLayoutStrategy.h | 3 +- mozilla/layout/tables/nsTableFrame.cpp | 20 +++ mozilla/layout/tables/nsTableFrame.h | 3 + 12 files changed, 216 insertions(+), 132 deletions(-) diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index 533172e14c7..7fa7fcfee3e 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -21,6 +21,7 @@ */ #include "BasicTableLayoutStrategy.h" +#include "nsIPresContext.h" #include "nsTableFrame.h" #include "nsTableColFrame.h" #include "nsTableCellFrame.h" @@ -38,22 +39,22 @@ static PRBool gsDebugBalance = PR_TRUE; #endif static PRInt32 gsDebugCount = 0; +// the logic here is kept in synch with that in CalculateTotals. PRBool CanAllocate(PRInt32 aTypeToAllocate, PRInt32 aTypeAlreadyAllocated, nsTableColFrame* aColFrame, + PRBool aIsNavQuirks, PRBool& aConsiderAdj) { aConsiderAdj = PR_TRUE; if ((aTypeToAllocate == FIX_ADJ) && (aTypeAlreadyAllocated == FIX)) { return PR_TRUE; } - if ((aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX_ADJ)) { + if (aIsNavQuirks && (aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX_ADJ)) { aConsiderAdj = PR_FALSE; - return PR_TRUE; - } - if ((aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX) && - (aColFrame->GetWidth(DES_ADJ) > aColFrame->GetWidth(DES_CON))) { - return PR_TRUE; + if (aColFrame->GetWidth(FIX) <= 0) { // there is no FIX width + return PR_TRUE; + } } return PR_FALSE; } @@ -91,7 +92,9 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex mCellSpacingTotal = 0; mCols = mTableFrame->GetEffectiveCOLSAttribute(); // assign the width of all fixed-width columns - AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState, p2t); // set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths if (nsnull != aMaxElementSize) { @@ -163,6 +166,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont nscoord aMaxWidthIn) { if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d count=%d \n", aMaxWidthIn, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);} + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); ContinuingFrameCheck(); if (!aTableStyle) { @@ -202,7 +207,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont // auto table sizing will get as big as it should nscoord basis = (NS_UNCONSTRAINEDSIZE == maxWidth) ? NS_UNCONSTRAINEDSIZE : maxWidth - mCellSpacingTotal; - perAdjTableWidth = AssignPercentageColumnWidths(basis, tableIsAutoWidth); + perAdjTableWidth = AssignPercentageColumnWidths(basis, tableIsAutoWidth, p2t); } // set the table's columns to the min width @@ -255,7 +260,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, PCT, PR_FALSE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, PCT, PR_FALSE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -266,7 +271,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, FIX, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, FIX, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -277,7 +282,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, FIX_ADJ, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, FIX_ADJ, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -288,7 +293,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, MIN_PRO, PR_FALSE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, MIN_PRO, PR_FALSE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -300,7 +305,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, DES_CON, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, DES_CON, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -326,10 +331,10 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont } } if (tableIsAutoWidth) { - AllocateUnconstrained(perAdjTableWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(perAdjTableWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } else { - AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } } // give the proportional cols the rest up to the max width in quirks mode @@ -339,7 +344,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont allocTypes[colX] = -1; } } - AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } @@ -360,7 +365,7 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated, nscoord newWidth = colFrame->GetWidth(aWidthType); PRBool useAdj; - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -387,7 +392,8 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated, void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount, PRInt32* aAllocTypes, - PRBool aSkip0Proportional) + PRBool aSkip0Proportional, + float aPixelToTwips) { nscoord divisor = 0; PRInt32 numColsAllocated = 0; @@ -412,7 +418,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount, float percent = (divisor == 0) ? (1.0f / ((float)numColsAllocated)) : ((float)oldWidth) / ((float)divisor); - nscoord addition = NSToCoordRound(((float)aAllocAmount) * percent); + nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)aAllocAmount) * percent), aPixelToTwips); if (addition > (aAllocAmount - totalAllocated)) { mTableFrame->SetColumnWidth(colX, oldWidth + (aAllocAmount - totalAllocated)); break; @@ -447,7 +453,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIn PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - nscoord aPercentBase) + nscoord aPercentBase, + float aPixelToTwips) { if (!aCellFrame || (aColIndex < 0) || (aColIndex < 0) || (aColSpan < 0)) { NS_ASSERTION(PR_FALSE, "ComputeColspanWidths called incorrectly"); @@ -483,14 +490,14 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIn // allocate auto cells. for (PRInt32 limitX = LIMIT_CON; limitX <= LIMIT_NONE; limitX++) { if (ComputeColspanWidths(aWidthIndex, aCellFrame, cellWidth, - aColIndex, aColSpan, aConsiderPct, limitX)) { + aColIndex, aColSpan, aConsiderPct, limitX, aPixelToTwips)) { return; } } } else { // for des width, just allocate auto cells ComputeColspanWidths(aWidthIndex, aCellFrame, cellWidth, - aColIndex, aColSpan, aConsiderPct, LIMIT_NONE); + aColIndex, aColSpan, aConsiderPct, LIMIT_NONE, aPixelToTwips); } } @@ -502,7 +509,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - PRInt32 aLimitType) + PRInt32 aLimitType, + float aPixelToTwips) { PRBool result = PR_TRUE; // skip DES_CON if there is a FIX since FIX is really the desired size @@ -664,6 +672,7 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, ? NSToCoordRound( ((float)availWidth) / ((float)aColSpan) ) : NSToCoordRound( (((float)numerator) / ((float)divisor)) * availWidth); if (addition > 0) { + addition = nsTableFrame::RoundToPixel(addition, aPixelToTwips); nscoord newColAdjWidth = colWidth + addition; if (newColAdjWidth > minWidth) { if (FIX == aWidthIndex) { @@ -692,7 +701,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aMaxWidth, - const nsHTMLReflowState& aReflowState) + const nsHTMLReflowState& aReflowState, + float aPixelToTwips) { if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d count=%d \n", aMaxWidth, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);} PRBool rv = PR_FALSE; @@ -860,7 +870,8 @@ BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* } // set MIN_ADJ, DES_ADJ, FIX_ADJ for (PRInt32 widthX = 0; widthX < NUM_MAJOR_WIDTHS; widthX++) { - ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, aReflowState.mComputedWidth); + ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, + aReflowState.mComputedWidth, aPixelToTwips); } } } @@ -891,7 +902,8 @@ BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* // Determine percentage col widths for each col frame nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, - PRBool aTableIsAutoWidth) + PRBool aTableIsAutoWidth, + float aPixelToTwips) { PRInt32 numRows = mTableFrame->GetRowCount(); PRInt32 numCols = mTableFrame->GetColCount(); @@ -938,7 +950,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, cellDesWidth += spanFrame->GetDesWidth(); } // figure the basis using the cell's desired width and percent - colBasis = NSToCoordRound((float)cellDesWidth / percent); + colBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)cellDesWidth / percent), aPixelToTwips); perTotal += percent; } } @@ -951,7 +963,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, colBasis = 0; if (percent > 0.0f) { nscoord desWidth = colFrame->GetDesWidth(); - colBasis = NSToCoordRound((float)desWidth / percent); + colBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)desWidth / percent), aPixelToTwips); } } } @@ -976,7 +988,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, // compute a basis considering total percentages and the desired width of everything else if (perTotal < 1.0f) { if (perTotal > 0.0f) { - nscoord otherBasis = NSToCoordRound((float)prefWidthTotal / (1.0f - perTotal)); + nscoord otherBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)prefWidthTotal / (1.0f - perTotal)), aPixelToTwips); basis = PR_MAX(basis, otherBasis); } } @@ -1030,7 +1042,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, nsStyleCoord colStyleWidth = colFrame->GetStyleWidth(); if (eStyleUnit_Percent == colStyleWidth.GetUnit()) { maxColPct = colStyleWidth.GetPercentValue(); - maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct ); + maxColPctWidth = nsTableFrame::RoundToPixel(NSToCoordRound( ((float)basis) * maxColPct ), aPixelToTwips); } } // conflicting pct/fixed widths are recorded. Nav 4.x may be changing the @@ -1061,7 +1073,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, float cellPct = 0.0f; if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) { cellPct = cellPosition->mWidth.GetPercentValue(); - cellPctWidth = NSToCoordRound( ((float)basis) * cellPct ); + cellPctWidth = nsTableFrame::RoundToPixel(NSToCoordRound( ((float)basis) * cellPct ), aPixelToTwips); if (!mIsNavQuirksMode) { // need to add padding nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame); @@ -1109,7 +1121,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, : (avail / (float)basis) * (((float)colWidth) / (float)spanTotal); if (colPctAdj > 0) { nscoord colPctAdjWidth = colFrame->GetWidth(PCT_ADJ); - nscoord newColPctAdjWidth = NSToCoordRound(colPctAdj * (float)basis); + nscoord newColPctAdjWidth = nsTableFrame::RoundToPixel(NSToCoordRound(colPctAdj * (float)basis), aPixelToTwips); if (newColPctAdjWidth > colPctAdjWidth) { newColPctAdjWidth = PR_MAX(newColPctAdjWidth, minWidth); if (newColPctAdjWidth > colFrame->GetWidth(PCT)) { @@ -1201,7 +1213,8 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const return maxWidth; } -// calculate totals by width type. +// calculate totals by width type. The logic here is kept in synch with +// that in CanAllocate. void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, PRInt32* aTotalCounts, PRInt32* aTotalWidths, @@ -1221,7 +1234,9 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, nscoord spacingX = mTableFrame->GetCellSpacingX(); PRInt32 numCols = mTableFrame->GetColCount(); - for (PRInt32 colX = 0; colX < numCols; colX++) { + PRInt32 colX; + + for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { aCellSpacing += spacingX; @@ -1264,8 +1279,8 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, else { // there was no fix aMinWidths[FIX_ADJ] += minCol; } - // include the DES_CON of a FIX_ADJ that has no FIX - if ((desCon > fixAdj) && (fix <= 0)) { + // include the DES_CON of a FIX_ADJ that has no FIX + if (mIsNavQuirksMode && (desCon > fixAdj) && (fix <= 0)) { aTotalCounts[DES_CON]++; aTotalWidths[DES_CON] += desCon; aTotalAvailWidths[DES_CON] += desCon; @@ -1275,14 +1290,6 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, } } } - else { - nscoord desAdj = colFrame->GetWidth(DES_ADJ); - if ((desAdj > desCon) && (desAdj > fix)) { - aTotalCounts[DES_CON]++; - aTotalWidths[DES_CON] += desAdj; - aTotalAvailWidths[DES_CON] += desAdj - fix; - } - } continue; } @@ -1352,7 +1359,8 @@ void AC_Increase(PRInt32 aNumAutoCols, nsColInfo** aColInfo, PRInt32 aDivisor, - PRInt32& aAvailWidth) + PRInt32& aAvailWidth, + float aPixelToTwips) { for (PRInt32 i = 0; i < aNumAutoCols; i++) { if ((aAvailWidth <= 0) || (aDivisor <= 0)) { @@ -1362,7 +1370,7 @@ AC_Increase(PRInt32 aNumAutoCols, float percent = ((float)aColInfo[i]->mMaxWidth - (float)aColInfo[i]->mMinWidth) / (float)aDivisor; aDivisor -= aColInfo[i]->mMaxWidth - aColInfo[i]->mMinWidth; - nscoord addition = NSToCoordRound(((float)(aAvailWidth)) * percent); + nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)(aAvailWidth)) * percent), aPixelToTwips); // if its the last col, try to give what's left to it if ((i == aNumAutoCols - 1) && (addition < aAvailWidth)) { addition = aAvailWidth; @@ -1380,7 +1388,8 @@ void AC_Decrease(PRInt32 aNumAutoCols, nsColInfo** aColInfo, PRInt32 aDivisor, - PRInt32& aExcess) + PRInt32& aExcess, + float aPixelToTwips) { for (PRInt32 i = 0; i < aNumAutoCols; i++) { if ((aExcess <= 0) || (aDivisor <= 0)) { @@ -1388,7 +1397,7 @@ AC_Decrease(PRInt32 aNumAutoCols, } float percent = ((float)aColInfo[i]->mMaxWidth) / (float)aDivisor; aDivisor -= aColInfo[i]->mMaxWidth; - nscoord reduction = NSToCoordRound(((float)(aExcess)) * percent); + nscoord reduction = nsTableFrame::RoundToPixel(NSToCoordRound(((float)(aExcess)) * percent), aPixelToTwips); // if its the last col, try to remove the remaining excess from it if ((i == aNumAutoCols - 1) && (reduction < aExcess)) { reduction = aExcess; @@ -1422,7 +1431,8 @@ AC_Sort(nsColInfo** aColInfo, PRInt32 aNumCols) void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, PRInt32 aWidthType, PRBool aStartAtMin, - PRInt32* aAllocTypes) + PRInt32* aAllocTypes, + float aPixelToTwips) { if ((0 == aAvailWidth) || (aWidthType < 0) || (aWidthType >= NUM_WIDTHS)) { NS_ASSERTION(PR_TRUE, "invalid args to AllocateConstrained"); @@ -1438,7 +1448,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // find out how many constrained cols there are for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -1463,7 +1473,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // set the col info entries for each constrained col for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -1519,7 +1529,8 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // compute the proportion to be added to each column, don't go beyond the col's // max. This algorithm assumes that the Weight works as stated above - AC_Increase(numConstrainedCols, colInfo, sumMaxConstraints - sumMinConstraints, availWidth); + AC_Increase(numConstrainedCols, colInfo, sumMaxConstraints - sumMinConstraints, + availWidth, aPixelToTwips); } else { // reduce each col width nscoord reduceWidth = maxMinDiff - aAvailWidth; @@ -1542,7 +1553,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // compute the proportion to be subtracted from each column, don't go beyond // the col's min. This algorithm assumes that the Weight works as stated above - AC_Decrease(numConstrainedCols, colInfo, sumMaxConstraints, reduceWidth); + AC_Decrease(numConstrainedCols, colInfo, sumMaxConstraints, reduceWidth, aPixelToTwips); } AC_Wrapup(mTableFrame, numConstrainedCols, colInfo); } diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h index dfe006d8d5d..ae863be38e0 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.h @@ -103,7 +103,8 @@ protected: */ virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState); + const nsHTMLReflowState& aReflowState, + float aPixelToTwips); /** * Calculate the adjusted widths (min, desired, fixed, or pct) for a cell @@ -119,7 +120,8 @@ protected: PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - nscoord aPercentBase); + nscoord aPercentBase, + float aPixelToTwips); /** * main helper for above. For min width calculations, it can get called up to @@ -137,10 +139,12 @@ protected: PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - PRInt32 aLimitType); + PRInt32 aLimitType, + float aPixelToTwips); nscoord AssignPercentageColumnWidths(nscoord aBasis, - PRBool aTableIsAutoWidth); + PRBool aTableIsAutoWidth, + float aPixelToTwips); void CalculateTotals(PRInt32& aCellSpacing, PRInt32* aTotalCounts, @@ -157,11 +161,13 @@ protected: void AllocateConstrained(PRInt32 aAvailWidth, PRInt32 aWidthType, PRBool aStartAtMin, - PRInt32* aAllocTypes); + PRInt32* aAllocTypes, + float aPixelToTwips); void AllocateUnconstrained(PRInt32 aAllocAmount, PRInt32* aAllocTypes, - PRBool aSkip0Proportional); + PRBool aSkip0Proportional, + float aPixelToTwips); /** return true if the colIndex is in the list of colIndexes */ virtual PRBool IsColumnInList(const PRInt32 colIndex, diff --git a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp index 1fdce56dfa9..59176d90813 100644 --- a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.cpp @@ -56,7 +56,8 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aP PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState) + const nsHTMLReflowState& aReflowState, + float aPixelToTwips) { // NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width"); const nsStylePosition* tablePosition; @@ -105,7 +106,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* (aComputedWidth != NS_UNCONSTRAINEDSIZE)) { // Only apply percentages if we're constrained. float percent = colPosition->mWidth.GetPercentValue(); - colWidths[colX] = NSToCoordRound(percent * (float)availWidth); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)availWidth), aPixelToTwips); } else if (eStyleUnit_Proportional == colPosition->mWidth.GetUnit() && colPosition->mWidth.GetIntValue() > 0) { @@ -128,7 +129,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* else if ((eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) && (aComputedWidth != NS_UNCONSTRAINEDSIZE)) { float percent = cellPosition->mWidth.GetPercentValue(); - colWidths[colX] = NSToCoordRound(percent * (float)availWidth / (float)colSpan); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)availWidth / (float)colSpan), aPixelToTwips); } } } @@ -151,7 +152,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* if (propInfo[colX] > 0) { // We're proportional float percent = ((float)propInfo[colX])/((float)propTotal); - colWidths[colX] = NSToCoordRound(percent * (float)remainingWidth); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)remainingWidth), aPixelToTwips); totalColWidth += colWidths[colX]; lastColAllocated = colX; } @@ -160,7 +161,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* else if (tableIsFixedWidth) { if (numCols > specifiedCols) { // allocate the extra space to the columns which have no width specified - nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols))); + nscoord colAlloc = nsTableFrame::RoundToPixel( NSToCoordRound(((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols))), aPixelToTwips); for (colX = 0; colX < numCols; colX++) { if (-1 == colWidths[colX]) { colWidths[colX] = colAlloc; @@ -173,7 +174,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* float divisor = (float)totalColWidth; for (colX = 0; colX < numCols; colX++) { if (colWidths[colX] > 0) { - nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor); + nscoord colAlloc = nsTableFrame::RoundToPixel(NSToCoordRound(remainingWidth * colWidths[colX] / divisor), aPixelToTwips); colWidths[colX] += colAlloc; totalColWidth += colAlloc; lastColAllocated = colX; diff --git a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.h b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.h index 15e5e2cb1fa..e7f5cc8d388 100644 --- a/mozilla/layout/html/table/src/FixedTableLayoutStrategy.h +++ b/mozilla/layout/html/table/src/FixedTableLayoutStrategy.h @@ -98,7 +98,8 @@ protected: */ virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState); + const nsHTMLReflowState& aReflowState, + float aPixelToTwips); }; diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index b98c7963522..fcb2da2bcdb 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -263,6 +263,26 @@ nsTableFrame::Destroy(nsIPresContext* aPresContext) return nsHTMLContainerFrame::Destroy(aPresContext); } +nscoord +nsTableFrame::RoundToPixel(nscoord aValue, + float aPixelToTwips) +{ + nscoord halfPixel = NSToCoordRound(aPixelToTwips / 2.0f); + nscoord fullPixel = NSToCoordRound(aPixelToTwips); + PRInt32 excess = aValue % fullPixel; + if (0 == excess) { + return aValue; + } + else { + if (excess > halfPixel) { + return aValue + (fullPixel - excess); + } + else { + return aValue - excess; + } + } +} + // Helper function. It marks the table frame as dirty and generates // a reflow command nsresult diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index 667b50148a8..2afd120b51b 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -106,6 +106,9 @@ public: nsIFrame* aPrevInFlow); + static nscoord RoundToPixel(nscoord aValue, + float aPixelToTwips); + NS_IMETHOD IsPercentageBase(PRBool& aBase) const; static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext, diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index 533172e14c7..7fa7fcfee3e 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -21,6 +21,7 @@ */ #include "BasicTableLayoutStrategy.h" +#include "nsIPresContext.h" #include "nsTableFrame.h" #include "nsTableColFrame.h" #include "nsTableCellFrame.h" @@ -38,22 +39,22 @@ static PRBool gsDebugBalance = PR_TRUE; #endif static PRInt32 gsDebugCount = 0; +// the logic here is kept in synch with that in CalculateTotals. PRBool CanAllocate(PRInt32 aTypeToAllocate, PRInt32 aTypeAlreadyAllocated, nsTableColFrame* aColFrame, + PRBool aIsNavQuirks, PRBool& aConsiderAdj) { aConsiderAdj = PR_TRUE; if ((aTypeToAllocate == FIX_ADJ) && (aTypeAlreadyAllocated == FIX)) { return PR_TRUE; } - if ((aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX_ADJ)) { + if (aIsNavQuirks && (aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX_ADJ)) { aConsiderAdj = PR_FALSE; - return PR_TRUE; - } - if ((aTypeToAllocate == DES_CON) && (aTypeAlreadyAllocated == FIX) && - (aColFrame->GetWidth(DES_ADJ) > aColFrame->GetWidth(DES_CON))) { - return PR_TRUE; + if (aColFrame->GetWidth(FIX) <= 0) { // there is no FIX width + return PR_TRUE; + } } return PR_FALSE; } @@ -91,7 +92,9 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex mCellSpacingTotal = 0; mCols = mTableFrame->GetEffectiveCOLSAttribute(); // assign the width of all fixed-width columns - AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState); + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); + AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState, p2t); // set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths if (nsnull != aMaxElementSize) { @@ -163,6 +166,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont nscoord aMaxWidthIn) { if (gsDebugBalance) {printf("BalanceColumnWidths en max=%d count=%d \n", aMaxWidthIn, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);} + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); ContinuingFrameCheck(); if (!aTableStyle) { @@ -202,7 +207,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont // auto table sizing will get as big as it should nscoord basis = (NS_UNCONSTRAINEDSIZE == maxWidth) ? NS_UNCONSTRAINEDSIZE : maxWidth - mCellSpacingTotal; - perAdjTableWidth = AssignPercentageColumnWidths(basis, tableIsAutoWidth); + perAdjTableWidth = AssignPercentageColumnWidths(basis, tableIsAutoWidth, p2t); } // set the table's columns to the min width @@ -255,7 +260,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, PCT, PR_FALSE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, PCT, PR_FALSE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -266,7 +271,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, FIX, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, FIX, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -277,7 +282,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, FIX_ADJ, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, FIX_ADJ, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -288,7 +293,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, MIN_PRO, PR_FALSE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, MIN_PRO, PR_FALSE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -300,7 +305,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont //NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated"); } else { - AllocateConstrained(maxWidth - totalAllocated, DES_CON, PR_TRUE, allocTypes); + AllocateConstrained(maxWidth - totalAllocated, DES_CON, PR_TRUE, allocTypes, p2t); return BCW_Wrapup(aPresContext, this, mTableFrame, allocTypes); } } @@ -326,10 +331,10 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont } } if (tableIsAutoWidth) { - AllocateUnconstrained(perAdjTableWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(perAdjTableWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } else { - AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } } // give the proportional cols the rest up to the max width in quirks mode @@ -339,7 +344,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont allocTypes[colX] = -1; } } - AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional); + AllocateUnconstrained(maxWidth - totalAllocated, allocTypes, skip0Proportional, p2t); } @@ -360,7 +365,7 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated, nscoord newWidth = colFrame->GetWidth(aWidthType); PRBool useAdj; - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -387,7 +392,8 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated, void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount, PRInt32* aAllocTypes, - PRBool aSkip0Proportional) + PRBool aSkip0Proportional, + float aPixelToTwips) { nscoord divisor = 0; PRInt32 numColsAllocated = 0; @@ -412,7 +418,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount, float percent = (divisor == 0) ? (1.0f / ((float)numColsAllocated)) : ((float)oldWidth) / ((float)divisor); - nscoord addition = NSToCoordRound(((float)aAllocAmount) * percent); + nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)aAllocAmount) * percent), aPixelToTwips); if (addition > (aAllocAmount - totalAllocated)) { mTableFrame->SetColumnWidth(colX, oldWidth + (aAllocAmount - totalAllocated)); break; @@ -447,7 +453,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIn PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - nscoord aPercentBase) + nscoord aPercentBase, + float aPixelToTwips) { if (!aCellFrame || (aColIndex < 0) || (aColIndex < 0) || (aColSpan < 0)) { NS_ASSERTION(PR_FALSE, "ComputeColspanWidths called incorrectly"); @@ -483,14 +490,14 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIn // allocate auto cells. for (PRInt32 limitX = LIMIT_CON; limitX <= LIMIT_NONE; limitX++) { if (ComputeColspanWidths(aWidthIndex, aCellFrame, cellWidth, - aColIndex, aColSpan, aConsiderPct, limitX)) { + aColIndex, aColSpan, aConsiderPct, limitX, aPixelToTwips)) { return; } } } else { // for des width, just allocate auto cells ComputeColspanWidths(aWidthIndex, aCellFrame, cellWidth, - aColIndex, aColSpan, aConsiderPct, LIMIT_NONE); + aColIndex, aColSpan, aConsiderPct, LIMIT_NONE, aPixelToTwips); } } @@ -502,7 +509,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - PRInt32 aLimitType) + PRInt32 aLimitType, + float aPixelToTwips) { PRBool result = PR_TRUE; // skip DES_CON if there is a FIX since FIX is really the desired size @@ -664,6 +672,7 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, ? NSToCoordRound( ((float)availWidth) / ((float)aColSpan) ) : NSToCoordRound( (((float)numerator) / ((float)divisor)) * availWidth); if (addition > 0) { + addition = nsTableFrame::RoundToPixel(addition, aPixelToTwips); nscoord newColAdjWidth = colWidth + addition; if (newColAdjWidth > minWidth) { if (FIX == aWidthIndex) { @@ -692,7 +701,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex, PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aMaxWidth, - const nsHTMLReflowState& aReflowState) + const nsHTMLReflowState& aReflowState, + float aPixelToTwips) { if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d count=%d \n", aMaxWidth, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);} PRBool rv = PR_FALSE; @@ -860,7 +870,8 @@ BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* } // set MIN_ADJ, DES_ADJ, FIX_ADJ for (PRInt32 widthX = 0; widthX < NUM_MAJOR_WIDTHS; widthX++) { - ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, aReflowState.mComputedWidth); + ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, + aReflowState.mComputedWidth, aPixelToTwips); } } } @@ -891,7 +902,8 @@ BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* // Determine percentage col widths for each col frame nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, - PRBool aTableIsAutoWidth) + PRBool aTableIsAutoWidth, + float aPixelToTwips) { PRInt32 numRows = mTableFrame->GetRowCount(); PRInt32 numCols = mTableFrame->GetColCount(); @@ -938,7 +950,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, cellDesWidth += spanFrame->GetDesWidth(); } // figure the basis using the cell's desired width and percent - colBasis = NSToCoordRound((float)cellDesWidth / percent); + colBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)cellDesWidth / percent), aPixelToTwips); perTotal += percent; } } @@ -951,7 +963,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, colBasis = 0; if (percent > 0.0f) { nscoord desWidth = colFrame->GetDesWidth(); - colBasis = NSToCoordRound((float)desWidth / percent); + colBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)desWidth / percent), aPixelToTwips); } } } @@ -976,7 +988,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, // compute a basis considering total percentages and the desired width of everything else if (perTotal < 1.0f) { if (perTotal > 0.0f) { - nscoord otherBasis = NSToCoordRound((float)prefWidthTotal / (1.0f - perTotal)); + nscoord otherBasis = nsTableFrame::RoundToPixel(NSToCoordRound((float)prefWidthTotal / (1.0f - perTotal)), aPixelToTwips); basis = PR_MAX(basis, otherBasis); } } @@ -1030,7 +1042,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, nsStyleCoord colStyleWidth = colFrame->GetStyleWidth(); if (eStyleUnit_Percent == colStyleWidth.GetUnit()) { maxColPct = colStyleWidth.GetPercentValue(); - maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct ); + maxColPctWidth = nsTableFrame::RoundToPixel(NSToCoordRound( ((float)basis) * maxColPct ), aPixelToTwips); } } // conflicting pct/fixed widths are recorded. Nav 4.x may be changing the @@ -1061,7 +1073,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, float cellPct = 0.0f; if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) { cellPct = cellPosition->mWidth.GetPercentValue(); - cellPctWidth = NSToCoordRound( ((float)basis) * cellPct ); + cellPctWidth = nsTableFrame::RoundToPixel(NSToCoordRound( ((float)basis) * cellPct ), aPixelToTwips); if (!mIsNavQuirksMode) { // need to add padding nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame); @@ -1109,7 +1121,7 @@ BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn, : (avail / (float)basis) * (((float)colWidth) / (float)spanTotal); if (colPctAdj > 0) { nscoord colPctAdjWidth = colFrame->GetWidth(PCT_ADJ); - nscoord newColPctAdjWidth = NSToCoordRound(colPctAdj * (float)basis); + nscoord newColPctAdjWidth = nsTableFrame::RoundToPixel(NSToCoordRound(colPctAdj * (float)basis), aPixelToTwips); if (newColPctAdjWidth > colPctAdjWidth) { newColPctAdjWidth = PR_MAX(newColPctAdjWidth, minWidth); if (newColPctAdjWidth > colFrame->GetWidth(PCT)) { @@ -1201,7 +1213,8 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const return maxWidth; } -// calculate totals by width type. +// calculate totals by width type. The logic here is kept in synch with +// that in CanAllocate. void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, PRInt32* aTotalCounts, PRInt32* aTotalWidths, @@ -1221,7 +1234,9 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, nscoord spacingX = mTableFrame->GetCellSpacingX(); PRInt32 numCols = mTableFrame->GetColCount(); - for (PRInt32 colX = 0; colX < numCols; colX++) { + PRInt32 colX; + + for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { aCellSpacing += spacingX; @@ -1264,8 +1279,8 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, else { // there was no fix aMinWidths[FIX_ADJ] += minCol; } - // include the DES_CON of a FIX_ADJ that has no FIX - if ((desCon > fixAdj) && (fix <= 0)) { + // include the DES_CON of a FIX_ADJ that has no FIX + if (mIsNavQuirksMode && (desCon > fixAdj) && (fix <= 0)) { aTotalCounts[DES_CON]++; aTotalWidths[DES_CON] += desCon; aTotalAvailWidths[DES_CON] += desCon; @@ -1275,14 +1290,6 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32& aCellSpacing, } } } - else { - nscoord desAdj = colFrame->GetWidth(DES_ADJ); - if ((desAdj > desCon) && (desAdj > fix)) { - aTotalCounts[DES_CON]++; - aTotalWidths[DES_CON] += desAdj; - aTotalAvailWidths[DES_CON] += desAdj - fix; - } - } continue; } @@ -1352,7 +1359,8 @@ void AC_Increase(PRInt32 aNumAutoCols, nsColInfo** aColInfo, PRInt32 aDivisor, - PRInt32& aAvailWidth) + PRInt32& aAvailWidth, + float aPixelToTwips) { for (PRInt32 i = 0; i < aNumAutoCols; i++) { if ((aAvailWidth <= 0) || (aDivisor <= 0)) { @@ -1362,7 +1370,7 @@ AC_Increase(PRInt32 aNumAutoCols, float percent = ((float)aColInfo[i]->mMaxWidth - (float)aColInfo[i]->mMinWidth) / (float)aDivisor; aDivisor -= aColInfo[i]->mMaxWidth - aColInfo[i]->mMinWidth; - nscoord addition = NSToCoordRound(((float)(aAvailWidth)) * percent); + nscoord addition = nsTableFrame::RoundToPixel(NSToCoordRound(((float)(aAvailWidth)) * percent), aPixelToTwips); // if its the last col, try to give what's left to it if ((i == aNumAutoCols - 1) && (addition < aAvailWidth)) { addition = aAvailWidth; @@ -1380,7 +1388,8 @@ void AC_Decrease(PRInt32 aNumAutoCols, nsColInfo** aColInfo, PRInt32 aDivisor, - PRInt32& aExcess) + PRInt32& aExcess, + float aPixelToTwips) { for (PRInt32 i = 0; i < aNumAutoCols; i++) { if ((aExcess <= 0) || (aDivisor <= 0)) { @@ -1388,7 +1397,7 @@ AC_Decrease(PRInt32 aNumAutoCols, } float percent = ((float)aColInfo[i]->mMaxWidth) / (float)aDivisor; aDivisor -= aColInfo[i]->mMaxWidth; - nscoord reduction = NSToCoordRound(((float)(aExcess)) * percent); + nscoord reduction = nsTableFrame::RoundToPixel(NSToCoordRound(((float)(aExcess)) * percent), aPixelToTwips); // if its the last col, try to remove the remaining excess from it if ((i == aNumAutoCols - 1) && (reduction < aExcess)) { reduction = aExcess; @@ -1422,7 +1431,8 @@ AC_Sort(nsColInfo** aColInfo, PRInt32 aNumCols) void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, PRInt32 aWidthType, PRBool aStartAtMin, - PRInt32* aAllocTypes) + PRInt32* aAllocTypes, + float aPixelToTwips) { if ((0 == aAvailWidth) || (aWidthType < 0) || (aWidthType >= NUM_WIDTHS)) { NS_ASSERTION(PR_TRUE, "invalid args to AllocateConstrained"); @@ -1438,7 +1448,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // find out how many constrained cols there are for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -1463,7 +1473,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // set the col info entries for each constrained col for (colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, useAdj)) { + if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame, mIsNavQuirksMode, useAdj)) { if (-1 != aAllocTypes[colX]) { continue; } @@ -1519,7 +1529,8 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // compute the proportion to be added to each column, don't go beyond the col's // max. This algorithm assumes that the Weight works as stated above - AC_Increase(numConstrainedCols, colInfo, sumMaxConstraints - sumMinConstraints, availWidth); + AC_Increase(numConstrainedCols, colInfo, sumMaxConstraints - sumMinConstraints, + availWidth, aPixelToTwips); } else { // reduce each col width nscoord reduceWidth = maxMinDiff - aAvailWidth; @@ -1542,7 +1553,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth, // compute the proportion to be subtracted from each column, don't go beyond // the col's min. This algorithm assumes that the Weight works as stated above - AC_Decrease(numConstrainedCols, colInfo, sumMaxConstraints, reduceWidth); + AC_Decrease(numConstrainedCols, colInfo, sumMaxConstraints, reduceWidth, aPixelToTwips); } AC_Wrapup(mTableFrame, numConstrainedCols, colInfo); } diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.h b/mozilla/layout/tables/BasicTableLayoutStrategy.h index dfe006d8d5d..ae863be38e0 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.h +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.h @@ -103,7 +103,8 @@ protected: */ virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState); + const nsHTMLReflowState& aReflowState, + float aPixelToTwips); /** * Calculate the adjusted widths (min, desired, fixed, or pct) for a cell @@ -119,7 +120,8 @@ protected: PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - nscoord aPercentBase); + nscoord aPercentBase, + float aPixelToTwips); /** * main helper for above. For min width calculations, it can get called up to @@ -137,10 +139,12 @@ protected: PRInt32 aColIndex, PRInt32 aColSpan, PRBool aConsiderPct, - PRInt32 aLimitType); + PRInt32 aLimitType, + float aPixelToTwips); nscoord AssignPercentageColumnWidths(nscoord aBasis, - PRBool aTableIsAutoWidth); + PRBool aTableIsAutoWidth, + float aPixelToTwips); void CalculateTotals(PRInt32& aCellSpacing, PRInt32* aTotalCounts, @@ -157,11 +161,13 @@ protected: void AllocateConstrained(PRInt32 aAvailWidth, PRInt32 aWidthType, PRBool aStartAtMin, - PRInt32* aAllocTypes); + PRInt32* aAllocTypes, + float aPixelToTwips); void AllocateUnconstrained(PRInt32 aAllocAmount, PRInt32* aAllocTypes, - PRBool aSkip0Proportional); + PRBool aSkip0Proportional, + float aPixelToTwips); /** return true if the colIndex is in the list of colIndexes */ virtual PRBool IsColumnInList(const PRInt32 colIndex, diff --git a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp index 1fdce56dfa9..59176d90813 100644 --- a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp @@ -56,7 +56,8 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aP PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState) + const nsHTMLReflowState& aReflowState, + float aPixelToTwips) { // NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width"); const nsStylePosition* tablePosition; @@ -105,7 +106,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* (aComputedWidth != NS_UNCONSTRAINEDSIZE)) { // Only apply percentages if we're constrained. float percent = colPosition->mWidth.GetPercentValue(); - colWidths[colX] = NSToCoordRound(percent * (float)availWidth); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)availWidth), aPixelToTwips); } else if (eStyleUnit_Proportional == colPosition->mWidth.GetUnit() && colPosition->mWidth.GetIntValue() > 0) { @@ -128,7 +129,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* else if ((eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) && (aComputedWidth != NS_UNCONSTRAINEDSIZE)) { float percent = cellPosition->mWidth.GetPercentValue(); - colWidths[colX] = NSToCoordRound(percent * (float)availWidth / (float)colSpan); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)availWidth / (float)colSpan), aPixelToTwips); } } } @@ -151,7 +152,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* if (propInfo[colX] > 0) { // We're proportional float percent = ((float)propInfo[colX])/((float)propTotal); - colWidths[colX] = NSToCoordRound(percent * (float)remainingWidth); + colWidths[colX] = nsTableFrame::RoundToPixel(NSToCoordRound(percent * (float)remainingWidth), aPixelToTwips); totalColWidth += colWidths[colX]; lastColAllocated = colX; } @@ -160,7 +161,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* else if (tableIsFixedWidth) { if (numCols > specifiedCols) { // allocate the extra space to the columns which have no width specified - nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols))); + nscoord colAlloc = nsTableFrame::RoundToPixel( NSToCoordRound(((float)remainingWidth) / (((float)numCols) - ((float)specifiedCols))), aPixelToTwips); for (colX = 0; colX < numCols; colX++) { if (-1 == colWidths[colX]) { colWidths[colX] = colAlloc; @@ -173,7 +174,7 @@ FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* float divisor = (float)totalColWidth; for (colX = 0; colX < numCols; colX++) { if (colWidths[colX] > 0) { - nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor); + nscoord colAlloc = nsTableFrame::RoundToPixel(NSToCoordRound(remainingWidth * colWidths[colX] / divisor), aPixelToTwips); colWidths[colX] += colAlloc; totalColWidth += colAlloc; lastColAllocated = colX; diff --git a/mozilla/layout/tables/FixedTableLayoutStrategy.h b/mozilla/layout/tables/FixedTableLayoutStrategy.h index 15e5e2cb1fa..e7f5cc8d388 100644 --- a/mozilla/layout/tables/FixedTableLayoutStrategy.h +++ b/mozilla/layout/tables/FixedTableLayoutStrategy.h @@ -98,7 +98,8 @@ protected: */ virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext, nscoord aComputedWidth, - const nsHTMLReflowState& aReflowState); + const nsHTMLReflowState& aReflowState, + float aPixelToTwips); }; diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index b98c7963522..fcb2da2bcdb 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -263,6 +263,26 @@ nsTableFrame::Destroy(nsIPresContext* aPresContext) return nsHTMLContainerFrame::Destroy(aPresContext); } +nscoord +nsTableFrame::RoundToPixel(nscoord aValue, + float aPixelToTwips) +{ + nscoord halfPixel = NSToCoordRound(aPixelToTwips / 2.0f); + nscoord fullPixel = NSToCoordRound(aPixelToTwips); + PRInt32 excess = aValue % fullPixel; + if (0 == excess) { + return aValue; + } + else { + if (excess > halfPixel) { + return aValue + (fullPixel - excess); + } + else { + return aValue - excess; + } + } +} + // Helper function. It marks the table frame as dirty and generates // a reflow command nsresult diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 667b50148a8..2afd120b51b 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -106,6 +106,9 @@ public: nsIFrame* aPrevInFlow); + static nscoord RoundToPixel(nscoord aValue, + float aPixelToTwips); + NS_IMETHOD IsPercentageBase(PRBool& aBase) const; static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext,