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, 2007, 2008, 2009, 2010, 2013 Apple Inc. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 // layout. | 96 // layout. |
97 if (Style()->IsFixedTableLayout()) | 97 if (Style()->IsFixedTableLayout()) |
98 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmFixed>(this); | 98 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmFixed>(this); |
99 else | 99 else |
100 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmAuto>(this); | 100 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmAuto>(this); |
101 } | 101 } |
102 | 102 |
103 if (!old_style) | 103 if (!old_style) |
104 return; | 104 return; |
105 | 105 |
106 if (old_style->BorderCollapse() != StyleRef().BorderCollapse()) { | 106 if (old_style->BorderCollapse() != StyleRef().BorderCollapse()) |
107 InvalidateCollapsedBorders(); | 107 SetNeedsInvalidateCollapsedBordersForAllCells(); |
108 } else { | 108 else if (LayoutTableBoxComponent:: |
109 LayoutTableBoxComponent::InvalidateCollapsedBordersOnStyleChange( | 109 NeedsInvalidateCollapsedBordersOnStyleChange(*this, *this, diff, |
110 *this, *this, diff, *old_style); | 110 *old_style)) |
111 } | 111 InvalidateCollapsedBordersOfAffectedCells(); |
112 | 112 |
113 if (LayoutTableBoxComponent::DoCellsHaveDirtyWidth(*this, *this, diff, | 113 if (LayoutTableBoxComponent::DoCellsHaveDirtyWidth(*this, *this, diff, |
114 *old_style)) | 114 *old_style)) |
115 MarkAllCellsWidthsDirtyAndOrNeedsLayout(kMarkDirtyAndNeedsLayout); | 115 MarkAllCellsWidthsDirtyAndOrNeedsLayout(kMarkDirtyAndNeedsLayout); |
116 } | 116 } |
117 | 117 |
118 static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr, | 118 static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr, |
119 LayoutObject* before) { | 119 LayoutObject* before) { |
120 if (!before || !ptr) | 120 if (!before || !ptr) |
121 return; | 121 return; |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 row = row->NextRow()) { | 800 row = row->NextRow()) { |
801 for (LayoutTableCell* cell = row->FirstCell(); cell; | 801 for (LayoutTableCell* cell = row->FirstCell(); cell; |
802 cell = cell->NextCell()) { | 802 cell = cell->NextCell()) { |
803 DCHECK_EQ(cell->Table(), this); | 803 DCHECK_EQ(cell->Table(), this); |
804 cell->InvalidateCollapsedBorderValues(); | 804 cell->InvalidateCollapsedBorderValues(); |
805 } | 805 } |
806 } | 806 } |
807 } | 807 } |
808 } | 808 } |
809 | 809 |
810 void LayoutTable::InvalidateCollapsedBordersOfAffectedCells() { | |
811 DCHECK(CollapseBorders()); | |
812 if (NeedsInvalidateCollapsedBordersForAllCells()) | |
813 return; | |
814 | |
815 RecalcSectionsIfNeeded(); | |
816 InvalidateCollapsedBorders(); | |
817 | |
818 auto* top_section = TopNonEmptySection(); | |
819 if (!top_section) | |
820 return; | |
821 | |
822 // Invalidate cells in the top row. | |
823 top_section->InvalidateCellCollapsedBordersIntersectingRow(0); | |
824 | |
825 LayoutTableSection* bottom_section = nullptr; | |
826 for (auto* section = top_section; section; | |
827 section = SectionBelow(section, kSkipEmptySections)) { | |
828 auto num_effective_columns = section->NumEffectiveColumns(); | |
829 for (unsigned r = 0; r < section->NumRows(); ++r) { | |
830 if (auto* cell = section->PrimaryCellAt(r, 0)) | |
831 cell->InvalidateCollapsedBorderValues(); | |
832 if (auto* cell = section->PrimaryCellAt(r, num_effective_columns - 1)) | |
833 cell->InvalidateCollapsedBorderValues(); | |
834 } | |
835 bottom_section = section; | |
836 } | |
837 | |
838 if (bottom_section != top_section || bottom_section->NumRows() > 1) { | |
839 bottom_section->InvalidateCellCollapsedBordersIntersectingRow( | |
840 bottom_section->NumRows() - 1); | |
841 } | |
842 } | |
843 | |
810 // Collect all the unique border values that we want to paint in a sorted list. | 844 // Collect all the unique border values that we want to paint in a sorted list. |
811 // During the collection, each cell saves its recalculated borders into the | 845 // During the collection, each cell saves its recalculated borders into the |
812 // cache of its containing section, and invalidates itself if any border | 846 // cache of its containing section, and invalidates itself if any border |
813 // changes. This method doesn't affect layout. | 847 // changes. This method doesn't affect layout. |
814 void LayoutTable::RecalcCollapsedBordersIfNeeded() { | 848 void LayoutTable::RecalcCollapsedBordersIfNeeded() { |
815 if (collapsed_borders_valid_ || !CollapseBorders()) | 849 if (collapsed_borders_valid_ || !CollapseBorders()) |
816 return; | 850 return; |
817 collapsed_borders_valid_ = true; | 851 collapsed_borders_valid_ = true; |
818 collapsed_borders_.clear(); | 852 collapsed_borders_.clear(); |
819 for (LayoutObject* section = FirstChild(); section; | 853 for (LayoutObject* section = FirstChild(); section; |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 child = child->PreviousSibling()) { | 1522 child = child->PreviousSibling()) { |
1489 if (child->IsTableSection()) | 1523 if (child->IsTableSection()) |
1490 return ToLayoutTableSection(child); | 1524 return ToLayoutTableSection(child); |
1491 } | 1525 } |
1492 | 1526 |
1493 return nullptr; | 1527 return nullptr; |
1494 } | 1528 } |
1495 | 1529 |
1496 LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell* cell) const { | 1530 LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell* cell) const { |
1497 RecalcSectionsIfNeeded(); | 1531 RecalcSectionsIfNeeded(); |
1498 | 1532 return cell->Section()->PrimaryCellAboveInTable( |
1499 // Find the section and row to look in | 1533 cell->RowIndex(), |
wkorman
2017/04/27 22:05:36
Is the simplified logic here and in CellBelow bene
| |
1500 unsigned r = cell->RowIndex(); | 1534 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex())); |
1501 LayoutTableSection* section = nullptr; | |
1502 unsigned r_above = 0; | |
1503 if (r > 0) { | |
1504 // cell is not in the first row, so use the above row in its own section | |
1505 section = cell->Section(); | |
1506 r_above = r - 1; | |
1507 } else { | |
1508 section = SectionAbove(cell->Section(), kSkipEmptySections); | |
1509 if (section) { | |
1510 DCHECK(section->NumRows()); | |
1511 r_above = section->NumRows() - 1; | |
1512 } | |
1513 } | |
1514 | |
1515 // Look up the cell in the section's grid, which requires effective col index | |
1516 if (section) { | |
1517 unsigned eff_col = | |
1518 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()); | |
1519 return section->PrimaryCellAt(r_above, eff_col); | |
1520 } | |
1521 return nullptr; | |
1522 } | 1535 } |
1523 | 1536 |
1524 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const { | 1537 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const { |
1525 RecalcSectionsIfNeeded(); | 1538 RecalcSectionsIfNeeded(); |
1526 | 1539 return cell->Section()->PrimaryCellBelowInTable( |
1527 // Find the section and row to look in | 1540 cell->RowIndex(), |
1528 unsigned r = cell->RowIndex() + cell->RowSpan() - 1; | 1541 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex())); |
1529 LayoutTableSection* section = nullptr; | |
1530 unsigned r_below = 0; | |
1531 if (r < cell->Section()->NumRows() - 1) { | |
1532 // The cell is not in the last row, so use the next row in the section. | |
1533 section = cell->Section(); | |
1534 r_below = r + 1; | |
1535 } else { | |
1536 section = SectionBelow(cell->Section(), kSkipEmptySections); | |
1537 if (section) | |
1538 r_below = 0; | |
1539 } | |
1540 | |
1541 // Look up the cell in the section's grid, which requires effective col index | |
1542 if (section) { | |
1543 unsigned eff_col = | |
1544 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()); | |
1545 return section->PrimaryCellAt(r_below, eff_col); | |
1546 } | |
1547 return nullptr; | |
1548 } | 1542 } |
1549 | 1543 |
1550 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const { | 1544 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const { |
1551 RecalcSectionsIfNeeded(); | 1545 RecalcSectionsIfNeeded(); |
1552 | 1546 |
1553 LayoutTableSection* section = cell->Section(); | 1547 LayoutTableSection* section = cell->Section(); |
1554 unsigned eff_col = | 1548 unsigned eff_col = |
1555 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()); | 1549 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()); |
1556 if (!eff_col) | 1550 if (!eff_col) |
1557 return nullptr; | 1551 return nullptr; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 } | 1756 } |
1763 | 1757 |
1764 LayoutUnit LayoutTable::PaddingRight() const { | 1758 LayoutUnit LayoutTable::PaddingRight() const { |
1765 if (CollapseBorders()) | 1759 if (CollapseBorders()) |
1766 return LayoutUnit(); | 1760 return LayoutUnit(); |
1767 | 1761 |
1768 return LayoutBlock::PaddingRight(); | 1762 return LayoutBlock::PaddingRight(); |
1769 } | 1763 } |
1770 | 1764 |
1771 } // namespace blink | 1765 } // namespace blink |
OLD | NEW |