| Index: Source/core/rendering/RenderTableSection.cpp
|
| diff --git a/Source/core/rendering/RenderTableSection.cpp b/Source/core/rendering/RenderTableSection.cpp
|
| index 9bca8347a798ce6c39c6a9ee0f024e9ca4357f41..d8f632d00e89217501a10365948b4e98496c3d98 100644
|
| --- a/Source/core/rendering/RenderTableSection.cpp
|
| +++ b/Source/core/rendering/RenderTableSection.cpp
|
| @@ -252,6 +252,123 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row)
|
| cell->setCol(table()->effColToCol(col));
|
| }
|
|
|
| +void RenderTableSection::populateSpanningRowsHeightFromCell(RenderTableCell* cell, struct SpanningRowsHeight& spanningRowsHeight)
|
| +{
|
| + const unsigned rowSpan = cell->rowSpan();
|
| + const unsigned rowIndex = cell->rowIndex();
|
| +
|
| + spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing = cell->logicalHeightForRowSizing();
|
| +
|
| + spanningRowsHeight.rowHeight.resize(rowSpan);
|
| + spanningRowsHeight.totalRowsHeight = 0;
|
| + for (unsigned row = 0; row < rowSpan; row++) {
|
| + unsigned actualRow = row + rowIndex;
|
| + spanningRowsHeight.rowHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - borderSpacingForRow(actualRow);
|
| + spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row];
|
| + spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpacingForRow(actualRow);
|
| + }
|
| + // We don't span the following row so its border-spacing (if any) should be included.
|
| + spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += borderSpacingForRow(rowIndex + rowSpan - 1);
|
| +}
|
| +
|
| +void RenderTableSection::distributeExtraRowSpanHeightToPercentRows(RenderTableCell* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsHeight)
|
| +{
|
| + if (!extraRowSpanningHeight || !totalPercent)
|
| + return;
|
| +
|
| + const unsigned rowSpan = cell->rowSpan();
|
| + const unsigned rowIndex = cell->rowIndex();
|
| + int percent = min(totalPercent, 100);
|
| + const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight;
|
| +
|
| + // Our algorithm matches Firefox. Extra spanning height would be distributed Only in first percent height rows
|
| + // those total percent is 100. Other percent rows would be uneffected even extra spanning height is remain.
|
| + int accumulatedPositionIncrease = 0;
|
| + for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
|
| + if (percent > 0 && extraRowSpanningHeight > 0) {
|
| + if (m_grid[row].logicalHeight.isPercent()) {
|
| + int toAdd = (tableHeight * m_grid[row].logicalHeight.percent() / 100) - rowsHeight[row - rowIndex];
|
| + // FIXME: Note that this is wrong if we have a percentage above 100% and may make us grow
|
| + // above the available space.
|
| +
|
| + toAdd = min(toAdd, extraRowSpanningHeight);
|
| + accumulatedPositionIncrease += toAdd;
|
| + extraRowSpanningHeight -= toAdd;
|
| + percent -= m_grid[row].logicalHeight.percent();
|
| + }
|
| + }
|
| + m_rowPos[row + 1] += accumulatedPositionIncrease;
|
| + }
|
| +}
|
| +
|
| +void RenderTableSection::distributeExtraRowSpanHeightToAutoRows(RenderTableCell* cell, int totalAutoRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHeight)
|
| +{
|
| + if (!extraRowSpanningHeight || !totalAutoRowsHeight)
|
| + return;
|
| +
|
| + const unsigned rowSpan = cell->rowSpan();
|
| + const unsigned rowIndex = cell->rowIndex();
|
| + int accumulatedPositionIncrease = 0;
|
| + int remainder = 0;
|
| +
|
| + // Aspect ratios of auto rows should not change otherwise table may look different than user expected.
|
| + // So extra height distributed in auto spanning rows based on their weight in spanning cell.
|
| + for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
|
| + if (m_grid[row].logicalHeight.isAuto()) {
|
| + accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) / totalAutoRowsHeight;
|
| + remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalAutoRowsHeight;
|
| +
|
| + // While whole extra spanning height is distributing in auto spanning rows, rational parts remains
|
| + // in every integer division. So accumulating all remainder part in integer division and when total remainder
|
| + // is equvalent to divisor then 1 unit increased in row position.
|
| + // Note that this algorithm is biased towards adding more space towards the lower rows.
|
| + if (remainder >= totalAutoRowsHeight) {
|
| + remainder -= totalAutoRowsHeight;
|
| + accumulatedPositionIncrease++;
|
| + }
|
| + }
|
| + m_rowPos[row + 1] += accumulatedPositionIncrease;
|
| + }
|
| +
|
| + ASSERT(!remainder);
|
| +
|
| + extraRowSpanningHeight -= accumulatedPositionIncrease;
|
| +}
|
| +
|
| +void RenderTableSection::distributeExtraRowSpanHeightToRemainingRows(RenderTableCell* cell, int totalRemainingRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHeight)
|
| +{
|
| + if (!extraRowSpanningHeight || !totalRemainingRowsHeight)
|
| + return;
|
| +
|
| + const unsigned rowSpan = cell->rowSpan();
|
| + const unsigned rowIndex = cell->rowIndex();
|
| + int accumulatedPositionIncrease = 0;
|
| + int remainder = 0;
|
| +
|
| + // Aspect ratios of the rows should not change otherwise table may look different than user expected.
|
| + // So extra height distribution in remaining spanning rows based on their weight in spanning cell.
|
| + for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
|
| + if (!m_grid[row].logicalHeight.isPercent()) {
|
| + accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) / totalRemainingRowsHeight;
|
| + remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalRemainingRowsHeight;
|
| +
|
| + // While whole extra spanning height is distributing in remaining spanning rows, rational parts remains
|
| + // in every integer division. So accumulating all remainder part in integer division and when total remainder
|
| + // is equvalent to divisor then 1 unit increased in row position.
|
| + // Note that this algorithm is biased towards adding more space towards the lower rows.
|
| + if (remainder >= totalRemainingRowsHeight) {
|
| + remainder -= totalRemainingRowsHeight;
|
| + accumulatedPositionIncrease++;
|
| + }
|
| + }
|
| + m_rowPos[row + 1] += accumulatedPositionIncrease;
|
| + }
|
| +
|
| + ASSERT(!remainder);
|
| +
|
| + extraRowSpanningHeight -= accumulatedPositionIncrease;
|
| +}
|
| +
|
| // Distribute rowSpan cell height in rows those comes in rowSpan cell based on the ratio of row's height if
|
| // 1. RowSpan cell height is greater then the total height of rows in rowSpan cell
|
| void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells& rowSpanCells)
|
| @@ -262,38 +379,40 @@ void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells&
|
| RenderTableCell* cell = rowSpanCells[0];
|
|
|
| unsigned rowSpan = cell->rowSpan();
|
| - unsigned rowIndex = cell->rowIndex();
|
| - int initialPos = m_rowPos[rowIndex + rowSpan];
|
|
|
| - int totalRowsHeight = 0;
|
| - int rowSpanCellHeight = cell->logicalHeightForRowSizing();
|
| - Vector<int> rowsHeight(rowSpan);
|
| + struct SpanningRowsHeight spanningRowsHeight;
|
|
|
| - // Getting height of rows in current rowSpan cell, getting total height of rows and adjusting rowSpan cell height with border spacing.
|
| - for (unsigned row = 0; row < rowSpan; row++) {
|
| - unsigned actualRow = row + rowIndex;
|
| - rowsHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - borderSpacingForRow(actualRow);
|
| - totalRowsHeight += rowsHeight[row];
|
| - rowSpanCellHeight -= borderSpacingForRow(actualRow);
|
| - }
|
| - rowSpanCellHeight += borderSpacingForRow(rowIndex + rowSpan - 1);
|
| + populateSpanningRowsHeightFromCell(cell, spanningRowsHeight);
|
|
|
| - if (!totalRowsHeight || rowSpanCellHeight <= totalRowsHeight)
|
| + if (!spanningRowsHeight.totalRowsHeight || spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight)
|
| return;
|
|
|
| - // Recalculating the height of rows based on rowSpan cell height if rowSpan cell height is more than total height of rows.
|
| - int remainingHeight = rowSpanCellHeight;
|
| + unsigned rowIndex = cell->rowIndex();
|
| + int totalPercent = 0;
|
| + int totalAutoRowsHeight = 0;
|
| + int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight;
|
|
|
| + // Calculate total percentage, total auto rows height and total rows height except percent rows.
|
| for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
|
| - int rowHeight = (rowSpanCellHeight * rowsHeight[row - rowIndex]) / totalRowsHeight;
|
| - remainingHeight -= rowHeight;
|
| - m_rowPos[row + 1] = m_rowPos[row] + rowHeight + borderSpacingForRow(row);
|
| + if (m_grid[row].logicalHeight.isPercent()) {
|
| + totalPercent += m_grid[row].logicalHeight.percent();
|
| + totalRemainingRowsHeight -= spanningRowsHeight.rowHeight[row - rowIndex];
|
| + } else if (m_grid[row].logicalHeight.isAuto()) {
|
| + totalAutoRowsHeight += spanningRowsHeight.rowHeight[row - rowIndex];
|
| + }
|
| }
|
| - // Remaining height added in the last row under rowSpan cell
|
| - m_rowPos[rowIndex + rowSpan] += remainingHeight;
|
| +
|
| + int initialPos = m_rowPos[rowIndex + rowSpan];
|
| + int extraRowSpanningHeight = spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing - spanningRowsHeight.totalRowsHeight;
|
| +
|
| + distributeExtraRowSpanHeightToPercentRows(cell, totalPercent, extraRowSpanningHeight, spanningRowsHeight.rowHeight);
|
| + distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, extraRowSpanningHeight, spanningRowsHeight.rowHeight);
|
| + distributeExtraRowSpanHeightToRemainingRows(cell, totalRemainingRowsHeight, extraRowSpanningHeight, spanningRowsHeight.rowHeight);
|
| +
|
| + ASSERT(!extraRowSpanningHeight);
|
|
|
| // Getting total changed height in the table
|
| - unsigned changedHeight = changedHeight = m_rowPos[rowIndex + rowSpan] - initialPos;
|
| + unsigned changedHeight = m_rowPos[rowIndex + rowSpan] - initialPos;
|
|
|
| if (changedHeight) {
|
| unsigned totalRows = m_grid.size();
|
|
|