| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 LayoutTableSection::LayoutTableSection(Element* element) | 99 LayoutTableSection::LayoutTableSection(Element* element) |
| 100 : LayoutTableBoxComponent(element), | 100 : LayoutTableBoxComponent(element), |
| 101 m_cCol(0), | 101 m_cCol(0), |
| 102 m_cRow(0), | 102 m_cRow(0), |
| 103 m_outerBorderStart(0), | 103 m_outerBorderStart(0), |
| 104 m_outerBorderEnd(0), | 104 m_outerBorderEnd(0), |
| 105 m_outerBorderBefore(0), | 105 m_outerBorderBefore(0), |
| 106 m_outerBorderAfter(0), | 106 m_outerBorderAfter(0), |
| 107 m_needsCellRecalc(false), | 107 m_needsCellRecalc(false), |
| 108 m_forceSlowPaintPathWithOverflowingCell(false), | 108 m_forceSlowPaintPathWithOverflowingCell(false), |
| 109 m_hasMultipleCellLevels(false) { | 109 m_hasMultipleCellLevels(false), |
| 110 m_hasSpanningCells(false) { |
| 110 // init LayoutObject attributes | 111 // init LayoutObject attributes |
| 111 setInline(false); // our object is not Inline | 112 setInline(false); // our object is not Inline |
| 112 } | 113 } |
| 113 | 114 |
| 114 LayoutTableSection::~LayoutTableSection() {} | 115 LayoutTableSection::~LayoutTableSection() {} |
| 115 | 116 |
| 116 void LayoutTableSection::styleDidChange(StyleDifference diff, | 117 void LayoutTableSection::styleDidChange(StyleDifference diff, |
| 117 const ComputedStyle* oldStyle) { | 118 const ComputedStyle* oldStyle) { |
| 118 DCHECK(style()->display() == EDisplay::kTableFooterGroup || | 119 DCHECK(style()->display() == EDisplay::kTableFooterGroup || |
| 119 style()->display() == EDisplay::kTableRowGroup || | 120 style()->display() == EDisplay::kTableRowGroup || |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { | 241 void LayoutTableSection::addCell(LayoutTableCell* cell, LayoutTableRow* row) { |
| 241 // 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' |
| 242 // representation will have drifted from the table's representation. Also | 243 // representation will have drifted from the table's representation. Also |
| 243 // 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' |
| 244 // with the table's. | 245 // with the table's. |
| 245 if (needsCellRecalc()) | 246 if (needsCellRecalc()) |
| 246 return; | 247 return; |
| 247 | 248 |
| 248 unsigned rSpan = cell->rowSpan(); | 249 unsigned rSpan = cell->rowSpan(); |
| 249 unsigned cSpan = cell->colSpan(); | 250 unsigned cSpan = cell->colSpan(); |
| 251 if (rSpan > 1 || cSpan > 1) |
| 252 m_hasSpanningCells = true; |
| 253 |
| 250 const Vector<LayoutTable::ColumnStruct>& columns = | 254 const Vector<LayoutTable::ColumnStruct>& columns = |
| 251 table()->effectiveColumns(); | 255 table()->effectiveColumns(); |
| 252 unsigned insertionRow = row->rowIndex(); | 256 unsigned insertionRow = row->rowIndex(); |
| 253 | 257 |
| 254 // ### mozilla still seems to do the old HTML way, even for strict DTD | 258 // ### mozilla still seems to do the old HTML way, even for strict DTD |
| 255 // (see the annotation on table cell layouting in the CSS specs and the | 259 // (see the annotation on table cell layouting in the CSS specs and the |
| 256 // testcase below: | 260 // testcase below: |
| 257 // <TABLE border> | 261 // <TABLE border> |
| 258 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 | 262 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 |
| 259 // <TR><TD colspan="2">5 | 263 // <TR><TD colspan="2">5 |
| (...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1539 if (coveredRows.start() == m_rowPos.size() - 1 && | 1543 if (coveredRows.start() == m_rowPos.size() - 1 && |
| 1540 m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= | 1544 m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= |
| 1541 damageRect.y()) | 1545 damageRect.y()) |
| 1542 coveredRows.decreaseStart(); | 1546 coveredRows.decreaseStart(); |
| 1543 | 1547 |
| 1544 if (!coveredRows.end() && | 1548 if (!coveredRows.end() && |
| 1545 m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY()) | 1549 m_rowPos[0] - table()->outerBorderBefore() <= damageRect.maxY()) |
| 1546 coveredRows.increaseEnd(); | 1550 coveredRows.increaseEnd(); |
| 1547 | 1551 |
| 1548 coveredRows.ensureConsistency(m_grid.size()); | 1552 coveredRows.ensureConsistency(m_grid.size()); |
| 1553 if (!m_hasSpanningCells || !coveredRows.start() || |
| 1554 coveredRows.start() >= m_grid.size()) |
| 1555 return coveredRows; |
| 1549 | 1556 |
| 1550 return coveredRows; | 1557 // If there are any cells spanning into the first row, expand coveredRows |
| 1558 // to cover the primary cells. |
| 1559 unsigned nCols = numCols(coveredRows.start()); |
| 1560 unsigned smallestRow = coveredRows.start(); |
| 1561 CellSpan coveredColumns = spannedEffectiveColumns(damageRect); |
| 1562 for (unsigned c = coveredColumns.start(); |
| 1563 c < std::min(coveredColumns.end(), nCols); ++c) { |
| 1564 if (const auto* cell = primaryCellAt(coveredRows.start(), c)) { |
| 1565 smallestRow = std::min(smallestRow, cell->rowIndex()); |
| 1566 if (!smallestRow) |
| 1567 break; |
| 1568 } |
| 1569 } |
| 1570 return CellSpan(smallestRow, coveredRows.end()); |
| 1551 } | 1571 } |
| 1552 | 1572 |
| 1553 CellSpan LayoutTableSection::dirtiedEffectiveColumns( | 1573 CellSpan LayoutTableSection::dirtiedEffectiveColumns( |
| 1554 const LayoutRect& damageRect) const { | 1574 const LayoutRect& damageRect) const { |
| 1555 if (m_forceSlowPaintPathWithOverflowingCell) | 1575 if (m_forceSlowPaintPathWithOverflowingCell) |
| 1556 return fullTableEffectiveColumnSpan(); | 1576 return fullTableEffectiveColumnSpan(); |
| 1557 | 1577 |
| 1558 CHECK(table()->numEffectiveColumns()); | 1578 CHECK(table()->numEffectiveColumns()); |
| 1559 CellSpan coveredColumns = spannedEffectiveColumns(damageRect); | 1579 CellSpan coveredColumns = spannedEffectiveColumns(damageRect); |
| 1560 | 1580 |
| 1561 const Vector<int>& columnPos = table()->effectiveColumnPositions(); | 1581 const Vector<int>& columnPos = table()->effectiveColumnPositions(); |
| 1562 // To issue paint invalidations for the border we might need to paint | 1582 // To issue paint invalidations for the border we might need to paint |
| 1563 // invalidate the first or last column even if they are not spanned | 1583 // invalidate the first or last column even if they are not spanned |
| 1564 // themselves. | 1584 // themselves. |
| 1565 CHECK_LT(coveredColumns.start(), columnPos.size()); | 1585 CHECK_LT(coveredColumns.start(), columnPos.size()); |
| 1566 if (coveredColumns.start() == columnPos.size() - 1 && | 1586 if (coveredColumns.start() == columnPos.size() - 1 && |
| 1567 columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= | 1587 columnPos[columnPos.size() - 1] + table()->outerBorderEnd() >= |
| 1568 damageRect.x()) | 1588 damageRect.x()) |
| 1569 coveredColumns.decreaseStart(); | 1589 coveredColumns.decreaseStart(); |
| 1570 | 1590 |
| 1571 if (!coveredColumns.end() && | 1591 if (!coveredColumns.end() && |
| 1572 columnPos[0] - table()->outerBorderStart() <= damageRect.maxX()) | 1592 columnPos[0] - table()->outerBorderStart() <= damageRect.maxX()) |
| 1573 coveredColumns.increaseEnd(); | 1593 coveredColumns.increaseEnd(); |
| 1574 | 1594 |
| 1575 coveredColumns.ensureConsistency(table()->numEffectiveColumns()); | 1595 coveredColumns.ensureConsistency(table()->numEffectiveColumns()); |
| 1596 if (!m_hasSpanningCells || !coveredColumns.start()) |
| 1597 return coveredColumns; |
| 1576 | 1598 |
| 1577 return coveredColumns; | 1599 // If there are any cells spanning into the first column, expand |
| 1600 // coveredRows to cover the primary cells. |
| 1601 unsigned smallestColumn = coveredColumns.start(); |
| 1602 CellSpan coveredRows = spannedRows(damageRect); |
| 1603 for (unsigned r = coveredRows.start(); r < coveredRows.end(); ++r) { |
| 1604 const auto& row = m_grid[r].row; |
| 1605 if (coveredColumns.start() < row.size()) { |
| 1606 unsigned c = coveredColumns.start(); |
| 1607 while (c && row[c].inColSpan) |
| 1608 --c; |
| 1609 smallestColumn = std::min(c, smallestColumn); |
| 1610 if (!smallestColumn) |
| 1611 break; |
| 1612 } |
| 1613 } |
| 1614 return CellSpan(smallestColumn, coveredColumns.end()); |
| 1578 } | 1615 } |
| 1579 | 1616 |
| 1580 CellSpan LayoutTableSection::spannedRows(const LayoutRect& flippedRect) const { | 1617 CellSpan LayoutTableSection::spannedRows(const LayoutRect& flippedRect) const { |
| 1581 // Find the first row that starts after rect top. | 1618 // Find the first row that starts after rect top. |
| 1582 unsigned nextRow = | 1619 unsigned nextRow = |
| 1583 std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - | 1620 std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - |
| 1584 m_rowPos.begin(); | 1621 m_rowPos.begin(); |
| 1585 | 1622 |
| 1586 // After all rows. | 1623 // After all rows. |
| 1587 if (nextRow == m_rowPos.size()) | 1624 if (nextRow == m_rowPos.size()) |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 return primaryCellAt(0, adjoiningStartCellColumnIndex); | 1761 return primaryCellAt(0, adjoiningStartCellColumnIndex); |
| 1725 } | 1762 } |
| 1726 | 1763 |
| 1727 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() | 1764 const LayoutTableCell* LayoutTableSection::firstRowCellAdjoiningTableEnd() |
| 1728 const { | 1765 const { |
| 1729 unsigned adjoiningEndCellColumnIndex = | 1766 unsigned adjoiningEndCellColumnIndex = |
| 1730 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; | 1767 hasSameDirectionAs(table()) ? table()->lastEffectiveColumnIndex() : 0; |
| 1731 return primaryCellAt(0, adjoiningEndCellColumnIndex); | 1768 return primaryCellAt(0, adjoiningEndCellColumnIndex); |
| 1732 } | 1769 } |
| 1733 | 1770 |
| 1771 const LayoutTableCell* LayoutTableSection::originatingCellAt( |
| 1772 unsigned row, |
| 1773 unsigned effectiveColumn) const { |
| 1774 const auto& rowVector = m_grid[row].row; |
| 1775 if (effectiveColumn >= rowVector.size()) |
| 1776 return nullptr; |
| 1777 const auto& cellStruct = rowVector[effectiveColumn]; |
| 1778 if (cellStruct.inColSpan) |
| 1779 return nullptr; |
| 1780 if (const auto* cell = cellStruct.primaryCell()) { |
| 1781 if (cell->rowIndex() == row) |
| 1782 return cell; |
| 1783 } |
| 1784 return nullptr; |
| 1785 } |
| 1786 |
| 1734 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { | 1787 void LayoutTableSection::appendEffectiveColumn(unsigned pos) { |
| 1735 ASSERT(!m_needsCellRecalc); | 1788 ASSERT(!m_needsCellRecalc); |
| 1736 | 1789 |
| 1737 for (unsigned row = 0; row < m_grid.size(); ++row) | 1790 for (unsigned row = 0; row < m_grid.size(); ++row) |
| 1738 m_grid[row].row.resize(pos + 1); | 1791 m_grid[row].row.resize(pos + 1); |
| 1739 } | 1792 } |
| 1740 | 1793 |
| 1741 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { | 1794 void LayoutTableSection::splitEffectiveColumn(unsigned pos, unsigned first) { |
| 1742 ASSERT(!m_needsCellRecalc); | 1795 ASSERT(!m_needsCellRecalc); |
| 1743 | 1796 |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2079 transformState.flatten(); | 2132 transformState.flatten(); |
| 2080 FloatRect rect = transformState.lastPlanarQuad().boundingBox(); | 2133 FloatRect rect = transformState.lastPlanarQuad().boundingBox(); |
| 2081 rect.setHeight(table()->logicalHeight()); | 2134 rect.setHeight(table()->logicalHeight()); |
| 2082 transformState.setQuad(FloatQuad(rect)); | 2135 transformState.setQuad(FloatQuad(rect)); |
| 2083 } | 2136 } |
| 2084 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpaceInternal( | 2137 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpaceInternal( |
| 2085 ancestor, transformState, flags); | 2138 ancestor, transformState, flags); |
| 2086 } | 2139 } |
| 2087 | 2140 |
| 2088 } // namespace blink | 2141 } // namespace blink |
| OLD | NEW |