From b48cdf9fa0f0df82b68dbda7e3620d8c5ccbf76a Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Sun, 15 Jun 2014 00:53:00 +0200 Subject: [PATCH] Bug 330964 - Make nsTableFrame::GetCellSpacing[XY] take an argument. r=roc --- layout/tables/BasicTableLayoutStrategy.cpp | 19 ++-- layout/tables/FixedTableLayoutStrategy.cpp | 10 +- layout/tables/nsTableCellFrame.cpp | 5 +- layout/tables/nsTableFrame.cpp | 105 ++++++++++++++++----- layout/tables/nsTableFrame.h | 64 ++++++++++++- layout/tables/nsTableRowFrame.cpp | 37 ++++---- layout/tables/nsTableRowGroupFrame.cpp | 27 +++--- 7 files changed, 188 insertions(+), 79 deletions(-) diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index f1cfb9b14582..7fbff211e7dc 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -435,9 +435,9 @@ BasicTableLayoutStrategy::ComputeIntrinsicWidths(nsRenderingContext* aRenderingC nscoord min = 0, pref = 0, max_small_pct_pref = 0, nonpct_pref_total = 0; float pct_total = 0.0f; // always from 0.0f - 1.0f int32_t colCount = cellMap->GetColCount(); - nscoord spacing = mTableFrame->GetCellSpacingX(); - nscoord add = spacing; // add (colcount + 1) * spacing for columns - // where a cell originates + // add a total of (colcount + 1) lots of cellSpacingX for columns where a + // cell originates + nscoord add = mTableFrame->GetCellSpacingX(colCount); for (int32_t col = 0; col < colCount; ++col) { nsTableColFrame *colFrame = mTableFrame->GetColFrame(col); @@ -446,7 +446,7 @@ BasicTableLayoutStrategy::ComputeIntrinsicWidths(nsRenderingContext* aRenderingC continue; } if (mTableFrame->ColumnHasCellSpacingBefore(col)) { - add += spacing; + add += mTableFrame->GetCellSpacingX(col - 1); } min += colFrame->GetMinCoord(); pref = NSCoordSaturatingAdd(pref, colFrame->GetPrefCoord()); @@ -654,22 +654,23 @@ BasicTableLayoutStrategy::DistributeWidthToColumns(nscoord aWidth, aColCount == mTableFrame->GetCellMap()->GetColCount()), "Computing final column widths, but didn't get full column range"); - // border-spacing isn't part of the basis for percentages. - nscoord spacing = mTableFrame->GetCellSpacingX(); - nscoord subtract = 0; + + nscoord subtract = 0; // aWidth initially includes border-spacing for the boundaries in between // each of the columns. We start at aFirstCol + 1 because the first // in-between boundary would be at the left edge of column aFirstCol + 1 for (int32_t col = aFirstCol + 1; col < aFirstCol + aColCount; ++col) { if (mTableFrame->ColumnHasCellSpacingBefore(col)) { - subtract += spacing; + // border-spacing isn't part of the basis for percentages. + subtract += mTableFrame->GetCellSpacingX(col - 1); } } if (aWidthType == BTLS_FINAL_WIDTH) { // If we're computing final col-width, then aWidth initially includes // border spacing on the table's far left + far right edge, too. Need // to subtract those out, too. - subtract += spacing * 2; + subtract += (mTableFrame->GetCellSpacingX(-1) + + mTableFrame->GetCellSpacingX(aColCount)); } aWidth = NSCoordSaturatingSubtract(aWidth, subtract, nscoord_MAX); diff --git a/layout/tables/FixedTableLayoutStrategy.cpp b/layout/tables/FixedTableLayoutStrategy.cpp index ad686f15231f..316b9c9eb28d 100644 --- a/layout/tables/FixedTableLayoutStrategy.cpp +++ b/layout/tables/FixedTableLayoutStrategy.cpp @@ -51,12 +51,11 @@ FixedTableLayoutStrategy::GetMinWidth(nsRenderingContext* aRenderingContext) nsTableCellMap *cellMap = mTableFrame->GetCellMap(); int32_t colCount = cellMap->GetColCount(); - nscoord spacing = mTableFrame->GetCellSpacingX(); nscoord result = 0; if (colCount > 0) { - result += spacing * (colCount + 1); + result += mTableFrame->GetCellSpacingX(-1, colCount); } for (int32_t col = 0; col < colCount; ++col) { @@ -65,6 +64,7 @@ FixedTableLayoutStrategy::GetMinWidth(nsRenderingContext* aRenderingContext) NS_ERROR("column frames out of sync with cell map"); continue; } + nscoord spacing = mTableFrame->GetCellSpacingX(col); const nsStyleCoord *styleWidth = &colFrame->StylePosition()->mWidth; if (styleWidth->ConvertsToLength()) { @@ -161,7 +161,6 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt nsTableCellMap *cellMap = mTableFrame->GetCellMap(); int32_t colCount = cellMap->GetColCount(); - nscoord spacing = mTableFrame->GetCellSpacingX(); if (colCount == 0) { // No Columns - nothing to compute @@ -169,8 +168,8 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt } // border-spacing isn't part of the basis for percentages. - tableWidth -= spacing * (colCount + 1); - + tableWidth -= mTableFrame->GetCellSpacingX(-1, colCount); + // store the old column widths. We might call multiple times SetFinalWidth // on the columns, due to this we can't compare at the last call that the // width has changed with the respect to the last call to @@ -281,6 +280,7 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt // row, split up the space evenly. (XXX This // isn't quite right if some of the columns it's // in have specified widths. Should we care?) + nscoord spacing = mTableFrame->GetCellSpacingX(col); colWidth = ((colWidth + spacing) / colSpan) - spacing; if (colWidth < 0) colWidth = 0; diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 9e2aec71fa68..ab8f4fd55837 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -828,9 +828,10 @@ CalcUnpaginagedHeight(nsPresContext* aPresContext, int32_t rowIndex; firstCellInFlow->GetRowIndex(rowIndex); int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(*firstCellInFlow); - nscoord cellSpacing = firstTableInFlow->GetCellSpacingY(); - nscoord computedHeight = ((rowSpan - 1) * cellSpacing) - aVerticalBorderPadding; + nscoord computedHeight = firstTableInFlow->GetCellSpacingY(rowIndex, + rowIndex + rowSpan - 1); + computedHeight -= aVerticalBorderPadding; int32_t rowX; for (row = firstRGInFlow->GetFirstRow(), rowX = 0; row; row = row->GetNextRow(), rowX++) { if (rowX > rowIndex + rowSpan - 1) { diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index abab8071c5cb..8ccec7bcf184 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -84,22 +84,24 @@ struct nsTableReflowState { { nsTableFrame* table = static_cast(aTableFrame.FirstInFlow()); nsMargin borderPadding = table->GetChildAreaOffset(&reflowState); - nscoord cellSpacingX = table->GetCellSpacingX(); - x = borderPadding.left + cellSpacingX; + x = borderPadding.left + table->GetCellSpacingX(-1); y = borderPadding.top; //cellspacing added during reflow availSize.width = aAvailWidth; if (NS_UNCONSTRAINEDSIZE != availSize.width) { + int32_t colCount = table->GetColCount(); availSize.width -= borderPadding.left + borderPadding.right - + (2 * cellSpacingX); + + table->GetCellSpacingX(-1) + + table->GetCellSpacingX(colCount); availSize.width = std::max(0, availSize.width); } availSize.height = aAvailHeight; if (NS_UNCONSTRAINEDSIZE != availSize.height) { availSize.height -= borderPadding.top + borderPadding.bottom - + (2 * table->GetCellSpacingY()); + + table->GetCellSpacingY(-1) + + table->GetCellSpacingY(table->GetRowCount()); availSize.height = std::max(0, availSize.height); } } @@ -1419,18 +1421,18 @@ void nsTableFrame::SetColumnDimensions(nscoord aHeight, const nsMargin& aBorderPadding) { - nscoord cellSpacingX = GetCellSpacingX(); - nscoord cellSpacingY = GetCellSpacingY(); nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom + - 2* cellSpacingY; + GetCellSpacingY(-1) + + GetCellSpacingY(GetRowCount()); nsTableIterator iter(mColGroups); nsIFrame* colGroupFrame = iter.First(); bool tableIsLTR = StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR; int32_t colX =tableIsLTR ? 0 : std::max(0, GetColCount() - 1); + nscoord cellSpacingX = GetCellSpacingX(colX); int32_t tableColIncr = tableIsLTR ? 1 : -1; - nsPoint colGroupOrigin(aBorderPadding.left + cellSpacingX, - aBorderPadding.top + cellSpacingY); + nsPoint colGroupOrigin(aBorderPadding.left + GetCellSpacingX(-1), + aBorderPadding.top + GetCellSpacingY(-1)); while (colGroupFrame) { MOZ_ASSERT(colGroupFrame->GetType() == nsGkAtoms::tableColGroupFrame); nscoord colGroupWidth = 0; @@ -1444,6 +1446,7 @@ nsTableFrame::SetColumnDimensions(nscoord aHeight, nscoord colWidth = GetColumnWidth(colX); nsRect colRect(colOrigin.x, colOrigin.y, colWidth, colHeight); colFrame->SetRect(colRect); + cellSpacingX = GetCellSpacingX(colX); colOrigin.x += colWidth + cellSpacingX; colGroupWidth += colWidth + cellSpacingX; colX += tableColIncr; @@ -1855,7 +1858,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext, if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { // if there is an incomplete child, then set the desired height to include it but not the next one nsMargin borderPadding = GetChildAreaOffset(&aReflowState); - aDesiredSize.Height() = borderPadding.bottom + GetCellSpacingY() + + aDesiredSize.Height() = borderPadding.bottom + GetCellSpacingY(GetRowCount()) + lastChildReflowed->GetRect().YMost(); } haveDesiredHeight = true; @@ -2109,7 +2112,8 @@ nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize, nsTableFrame* firstInFlow = static_cast(FirstInFlow()); nscoord width = firstInFlow->GetCollapsedWidth(aBorderPadding); - nscoord rgWidth = width - 2 * GetCellSpacingX(); + nscoord rgWidth = width - GetCellSpacingX(-1) - + GetCellSpacingX(GetColCount()); nsOverflowAreas overflow; // Walk the list of children for (uint32_t childX = 0; childX < rowGroups.Length(); childX++) { @@ -2131,8 +2135,7 @@ nscoord nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding) { NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedWidth called on next in flow"); - nscoord cellSpacingX = GetCellSpacingX(); - nscoord width = cellSpacingX; + nscoord width = GetCellSpacingX(GetColCount()); width += aBorderPadding.left + aBorderPadding.right; for (nsIFrame* groupFrame = mColGroups.FirstChild(); groupFrame; groupFrame = groupFrame->GetNextSibling()) { @@ -2150,7 +2153,7 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding) if (!collapseGroup && !collapseCol) { width += colWidth; if (ColumnHasCellSpacingBefore(colX)) - width += cellSpacingX; + width += GetCellSpacingX(colX-1); } else { SetNeedToCollapse(true); @@ -2838,7 +2841,7 @@ nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState, -1, -1, nsHTMLReflowState::CALLER_WILL_INIT); InitChildReflowState(footerReflowState); - aReflowState.y += GetCellSpacingY(); + aReflowState.y += GetCellSpacingY(GetRowCount()); nsRect origTfootRect = aTfoot->GetRect(); nsRect origTfootVisualOverflow = aTfoot->GetVisualOverflowRect(); @@ -2864,7 +2867,6 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, aLastChildReflowed = nullptr; nsIFrame* prevKidFrame = nullptr; - nscoord cellSpacingY = GetCellSpacingY(); nsPresContext* presContext = PresContext(); // XXXldb Should we be checking constrained height instead? @@ -2912,6 +2914,9 @@ nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState, bool allowRepeatedFooter = false; for (size_t childX = 0; childX < rowGroups.Length(); childX++) { nsIFrame* kidFrame = rowGroups[childX]; + nsTableRowGroupFrame* rowGroupFrame = rowGroups[childX]; + nscoord cellSpacingY = GetCellSpacingY(rowGroupFrame->GetStartRowIndex()+ + rowGroupFrame->GetRowCount()); // Get the frame state bits // See if we should only reflow the dirty child frames if (reflowAllKids || @@ -3167,7 +3172,6 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef aDesiredSize.Height() = 0; return; } - nscoord cellSpacingY = GetCellSpacingY(); nsMargin borderPadding = GetChildAreaOffset(&aReflowState); // get the natural height based on the last child's (row group) rect @@ -3190,9 +3194,11 @@ nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLRef int32_t colCount = cellMap->GetColCount(); nscoord desiredHeight = borderPadding.top + borderPadding.bottom; if (rowCount > 0 && colCount > 0) { - desiredHeight += cellSpacingY; + desiredHeight += GetCellSpacingY(-1); for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) { - desiredHeight += rowGroups[rgX]->GetSize().height + cellSpacingY; + desiredHeight += rowGroups[rgX]->GetSize().height + + GetCellSpacingY(rowGroups[rgX]->GetRowCount() + + rowGroups[rgX]->GetStartRowIndex()); } } @@ -3252,8 +3258,6 @@ void nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, nscoord aAmount) { - nscoord cellSpacingY = GetCellSpacingY(); - nsMargin borderPadding = GetChildAreaOffset(&aReflowState); RowGroupArray rowGroups; @@ -3263,8 +3267,8 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, // distribute space to each pct height row whose row group doesn't have a computed // height, and base the pct on the table height. If the row group had a computed // height, then this was already done in nsTableRowGroupFrame::CalculateRowHeights - nscoord pctBasis = aReflowState.ComputedHeight() - (GetCellSpacingY() * (GetRowCount() + 1)); - nscoord yOriginRG = borderPadding.top + GetCellSpacingY(); + nscoord pctBasis = aReflowState.ComputedHeight() - GetCellSpacingY(-1, GetRowCount()); + nscoord yOriginRG = borderPadding.top + GetCellSpacingY(0); nscoord yEndRG = yOriginRG; uint32_t rgX; for (rgX = 0; rgX < rowGroups.Length(); rgX++) { @@ -3276,6 +3280,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { nsRect rowRect = rowFrame->GetRect(); + nscoord cellSpacingY = GetCellSpacingY(rowFrame->GetRowIndex()); if ((amountUsed < aAmount) && rowFrame->HasPctHeight()) { nscoord pctHeight = rowFrame->GetHeight(pctBasis); nscoord amountForRow = std::min(aAmount - amountUsed, pctHeight - rowRect.height); @@ -3401,7 +3406,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, } // allocate the extra height to the unstyled row groups and rows nscoord heightToDistribute = aAmount - amountUsed; - yOriginRG = borderPadding.top + cellSpacingY; + yOriginRG = borderPadding.top + GetCellSpacingY(-1); yEndRG = yOriginRG; for (rgX = 0; rgX < rowGroups.Length(); rgX++) { nsTableRowGroupFrame* rgFrame = rowGroups[rgX]; @@ -3413,6 +3418,7 @@ nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState, if (!firstUnStyledRG || !rgFrame->HasStyleHeight() || !eligibleRows) { nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); while (rowFrame) { + nscoord cellSpacingY = GetCellSpacingY(rowFrame->GetRowIndex()); nsRect rowRect = rowFrame->GetRect(); nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect(); // see if there is an eligible row or we distribute to all rows @@ -3507,7 +3513,6 @@ int32_t nsTableFrame::GetColumnWidth(int32_t aColIndex) return firstInFlow->GetColumnWidth(aColIndex); } -// XXX: could cache this. But be sure to check style changes if you do! nscoord nsTableFrame::GetCellSpacingX() { if (IsBorderCollapse()) @@ -3516,7 +3521,31 @@ nscoord nsTableFrame::GetCellSpacingX() return StyleTableBorder()->mBorderSpacingX; } -// XXX: could cache this. But be sure to check style changes if you do! +// XXX: could cache this. But be sure to check style changes if you do! +nscoord nsTableFrame::GetCellSpacingX(int32_t aColIndex) +{ + NS_ASSERTION(aColIndex >= -1 && aColIndex <= GetColCount(), + "Column index exceeds the bounds of the table"); + // Index is irrelevant for ordinary tables. We check that it falls within + // appropriate bounds to increase confidence of correctness in situations + // where it does matter. + return GetCellSpacingX(); +} + +nscoord nsTableFrame::GetCellSpacingX(int32_t aStartColIndex, + int32_t aEndColIndex) +{ + NS_ASSERTION(aStartColIndex >= -1 && aStartColIndex <= GetColCount(), + "Start column index exceeds the bounds of the table"); + NS_ASSERTION(aEndColIndex >= -1 && aEndColIndex <= GetColCount(), + "End column index exceeds the bounds of the table"); + NS_ASSERTION(aStartColIndex <= aEndColIndex, + "End index must not be less than start index"); + // Only one possible value so just multiply it out. Tables where index + // matters will override this function + return GetCellSpacingX() * (aEndColIndex - aStartColIndex); +} + nscoord nsTableFrame::GetCellSpacingY() { if (IsBorderCollapse()) @@ -3525,6 +3554,30 @@ nscoord nsTableFrame::GetCellSpacingY() return StyleTableBorder()->mBorderSpacingY; } +// XXX: could cache this. But be sure to check style changes if you do! +nscoord nsTableFrame::GetCellSpacingY(int32_t aRowIndex) +{ + NS_ASSERTION(aRowIndex >= -1 && aRowIndex <= GetRowCount(), + "Row index exceeds the bounds of the table"); + // Index is irrelevant for ordinary tables. We check that it falls within + // appropriate bounds to increase confidence of correctness in situations + // where it does matter. + return GetCellSpacingY(); +} + +nscoord nsTableFrame::GetCellSpacingY(int32_t aStartRowIndex, + int32_t aEndRowIndex) +{ + NS_ASSERTION(aStartRowIndex >= -1 && aStartRowIndex <= GetRowCount(), + "Start row index exceeds the bounds of the table"); + NS_ASSERTION(aEndRowIndex >= -1 && aEndRowIndex <= GetRowCount(), + "End row index exceeds the bounds of the table"); + NS_ASSERTION(aStartRowIndex <= aEndRowIndex, + "End index must not be less than start index"); + // Only one possible value so just multiply it out. Tables where index + // matters will override this function + return GetCellSpacingY() * (aEndRowIndex - aStartRowIndex); +} /* virtual */ nscoord nsTableFrame::GetBaseline() const diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index 01e8ccaf138c..99b03bf236ea 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -373,12 +373,68 @@ public: /** return the width of the column at aColIndex */ int32_t GetColumnWidth(int32_t aColIndex); - /** helper to get the cell spacing X style value */ - nscoord GetCellSpacingX(); + /** Helper to get the cell spacing X style value. + * The argument refers to the space between column aColIndex and column + * aColIndex + 1. An index of -1 indicates the padding between the table + * and the left border, an index equal to the number of columns indicates + * the padding between the table and the right border. + * + * Although in this class cell spacing does not depend on the index, it + * may be important for overriding classes. + */ + virtual nscoord GetCellSpacingX(int32_t aColIndex); - /** helper to get the cell spacing Y style value */ + /** Helper to find the sum of the cell spacing between arbitrary columns. + * The argument refers to the space between column aColIndex and column + * aColIndex + 1. An index of -1 indicates the padding between the table + * and the left border, an index equal to the number of columns indicates + * the padding between the table and the right border. + * + * This method is equivalent to + * nscoord result = 0; + * for (i = aStartColIndex; i < aEndColIndex; i++) { + * result += GetCellSpacingX(i); + * } + * return result; + */ + virtual nscoord GetCellSpacingX(int32_t aStartColIndex, + int32_t aEndColIndex); + + /** Helper to get the cell spacing Y style value. + * The argument refers to the space between row aRowIndex and row + * aRowIndex + 1. An index of -1 indicates the padding between the table + * and the top border, an index equal to the number of rows indicates + * the padding between the table and the bottom border. + * + * Although in this class cell spacing does not depend on the index, it + * may be important for overriding classes. + */ + virtual nscoord GetCellSpacingY(int32_t aRowIndex); + + /** Helper to find the sum of the cell spacing between arbitrary rows. + * The argument refers to the space between row aRowIndex and row + * aRowIndex + 1. An index of -1 indicates the padding between the table + * and the top border, an index equal to the number of rows indicates + * the padding between the table and the bottom border. + * + * This method is equivalent to + * nscoord result = 0; + * for (i = aStartRowIndex; i < aEndRowIndex; i++) { + * result += GetCellSpacingY(i); + * } + * return result; + */ + virtual nscoord GetCellSpacingY(int32_t aStartRowIndex, + int32_t aEndRowIndex); + +private: + /* For the base implementation of nsTableFrame, cell spacing does not depend + * on row/column indexing. + */ + nscoord GetCellSpacingX(); nscoord GetCellSpacingY(); - + +public: virtual nscoord GetBaseline() const MOZ_OVERRIDE; /** return the row span of a cell, taking into account row span magic at the bottom * of a table. The row span equals the number of rows spanned by aCell starting at diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 3a24a9407b88..40691e3e3ee2 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -276,7 +276,6 @@ GetHeightOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame, nsTableFrame& aTableFrame) { nscoord height = 0; - nscoord cellSpacingY = aTableFrame.GetCellSpacingY(); int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(aTableCellFrame); // add in height of rows spanned beyond the 1st one nsIFrame* nextRow = aTableCellFrame.GetParent()->GetNextSibling(); @@ -285,7 +284,7 @@ GetHeightOfRowsSpannedBelowFirst(nsTableCellFrame& aTableCellFrame, height += nextRow->GetSize().height; rowX++; } - height += cellSpacingY; + height += aTableFrame.GetCellSpacingY(rowX); nextRow = nextRow->GetNextSibling(); } return height; @@ -682,8 +681,7 @@ nsTableRowFrame::CalculateCellActualHeight(nsTableCellFrame* aCellFrame, // column widths taking into account column spans and column spacing static nscoord CalcAvailWidth(nsTableFrame& aTableFrame, - nsTableCellFrame& aCellFrame, - nscoord aCellSpacingX) + nsTableCellFrame& aCellFrame) { nscoord cellAvailWidth = 0; int32_t colIndex; @@ -695,7 +693,7 @@ CalcAvailWidth(nsTableFrame& aTableFrame, cellAvailWidth += aTableFrame.GetColumnWidth(colIndex + spanX); if (spanX > 0 && aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) { - cellAvailWidth += aCellSpacingX; + cellAvailWidth += aTableFrame.GetCellSpacingX(colIndex + spanX - 1); } } return cellAvailWidth; @@ -706,7 +704,6 @@ GetSpaceBetween(int32_t aPrevColIndex, int32_t aColIndex, int32_t aColSpan, nsTableFrame& aTableFrame, - nscoord aCellSpacingX, bool aIsLeftToRight, bool aCheckVisibility) { @@ -731,7 +728,7 @@ GetSpaceBetween(int32_t aPrevColIndex, space += aTableFrame.GetColumnWidth(colX); } if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) { - space += aCellSpacingX; + space += aTableFrame.GetCellSpacingX(colX - 1); } } } @@ -755,7 +752,7 @@ GetSpaceBetween(int32_t aPrevColIndex, space += aTableFrame.GetColumnWidth(colX); } if (!isCollapsed && aTableFrame.ColumnHasCellSpacingBefore(colX)) { - space += aCellSpacingX; + space += aTableFrame.GetCellSpacingX(colX - 1); } } } @@ -793,7 +790,6 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, const bool isPaginated = aPresContext->IsPaginated(); const bool borderCollapse = aTableFrame.IsBorderCollapse(); - nscoord cellSpacingX = aTableFrame.GetCellSpacingX(); int32_t cellColSpan = 1; // must be defined here so it's set properly for non-cell kids nsTableIterator iter(*this); @@ -855,7 +851,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) || (!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) { x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame, - cellSpacingX, iter.IsLeftToRight(), false); + iter.IsLeftToRight(), false); } // remember the rightmost (ltr) or leftmost (rtl) column this cell spans into @@ -870,7 +866,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, if (doReflowChild) { // Calculate the available width for the table cell using the known column widths nscoord availCellWidth = - CalcAvailWidth(aTableFrame, *cellFrame, cellSpacingX); + CalcAvailWidth(aTableFrame, *cellFrame); nsHTMLReflowMetrics desiredSize(aReflowState); @@ -979,7 +975,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, } } ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame); - x += cellSpacingX; + x += aTableFrame.GetCellSpacingX(cellColIndex); } // just set our width to what was available. The table will calculate the width and not use our value. @@ -1144,13 +1140,13 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, rowRect.width = aWidth; nsOverflowAreas overflow; nscoord shift = 0; - nscoord cellSpacingX = tableFrame->GetCellSpacingX(); - nscoord cellSpacingY = tableFrame->GetCellSpacingY(); if (aCollapseGroup || collapseRow) { nsTableCellFrame* cellFrame = GetFirstCell(); aDidCollapse = true; - shift = rowRect.height + cellSpacingY; + int32_t rowIndex; + cellFrame->GetRowIndex(rowIndex); + shift = rowRect.height + tableFrame->GetCellSpacingY(rowIndex); while (cellFrame) { nsRect cRect = cellFrame->GetRect(); // If aRowOffset != 0, there's no point in invalidating the cells, since @@ -1177,8 +1173,6 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, int32_t colIncrement = iter.IsLeftToRight() ? 1 : -1; - //nscoord x = cellSpacingX; - nsIFrame* kidFrame = iter.First(); while (kidFrame) { nsTableCellFrame *cellFrame = do_QueryFrame(kidFrame); @@ -1193,7 +1187,7 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, (!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) { x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, - *tableFrame, cellSpacingX, iter.IsLeftToRight(), + *tableFrame, iter.IsLeftToRight(), true); } nsRect cRect(x, 0, 0, rowRect.height); @@ -1228,14 +1222,14 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, nextColFrame->StyleVisibility(); if ( (NS_STYLE_VISIBILITY_COLLAPSE != nextColVis->mVisible) && tableFrame->ColumnHasCellSpacingBefore(colX + colIncrement)) { - cRect.width += cellSpacingX; + cRect.width += tableFrame->GetCellSpacingX(cellColIndex); } } } } x += cRect.width; if (isVisible) - x += cellSpacingX; + x += tableFrame->GetCellSpacingX(cellColIndex); int32_t actualRowSpan = tableFrame->GetEffectiveRowSpan(*cellFrame); nsTableRowFrame* rowFrame = GetNextRow(); for (actualRowSpan--; actualRowSpan > 0 && rowFrame; actualRowSpan--) { @@ -1244,7 +1238,8 @@ nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset, nextRowVis->mVisible); if (!collapseNextRow) { nsRect nextRect = rowFrame->GetRect(); - cRect.height += nextRect.height + cellSpacingY; + cRect.height += nextRect.height + + tableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); } rowFrame = rowFrame->GetNextRow(); } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index c0d8951ac8b7..d7d74ef3300a 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -341,7 +341,6 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); const bool borderCollapse = tableFrame->IsBorderCollapse(); - nscoord cellSpacingY = tableFrame->GetCellSpacingY(); // XXXldb Should we really be checking this rather than available height? // (Think about multi-column layout!) @@ -362,7 +361,7 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, NS_NOTREACHED("yikes, a non-row child"); continue; } - + nscoord cellSpacingY = tableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); haveRow = true; // Reflow the row frame @@ -453,7 +452,8 @@ nsTableRowGroupFrame::ReflowChildren(nsPresContext* aPresContext, } if (haveRow) - aReflowState.y -= cellSpacingY; + aReflowState.y -= tableFrame->GetCellSpacingY(GetStartRowIndex() + + GetRowCount()); // Return our desired rect aDesiredSize.Width() = aReflowState.reflowState.AvailableWidth(); @@ -537,9 +537,6 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); const bool isPaginated = aPresContext->IsPaginated(); - // all table cells have the same top and bottom margins, namely cellSpacingY - nscoord cellSpacingY = tableFrame->GetCellSpacingY(); - int32_t numEffCols = tableFrame->GetEffectiveColCount(); int32_t startRowIndex = GetStartRowIndex(); @@ -619,6 +616,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, nsTableCellFrame* cellFrame = rowFrame->GetFirstCell(); // iteratate the row's cell frames while (cellFrame) { + nscoord cellSpacingY = tableFrame->GetCellSpacingY(startRowIndex + rowIndex); int32_t rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex, *cellFrame); if ((rowIndex + rowSpan) > numRows) { // there might be rows pushed already to the nextInFlow @@ -736,7 +734,8 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, } bool styleHeightAllocation = false; - nscoord rowGroupHeight = startRowGroupHeight + heightOfRows + ((numRows - 1) * cellSpacingY); + nscoord rowGroupHeight = startRowGroupHeight + heightOfRows + + tableFrame->GetCellSpacingY(0, numRows-1); // if we have a style height, allocate the extra height to unconstrained rows if ((aReflowState.ComputedHeight() > rowGroupHeight) && (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight())) { @@ -795,7 +794,7 @@ nsTableRowGroupFrame::CalculateRowHeights(nsPresContext* aPresContext, nsTableFrame::RePositionViews(rowFrame); // XXXbz we don't need to update our overflow area? } - yOrigin += rowHeight + cellSpacingY; + yOrigin += rowHeight + tableFrame->GetCellSpacingY(startRowIndex + rowIndex); } if (isPaginated && styleHeightAllocation) { @@ -839,7 +838,8 @@ nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset, groupRect.height -= yGroupOffset; if (didCollapse) { // add back the cellspacing between rowgroups - groupRect.height += tableFrame->GetCellSpacingY(); + groupRect.height += tableFrame->GetCellSpacingY(GetStartRowIndex() + + GetRowCount()); } groupRect.y -= aYTotalOffset; @@ -1050,7 +1050,6 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, nscoord availHeight = aReflowState.AvailableHeight(); const bool borderCollapse = aTableFrame->IsBorderCollapse(); - nscoord cellSpacingY = aTableFrame->GetCellSpacingY(); // get the page height nscoord pageHeight = aPresContext->GetPageSize().height; @@ -1068,6 +1067,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, // in the available space for (nsTableRowFrame* rowFrame = firstRowThisPage; rowFrame; rowFrame = rowFrame->GetNextRow()) { bool rowIsOnPage = true; + nscoord cellSpacingY = aTableFrame->GetCellSpacingY(rowFrame->GetRowIndex()); nsRect rowRect = rowFrame->GetRect(); // See if the row fits on this page if (rowRect.YMost() > availHeight) { @@ -1512,8 +1512,11 @@ nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState) { nscoord result = 0; nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); + int32_t startRowIndex = GetStartRowIndex(); if ((aReflowState.ComputedHeight() > 0) && (aReflowState.ComputedHeight() < NS_UNCONSTRAINEDSIZE)) { - nscoord cellSpacing = std::max(0, GetRowCount() - 1) * tableFrame->GetCellSpacingY(); + nscoord cellSpacing = tableFrame->GetCellSpacingY(startRowIndex, + std::max(startRowIndex, + startRowIndex + GetRowCount() - 1)); result = aReflowState.ComputedHeight() - cellSpacing; } else { @@ -1523,7 +1526,7 @@ nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState) } if (parentRS && (tableFrame == parentRS->frame) && (parentRS->ComputedHeight() > 0) && (parentRS->ComputedHeight() < NS_UNCONSTRAINEDSIZE)) { - nscoord cellSpacing = std::max(0, tableFrame->GetRowCount() + 1) * tableFrame->GetCellSpacingY(); + nscoord cellSpacing = tableFrame->GetCellSpacingY(-1, tableFrame->GetRowCount()); result = parentRS->ComputedHeight() - cellSpacing; } }