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 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 const Vector<int>& column_pos = Table()->EffectiveColumnPositions(); | 1522 const Vector<int>& column_pos = Table()->EffectiveColumnPositions(); |
1523 // FIXME: The table's direction should determine our row's direction, not the | 1523 // FIXME: The table's direction should determine our row's direction, not the |
1524 // section's (see bug 96691). | 1524 // section's (see bug 96691). |
1525 if (!Style()->IsLeftToRightDirection()) | 1525 if (!Style()->IsLeftToRightDirection()) |
1526 table_aligned_rect.SetX(column_pos[column_pos.size() - 1] - | 1526 table_aligned_rect.SetX(column_pos[column_pos.size() - 1] - |
1527 table_aligned_rect.MaxX()); | 1527 table_aligned_rect.MaxX()); |
1528 | 1528 |
1529 return table_aligned_rect; | 1529 return table_aligned_rect; |
1530 } | 1530 } |
1531 | 1531 |
1532 CellSpan LayoutTableSection::DirtiedRows(const LayoutRect& damage_rect) const { | 1532 void LayoutTableSection::DirtiedRowsAndEffectiveColumns( |
1533 if (force_full_paint_) | 1533 const LayoutRect& damage_rect, |
1534 return FullSectionRowSpan(); | 1534 CellSpan& rows, |
| 1535 CellSpan& columns) const { |
| 1536 if (!grid_.size()) { |
| 1537 rows = CellSpan(); |
| 1538 columns = CellSpan(); |
| 1539 } |
1535 | 1540 |
1536 if (!grid_.size()) | 1541 if (force_full_paint_) { |
1537 return CellSpan(0, 0); | 1542 rows = FullSectionRowSpan(); |
| 1543 columns = FullTableEffectiveColumnSpan(); |
| 1544 return; |
| 1545 } |
1538 | 1546 |
1539 CellSpan covered_rows = SpannedRows(damage_rect); | 1547 rows = SpannedRows(damage_rect); |
| 1548 columns = SpannedEffectiveColumns(damage_rect); |
1540 | 1549 |
1541 // To paint the border we might need to paint the first or last row even if | 1550 // Expand by one cell in each direction to cover any collapsed borders. |
1542 // they are not spanned themselves. | 1551 if (Table()->ShouldCollapseBorders()) { |
1543 CHECK_LT(covered_rows.Start(), row_pos_.size()); | 1552 if (rows.Start() > 0) |
1544 if (covered_rows.Start() == row_pos_.size() - 1 && | 1553 rows.DecreaseStart(); |
1545 row_pos_[row_pos_.size() - 1] + Table()->OuterBorderAfter() >= | 1554 if (rows.End() < grid_.size()) |
1546 damage_rect.Y()) | 1555 rows.IncreaseEnd(); |
1547 covered_rows.DecreaseStart(); | 1556 if (columns.Start() > 0) |
| 1557 columns.DecreaseStart(); |
| 1558 if (columns.End() < Table()->NumEffectiveColumns()) |
| 1559 columns.IncreaseEnd(); |
| 1560 } |
1548 | 1561 |
1549 if (!covered_rows.end() && | 1562 rows.EnsureConsistency(grid_.size()); |
1550 row_pos_[0] - Table()->OuterBorderBefore() <= damage_rect.MaxY()) | 1563 columns.EnsureConsistency(Table()->NumEffectiveColumns()); |
1551 covered_rows.IncreaseEnd(); | |
1552 | 1564 |
1553 covered_rows.EnsureConsistency(grid_.size()); | 1565 if (!has_spanning_cells_) |
1554 if (!has_spanning_cells_ || !covered_rows.Start() || | 1566 return; |
1555 covered_rows.Start() >= grid_.size()) | |
1556 return covered_rows; | |
1557 | 1567 |
1558 // If there are any cells spanning into the first row, expand covered_rows | 1568 if (rows.Start() > 0 && rows.Start() < grid_.size()) { |
1559 // to cover the primary cells. | 1569 // If there are any cells spanning into the first row, expand |rows| to |
1560 unsigned n_cols = NumEffectiveColumns(covered_rows.Start()); | 1570 // cover the cells. |
1561 unsigned smallest_row = covered_rows.Start(); | 1571 unsigned n_cols = NumEffectiveColumns(rows.Start()); |
1562 CellSpan covered_columns = SpannedEffectiveColumns(damage_rect); | 1572 unsigned smallest_row = rows.Start(); |
1563 for (unsigned c = covered_columns.Start(); | 1573 for (unsigned c = columns.Start(); c < std::min(columns.End(), n_cols); |
1564 c < std::min(covered_columns.end(), n_cols); ++c) { | 1574 ++c) { |
1565 if (const auto* cell = PrimaryCellAt(covered_rows.Start(), c)) { | 1575 for (const auto* cell : GridCellAt(rows.Start(), c).Cells()) { |
1566 smallest_row = std::min(smallest_row, cell->RowIndex()); | 1576 smallest_row = std::min(smallest_row, cell->RowIndex()); |
1567 if (!smallest_row) | 1577 if (!smallest_row) |
1568 break; | 1578 break; |
| 1579 } |
1569 } | 1580 } |
| 1581 rows = CellSpan(smallest_row, rows.End()); |
1570 } | 1582 } |
1571 return CellSpan(smallest_row, covered_rows.end()); | |
1572 } | |
1573 | 1583 |
1574 CellSpan LayoutTableSection::DirtiedEffectiveColumns( | 1584 if (columns.Start() > 0 && columns.Start() < Table()->NumEffectiveColumns()) { |
1575 const LayoutRect& damage_rect) const { | 1585 // If there are any cells spanning into the first column, expand |columns| |
1576 if (force_full_paint_) | 1586 // to cover the cells. |
1577 return FullTableEffectiveColumnSpan(); | 1587 unsigned smallest_column = columns.Start(); |
1578 | 1588 for (unsigned r = rows.Start(); r < rows.End(); ++r) { |
1579 CHECK(Table()->NumEffectiveColumns()); | 1589 const auto& grid_cells = grid_[r].grid_cells; |
1580 CellSpan covered_columns = SpannedEffectiveColumns(damage_rect); | 1590 if (columns.Start() < grid_cells.size()) { |
1581 | 1591 unsigned c = columns.Start(); |
1582 const Vector<int>& column_pos = Table()->EffectiveColumnPositions(); | 1592 while (c && grid_cells[c].InColSpan()) |
1583 // To paint the border we might need to paint the first or last column even if | 1593 --c; |
1584 // they are not spanned themselves. | 1594 smallest_column = std::min(c, smallest_column); |
1585 CHECK_LT(covered_columns.Start(), column_pos.size()); | 1595 if (!smallest_column) |
1586 if (covered_columns.Start() == column_pos.size() - 1 && | 1596 break; |
1587 column_pos[column_pos.size() - 1] + Table()->OuterBorderEnd() >= | 1597 } |
1588 damage_rect.X()) | |
1589 covered_columns.DecreaseStart(); | |
1590 | |
1591 if (!covered_columns.end() && | |
1592 column_pos[0] - Table()->OuterBorderStart() <= damage_rect.MaxX()) | |
1593 covered_columns.IncreaseEnd(); | |
1594 | |
1595 covered_columns.EnsureConsistency(Table()->NumEffectiveColumns()); | |
1596 if (!has_spanning_cells_ || !covered_columns.Start()) | |
1597 return covered_columns; | |
1598 | |
1599 // If there are any cells spanning into the first column, expand | |
1600 // covered_columns to cover the primary cells. | |
1601 unsigned smallest_column = covered_columns.Start(); | |
1602 CellSpan covered_rows = SpannedRows(damage_rect); | |
1603 for (unsigned r = covered_rows.Start(); r < covered_rows.end(); ++r) { | |
1604 const auto& grid_cells = grid_[r].grid_cells; | |
1605 if (covered_columns.Start() < grid_cells.size()) { | |
1606 unsigned c = covered_columns.Start(); | |
1607 while (c && grid_cells[c].InColSpan()) | |
1608 --c; | |
1609 smallest_column = std::min(c, smallest_column); | |
1610 if (!smallest_column) | |
1611 break; | |
1612 } | 1598 } |
| 1599 columns = CellSpan(smallest_column, columns.End()); |
1613 } | 1600 } |
1614 return CellSpan(smallest_column, covered_columns.end()); | |
1615 } | 1601 } |
1616 | 1602 |
1617 CellSpan LayoutTableSection::SpannedRows(const LayoutRect& flipped_rect) const { | 1603 CellSpan LayoutTableSection::SpannedRows(const LayoutRect& flipped_rect) const { |
1618 // Find the first row that starts after rect top. | 1604 // Find the first row that starts after rect top. |
1619 unsigned next_row = | 1605 unsigned next_row = |
1620 std::upper_bound(row_pos_.begin(), row_pos_.end(), flipped_rect.Y()) - | 1606 std::upper_bound(row_pos_.begin(), row_pos_.end(), flipped_rect.Y()) - |
1621 row_pos_.begin(); | 1607 row_pos_.begin(); |
1622 | 1608 |
1623 // After all rows. | 1609 // After all rows. |
1624 if (next_row == row_pos_.size()) | 1610 if (next_row == row_pos_.size()) |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 | 1848 |
1863 LayoutRect hit_test_rect = LayoutRect(location_in_container.BoundingBox()); | 1849 LayoutRect hit_test_rect = LayoutRect(location_in_container.BoundingBox()); |
1864 hit_test_rect.MoveBy(-adjusted_location); | 1850 hit_test_rect.MoveBy(-adjusted_location); |
1865 | 1851 |
1866 LayoutRect table_aligned_rect = | 1852 LayoutRect table_aligned_rect = |
1867 LogicalRectForWritingModeAndDirection(hit_test_rect); | 1853 LogicalRectForWritingModeAndDirection(hit_test_rect); |
1868 CellSpan row_span = SpannedRows(table_aligned_rect); | 1854 CellSpan row_span = SpannedRows(table_aligned_rect); |
1869 CellSpan column_span = SpannedEffectiveColumns(table_aligned_rect); | 1855 CellSpan column_span = SpannedEffectiveColumns(table_aligned_rect); |
1870 | 1856 |
1871 // Now iterate over the spanned rows and columns. | 1857 // Now iterate over the spanned rows and columns. |
1872 for (unsigned hit_row = row_span.Start(); hit_row < row_span.end(); | 1858 for (unsigned hit_row = row_span.Start(); hit_row < row_span.End(); |
1873 ++hit_row) { | 1859 ++hit_row) { |
1874 unsigned n_cols = NumEffectiveColumns(hit_row); | 1860 unsigned n_cols = NumEffectiveColumns(hit_row); |
1875 for (unsigned hit_column = column_span.Start(); | 1861 for (unsigned hit_column = column_span.Start(); |
1876 hit_column < n_cols && hit_column < column_span.end(); ++hit_column) { | 1862 hit_column < n_cols && hit_column < column_span.End(); ++hit_column) { |
1877 auto& grid_cell = GridCellAt(hit_row, hit_column); | 1863 auto& grid_cell = GridCellAt(hit_row, hit_column); |
1878 | 1864 |
1879 // If the cell is empty, there's nothing to do | 1865 // If the cell is empty, there's nothing to do |
1880 if (!grid_cell.HasCells()) | 1866 if (!grid_cell.HasCells()) |
1881 continue; | 1867 continue; |
1882 | 1868 |
1883 for (unsigned i = grid_cell.Cells().size(); i;) { | 1869 for (unsigned i = grid_cell.Cells().size(); i;) { |
1884 --i; | 1870 --i; |
1885 LayoutTableCell* cell = grid_cell.Cells()[i]; | 1871 LayoutTableCell* cell = grid_cell.Cells()[i]; |
1886 LayoutPoint cell_point = | 1872 LayoutPoint cell_point = |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() | 2131 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() |
2146 const { | 2132 const { |
2147 // LayoutTableSection paints background from columns. | 2133 // LayoutTableSection paints background from columns. |
2148 if (Table()->HasColElements()) | 2134 if (Table()->HasColElements()) |
2149 return false; | 2135 return false; |
2150 return LayoutTableBoxComponent:: | 2136 return LayoutTableBoxComponent:: |
2151 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); | 2137 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); |
2152 } | 2138 } |
2153 | 2139 |
2154 } // namespace blink | 2140 } // namespace blink |
OLD | NEW |