| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
| 3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
| 4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
| 5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. |
| 8 * All rights reserved. | 8 * All rights reserved. |
| 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 10 * | 10 * |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 namespace blink { | 41 namespace blink { |
| 42 | 42 |
| 43 using namespace HTMLNames; | 43 using namespace HTMLNames; |
| 44 | 44 |
| 45 // This variable is used to balance the memory consumption vs the paint | 45 // This variable is used to balance the memory consumption vs the paint |
| 46 // invalidation time on big tables. | 46 // invalidation time on big tables. |
| 47 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; | 47 static unsigned gMinTableSizeToUseFastPaintPathWithOverflowingCell = 75 * 75; |
| 48 | 48 |
| 49 static inline void setRowLogicalHeightToRowStyleLogicalHeight( | 49 static inline void setRowLogicalHeightToRowStyleLogicalHeight( |
| 50 LayoutTableSection::RowStruct& row) { | 50 LayoutTableSection::RowStruct& row) { |
| 51 ASSERT(row.rowLayoutObject); | 51 DCHECK(row.rowLayoutObject); |
| 52 row.logicalHeight = row.rowLayoutObject->style()->logicalHeight(); | 52 row.logicalHeight = row.rowLayoutObject->style()->logicalHeight(); |
| 53 } | 53 } |
| 54 | 54 |
| 55 static inline void updateLogicalHeightForCell( | 55 static inline void updateLogicalHeightForCell( |
| 56 LayoutTableSection::RowStruct& row, | 56 LayoutTableSection::RowStruct& row, |
| 57 const LayoutTableCell* cell) { | 57 const LayoutTableCell* cell) { |
| 58 // We ignore height settings on rowspan cells. | 58 // We ignore height settings on rowspan cells. |
| 59 if (cell->rowSpan() != 1) | 59 if (cell->rowSpan() != 1) |
| 60 return; | 60 return; |
| 61 | 61 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 LayoutTableRow* row = toLayoutTableRow(child); | 200 LayoutTableRow* row = toLayoutTableRow(child); |
| 201 m_grid[insertionRow].rowLayoutObject = row; | 201 m_grid[insertionRow].rowLayoutObject = row; |
| 202 row->setRowIndex(insertionRow); | 202 row->setRowIndex(insertionRow); |
| 203 | 203 |
| 204 if (!beforeChild) | 204 if (!beforeChild) |
| 205 setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); | 205 setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]); |
| 206 | 206 |
| 207 if (beforeChild && beforeChild->parent() != this) | 207 if (beforeChild && beforeChild->parent() != this) |
| 208 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); | 208 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); |
| 209 | 209 |
| 210 ASSERT(!beforeChild || beforeChild->isTableRow()); | 210 DCHECK(!beforeChild || beforeChild->isTableRow()); |
| 211 LayoutTableBoxComponent::addChild(child, beforeChild); | 211 LayoutTableBoxComponent::addChild(child, beforeChild); |
| 212 } | 212 } |
| 213 | 213 |
| 214 static inline void checkThatVectorIsDOMOrdered( | 214 static inline void checkThatVectorIsDOMOrdered( |
| 215 const Vector<LayoutTableCell*, 1>& cells) { | 215 const Vector<LayoutTableCell*, 1>& cells) { |
| 216 #ifndef NDEBUG | 216 #ifndef NDEBUG |
| 217 // This function should be called on a non-empty vector. | 217 // This function should be called on a non-empty vector. |
| 218 ASSERT(cells.size() > 0); | 218 DCHECK_GT(cells.size(), 0u); |
| 219 | 219 |
| 220 const LayoutTableCell* previousCell = cells[0]; | 220 const LayoutTableCell* previousCell = cells[0]; |
| 221 for (size_t i = 1; i < cells.size(); ++i) { | 221 for (size_t i = 1; i < cells.size(); ++i) { |
| 222 const LayoutTableCell* currentCell = cells[i]; | 222 const LayoutTableCell* currentCell = cells[i]; |
| 223 // The check assumes that all cells belong to the same row group. | 223 // The check assumes that all cells belong to the same row group. |
| 224 ASSERT(previousCell->section() == currentCell->section()); | 224 DCHECK_EQ(previousCell->section(), currentCell->section()); |
| 225 | 225 |
| 226 // 2 overlapping cells can't be on the same row. | 226 // 2 overlapping cells can't be on the same row. |
| 227 ASSERT(currentCell->row() != previousCell->row()); | 227 DCHECK_NE(currentCell->row(), previousCell->row()); |
| 228 | 228 |
| 229 // Look backwards in the tree for the previousCell's row. If we are | 229 // Look backwards in the tree for the previousCell's row. If we are |
| 230 // DOM ordered, we should find it. | 230 // DOM ordered, we should find it. |
| 231 const LayoutTableRow* row = currentCell->row(); | 231 const LayoutTableRow* row = currentCell->row(); |
| 232 for (; row && row != previousCell->row(); row = row->previousRow()) { | 232 for (; row && row != previousCell->row(); row = row->previousRow()) { |
| 233 } | 233 } |
| 234 ASSERT(row == previousCell->row()); | 234 DCHECK_EQ(row, previousCell->row()); |
| 235 | 235 |
| 236 previousCell = currentCell; | 236 previousCell = currentCell; |
| 237 } | 237 } |
| 238 #endif // NDEBUG | 238 #endif // NDEBUG |
| 239 } | 239 } |
| 240 | 240 |
| 241 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { | 241 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { |
| 242 // We don't insert the cell if we need cell recalc as our internal columns' | 242 // We don't insert the cell if we need cell recalc as our internal columns' |
| 243 // representation will have drifted from the table's representation. Also | 243 // representation will have drifted from the table's representation. Also |
| 244 // recalcCells will call addCell at a later time after sync'ing our columns' | 244 // recalcCells will call addCell at a later time after sync'ing our columns' |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 table()->appendEffectiveColumn(cSpan); | 283 table()->appendEffectiveColumn(cSpan); |
| 284 currentSpan = cSpan; | 284 currentSpan = cSpan; |
| 285 } else { | 285 } else { |
| 286 if (cSpan < columns[m_cCol].span) | 286 if (cSpan < columns[m_cCol].span) |
| 287 table()->splitEffectiveColumn(m_cCol, cSpan); | 287 table()->splitEffectiveColumn(m_cCol, cSpan); |
| 288 currentSpan = columns[m_cCol].span; | 288 currentSpan = columns[m_cCol].span; |
| 289 } | 289 } |
| 290 for (unsigned r = 0; r < rSpan; r++) { | 290 for (unsigned r = 0; r < rSpan; r++) { |
| 291 ensureCols(insertionRow + r, m_cCol + 1); | 291 ensureCols(insertionRow + r, m_cCol + 1); |
| 292 CellStruct& c = cellAt(insertionRow + r, m_cCol); | 292 CellStruct& c = cellAt(insertionRow + r, m_cCol); |
| 293 ASSERT(cell); | 293 DCHECK(cell); |
| 294 c.cells.push_back(cell); | 294 c.cells.push_back(cell); |
| 295 checkThatVectorIsDOMOrdered(c.cells); | 295 checkThatVectorIsDOMOrdered(c.cells); |
| 296 // If cells overlap then we take the slow path for painting. | 296 // If cells overlap then we take the slow path for painting. |
| 297 if (c.cells.size() > 1) | 297 if (c.cells.size() > 1) |
| 298 m_hasMultipleCellLevels = true; | 298 m_hasMultipleCellLevels = true; |
| 299 if (inColSpan) | 299 if (inColSpan) |
| 300 c.inColSpan = true; | 300 c.inColSpan = true; |
| 301 } | 301 } |
| 302 m_cCol++; | 302 m_cCol++; |
| 303 cSpan -= currentSpan; | 303 cSpan -= currentSpan; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 | 537 |
| 538 return false; | 538 return false; |
| 539 } | 539 } |
| 540 | 540 |
| 541 unsigned LayoutTableSection::calcRowHeightHavingOnlySpanningCells( | 541 unsigned LayoutTableSection::calcRowHeightHavingOnlySpanningCells( |
| 542 unsigned row, | 542 unsigned row, |
| 543 int& accumulatedCellPositionIncrease, | 543 int& accumulatedCellPositionIncrease, |
| 544 unsigned rowToApplyExtraHeight, | 544 unsigned rowToApplyExtraHeight, |
| 545 unsigned& extraTableHeightToPropgate, | 545 unsigned& extraTableHeightToPropgate, |
| 546 Vector<int>& rowsCountWithOnlySpanningCells) { | 546 Vector<int>& rowsCountWithOnlySpanningCells) { |
| 547 ASSERT(rowHasOnlySpanningCells(row)); | 547 DCHECK(rowHasOnlySpanningCells(row)); |
| 548 | 548 |
| 549 unsigned totalCols = m_grid[row].row.size(); | 549 unsigned totalCols = m_grid[row].row.size(); |
| 550 | 550 |
| 551 if (!totalCols) | 551 if (!totalCols) |
| 552 return 0; | 552 return 0; |
| 553 | 553 |
| 554 unsigned rowHeight = 0; | 554 unsigned rowHeight = 0; |
| 555 | 555 |
| 556 for (unsigned col = 0; col < totalCols; col++) { | 556 for (unsigned col = 0; col < totalCols; col++) { |
| 557 const CellStruct& rowSpanCell = cellAt(row, col); | 557 const CellStruct& rowSpanCell = cellAt(row, col); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 } | 599 } |
| 600 | 600 |
| 601 return rowHeight; | 601 return rowHeight; |
| 602 } | 602 } |
| 603 | 603 |
| 604 void LayoutTableSection::updateRowsHeightHavingOnlySpanningCells( | 604 void LayoutTableSection::updateRowsHeightHavingOnlySpanningCells( |
| 605 LayoutTableCell* cell, | 605 LayoutTableCell* cell, |
| 606 struct SpanningRowsHeight& spanningRowsHeight, | 606 struct SpanningRowsHeight& spanningRowsHeight, |
| 607 unsigned& extraHeightToPropagate, | 607 unsigned& extraHeightToPropagate, |
| 608 Vector<int>& rowsCountWithOnlySpanningCells) { | 608 Vector<int>& rowsCountWithOnlySpanningCells) { |
| 609 ASSERT(spanningRowsHeight.rowHeight.size()); | 609 DCHECK(spanningRowsHeight.rowHeight.size()); |
| 610 | 610 |
| 611 int accumulatedPositionIncrease = 0; | 611 int accumulatedPositionIncrease = 0; |
| 612 const unsigned rowSpan = cell->rowSpan(); | 612 const unsigned rowSpan = cell->rowSpan(); |
| 613 const unsigned rowIndex = cell->rowIndex(); | 613 const unsigned rowIndex = cell->rowIndex(); |
| 614 | 614 |
| 615 DCHECK_EQ(rowSpan, spanningRowsHeight.rowHeight.size()); | 615 DCHECK_EQ(rowSpan, spanningRowsHeight.rowHeight.size()); |
| 616 | 616 |
| 617 for (unsigned row = 0; row < spanningRowsHeight.rowHeight.size(); row++) { | 617 for (unsigned row = 0; row < spanningRowsHeight.rowHeight.size(); row++) { |
| 618 unsigned actualRow = row + rowIndex; | 618 unsigned actualRow = row + rowIndex; |
| 619 if (!spanningRowsHeight.rowHeight[row] && | 619 if (!spanningRowsHeight.rowHeight[row] && |
| 620 rowHasOnlySpanningCells(actualRow)) { | 620 rowHasOnlySpanningCells(actualRow)) { |
| 621 spanningRowsHeight.rowHeight[row] = calcRowHeightHavingOnlySpanningCells( | 621 spanningRowsHeight.rowHeight[row] = calcRowHeightHavingOnlySpanningCells( |
| 622 actualRow, accumulatedPositionIncrease, rowIndex + rowSpan, | 622 actualRow, accumulatedPositionIncrease, rowIndex + rowSpan, |
| 623 extraHeightToPropagate, rowsCountWithOnlySpanningCells); | 623 extraHeightToPropagate, rowsCountWithOnlySpanningCells); |
| 624 accumulatedPositionIncrease += spanningRowsHeight.rowHeight[row]; | 624 accumulatedPositionIncrease += spanningRowsHeight.rowHeight[row]; |
| 625 } | 625 } |
| 626 m_rowPos[actualRow + 1] += accumulatedPositionIncrease; | 626 m_rowPos[actualRow + 1] += accumulatedPositionIncrease; |
| 627 } | 627 } |
| 628 | 628 |
| 629 spanningRowsHeight.totalRowsHeight += accumulatedPositionIncrease; | 629 spanningRowsHeight.totalRowsHeight += accumulatedPositionIncrease; |
| 630 } | 630 } |
| 631 | 631 |
| 632 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on | 632 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on |
| 633 // the ratio of row's height if 1 RowSpan cell height is greater than the total | 633 // the ratio of row's height if 1 RowSpan cell height is greater than the total |
| 634 // height of rows in rowSpan cell. | 634 // height of rows in rowSpan cell. |
| 635 void LayoutTableSection::distributeRowSpanHeightToRows( | 635 void LayoutTableSection::distributeRowSpanHeightToRows( |
| 636 SpanningLayoutTableCells& rowSpanCells) { | 636 SpanningLayoutTableCells& rowSpanCells) { |
| 637 ASSERT(rowSpanCells.size()); | 637 DCHECK(rowSpanCells.size()); |
| 638 | 638 |
| 639 // 'rowSpanCells' list is already sorted based on the cells rowIndex in | 639 // 'rowSpanCells' list is already sorted based on the cells rowIndex in |
| 640 // ascending order | 640 // ascending order |
| 641 // Arrange row spanning cell in the order in which we need to process first. | 641 // Arrange row spanning cell in the order in which we need to process first. |
| 642 std::sort(rowSpanCells.begin(), rowSpanCells.end(), | 642 std::sort(rowSpanCells.begin(), rowSpanCells.end(), |
| 643 compareRowSpanCellsInHeightDistributionOrder); | 643 compareRowSpanCellsInHeightDistributionOrder); |
| 644 | 644 |
| 645 unsigned extraHeightToPropagate = 0; | 645 unsigned extraHeightToPropagate = 0; |
| 646 unsigned lastRowIndex = 0; | 646 unsigned lastRowIndex = 0; |
| 647 unsigned lastRowSpan = 0; | 647 unsigned lastRowSpan = 0; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 extraRowSpanningHeight, | 766 extraRowSpanningHeight, |
| 767 spanningRowsHeight.rowHeight); | 767 spanningRowsHeight.rowHeight); |
| 768 distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, | 768 distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, |
| 769 extraRowSpanningHeight, | 769 extraRowSpanningHeight, |
| 770 spanningRowsHeight.rowHeight); | 770 spanningRowsHeight.rowHeight); |
| 771 distributeExtraRowSpanHeightToRemainingRows( | 771 distributeExtraRowSpanHeightToRemainingRows( |
| 772 cell, totalRemainingRowsHeight, extraRowSpanningHeight, | 772 cell, totalRemainingRowsHeight, extraRowSpanningHeight, |
| 773 spanningRowsHeight.rowHeight); | 773 spanningRowsHeight.rowHeight); |
| 774 } | 774 } |
| 775 | 775 |
| 776 ASSERT(!extraRowSpanningHeight); | 776 DCHECK(!extraRowSpanningHeight); |
| 777 | 777 |
| 778 // Getting total changed height in the table | 778 // Getting total changed height in the table |
| 779 extraHeightToPropagate = | 779 extraHeightToPropagate = |
| 780 m_rowPos[spanningCellEndIndex] - originalBeforePosition; | 780 m_rowPos[spanningCellEndIndex] - originalBeforePosition; |
| 781 } | 781 } |
| 782 | 782 |
| 783 if (extraHeightToPropagate) { | 783 if (extraHeightToPropagate) { |
| 784 // Apply changed height by rowSpan cells to rows present at the end of the | 784 // Apply changed height by rowSpan cells to rows present at the end of the |
| 785 // table | 785 // table |
| 786 for (unsigned row = lastRowIndex + lastRowSpan + 1; row <= m_grid.size(); | 786 for (unsigned row = lastRowIndex + lastRowSpan + 1; row <= m_grid.size(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 std::max<int>(m_rowPos[row + 1], m_rowPos[row] + m_grid[row].baseline + | 819 std::max<int>(m_rowPos[row + 1], m_rowPos[row] + m_grid[row].baseline + |
| 820 cellStartRowBaselineDescent); | 820 cellStartRowBaselineDescent); |
| 821 } | 821 } |
| 822 } | 822 } |
| 823 | 823 |
| 824 int LayoutTableSection::calcRowLogicalHeight() { | 824 int LayoutTableSection::calcRowLogicalHeight() { |
| 825 #if DCHECK_IS_ON() | 825 #if DCHECK_IS_ON() |
| 826 SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); | 826 SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); |
| 827 #endif | 827 #endif |
| 828 | 828 |
| 829 ASSERT(!needsLayout()); | 829 DCHECK(!needsLayout()); |
| 830 | 830 |
| 831 LayoutTableCell* cell; | 831 LayoutTableCell* cell; |
| 832 | 832 |
| 833 // We may have to forcefully lay out cells here, in which case we need a | 833 // We may have to forcefully lay out cells here, in which case we need a |
| 834 // layout state. | 834 // layout state. |
| 835 LayoutState state(*this); | 835 LayoutState state(*this); |
| 836 | 836 |
| 837 m_rowPos.resize(m_grid.size() + 1); | 837 m_rowPos.resize(m_grid.size() + 1); |
| 838 | 838 |
| 839 // We ignore the border-spacing on any non-top section as it is already | 839 // We ignore the border-spacing on any non-top section as it is already |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 } | 929 } |
| 930 | 930 |
| 931 // Add the border-spacing to our final position. | 931 // Add the border-spacing to our final position. |
| 932 m_rowPos[r + 1] += borderSpacingForRow(r); | 932 m_rowPos[r + 1] += borderSpacingForRow(r); |
| 933 m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r]); | 933 m_rowPos[r + 1] = std::max(m_rowPos[r + 1], m_rowPos[r]); |
| 934 } | 934 } |
| 935 | 935 |
| 936 if (!rowSpanCells.isEmpty()) | 936 if (!rowSpanCells.isEmpty()) |
| 937 distributeRowSpanHeightToRows(rowSpanCells); | 937 distributeRowSpanHeightToRows(rowSpanCells); |
| 938 | 938 |
| 939 ASSERT(!needsLayout()); | 939 DCHECK(!needsLayout()); |
| 940 | 940 |
| 941 return m_rowPos[m_grid.size()]; | 941 return m_rowPos[m_grid.size()]; |
| 942 } | 942 } |
| 943 | 943 |
| 944 void LayoutTableSection::layout() { | 944 void LayoutTableSection::layout() { |
| 945 ASSERT(needsLayout()); | 945 DCHECK(needsLayout()); |
| 946 LayoutAnalyzer::Scope analyzer(*this); | 946 LayoutAnalyzer::Scope analyzer(*this); |
| 947 CHECK(!needsCellRecalc()); | 947 CHECK(!needsCellRecalc()); |
| 948 ASSERT(!table()->needsSectionRecalc()); | 948 DCHECK(!table()->needsSectionRecalc()); |
| 949 | 949 |
| 950 // addChild may over-grow m_grid but we don't want to throw away the memory | 950 // addChild may over-grow m_grid but we don't want to throw away the memory |
| 951 // too early as addChild can be called in a loop (e.g during parsing). Doing | 951 // too early as addChild can be called in a loop (e.g during parsing). Doing |
| 952 // it now ensures we have a stable-enough structure. | 952 // it now ensures we have a stable-enough structure. |
| 953 m_grid.shrinkToFit(); | 953 m_grid.shrinkToFit(); |
| 954 | 954 |
| 955 LayoutState state(*this); | 955 LayoutState state(*this); |
| 956 | 956 |
| 957 const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 957 const Vector<int>& columnPos = table()->effectiveColumnPositions(); |
| 958 LayoutUnit rowLogicalTop; | 958 LayoutUnit rowLogicalTop; |
| 959 | 959 |
| 960 SubtreeLayoutScope layouter(*this); | 960 SubtreeLayoutScope layouter(*this); |
| 961 for (unsigned r = 0; r < m_grid.size(); ++r) { | 961 for (unsigned r = 0; r < m_grid.size(); ++r) { |
| 962 Row& row = m_grid[r].row; | 962 Row& row = m_grid[r].row; |
| 963 unsigned cols = row.size(); | 963 unsigned cols = row.size(); |
| 964 // First, propagate our table layout's information to the cells. This will | 964 // First, propagate our table layout's information to the cells. This will |
| 965 // mark the row as needing layout if there was a column logical width | 965 // mark the row as needing layout if there was a column logical width |
| 966 // change. | 966 // change. |
| 967 for (unsigned startColumn = 0; startColumn < cols; ++startColumn) { | 967 for (unsigned startColumn = 0; startColumn < cols; ++startColumn) { |
| 968 CellStruct& current = row[startColumn]; | 968 CellStruct& current = row[startColumn]; |
| 969 LayoutTableCell* cell = current.primaryCell(); | 969 LayoutTableCell* cell = current.primaryCell(); |
| 970 if (!cell || current.inColSpan) | 970 if (!cell || current.inColSpan) |
| 971 continue; | 971 continue; |
| 972 | 972 |
| 973 unsigned endCol = startColumn; | 973 unsigned endCol = startColumn; |
| 974 unsigned cspan = cell->colSpan(); | 974 unsigned cspan = cell->colSpan(); |
| 975 while (cspan && endCol < cols) { | 975 while (cspan && endCol < cols) { |
| 976 ASSERT(endCol < table()->effectiveColumns().size()); | 976 DCHECK_LT(endCol, table()->effectiveColumns().size()); |
| 977 cspan -= table()->effectiveColumns()[endCol].span; | 977 cspan -= table()->effectiveColumns()[endCol].span; |
| 978 endCol++; | 978 endCol++; |
| 979 } | 979 } |
| 980 int tableLayoutLogicalWidth = columnPos[endCol] - columnPos[startColumn] - | 980 int tableLayoutLogicalWidth = columnPos[endCol] - columnPos[startColumn] - |
| 981 table()->hBorderSpacing(); | 981 table()->hBorderSpacing(); |
| 982 cell->setCellLogicalWidth(tableLayoutLogicalWidth, layouter); | 982 cell->setCellLogicalWidth(tableLayoutLogicalWidth, layouter); |
| 983 } | 983 } |
| 984 | 984 |
| 985 if (LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject) { | 985 if (LayoutTableRow* rowLayoutObject = m_grid[r].rowLayoutObject) { |
| 986 if (state.isPaginated()) | 986 if (state.isPaginated()) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1017 int toAdd = std::min<int>( | 1017 int toAdd = std::min<int>( |
| 1018 extraLogicalHeight, | 1018 extraLogicalHeight, |
| 1019 (totalHeight * m_grid[r].logicalHeight.percent() / 100) - rowHeight); | 1019 (totalHeight * m_grid[r].logicalHeight.percent() / 100) - rowHeight); |
| 1020 // If toAdd is negative, then we don't want to shrink the row (this bug | 1020 // If toAdd is negative, then we don't want to shrink the row (this bug |
| 1021 // affected Outlook Web Access). | 1021 // affected Outlook Web Access). |
| 1022 toAdd = std::max(0, toAdd); | 1022 toAdd = std::max(0, toAdd); |
| 1023 totalLogicalHeightAdded += toAdd; | 1023 totalLogicalHeightAdded += toAdd; |
| 1024 extraLogicalHeight -= toAdd; | 1024 extraLogicalHeight -= toAdd; |
| 1025 totalPercent -= m_grid[r].logicalHeight.percent(); | 1025 totalPercent -= m_grid[r].logicalHeight.percent(); |
| 1026 } | 1026 } |
| 1027 ASSERT(totalRows >= 1); | 1027 DCHECK_GE(totalRows, 1u); |
| 1028 if (r < totalRows - 1) | 1028 if (r < totalRows - 1) |
| 1029 rowHeight = m_rowPos[r + 2] - m_rowPos[r + 1]; | 1029 rowHeight = m_rowPos[r + 2] - m_rowPos[r + 1]; |
| 1030 m_rowPos[r + 1] += totalLogicalHeightAdded; | 1030 m_rowPos[r + 1] += totalLogicalHeightAdded; |
| 1031 } | 1031 } |
| 1032 } | 1032 } |
| 1033 | 1033 |
| 1034 void LayoutTableSection::distributeExtraLogicalHeightToAutoRows( | 1034 void LayoutTableSection::distributeExtraLogicalHeightToAutoRows( |
| 1035 int& extraLogicalHeight, | 1035 int& extraLogicalHeight, |
| 1036 unsigned autoRowsCount) { | 1036 unsigned autoRowsCount) { |
| 1037 if (!autoRowsCount) | 1037 if (!autoRowsCount) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 return true; | 1113 return true; |
| 1114 return cellDescendant->isBox() && | 1114 return cellDescendant->isBox() && |
| 1115 toLayoutBox(cellDescendant)->shouldBeConsideredAsReplaced(); | 1115 toLayoutBox(cellDescendant)->shouldBeConsideredAsReplaced(); |
| 1116 } | 1116 } |
| 1117 | 1117 |
| 1118 void LayoutTableSection::layoutRows() { | 1118 void LayoutTableSection::layoutRows() { |
| 1119 #if DCHECK_IS_ON() | 1119 #if DCHECK_IS_ON() |
| 1120 SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); | 1120 SetLayoutNeededForbiddenScope layoutForbiddenScope(*this); |
| 1121 #endif | 1121 #endif |
| 1122 | 1122 |
| 1123 ASSERT(!needsLayout()); | 1123 DCHECK(!needsLayout()); |
| 1124 | 1124 |
| 1125 LayoutAnalyzer::Scope analyzer(*this); | 1125 LayoutAnalyzer::Scope analyzer(*this); |
| 1126 | 1126 |
| 1127 // FIXME: Changing the height without a layout can change the overflow so it | 1127 // FIXME: Changing the height without a layout can change the overflow so it |
| 1128 // seems wrong. | 1128 // seems wrong. |
| 1129 | 1129 |
| 1130 unsigned totalRows = m_grid.size(); | 1130 unsigned totalRows = m_grid.size(); |
| 1131 | 1131 |
| 1132 // Set the width of our section now. The rows will also be this width. | 1132 // Set the width of our section now. The rows will also be this width. |
| 1133 setLogicalWidth(table()->contentLogicalWidth()); | 1133 setLogicalWidth(table()->contentLogicalWidth()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 // need a layout. In this case, we know we're going to issue paint | 1211 // need a layout. In this case, we know we're going to issue paint |
| 1212 // invalidations ourselves (and the child) anyway. | 1212 // invalidations ourselves (and the child) anyway. |
| 1213 if (!table()->selfNeedsLayout()) | 1213 if (!table()->selfNeedsLayout()) |
| 1214 cell->setMayNeedPaintInvalidation(); | 1214 cell->setMayNeedPaintInvalidation(); |
| 1215 } | 1215 } |
| 1216 } | 1216 } |
| 1217 if (rowLayoutObject) | 1217 if (rowLayoutObject) |
| 1218 rowLayoutObject->computeOverflow(); | 1218 rowLayoutObject->computeOverflow(); |
| 1219 } | 1219 } |
| 1220 | 1220 |
| 1221 ASSERT(!needsLayout()); | 1221 DCHECK(!needsLayout()); |
| 1222 | 1222 |
| 1223 setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); | 1223 setLogicalHeight(LayoutUnit(m_rowPos[totalRows])); |
| 1224 | 1224 |
| 1225 computeOverflowFromCells(totalRows, table()->numEffectiveColumns()); | 1225 computeOverflowFromCells(totalRows, table()->numEffectiveColumns()); |
| 1226 } | 1226 } |
| 1227 | 1227 |
| 1228 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, | 1228 int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, |
| 1229 LayoutUnit logicalOffset) const { | 1229 LayoutUnit logicalOffset) const { |
| 1230 DCHECK(row); | 1230 DCHECK(row); |
| 1231 if (row->getPaginationBreakability() == AllowAnyBreaks) | 1231 if (row->getPaginationBreakability() == AllowAnyBreaks) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1298 // overflowing cells as the hit testing code rely on this information. | 1298 // overflowing cells as the hit testing code rely on this information. |
| 1299 m_forceSlowPaintPathWithOverflowingCell = true; | 1299 m_forceSlowPaintPathWithOverflowingCell = true; |
| 1300 // The slow path does not make any use of the overflowing cells info, | 1300 // The slow path does not make any use of the overflowing cells info, |
| 1301 // don't hold on to the memory. | 1301 // don't hold on to the memory. |
| 1302 m_overflowingCells.clear(); | 1302 m_overflowingCells.clear(); |
| 1303 } | 1303 } |
| 1304 } | 1304 } |
| 1305 } | 1305 } |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 ASSERT(hasOverflowingCell == this->hasOverflowingCell()); | 1308 #if DCHECK_IS_ON() |
| 1309 DCHECK_EQ(hasOverflowingCell, this->hasOverflowingCell()); |
| 1310 #endif |
| 1309 } | 1311 } |
| 1310 | 1312 |
| 1311 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { | 1313 bool LayoutTableSection::recalcChildOverflowAfterStyleChange() { |
| 1312 ASSERT(childNeedsOverflowRecalcAfterStyleChange()); | 1314 DCHECK(childNeedsOverflowRecalcAfterStyleChange()); |
| 1313 clearChildNeedsOverflowRecalcAfterStyleChange(); | 1315 clearChildNeedsOverflowRecalcAfterStyleChange(); |
| 1314 unsigned totalRows = m_grid.size(); | 1316 unsigned totalRows = m_grid.size(); |
| 1315 bool childrenOverflowChanged = false; | 1317 bool childrenOverflowChanged = false; |
| 1316 for (unsigned r = 0; r < totalRows; r++) { | 1318 for (unsigned r = 0; r < totalRows; r++) { |
| 1317 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); | 1319 LayoutTableRow* rowLayouter = rowLayoutObjectAt(r); |
| 1318 if (!rowLayouter || | 1320 if (!rowLayouter || |
| 1319 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) | 1321 !rowLayouter->childNeedsOverflowRecalcAfterStyleChange()) |
| 1320 continue; | 1322 continue; |
| 1321 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); | 1323 rowLayouter->clearChildNeedsOverflowRecalcAfterStyleChange(); |
| 1322 bool rowChildrenOverflowChanged = false; | 1324 bool rowChildrenOverflowChanged = false; |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 columnPos.end(), flippedRect.maxX()) - | 1671 columnPos.end(), flippedRect.maxX()) - |
| 1670 columnPos.begin(); | 1672 columnPos.begin(); |
| 1671 if (endColumn == columnPos.size()) | 1673 if (endColumn == columnPos.size()) |
| 1672 endColumn = columnPos.size() - 1; | 1674 endColumn = columnPos.size() - 1; |
| 1673 } | 1675 } |
| 1674 | 1676 |
| 1675 return CellSpan(startColumn, endColumn); | 1677 return CellSpan(startColumn, endColumn); |
| 1676 } | 1678 } |
| 1677 | 1679 |
| 1678 void LayoutTableSection::recalcCells() { | 1680 void LayoutTableSection::recalcCells() { |
| 1679 ASSERT(m_needsCellRecalc); | 1681 DCHECK(m_needsCellRecalc); |
| 1680 // We reset the flag here to ensure that |addCell| works. This is safe to do | 1682 // We reset the flag here to ensure that |addCell| works. This is safe to do |
| 1681 // as fillRowsWithDefaultStartingAtPosition makes sure we match the table's | 1683 // as fillRowsWithDefaultStartingAtPosition makes sure we match the table's |
| 1682 // columns representation. | 1684 // columns representation. |
| 1683 m_needsCellRecalc = false; | 1685 m_needsCellRecalc = false; |
| 1684 | 1686 |
| 1685 m_cCol = 0; | 1687 m_cCol = 0; |
| 1686 m_cRow = 0; | 1688 m_cRow = 0; |
| 1687 m_grid.clear(); | 1689 m_grid.clear(); |
| 1688 | 1690 |
| 1689 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { | 1691 for (LayoutTableRow* row = firstRow(); row; row = row->nextRow()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1735 if (cell.hasCells() || cell.inColSpan) | 1737 if (cell.hasCells() || cell.inColSpan) |
| 1736 result = c; | 1738 result = c; |
| 1737 } | 1739 } |
| 1738 } | 1740 } |
| 1739 | 1741 |
| 1740 return result + 1; | 1742 return result + 1; |
| 1741 } | 1743 } |
| 1742 | 1744 |
| 1743 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( | 1745 const BorderValue& LayoutTableSection::borderAdjoiningStartCell( |
| 1744 const LayoutTableCell* cell) const { | 1746 const LayoutTableCell* cell) const { |
| 1745 ASSERT(cell->isFirstOrLastCellInRow()); | 1747 #if DCHECK_IS_ON() |
| 1748 DCHECK(cell->isFirstOrLastCellInRow()); |
| 1749 #endif |
| 1746 return hasSameDirectionAs(cell) ? style()->borderStart() | 1750 return hasSameDirectionAs(cell) ? style()->borderStart() |
| 1747 : style()->borderEnd(); | 1751 : style()->borderEnd(); |
| 1748 } | 1752 } |
| 1749 | 1753 |
| 1750 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( | 1754 const BorderValue& LayoutTableSection::borderAdjoiningEndCell( |
| 1751 const LayoutTableCell* cell) const { | 1755 const LayoutTableCell* cell) const { |
| 1752 ASSERT(cell->isFirstOrLastCellInRow()); | 1756 #if DCHECK_IS_ON() |
| 1757 DCHECK(cell->isFirstOrLastCellInRow()); |
| 1758 #endif |
| 1753 return hasSameDirectionAs(cell) ? style()->borderEnd() | 1759 return hasSameDirectionAs(cell) ? style()->borderEnd() |
| 1754 : style()->borderStart(); | 1760 : style()->borderStart(); |
| 1755 } | 1761 } |
| 1756 | 1762 |
| 1757 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() | 1763 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableStart() |
| 1758 const { | 1764 const { |
| 1759 unsigned adjoiningStartCellColumnIndex = | 1765 unsigned adjoiningStartCellColumnIndex = |
| 1760 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); | 1766 hasSameDirectionAs(table()) ? 0 : table()->lastEffectiveColumnIndex(); |
| 1761 return primaryCellAt(0, adjoiningStartCellColumnIndex); | 1767 return primaryCellAt(0, adjoiningStartCellColumnIndex); |
| 1762 } | 1768 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1778 if (cellStruct.inColSpan) | 1784 if (cellStruct.inColSpan) |
| 1779 return nullptr; | 1785 return nullptr; |
| 1780 if (const auto* cell = cellStruct.primaryCell()) { | 1786 if (const auto* cell = cellStruct.primaryCell()) { |
| 1781 if (cell->rowIndex() == row) | 1787 if (cell->rowIndex() == row) |
| 1782 return cell; | 1788 return cell; |
| 1783 } | 1789 } |
| 1784 return nullptr; | 1790 return nullptr; |
| 1785 } | 1791 } |
| 1786 | 1792 |
| 1787 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { | 1793 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { |
| 1788 ASSERT(!m_needsCellRecalc); | 1794 DCHECK(!m_needsCellRecalc); |
| 1789 | 1795 |
| 1790 for (unsigned row = 0; row < m_grid.size(); ++row) | 1796 for (unsigned row = 0; row < m_grid.size(); ++row) |
| 1791 m_grid[row].row.resize(pos + 1); | 1797 m_grid[row].row.resize(pos + 1); |
| 1792 } | 1798 } |
| 1793 | 1799 |
| 1794 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { | 1800 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { |
| 1795 ASSERT(!m_needsCellRecalc); | 1801 DCHECK(!m_needsCellRecalc); |
| 1796 | 1802 |
| 1797 if (m_cCol > pos) | 1803 if (m_cCol > pos) |
| 1798 m_cCol++; | 1804 m_cCol++; |
| 1799 for (unsigned row = 0; row < m_grid.size(); ++row) { | 1805 for (unsigned row = 0; row < m_grid.size(); ++row) { |
| 1800 Row& r = m_grid[row].row; | 1806 Row& r = m_grid[row].row; |
| 1801 ensureCols(row, pos + 2); | 1807 ensureCols(row, pos + 2); |
| 1802 r.insert(pos + 1, CellStruct()); | 1808 r.insert(pos + 1, CellStruct()); |
| 1803 if (r[pos].hasCells()) { | 1809 if (r[pos].hasCells()) { |
| 1804 r[pos + 1].cells.appendVector(r[pos].cells); | 1810 r[pos + 1].cells.appendVector(r[pos].cells); |
| 1805 LayoutTableCell* cell = r[pos].primaryCell(); | 1811 LayoutTableCell* cell = r[pos].primaryCell(); |
| 1806 ASSERT(cell); | 1812 DCHECK(cell); |
| 1807 ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0)); | 1813 DCHECK_GE(cell->colSpan(), (r[pos].inColSpan ? 1u : 0)); |
| 1808 unsigned colleft = cell->colSpan() - r[pos].inColSpan; | 1814 unsigned colleft = cell->colSpan() - r[pos].inColSpan; |
| 1809 if (first > colleft) | 1815 if (first > colleft) |
| 1810 r[pos + 1].inColSpan = 0; | 1816 r[pos + 1].inColSpan = 0; |
| 1811 else | 1817 else |
| 1812 r[pos + 1].inColSpan = first + r[pos].inColSpan; | 1818 r[pos + 1].inColSpan = first + r[pos].inColSpan; |
| 1813 } else { | 1819 } else { |
| 1814 r[pos + 1].inColSpan = 0; | 1820 r[pos + 1].inColSpan = 0; |
| 1815 } | 1821 } |
| 1816 } | 1822 } |
| 1817 } | 1823 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1985 if (cell.isBaselineAligned()) { | 1991 if (cell.isBaselineAligned()) { |
| 1986 int baseline = cell.cellBaselinePosition(); | 1992 int baseline = cell.cellBaselinePosition(); |
| 1987 if (baseline > cell.borderBefore() + cell.paddingBefore()) | 1993 if (baseline > cell.borderBefore() + cell.paddingBefore()) |
| 1988 m_grid[rowIndex].baseline = std::max(m_grid[rowIndex].baseline, baseline); | 1994 m_grid[rowIndex].baseline = std::max(m_grid[rowIndex].baseline, baseline); |
| 1989 } | 1995 } |
| 1990 } | 1996 } |
| 1991 | 1997 |
| 1992 int LayoutTableSection::logicalHeightForRow( | 1998 int LayoutTableSection::logicalHeightForRow( |
| 1993 const LayoutTableRow& rowObject) const { | 1999 const LayoutTableRow& rowObject) const { |
| 1994 unsigned rowIndex = rowObject.rowIndex(); | 2000 unsigned rowIndex = rowObject.rowIndex(); |
| 1995 DCHECK(rowIndex < m_grid.size()); | 2001 DCHECK_LT(rowIndex, m_grid.size()); |
| 1996 int logicalHeight = 0; | 2002 int logicalHeight = 0; |
| 1997 const Row& row = m_grid[rowIndex].row; | 2003 const Row& row = m_grid[rowIndex].row; |
| 1998 unsigned cols = row.size(); | 2004 unsigned cols = row.size(); |
| 1999 for (unsigned colIndex = 0; colIndex < cols; colIndex++) { | 2005 for (unsigned colIndex = 0; colIndex < cols; colIndex++) { |
| 2000 const CellStruct& cellStruct = cellAt(rowIndex, colIndex); | 2006 const CellStruct& cellStruct = cellAt(rowIndex, colIndex); |
| 2001 const LayoutTableCell* cell = cellStruct.primaryCell(); | 2007 const LayoutTableCell* cell = cellStruct.primaryCell(); |
| 2002 if (!cell || cellStruct.inColSpan) | 2008 if (!cell || cellStruct.inColSpan) |
| 2003 continue; | 2009 continue; |
| 2004 unsigned rowSpan = cell->rowSpan(); | 2010 unsigned rowSpan = cell->rowSpan(); |
| 2005 if (rowSpan == 1) { | 2011 if (rowSpan == 1) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2132 transformState.flatten(); | 2138 transformState.flatten(); |
| 2133 FloatRect rect = transformState.lastPlanarQuad().boundingBox(); | 2139 FloatRect rect = transformState.lastPlanarQuad().boundingBox(); |
| 2134 rect.setHeight(table()->logicalHeight()); | 2140 rect.setHeight(table()->logicalHeight()); |
| 2135 transformState.setQuad(FloatQuad(rect)); | 2141 transformState.setQuad(FloatQuad(rect)); |
| 2136 } | 2142 } |
| 2137 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpaceInternal( | 2143 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpaceInternal( |
| 2138 ancestor, transformState, flags); | 2144 ancestor, transformState, flags); |
| 2139 } | 2145 } |
| 2140 | 2146 |
| 2141 } // namespace blink | 2147 } // namespace blink |
| OLD | NEW |