Chromium Code Reviews| 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 24 matching lines...) Expand all Loading... | |
| 35 #include "core/layout/LayoutTableRow.h" | 35 #include "core/layout/LayoutTableRow.h" |
| 36 #include "core/layout/LayoutView.h" | 36 #include "core/layout/LayoutView.h" |
| 37 #include "core/layout/SubtreeLayoutScope.h" | 37 #include "core/layout/SubtreeLayoutScope.h" |
| 38 #include "core/paint/TableSectionPainter.h" | 38 #include "core/paint/TableSectionPainter.h" |
| 39 #include "platform/wtf/HashSet.h" | 39 #include "platform/wtf/HashSet.h" |
| 40 | 40 |
| 41 namespace blink { | 41 namespace blink { |
| 42 | 42 |
| 43 using namespace HTMLNames; | 43 using namespace HTMLNames; |
| 44 | 44 |
| 45 static inline void SetRowLogicalHeightToRowStyleLogicalHeight( | 45 void LayoutTableSection::GridRow::SetRowLogicalHeightToRowStyleLogicalHeight() { |
| 46 LayoutTableSection::RowStruct& row) { | 46 DCHECK(row); |
| 47 DCHECK(row.row_layout_object); | 47 logical_height = row->StyleRef().LogicalHeight(); |
| 48 row.logical_height = row.row_layout_object->Style()->LogicalHeight(); | |
| 49 } | 48 } |
| 50 | 49 |
| 51 static inline void UpdateLogicalHeightForCell( | 50 void LayoutTableSection::GridRow::UpdateLogicalHeightForCell( |
| 52 LayoutTableSection::RowStruct& row, | |
| 53 const LayoutTableCell* cell) { | 51 const LayoutTableCell* cell) { |
| 54 // We ignore height settings on rowspan cells. | 52 // We ignore height settings on rowspan cells. |
| 55 if (cell->RowSpan() != 1) | 53 if (cell->RowSpan() != 1) |
| 56 return; | 54 return; |
| 57 | 55 |
| 58 Length logical_height = cell->Style()->LogicalHeight(); | 56 Length cell_logical_height = cell->StyleRef().LogicalHeight(); |
| 59 if (logical_height.IsPositive()) { | 57 if (cell_logical_height.IsPositive()) { |
| 60 Length c_row_logical_height = row.logical_height; | 58 switch (cell_logical_height.GetType()) { |
| 61 switch (logical_height.GetType()) { | |
| 62 case kPercent: | 59 case kPercent: |
| 63 // TODO(alancutter): Make this work correctly for calc lengths. | 60 // TODO(alancutter): Make this work correctly for calc lengths. |
| 64 if (!(c_row_logical_height.IsPercentOrCalc()) || | 61 if (!(logical_height.IsPercentOrCalc()) || |
| 65 (c_row_logical_height.IsPercent() && | 62 (logical_height.IsPercent() && |
| 66 c_row_logical_height.Percent() < logical_height.Percent())) | 63 logical_height.Percent() < cell_logical_height.Percent())) |
| 67 row.logical_height = logical_height; | 64 logical_height = cell_logical_height; |
| 68 break; | 65 break; |
| 69 case kFixed: | 66 case kFixed: |
| 70 if (c_row_logical_height.GetType() < kPercent || | 67 if (logical_height.GetType() < kPercent || |
| 71 (c_row_logical_height.IsFixed() && | 68 (logical_height.IsFixed() && |
| 72 c_row_logical_height.Value() < logical_height.Value())) | 69 logical_height.Value() < cell_logical_height.Value())) |
| 73 row.logical_height = logical_height; | 70 logical_height = cell_logical_height; |
| 74 break; | 71 break; |
| 75 default: | 72 default: |
| 76 break; | 73 break; |
| 77 } | 74 } |
| 78 } | 75 } |
| 79 } | 76 } |
| 80 | 77 |
| 81 void CellSpan::EnsureConsistency(const unsigned maximum_span_size) { | 78 void CellSpan::EnsureConsistency(const unsigned maximum_span_size) { |
| 82 static_assert(std::is_same<decltype(start_), unsigned>::value, | 79 static_assert(std::is_same<decltype(start_), unsigned>::value, |
| 83 "Asserts below assume start_ is unsigned"); | 80 "Asserts below assume start_ is unsigned"); |
| 84 static_assert(std::is_same<decltype(end_), unsigned>::value, | 81 static_assert(std::is_same<decltype(end_), unsigned>::value, |
| 85 "Asserts below assume end_ is unsigned"); | 82 "Asserts below assume end_ is unsigned"); |
| 86 CHECK_LE(start_, maximum_span_size); | 83 CHECK_LE(start_, maximum_span_size); |
| 87 CHECK_LE(end_, maximum_span_size); | 84 CHECK_LE(end_, maximum_span_size); |
| 88 CHECK_LE(start_, end_); | 85 CHECK_LE(start_, end_); |
| 89 } | 86 } |
| 90 | 87 |
| 91 LayoutTableSection::CellStruct::CellStruct() : in_col_span(false) {} | |
| 92 | |
| 93 LayoutTableSection::CellStruct::~CellStruct() {} | |
| 94 | |
| 95 LayoutTableSection::LayoutTableSection(Element* element) | 88 LayoutTableSection::LayoutTableSection(Element* element) |
| 96 : LayoutTableBoxComponent(element), | 89 : LayoutTableBoxComponent(element), |
| 97 c_col_(0), | 90 c_col_(0), |
| 98 c_row_(0), | 91 c_row_(0), |
| 99 outer_border_start_(0), | 92 outer_border_start_(0), |
| 100 outer_border_end_(0), | 93 outer_border_end_(0), |
| 101 outer_border_before_(0), | 94 outer_border_before_(0), |
| 102 outer_border_after_(0), | 95 outer_border_after_(0), |
| 103 needs_cell_recalc_(false), | 96 needs_cell_recalc_(false), |
| 104 force_full_paint_(false), | 97 force_full_paint_(false), |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 if (before_child) | 179 if (before_child) |
| 187 SetNeedsCellRecalc(); | 180 SetNeedsCellRecalc(); |
| 188 | 181 |
| 189 unsigned insertion_row = c_row_; | 182 unsigned insertion_row = c_row_; |
| 190 ++c_row_; | 183 ++c_row_; |
| 191 c_col_ = 0; | 184 c_col_ = 0; |
| 192 | 185 |
| 193 EnsureRows(c_row_); | 186 EnsureRows(c_row_); |
| 194 | 187 |
| 195 LayoutTableRow* row = ToLayoutTableRow(child); | 188 LayoutTableRow* row = ToLayoutTableRow(child); |
| 196 grid_[insertion_row].row_layout_object = row; | 189 grid_[insertion_row].row = row; |
| 197 row->SetRowIndex(insertion_row); | 190 row->SetRowIndex(insertion_row); |
| 198 | 191 |
| 199 if (!before_child) | 192 if (!before_child) |
| 200 SetRowLogicalHeightToRowStyleLogicalHeight(grid_[insertion_row]); | 193 grid_[insertion_row].SetRowLogicalHeightToRowStyleLogicalHeight(); |
| 201 | 194 |
| 202 if (before_child && before_child->Parent() != this) | 195 if (before_child && before_child->Parent() != this) |
| 203 before_child = SplitAnonymousBoxesAroundChild(before_child); | 196 before_child = SplitAnonymousBoxesAroundChild(before_child); |
| 204 | 197 |
| 205 DCHECK(!before_child || before_child->IsTableRow()); | 198 DCHECK(!before_child || before_child->IsTableRow()); |
| 206 LayoutTableBoxComponent::AddChild(child, before_child); | 199 LayoutTableBoxComponent::AddChild(child, before_child); |
| 207 } | 200 } |
| 208 | 201 |
| 209 static inline void CheckThatVectorIsDOMOrdered( | 202 static inline void CheckThatVectorIsDOMOrdered( |
| 210 const Vector<LayoutTableCell*, 1>& cells) { | 203 const Vector<LayoutTableCell*, 1>& cells) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 unsigned insertion_row = row->RowIndex(); | 244 unsigned insertion_row = row->RowIndex(); |
| 252 | 245 |
| 253 // ### mozilla still seems to do the old HTML way, even for strict DTD | 246 // ### mozilla still seems to do the old HTML way, even for strict DTD |
| 254 // (see the annotation on table cell layouting in the CSS specs and the | 247 // (see the annotation on table cell layouting in the CSS specs and the |
| 255 // testcase below: | 248 // testcase below: |
| 256 // <TABLE border> | 249 // <TABLE border> |
| 257 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 | 250 // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4 |
| 258 // <TR><TD colspan="2">5 | 251 // <TR><TD colspan="2">5 |
| 259 // </TABLE> | 252 // </TABLE> |
| 260 unsigned n_cols = NumCols(insertion_row); | 253 unsigned n_cols = NumCols(insertion_row); |
| 261 while (c_col_ < n_cols && (CellAt(insertion_row, c_col_).HasCells() || | 254 while (c_col_ < n_cols && (GridCellAt(insertion_row, c_col_).HasCells() || |
| 262 CellAt(insertion_row, c_col_).in_col_span)) | 255 GridCellAt(insertion_row, c_col_).InColSpan())) |
| 263 c_col_++; | 256 c_col_++; |
| 264 | 257 |
| 265 UpdateLogicalHeightForCell(grid_[insertion_row], cell); | 258 grid_[insertion_row].UpdateLogicalHeightForCell(cell); |
| 266 | 259 |
| 267 EnsureRows(insertion_row + r_span); | 260 EnsureRows(insertion_row + r_span); |
| 268 | 261 |
| 269 grid_[insertion_row].row_layout_object = row; | 262 grid_[insertion_row].row = row; |
| 270 | 263 |
| 271 unsigned col = c_col_; | 264 unsigned col = c_col_; |
| 272 // tell the cell where it is | 265 // tell the cell where it is |
| 273 bool in_col_span = false; | 266 bool in_col_span = false; |
| 274 unsigned col_size = columns.size(); | 267 unsigned col_size = columns.size(); |
| 275 while (c_span) { | 268 while (c_span) { |
| 276 unsigned current_span; | 269 unsigned current_span; |
| 277 if (c_col_ >= col_size) { | 270 if (c_col_ >= col_size) { |
| 278 Table()->AppendEffectiveColumn(c_span); | 271 Table()->AppendEffectiveColumn(c_span); |
| 279 current_span = c_span; | 272 current_span = c_span; |
| 280 } else { | 273 } else { |
| 281 if (c_span < columns[c_col_].span) | 274 if (c_span < columns[c_col_].span) |
| 282 Table()->SplitEffectiveColumn(c_col_, c_span); | 275 Table()->SplitEffectiveColumn(c_col_, c_span); |
| 283 current_span = columns[c_col_].span; | 276 current_span = columns[c_col_].span; |
| 284 } | 277 } |
| 285 for (unsigned r = 0; r < r_span; r++) { | 278 for (unsigned r = 0; r < r_span; r++) { |
| 286 EnsureCols(insertion_row + r, c_col_ + 1); | 279 EnsureCols(insertion_row + r, c_col_ + 1); |
| 287 CellStruct& c = CellAt(insertion_row + r, c_col_); | 280 auto& grid_cell = GridCellAt(insertion_row + r, c_col_); |
| 288 DCHECK(cell); | 281 DCHECK(cell); |
|
dgrogan
2017/05/15 19:53:38
Optional cleanup while you're here? I think this D
Xianzhu
2017/05/15 20:28:38
Done.
| |
| 289 c.cells.push_back(cell); | 282 grid_cell.Cells().push_back(cell); |
| 290 CheckThatVectorIsDOMOrdered(c.cells); | 283 CheckThatVectorIsDOMOrdered(grid_cell.Cells()); |
| 291 // If cells overlap then we take the special paint path for them. | 284 // If cells overlap then we take the special paint path for them. |
| 292 if (c.cells.size() > 1) | 285 if (grid_cell.Cells().size() > 1) |
| 293 has_multiple_cell_levels_ = true; | 286 has_multiple_cell_levels_ = true; |
| 294 if (in_col_span) | 287 if (in_col_span) |
| 295 c.in_col_span = true; | 288 grid_cell.SetInColSpan(true); |
| 296 } | 289 } |
| 297 c_col_++; | 290 c_col_++; |
| 298 c_span -= current_span; | 291 c_span -= current_span; |
| 299 in_col_span = true; | 292 in_col_span = true; |
| 300 } | 293 } |
| 301 cell->SetAbsoluteColumnIndex(Table()->EffectiveColumnToAbsoluteColumn(col)); | 294 cell->SetAbsoluteColumnIndex(Table()->EffectiveColumnToAbsoluteColumn(col)); |
| 302 } | 295 } |
| 303 | 296 |
| 304 bool LayoutTableSection::RowHasOnlySpanningCells(unsigned row) { | 297 bool LayoutTableSection::RowHasOnlySpanningCells(unsigned row) { |
| 305 unsigned total_cols = grid_[row].row.size(); | 298 if (grid_[row].grid_cells.IsEmpty()) |
| 306 | |
| 307 if (!total_cols) | |
| 308 return false; | 299 return false; |
| 309 | 300 |
| 310 for (unsigned col = 0; col < total_cols; col++) { | 301 for (const auto& grid_cell : grid_[row].grid_cells) { |
| 311 const CellStruct& row_span_cell = CellAt(row, col); | |
| 312 | |
| 313 // Empty cell is not a valid cell so it is not a rowspan cell. | 302 // Empty cell is not a valid cell so it is not a rowspan cell. |
| 314 if (row_span_cell.cells.IsEmpty()) | 303 if (!grid_cell.HasCells()) |
| 315 return false; | 304 return false; |
| 316 | 305 |
| 317 if (row_span_cell.cells[0]->RowSpan() == 1) | 306 if (grid_cell.Cells()[0]->RowSpan() == 1) |
| 318 return false; | 307 return false; |
| 319 } | 308 } |
| 320 | 309 |
| 321 return true; | 310 return true; |
| 322 } | 311 } |
| 323 | 312 |
| 324 void LayoutTableSection::PopulateSpanningRowsHeightFromCell( | 313 void LayoutTableSection::PopulateSpanningRowsHeightFromCell( |
| 325 LayoutTableCell* cell, | 314 LayoutTableCell* cell, |
| 326 struct SpanningRowsHeight& spanning_rows_height) { | 315 struct SpanningRowsHeight& spanning_rows_height) { |
| 327 const unsigned row_span = cell->RowSpan(); | 316 const unsigned row_span = cell->RowSpan(); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 } | 525 } |
| 537 | 526 |
| 538 unsigned LayoutTableSection::CalcRowHeightHavingOnlySpanningCells( | 527 unsigned LayoutTableSection::CalcRowHeightHavingOnlySpanningCells( |
| 539 unsigned row, | 528 unsigned row, |
| 540 int& accumulated_cell_position_increase, | 529 int& accumulated_cell_position_increase, |
| 541 unsigned row_to_apply_extra_height, | 530 unsigned row_to_apply_extra_height, |
| 542 unsigned& extra_table_height_to_propgate, | 531 unsigned& extra_table_height_to_propgate, |
| 543 Vector<int>& rows_count_with_only_spanning_cells) { | 532 Vector<int>& rows_count_with_only_spanning_cells) { |
| 544 DCHECK(RowHasOnlySpanningCells(row)); | 533 DCHECK(RowHasOnlySpanningCells(row)); |
| 545 | 534 |
| 546 unsigned total_cols = grid_[row].row.size(); | |
| 547 | |
| 548 if (!total_cols) | |
| 549 return 0; | |
| 550 | |
| 551 unsigned row_height = 0; | 535 unsigned row_height = 0; |
| 552 | 536 |
| 553 for (unsigned col = 0; col < total_cols; col++) { | 537 for (const auto& row_span_cell : grid_[row].grid_cells) { |
| 554 const CellStruct& row_span_cell = CellAt(row, col); | 538 DCHECK(row_span_cell.HasCells()); |
| 555 | 539 LayoutTableCell* cell = row_span_cell.Cells()[0]; |
| 556 if (!row_span_cell.cells.size()) | 540 DCHECK_GE(cell->RowSpan(), 2u); |
|
dgrogan
2017/05/15 19:53:38
Thanks for changing these continue to DCHECK, I wo
Xianzhu
2017/05/15 20:28:38
The new DCHECKs are ensured by the DCHECK at the b
| |
| 557 continue; | |
| 558 | |
| 559 LayoutTableCell* cell = row_span_cell.cells[0]; | |
| 560 | |
| 561 if (cell->RowSpan() < 2) | |
| 562 continue; | |
| 563 | 541 |
| 564 const unsigned cell_row_index = cell->RowIndex(); | 542 const unsigned cell_row_index = cell->RowIndex(); |
| 565 const unsigned cell_row_span = cell->RowSpan(); | 543 const unsigned cell_row_span = cell->RowSpan(); |
| 566 | 544 |
| 567 // As we are going from the top of the table to the bottom to calculate the | 545 // As we are going from the top of the table to the bottom to calculate the |
| 568 // row heights for rows that only contain spanning cells and all previous | 546 // row heights for rows that only contain spanning cells and all previous |
| 569 // rows are processed we only need to find the number of rows with spanning | 547 // rows are processed we only need to find the number of rows with spanning |
| 570 // cells from the current cell to the end of the current cells spanning | 548 // cells from the current cell to the end of the current cells spanning |
| 571 // height. | 549 // height. |
| 572 unsigned start_row_for_spanning_cell_count = std::max(cell_row_index, row); | 550 unsigned start_row_for_spanning_cell_count = std::max(cell_row_index, row); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 831 return Table()->VBorderSpacing(); | 809 return Table()->VBorderSpacing(); |
| 832 } | 810 } |
| 833 | 811 |
| 834 int LayoutTableSection::CalcRowLogicalHeight() { | 812 int LayoutTableSection::CalcRowLogicalHeight() { |
| 835 #if DCHECK_IS_ON() | 813 #if DCHECK_IS_ON() |
| 836 SetLayoutNeededForbiddenScope layout_forbidden_scope(*this); | 814 SetLayoutNeededForbiddenScope layout_forbidden_scope(*this); |
| 837 #endif | 815 #endif |
| 838 | 816 |
| 839 DCHECK(!NeedsLayout()); | 817 DCHECK(!NeedsLayout()); |
| 840 | 818 |
| 841 LayoutTableCell* cell; | |
| 842 | |
| 843 // We may have to forcefully lay out cells here, in which case we need a | 819 // We may have to forcefully lay out cells here, in which case we need a |
| 844 // layout state. | 820 // layout state. |
| 845 LayoutState state(*this); | 821 LayoutState state(*this); |
| 846 | 822 |
| 847 row_pos_.resize(grid_.size() + 1); | 823 row_pos_.resize(grid_.size() + 1); |
| 848 row_pos_[0] = VBorderSpacingBeforeFirstRow(); | 824 row_pos_[0] = VBorderSpacingBeforeFirstRow(); |
| 849 | 825 |
| 850 SpanningLayoutTableCells row_span_cells; | 826 SpanningLayoutTableCells row_span_cells; |
| 851 | 827 |
| 852 // At fragmentainer breaks we need to prevent rowspanned cells (and whatever | 828 // At fragmentainer breaks we need to prevent rowspanned cells (and whatever |
| 853 // else) from distributing their extra height requirements over the rows that | 829 // else) from distributing their extra height requirements over the rows that |
| 854 // it spans. Otherwise we'd need to refragment afterwards. | 830 // it spans. Otherwise we'd need to refragment afterwards. |
| 855 unsigned index_of_first_stretchable_row = 0; | 831 unsigned index_of_first_stretchable_row = 0; |
| 856 | 832 |
| 857 for (unsigned r = 0; r < grid_.size(); r++) { | 833 for (unsigned r = 0; r < grid_.size(); r++) { |
| 858 grid_[r].baseline = -1; | 834 grid_[r].baseline = -1; |
| 859 int baseline_descent = 0; | 835 int baseline_descent = 0; |
| 860 | 836 |
| 861 if (state.IsPaginated() && grid_[r].row_layout_object) | 837 if (state.IsPaginated() && grid_[r].row) |
| 862 row_pos_[r] += grid_[r].row_layout_object->PaginationStrut().Ceil(); | 838 row_pos_[r] += grid_[r].row->PaginationStrut().Ceil(); |
| 863 | 839 |
| 864 if (grid_[r].logical_height.IsSpecified()) { | 840 if (grid_[r].logical_height.IsSpecified()) { |
| 865 // Our base size is the biggest logical height from our cells' styles | 841 // Our base size is the biggest logical height from our cells' styles |
| 866 // (excluding row spanning cells). | 842 // (excluding row spanning cells). |
| 867 row_pos_[r + 1] = | 843 row_pos_[r + 1] = |
| 868 std::max(row_pos_[r] + MinimumValueForLength(grid_[r].logical_height, | 844 std::max(row_pos_[r] + MinimumValueForLength(grid_[r].logical_height, |
| 869 LayoutUnit()) | 845 LayoutUnit()) |
| 870 .Round(), | 846 .Round(), |
| 871 0); | 847 0); |
| 872 } else { | 848 } else { |
| 873 // Non-specified lengths are ignored because the row already accounts for | 849 // Non-specified lengths are ignored because the row already accounts for |
| 874 // the cells intrinsic logical height. | 850 // the cells intrinsic logical height. |
| 875 row_pos_[r + 1] = std::max(row_pos_[r], 0); | 851 row_pos_[r + 1] = std::max(row_pos_[r], 0); |
| 876 } | 852 } |
| 877 | 853 |
| 878 Row& row = grid_[r].row; | 854 for (auto& grid_cell : grid_[r].grid_cells) { |
| 879 unsigned total_cols = row.size(); | 855 if (grid_cell.InColSpan()) |
| 880 | |
| 881 for (unsigned c = 0; c < total_cols; c++) { | |
| 882 CellStruct& current = CellAt(r, c); | |
| 883 if (current.in_col_span) | |
| 884 continue; | 856 continue; |
| 885 for (unsigned i = 0; i < current.cells.size(); i++) { | 857 for (auto* cell : grid_cell.Cells()) { |
| 886 cell = current.cells[i]; | |
| 887 | |
| 888 // For row spanning cells, we only handle them for the first row they | 858 // For row spanning cells, we only handle them for the first row they |
| 889 // span. This ensures we take their baseline into account. | 859 // span. This ensures we take their baseline into account. |
| 890 if (cell->RowIndex() != r) | 860 if (cell->RowIndex() != r) |
| 891 continue; | 861 continue; |
| 892 | 862 |
| 893 if (r < index_of_first_stretchable_row || | 863 if (r < index_of_first_stretchable_row || |
| 894 (state.IsPaginated() && | 864 (state.IsPaginated() && |
| 895 CrossesPageBoundary( | 865 CrossesPageBoundary( |
| 896 LayoutUnit(row_pos_[r]), | 866 LayoutUnit(row_pos_[r]), |
| 897 LayoutUnit(cell->LogicalHeightForRowSizing())))) { | 867 LayoutUnit(cell->LogicalHeightForRowSizing())))) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 917 if (cell->RowSpan() == 1) | 887 if (cell->RowSpan() == 1) |
| 918 row_pos_[r + 1] = std::max( | 888 row_pos_[r + 1] = std::max( |
| 919 row_pos_[r + 1], row_pos_[r] + cell->LogicalHeightForRowSizing()); | 889 row_pos_[r + 1], row_pos_[r] + cell->LogicalHeightForRowSizing()); |
| 920 | 890 |
| 921 // Find out the baseline. The baseline is set on the first row in a | 891 // Find out the baseline. The baseline is set on the first row in a |
| 922 // rowSpan. | 892 // rowSpan. |
| 923 UpdateBaselineForCell(cell, r, baseline_descent); | 893 UpdateBaselineForCell(cell, r, baseline_descent); |
| 924 } | 894 } |
| 925 } | 895 } |
| 926 | 896 |
| 927 if (r < index_of_first_stretchable_row && grid_[r].row_layout_object) { | 897 if (r < index_of_first_stretchable_row && grid_[r].row) { |
| 928 // We're not allowed to resize this row. Just scratch what we've | 898 // We're not allowed to resize this row. Just scratch what we've |
| 929 // calculated so far, and use the height that we got during initial | 899 // calculated so far, and use the height that we got during initial |
| 930 // layout instead. | 900 // layout instead. |
| 931 row_pos_[r + 1] = | 901 row_pos_[r + 1] = row_pos_[r] + grid_[r].row->LogicalHeight().ToInt(); |
| 932 row_pos_[r] + grid_[r].row_layout_object->LogicalHeight().ToInt(); | |
| 933 } | 902 } |
| 934 | 903 |
| 935 // Add the border-spacing to our final position. | 904 // Add the border-spacing to our final position. |
| 936 row_pos_[r + 1] += BorderSpacingForRow(r); | 905 row_pos_[r + 1] += BorderSpacingForRow(r); |
| 937 row_pos_[r + 1] = std::max(row_pos_[r + 1], row_pos_[r]); | 906 row_pos_[r + 1] = std::max(row_pos_[r + 1], row_pos_[r]); |
| 938 } | 907 } |
| 939 | 908 |
| 940 if (!row_span_cells.IsEmpty()) | 909 if (!row_span_cells.IsEmpty()) |
| 941 DistributeRowSpanHeightToRows(row_span_cells); | 910 DistributeRowSpanHeightToRows(row_span_cells); |
| 942 | 911 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 956 // it now ensures we have a stable-enough structure. | 925 // it now ensures we have a stable-enough structure. |
| 957 grid_.ShrinkToFit(); | 926 grid_.ShrinkToFit(); |
| 958 | 927 |
| 959 LayoutState state(*this); | 928 LayoutState state(*this); |
| 960 | 929 |
| 961 const Vector<int>& column_pos = Table()->EffectiveColumnPositions(); | 930 const Vector<int>& column_pos = Table()->EffectiveColumnPositions(); |
| 962 LayoutUnit row_logical_top(VBorderSpacingBeforeFirstRow()); | 931 LayoutUnit row_logical_top(VBorderSpacingBeforeFirstRow()); |
| 963 | 932 |
| 964 SubtreeLayoutScope layouter(*this); | 933 SubtreeLayoutScope layouter(*this); |
| 965 for (unsigned r = 0; r < grid_.size(); ++r) { | 934 for (unsigned r = 0; r < grid_.size(); ++r) { |
| 966 Row& row = grid_[r].row; | 935 auto& grid_cells = grid_[r].grid_cells; |
| 967 unsigned cols = row.size(); | 936 unsigned cols = grid_cells.size(); |
| 968 // First, propagate our table layout's information to the cells. This will | 937 // First, propagate our table layout's information to the cells. This will |
| 969 // mark the row as needing layout if there was a column logical width | 938 // mark the row as needing layout if there was a column logical width |
| 970 // change. | 939 // change. |
| 971 for (unsigned start_column = 0; start_column < cols; ++start_column) { | 940 for (unsigned start_column = 0; start_column < cols; ++start_column) { |
| 972 CellStruct& current = row[start_column]; | 941 auto& grid_cell = grid_cells[start_column]; |
| 973 LayoutTableCell* cell = current.PrimaryCell(); | 942 LayoutTableCell* cell = grid_cell.PrimaryCell(); |
| 974 if (!cell || current.in_col_span) | 943 if (!cell || grid_cell.InColSpan()) |
| 975 continue; | 944 continue; |
| 976 | 945 |
| 977 unsigned end_col = start_column; | 946 unsigned end_col = start_column; |
| 978 unsigned cspan = cell->ColSpan(); | 947 unsigned cspan = cell->ColSpan(); |
| 979 while (cspan && end_col < cols) { | 948 while (cspan && end_col < cols) { |
| 980 DCHECK_LT(end_col, Table()->EffectiveColumns().size()); | 949 DCHECK_LT(end_col, Table()->EffectiveColumns().size()); |
| 981 cspan -= Table()->EffectiveColumns()[end_col].span; | 950 cspan -= Table()->EffectiveColumns()[end_col].span; |
| 982 end_col++; | 951 end_col++; |
| 983 } | 952 } |
| 984 int table_layout_logical_width = column_pos[end_col] - | 953 int table_layout_logical_width = column_pos[end_col] - |
| 985 column_pos[start_column] - | 954 column_pos[start_column] - |
| 986 Table()->HBorderSpacing(); | 955 Table()->HBorderSpacing(); |
| 987 cell->SetCellLogicalWidth(table_layout_logical_width, layouter); | 956 cell->SetCellLogicalWidth(table_layout_logical_width, layouter); |
| 988 } | 957 } |
| 989 | 958 |
| 990 if (LayoutTableRow* row_layout_object = grid_[r].row_layout_object) { | 959 if (LayoutTableRow* row = grid_[r].row) { |
| 991 if (state.IsPaginated()) | 960 if (state.IsPaginated()) |
| 992 row_layout_object->SetLogicalTop(row_logical_top); | 961 row->SetLogicalTop(row_logical_top); |
| 993 if (!row_layout_object->NeedsLayout()) | 962 if (!row->NeedsLayout()) |
| 994 MarkChildForPaginationRelayoutIfNeeded(*row_layout_object, layouter); | 963 MarkChildForPaginationRelayoutIfNeeded(*row, layouter); |
| 995 row_layout_object->LayoutIfNeeded(); | 964 row->LayoutIfNeeded(); |
| 996 if (state.IsPaginated()) { | 965 if (state.IsPaginated()) { |
| 997 AdjustRowForPagination(*row_layout_object, layouter); | 966 AdjustRowForPagination(*row, layouter); |
| 998 UpdateFragmentationInfoForChild(*row_layout_object); | 967 UpdateFragmentationInfoForChild(*row); |
| 999 row_logical_top = row_layout_object->LogicalBottom(); | 968 row_logical_top = row->LogicalBottom(); |
| 1000 row_logical_top += LayoutUnit(Table()->VBorderSpacing()); | 969 row_logical_top += LayoutUnit(Table()->VBorderSpacing()); |
| 1001 } | 970 } |
| 1002 } | 971 } |
| 1003 } | 972 } |
| 1004 | 973 |
| 1005 ClearNeedsLayout(); | 974 ClearNeedsLayout(); |
| 1006 } | 975 } |
| 1007 | 976 |
| 1008 void LayoutTableSection::DistributeExtraLogicalHeightToPercentRows( | 977 void LayoutTableSection::DistributeExtraLogicalHeightToPercentRows( |
| 1009 int& extra_logical_height, | 978 int& extra_logical_height, |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1145 unsigned total_rows = grid_.size(); | 1114 unsigned total_rows = grid_.size(); |
| 1146 | 1115 |
| 1147 // Set the width of our section now. The rows will also be this width. | 1116 // Set the width of our section now. The rows will also be this width. |
| 1148 SetLogicalWidth(Table()->ContentLogicalWidth()); | 1117 SetLogicalWidth(Table()->ContentLogicalWidth()); |
| 1149 | 1118 |
| 1150 int vspacing = Table()->VBorderSpacing(); | 1119 int vspacing = Table()->VBorderSpacing(); |
| 1151 LayoutState state(*this); | 1120 LayoutState state(*this); |
| 1152 | 1121 |
| 1153 // Set the rows' location and size. | 1122 // Set the rows' location and size. |
| 1154 for (unsigned r = 0; r < total_rows; r++) { | 1123 for (unsigned r = 0; r < total_rows; r++) { |
| 1155 LayoutTableRow* row_layout_object = grid_[r].row_layout_object; | 1124 if (LayoutTableRow* row = grid_[r].row) { |
| 1156 if (row_layout_object) { | 1125 row->SetLogicalLocation(LayoutPoint(0, row_pos_[r])); |
| 1157 row_layout_object->SetLogicalLocation(LayoutPoint(0, row_pos_[r])); | 1126 row->SetLogicalWidth(LogicalWidth()); |
| 1158 row_layout_object->SetLogicalWidth(LogicalWidth()); | |
| 1159 LayoutUnit row_logical_height(row_pos_[r + 1] - row_pos_[r] - vspacing); | 1127 LayoutUnit row_logical_height(row_pos_[r + 1] - row_pos_[r] - vspacing); |
| 1160 if (state.IsPaginated() && r + 1 < total_rows) { | 1128 if (state.IsPaginated() && r + 1 < total_rows) { |
| 1161 // If the next row has a pagination strut, we need to subtract it. It | 1129 // If the next row has a pagination strut, we need to subtract it. It |
| 1162 // should not be included in this row's height. | 1130 // should not be included in this row's height. |
| 1163 if (LayoutTableRow* next_row_object = grid_[r + 1].row_layout_object) | 1131 if (LayoutTableRow* next_row_object = grid_[r + 1].row) |
| 1164 row_logical_height -= next_row_object->PaginationStrut(); | 1132 row_logical_height -= next_row_object->PaginationStrut(); |
| 1165 } | 1133 } |
| 1166 row_layout_object->SetLogicalHeight(row_logical_height); | 1134 row->SetLogicalHeight(row_logical_height); |
| 1167 row_layout_object->UpdateAfterLayout(); | 1135 row->UpdateAfterLayout(); |
| 1168 } | 1136 } |
| 1169 } | 1137 } |
| 1170 | 1138 |
| 1171 // Vertically align and flex the cells in each row. | 1139 // Vertically align and flex the cells in each row. |
| 1172 for (unsigned r = 0; r < total_rows; r++) { | 1140 for (unsigned r = 0; r < total_rows; r++) { |
| 1173 LayoutTableRow* row_layout_object = grid_[r].row_layout_object; | 1141 LayoutTableRow* row = grid_[r].row; |
| 1174 | 1142 |
| 1175 unsigned n_cols = NumCols(r); | 1143 unsigned n_cols = NumCols(r); |
| 1176 for (unsigned c = 0; c < n_cols; c++) { | 1144 for (unsigned c = 0; c < n_cols; c++) { |
| 1177 LayoutTableCell* cell = OriginatingCellAt(r, c); | 1145 LayoutTableCell* cell = OriginatingCellAt(r, c); |
| 1178 if (!cell) | 1146 if (!cell) |
| 1179 continue; | 1147 continue; |
| 1180 | 1148 |
| 1181 int r_height; | 1149 int r_height; |
| 1182 int row_logical_top; | 1150 int row_logical_top; |
| 1183 unsigned row_span = std::max(1U, cell->RowSpan()); | 1151 unsigned row_span = std::max(1U, cell->RowSpan()); |
| 1184 unsigned end_row_index = std::min(r + row_span, total_rows) - 1; | 1152 unsigned end_row_index = std::min(r + row_span, total_rows) - 1; |
| 1185 LayoutTableRow* last_row_object = grid_[end_row_index].row_layout_object; | 1153 LayoutTableRow* last_row_object = grid_[end_row_index].row; |
| 1186 if (last_row_object && row_layout_object) { | 1154 if (last_row_object && row) { |
| 1187 row_logical_top = row_layout_object->LogicalTop().ToInt(); | 1155 row_logical_top = row->LogicalTop().ToInt(); |
| 1188 r_height = last_row_object->LogicalBottom().ToInt() - row_logical_top; | 1156 r_height = last_row_object->LogicalBottom().ToInt() - row_logical_top; |
| 1189 } else { | 1157 } else { |
| 1190 r_height = row_pos_[end_row_index + 1] - row_pos_[r] - vspacing; | 1158 r_height = row_pos_[end_row_index + 1] - row_pos_[r] - vspacing; |
| 1191 row_logical_top = row_pos_[r]; | 1159 row_logical_top = row_pos_[r]; |
| 1192 } | 1160 } |
| 1193 | 1161 |
| 1194 RelayoutCellIfFlexed(*cell, r, r_height); | 1162 RelayoutCellIfFlexed(*cell, r, r_height); |
| 1195 | 1163 |
| 1196 SubtreeLayoutScope layouter(*cell); | 1164 SubtreeLayoutScope layouter(*cell); |
| 1197 EVerticalAlign cell_vertical_align; | 1165 EVerticalAlign cell_vertical_align; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1218 LayoutSize child_offset(cell->Location() - old_cell_rect.Location()); | 1186 LayoutSize child_offset(cell->Location() - old_cell_rect.Location()); |
| 1219 if (child_offset.Width() || child_offset.Height()) { | 1187 if (child_offset.Width() || child_offset.Height()) { |
| 1220 // If the child moved, we have to issue paint invalidations to it as | 1188 // If the child moved, we have to issue paint invalidations to it as |
| 1221 // well as any floating/positioned descendants. An exception is if we | 1189 // well as any floating/positioned descendants. An exception is if we |
| 1222 // need a layout. In this case, we know we're going to issue paint | 1190 // need a layout. In this case, we know we're going to issue paint |
| 1223 // invalidations ourselves (and the child) anyway. | 1191 // invalidations ourselves (and the child) anyway. |
| 1224 if (!Table()->SelfNeedsLayout()) | 1192 if (!Table()->SelfNeedsLayout()) |
| 1225 cell->SetMayNeedPaintInvalidation(); | 1193 cell->SetMayNeedPaintInvalidation(); |
| 1226 } | 1194 } |
| 1227 } | 1195 } |
| 1228 if (row_layout_object) | 1196 if (row) |
| 1229 row_layout_object->ComputeOverflow(); | 1197 row->ComputeOverflow(); |
| 1230 } | 1198 } |
| 1231 | 1199 |
| 1232 DCHECK(!NeedsLayout()); | 1200 DCHECK(!NeedsLayout()); |
| 1233 | 1201 |
| 1234 SetLogicalHeight(LayoutUnit(row_pos_[total_rows])); | 1202 SetLogicalHeight(LayoutUnit(row_pos_[total_rows])); |
| 1235 | 1203 |
| 1236 ComputeOverflowFromDescendants(); | 1204 ComputeOverflowFromDescendants(); |
| 1237 } | 1205 } |
| 1238 | 1206 |
| 1239 int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, | 1207 int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 : LastRow()->Style()->BorderAfter(); | 1361 : LastRow()->Style()->BorderAfter(); |
| 1394 if (rb.Style() == kBorderStyleHidden) | 1362 if (rb.Style() == kBorderStyleHidden) |
| 1395 return -1; | 1363 return -1; |
| 1396 if (rb.Style() > kBorderStyleHidden && rb.Width() > border_width) | 1364 if (rb.Style() > kBorderStyleHidden && rb.Width() > border_width) |
| 1397 border_width = rb.Width(); | 1365 border_width = rb.Width(); |
| 1398 | 1366 |
| 1399 bool all_hidden = true; | 1367 bool all_hidden = true; |
| 1400 unsigned r = side == kBorderBefore ? 0 : grid_.size() - 1; | 1368 unsigned r = side == kBorderBefore ? 0 : grid_.size() - 1; |
| 1401 unsigned n_cols = NumCols(r); | 1369 unsigned n_cols = NumCols(r); |
| 1402 for (unsigned c = 0; c < n_cols; c++) { | 1370 for (unsigned c = 0; c < n_cols; c++) { |
| 1403 const CellStruct& current = CellAt(r, c); | 1371 const auto& grid_cell = GridCellAt(r, c); |
| 1404 if (current.in_col_span || !current.HasCells()) | 1372 if (grid_cell.InColSpan() || !grid_cell.HasCells()) |
| 1405 continue; | 1373 continue; |
| 1406 const ComputedStyle& primary_cell_style = current.PrimaryCell()->StyleRef(); | 1374 const ComputedStyle& primary_cell_style = |
| 1375 grid_cell.PrimaryCell()->StyleRef(); | |
| 1407 // FIXME: Make this work with perpendicular and flipped cells. | 1376 // FIXME: Make this work with perpendicular and flipped cells. |
| 1408 const BorderValue& cb = side == kBorderBefore | 1377 const BorderValue& cb = side == kBorderBefore |
| 1409 ? primary_cell_style.BorderBefore() | 1378 ? primary_cell_style.BorderBefore() |
| 1410 : primary_cell_style.BorderAfter(); | 1379 : primary_cell_style.BorderAfter(); |
| 1411 // FIXME: Don't repeat for the same col group | 1380 // FIXME: Don't repeat for the same col group |
| 1412 LayoutTableCol* col = | 1381 LayoutTableCol* col = |
| 1413 Table()->ColElementAtAbsoluteColumn(c).InnermostColOrColGroup(); | 1382 Table()->ColElementAtAbsoluteColumn(c).InnermostColOrColGroup(); |
| 1414 if (col) { | 1383 if (col) { |
| 1415 const BorderValue& gb = side == kBorderBefore | 1384 const BorderValue& gb = side == kBorderBefore |
| 1416 ? col->Style()->BorderBefore() | 1385 ? col->Style()->BorderBefore() |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1462 if (gb.Style() == kBorderStyleHidden) | 1431 if (gb.Style() == kBorderStyleHidden) |
| 1463 return -1; | 1432 return -1; |
| 1464 if (gb.Style() > kBorderStyleHidden && gb.Width() > border_width) | 1433 if (gb.Style() > kBorderStyleHidden && gb.Width() > border_width) |
| 1465 border_width = gb.Width(); | 1434 border_width = gb.Width(); |
| 1466 } | 1435 } |
| 1467 | 1436 |
| 1468 bool all_hidden = true; | 1437 bool all_hidden = true; |
| 1469 for (unsigned r = 0; r < grid_.size(); r++) { | 1438 for (unsigned r = 0; r < grid_.size(); r++) { |
| 1470 if (col_index >= NumCols(r)) | 1439 if (col_index >= NumCols(r)) |
| 1471 continue; | 1440 continue; |
| 1472 const CellStruct& current = CellAt(r, col_index); | 1441 const auto& grid_cell = GridCellAt(r, col_index); |
| 1473 if (!current.HasCells()) | 1442 if (!grid_cell.HasCells()) |
| 1474 continue; | 1443 continue; |
| 1475 // FIXME: Don't repeat for the same cell | 1444 // FIXME: Don't repeat for the same cell |
| 1476 const ComputedStyle& primary_cell_style = current.PrimaryCell()->StyleRef(); | 1445 const ComputedStyle& primary_cell_style = |
| 1446 grid_cell.PrimaryCell()->StyleRef(); | |
| 1477 const ComputedStyle& primary_cell_parent_style = | 1447 const ComputedStyle& primary_cell_parent_style = |
| 1478 current.PrimaryCell()->Parent()->StyleRef(); | 1448 grid_cell.PrimaryCell()->Parent()->StyleRef(); |
| 1479 // FIXME: Make this work with perpendicular and flipped cells. | 1449 // FIXME: Make this work with perpendicular and flipped cells. |
| 1480 const BorderValue& cb = side == kBorderStart | 1450 const BorderValue& cb = side == kBorderStart |
| 1481 ? primary_cell_style.BorderStart() | 1451 ? primary_cell_style.BorderStart() |
| 1482 : primary_cell_style.BorderEnd(); | 1452 : primary_cell_style.BorderEnd(); |
| 1483 const BorderValue& rb = side == kBorderStart | 1453 const BorderValue& rb = side == kBorderStart |
| 1484 ? primary_cell_parent_style.BorderStart() | 1454 ? primary_cell_parent_style.BorderStart() |
| 1485 : primary_cell_parent_style.BorderEnd(); | 1455 : primary_cell_parent_style.BorderEnd(); |
| 1486 if (cb.Style() == kBorderStyleHidden || rb.Style() == kBorderStyleHidden) | 1456 if (cb.Style() == kBorderStyleHidden || rb.Style() == kBorderStyleHidden) |
| 1487 continue; | 1457 continue; |
| 1488 all_hidden = false; | 1458 all_hidden = false; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1507 } | 1477 } |
| 1508 | 1478 |
| 1509 int LayoutTableSection::FirstLineBoxBaseline() const { | 1479 int LayoutTableSection::FirstLineBoxBaseline() const { |
| 1510 if (!grid_.size()) | 1480 if (!grid_.size()) |
| 1511 return -1; | 1481 return -1; |
| 1512 | 1482 |
| 1513 int first_line_baseline = grid_[0].baseline; | 1483 int first_line_baseline = grid_[0].baseline; |
| 1514 if (first_line_baseline >= 0) | 1484 if (first_line_baseline >= 0) |
| 1515 return first_line_baseline + row_pos_[0]; | 1485 return first_line_baseline + row_pos_[0]; |
| 1516 | 1486 |
| 1517 const Row& first_row = grid_[0].row; | 1487 for (const auto& grid_cell : grid_[0].grid_cells) { |
| 1518 for (size_t i = 0; i < first_row.size(); ++i) { | 1488 if (const auto* cell = grid_cell.PrimaryCell()) { |
| 1519 const CellStruct& cs = first_row.at(i); | |
| 1520 const LayoutTableCell* cell = cs.PrimaryCell(); | |
| 1521 if (cell) | |
| 1522 first_line_baseline = | 1489 first_line_baseline = |
| 1523 std::max<int>(first_line_baseline, | 1490 std::max<int>(first_line_baseline, |
| 1524 (cell->LogicalTop() + cell->BorderBefore() + | 1491 (cell->LogicalTop() + cell->BorderBefore() + |
| 1525 cell->PaddingBefore() + cell->ContentLogicalHeight()) | 1492 cell->PaddingBefore() + cell->ContentLogicalHeight()) |
| 1526 .ToInt()); | 1493 .ToInt()); |
| 1494 } | |
| 1527 } | 1495 } |
| 1528 | 1496 |
| 1529 return first_line_baseline; | 1497 return first_line_baseline; |
| 1530 } | 1498 } |
| 1531 | 1499 |
| 1532 void LayoutTableSection::Paint(const PaintInfo& paint_info, | 1500 void LayoutTableSection::Paint(const PaintInfo& paint_info, |
| 1533 const LayoutPoint& paint_offset) const { | 1501 const LayoutPoint& paint_offset) const { |
| 1534 TableSectionPainter(*this).Paint(paint_info, paint_offset); | 1502 TableSectionPainter(*this).Paint(paint_info, paint_offset); |
| 1535 } | 1503 } |
| 1536 | 1504 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1618 | 1586 |
| 1619 covered_columns.EnsureConsistency(Table()->NumEffectiveColumns()); | 1587 covered_columns.EnsureConsistency(Table()->NumEffectiveColumns()); |
| 1620 if (!has_spanning_cells_ || !covered_columns.Start()) | 1588 if (!has_spanning_cells_ || !covered_columns.Start()) |
| 1621 return covered_columns; | 1589 return covered_columns; |
| 1622 | 1590 |
| 1623 // If there are any cells spanning into the first column, expand | 1591 // If there are any cells spanning into the first column, expand |
| 1624 // covered_columns to cover the primary cells. | 1592 // covered_columns to cover the primary cells. |
| 1625 unsigned smallest_column = covered_columns.Start(); | 1593 unsigned smallest_column = covered_columns.Start(); |
| 1626 CellSpan covered_rows = SpannedRows(damage_rect); | 1594 CellSpan covered_rows = SpannedRows(damage_rect); |
| 1627 for (unsigned r = covered_rows.Start(); r < covered_rows.end(); ++r) { | 1595 for (unsigned r = covered_rows.Start(); r < covered_rows.end(); ++r) { |
| 1628 const auto& row = grid_[r].row; | 1596 const auto& grid_cells = grid_[r].grid_cells; |
| 1629 if (covered_columns.Start() < row.size()) { | 1597 if (covered_columns.Start() < grid_cells.size()) { |
| 1630 unsigned c = covered_columns.Start(); | 1598 unsigned c = covered_columns.Start(); |
| 1631 while (c && row[c].in_col_span) | 1599 while (c && grid_cells[c].InColSpan()) |
| 1632 --c; | 1600 --c; |
| 1633 smallest_column = std::min(c, smallest_column); | 1601 smallest_column = std::min(c, smallest_column); |
| 1634 if (!smallest_column) | 1602 if (!smallest_column) |
| 1635 break; | 1603 break; |
| 1636 } | 1604 } |
| 1637 } | 1605 } |
| 1638 return CellSpan(smallest_column, covered_columns.end()); | 1606 return CellSpan(smallest_column, covered_columns.end()); |
| 1639 } | 1607 } |
| 1640 | 1608 |
| 1641 CellSpan LayoutTableSection::SpannedRows(const LayoutRect& flipped_rect) const { | 1609 CellSpan LayoutTableSection::SpannedRows(const LayoutRect& flipped_rect) const { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1709 c_col_ = 0; | 1677 c_col_ = 0; |
| 1710 c_row_ = 0; | 1678 c_row_ = 0; |
| 1711 grid_.clear(); | 1679 grid_.clear(); |
| 1712 | 1680 |
| 1713 for (LayoutTableRow* row = FirstRow(); row; row = row->NextRow()) { | 1681 for (LayoutTableRow* row = FirstRow(); row; row = row->NextRow()) { |
| 1714 unsigned insertion_row = c_row_; | 1682 unsigned insertion_row = c_row_; |
| 1715 ++c_row_; | 1683 ++c_row_; |
| 1716 c_col_ = 0; | 1684 c_col_ = 0; |
| 1717 EnsureRows(c_row_); | 1685 EnsureRows(c_row_); |
| 1718 | 1686 |
| 1719 grid_[insertion_row].row_layout_object = row; | 1687 grid_[insertion_row].row = row; |
| 1720 row->SetRowIndex(insertion_row); | 1688 row->SetRowIndex(insertion_row); |
| 1721 SetRowLogicalHeightToRowStyleLogicalHeight(grid_[insertion_row]); | 1689 grid_[insertion_row].SetRowLogicalHeightToRowStyleLogicalHeight(); |
| 1722 | 1690 |
| 1723 for (LayoutTableCell* cell = row->FirstCell(); cell; | 1691 for (LayoutTableCell* cell = row->FirstCell(); cell; |
| 1724 cell = cell->NextCell()) | 1692 cell = cell->NextCell()) |
| 1725 AddCell(cell, row); | 1693 AddCell(cell, row); |
| 1726 } | 1694 } |
| 1727 | 1695 |
| 1728 grid_.ShrinkToFit(); | 1696 grid_.ShrinkToFit(); |
| 1729 SetNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::kUnknown); | 1697 SetNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::kUnknown); |
| 1730 } | 1698 } |
| 1731 | 1699 |
| 1732 // FIXME: This function could be made O(1) in certain cases (like for the | 1700 // FIXME: This function could be made O(1) in certain cases (like for the |
| 1733 // non-most-constrainive cells' case). | 1701 // non-most-constrainive cells' case). |
| 1734 void LayoutTableSection::RowLogicalHeightChanged(LayoutTableRow* row) { | 1702 void LayoutTableSection::RowLogicalHeightChanged(LayoutTableRow* row) { |
| 1735 if (NeedsCellRecalc()) | 1703 if (NeedsCellRecalc()) |
| 1736 return; | 1704 return; |
| 1737 | 1705 |
| 1738 unsigned row_index = row->RowIndex(); | 1706 unsigned row_index = row->RowIndex(); |
| 1739 SetRowLogicalHeightToRowStyleLogicalHeight(grid_[row_index]); | 1707 grid_[row_index].SetRowLogicalHeightToRowStyleLogicalHeight(); |
| 1740 | 1708 |
| 1741 for (LayoutTableCell* cell = grid_[row_index].row_layout_object->FirstCell(); | 1709 for (LayoutTableCell* cell = grid_[row_index].row->FirstCell(); cell; |
| 1742 cell; cell = cell->NextCell()) | 1710 cell = cell->NextCell()) |
| 1743 UpdateLogicalHeightForCell(grid_[row_index], cell); | 1711 grid_[row_index].UpdateLogicalHeightForCell(cell); |
| 1744 } | 1712 } |
| 1745 | 1713 |
| 1746 void LayoutTableSection::SetNeedsCellRecalc() { | 1714 void LayoutTableSection::SetNeedsCellRecalc() { |
| 1747 needs_cell_recalc_ = true; | 1715 needs_cell_recalc_ = true; |
| 1748 if (LayoutTable* t = Table()) | 1716 if (LayoutTable* t = Table()) |
| 1749 t->SetNeedsSectionRecalc(); | 1717 t->SetNeedsSectionRecalc(); |
| 1750 } | 1718 } |
| 1751 | 1719 |
| 1752 unsigned LayoutTableSection::NumEffectiveColumns() const { | 1720 unsigned LayoutTableSection::NumEffectiveColumns() const { |
| 1753 unsigned result = 0; | 1721 unsigned result = 0; |
| 1754 | 1722 |
| 1755 for (unsigned r = 0; r < grid_.size(); ++r) { | 1723 for (unsigned r = 0; r < grid_.size(); ++r) { |
| 1756 unsigned n_cols = NumCols(r); | 1724 unsigned n_cols = NumCols(r); |
| 1757 for (unsigned c = result; c < n_cols; ++c) { | 1725 for (unsigned c = result; c < n_cols; ++c) { |
| 1758 const CellStruct& cell = CellAt(r, c); | 1726 const auto& grid_cell = GridCellAt(r, c); |
| 1759 if (cell.HasCells() || cell.in_col_span) | 1727 if (grid_cell.HasCells() || grid_cell.InColSpan()) |
| 1760 result = c; | 1728 result = c; |
| 1761 } | 1729 } |
| 1762 } | 1730 } |
| 1763 | 1731 |
| 1764 return result + 1; | 1732 return result + 1; |
| 1765 } | 1733 } |
| 1766 | 1734 |
| 1767 BorderValue LayoutTableSection::BorderAdjoiningStartCell( | 1735 BorderValue LayoutTableSection::BorderAdjoiningStartCell( |
| 1768 const LayoutTableCell* cell) const { | 1736 const LayoutTableCell* cell) const { |
| 1769 #if DCHECK_IS_ON() | 1737 #if DCHECK_IS_ON() |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1792 const LayoutTableCell* LayoutTableSection::FirstRowCellAdjoiningTableEnd() | 1760 const LayoutTableCell* LayoutTableSection::FirstRowCellAdjoiningTableEnd() |
| 1793 const { | 1761 const { |
| 1794 unsigned adjoining_end_cell_column_index = | 1762 unsigned adjoining_end_cell_column_index = |
| 1795 HasSameDirectionAs(Table()) ? Table()->LastEffectiveColumnIndex() : 0; | 1763 HasSameDirectionAs(Table()) ? Table()->LastEffectiveColumnIndex() : 0; |
| 1796 return PrimaryCellAt(0, adjoining_end_cell_column_index); | 1764 return PrimaryCellAt(0, adjoining_end_cell_column_index); |
| 1797 } | 1765 } |
| 1798 | 1766 |
| 1799 LayoutTableCell* LayoutTableSection::OriginatingCellAt( | 1767 LayoutTableCell* LayoutTableSection::OriginatingCellAt( |
| 1800 unsigned row, | 1768 unsigned row, |
| 1801 unsigned effective_column) { | 1769 unsigned effective_column) { |
| 1802 auto& row_vector = grid_[row].row; | 1770 if (effective_column >= NumCols(row)) |
| 1803 if (effective_column >= row_vector.size()) | |
| 1804 return nullptr; | 1771 return nullptr; |
| 1805 auto& cell_struct = row_vector[effective_column]; | 1772 auto& grid_cell = GridCellAt(row, effective_column); |
| 1806 if (cell_struct.in_col_span) | 1773 if (grid_cell.InColSpan()) |
| 1807 return nullptr; | 1774 return nullptr; |
| 1808 if (auto* cell = cell_struct.PrimaryCell()) { | 1775 if (auto* cell = grid_cell.PrimaryCell()) { |
| 1809 if (cell->RowIndex() == row) | 1776 if (cell->RowIndex() == row) |
| 1810 return cell; | 1777 return cell; |
| 1811 } | 1778 } |
| 1812 return nullptr; | 1779 return nullptr; |
| 1813 } | 1780 } |
| 1814 | 1781 |
| 1815 void LayoutTableSection::AppendEffectiveColumn(unsigned pos) { | 1782 void LayoutTableSection::AppendEffectiveColumn(unsigned pos) { |
| 1816 DCHECK(!needs_cell_recalc_); | 1783 DCHECK(!needs_cell_recalc_); |
| 1817 | 1784 |
| 1818 for (unsigned row = 0; row < grid_.size(); ++row) | 1785 for (auto& row : grid_) |
| 1819 grid_[row].row.resize(pos + 1); | 1786 row.grid_cells.resize(pos + 1); |
| 1820 } | 1787 } |
| 1821 | 1788 |
| 1822 void LayoutTableSection::SplitEffectiveColumn(unsigned pos, unsigned first) { | 1789 void LayoutTableSection::SplitEffectiveColumn(unsigned pos, unsigned first) { |
| 1823 DCHECK(!needs_cell_recalc_); | 1790 DCHECK(!needs_cell_recalc_); |
| 1824 | 1791 |
| 1825 if (c_col_ > pos) | 1792 if (c_col_ > pos) |
| 1826 c_col_++; | 1793 c_col_++; |
| 1827 for (unsigned row = 0; row < grid_.size(); ++row) { | 1794 for (unsigned row = 0; row < grid_.size(); ++row) { |
| 1828 Row& r = grid_[row].row; | 1795 auto& grid_cells = grid_[row].grid_cells; |
| 1829 EnsureCols(row, pos + 2); | 1796 EnsureCols(row, pos + 2); |
| 1830 r.insert(pos + 1, CellStruct()); | 1797 grid_cells.insert(pos + 1, TableGridCell()); |
| 1831 if (r[pos].HasCells()) { | 1798 if (grid_cells[pos].HasCells()) { |
| 1832 r[pos + 1].cells.AppendVector(r[pos].cells); | 1799 grid_cells[pos + 1].Cells().AppendVector(grid_cells[pos].Cells()); |
| 1833 LayoutTableCell* cell = r[pos].PrimaryCell(); | 1800 LayoutTableCell* cell = grid_cells[pos].PrimaryCell(); |
| 1834 DCHECK(cell); | 1801 DCHECK(cell); |
| 1835 DCHECK_GE(cell->ColSpan(), (r[pos].in_col_span ? 1u : 0)); | 1802 DCHECK_GE(cell->ColSpan(), (grid_cells[pos].InColSpan() ? 1u : 0)); |
| 1836 unsigned colleft = cell->ColSpan() - r[pos].in_col_span; | 1803 unsigned colleft = cell->ColSpan() - grid_cells[pos].InColSpan(); |
| 1837 if (first > colleft) | 1804 if (first > colleft) |
| 1838 r[pos + 1].in_col_span = 0; | 1805 grid_cells[pos + 1].SetInColSpan(false); |
| 1839 else | 1806 else |
| 1840 r[pos + 1].in_col_span = first + r[pos].in_col_span; | 1807 grid_cells[pos + 1].SetInColSpan(first || grid_cells[pos].InColSpan()); |
| 1841 } else { | 1808 } else { |
| 1842 r[pos + 1].in_col_span = 0; | 1809 grid_cells[pos + 1].SetInColSpan(false); |
| 1843 } | 1810 } |
| 1844 } | 1811 } |
| 1845 } | 1812 } |
| 1846 | 1813 |
| 1847 // Hit Testing | 1814 // Hit Testing |
| 1848 bool LayoutTableSection::NodeAtPoint( | 1815 bool LayoutTableSection::NodeAtPoint( |
| 1849 HitTestResult& result, | 1816 HitTestResult& result, |
| 1850 const HitTestLocation& location_in_container, | 1817 const HitTestLocation& location_in_container, |
| 1851 const LayoutPoint& accumulated_offset, | 1818 const LayoutPoint& accumulated_offset, |
| 1852 HitTestAction action) { | 1819 HitTestAction action) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1892 LogicalRectForWritingModeAndDirection(hit_test_rect); | 1859 LogicalRectForWritingModeAndDirection(hit_test_rect); |
| 1893 CellSpan row_span = SpannedRows(table_aligned_rect); | 1860 CellSpan row_span = SpannedRows(table_aligned_rect); |
| 1894 CellSpan column_span = SpannedEffectiveColumns(table_aligned_rect); | 1861 CellSpan column_span = SpannedEffectiveColumns(table_aligned_rect); |
| 1895 | 1862 |
| 1896 // Now iterate over the spanned rows and columns. | 1863 // Now iterate over the spanned rows and columns. |
| 1897 for (unsigned hit_row = row_span.Start(); hit_row < row_span.end(); | 1864 for (unsigned hit_row = row_span.Start(); hit_row < row_span.end(); |
| 1898 ++hit_row) { | 1865 ++hit_row) { |
| 1899 unsigned n_cols = NumCols(hit_row); | 1866 unsigned n_cols = NumCols(hit_row); |
| 1900 for (unsigned hit_column = column_span.Start(); | 1867 for (unsigned hit_column = column_span.Start(); |
| 1901 hit_column < n_cols && hit_column < column_span.end(); ++hit_column) { | 1868 hit_column < n_cols && hit_column < column_span.end(); ++hit_column) { |
| 1902 CellStruct& current = CellAt(hit_row, hit_column); | 1869 auto& grid_cell = GridCellAt(hit_row, hit_column); |
| 1903 | 1870 |
| 1904 // If the cell is empty, there's nothing to do | 1871 // If the cell is empty, there's nothing to do |
| 1905 if (!current.HasCells()) | 1872 if (!grid_cell.HasCells()) |
| 1906 continue; | 1873 continue; |
| 1907 | 1874 |
| 1908 for (unsigned i = current.cells.size(); i;) { | 1875 for (unsigned i = grid_cell.Cells().size(); i;) { |
| 1909 --i; | 1876 --i; |
| 1910 LayoutTableCell* cell = current.cells[i]; | 1877 LayoutTableCell* cell = grid_cell.Cells()[i]; |
| 1911 LayoutPoint cell_point = | 1878 LayoutPoint cell_point = |
| 1912 FlipForWritingModeForChild(cell, adjusted_location); | 1879 FlipForWritingModeForChild(cell, adjusted_location); |
| 1913 if (static_cast<LayoutObject*>(cell)->NodeAtPoint( | 1880 if (static_cast<LayoutObject*>(cell)->NodeAtPoint( |
| 1914 result, location_in_container, cell_point, action)) { | 1881 result, location_in_container, cell_point, action)) { |
| 1915 UpdateHitTestResult( | 1882 UpdateHitTestResult( |
| 1916 result, location_in_container.Point() - ToLayoutSize(cell_point)); | 1883 result, location_in_container.Point() - ToLayoutSize(cell_point)); |
| 1917 return true; | 1884 return true; |
| 1918 } | 1885 } |
| 1919 } | 1886 } |
| 1920 if (!result.GetHitTestRequest().ListBased()) | 1887 if (!result.GetHitTestRequest().ListBased()) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2019 if (baseline > cell.BorderBefore() + cell.PaddingBefore()) | 1986 if (baseline > cell.BorderBefore() + cell.PaddingBefore()) |
| 2020 grid_[row_index].baseline = std::max(grid_[row_index].baseline, baseline); | 1987 grid_[row_index].baseline = std::max(grid_[row_index].baseline, baseline); |
| 2021 } | 1988 } |
| 2022 } | 1989 } |
| 2023 | 1990 |
| 2024 int LayoutTableSection::LogicalHeightForRow( | 1991 int LayoutTableSection::LogicalHeightForRow( |
| 2025 const LayoutTableRow& row_object) const { | 1992 const LayoutTableRow& row_object) const { |
| 2026 unsigned row_index = row_object.RowIndex(); | 1993 unsigned row_index = row_object.RowIndex(); |
| 2027 DCHECK_LT(row_index, grid_.size()); | 1994 DCHECK_LT(row_index, grid_.size()); |
| 2028 int logical_height = 0; | 1995 int logical_height = 0; |
| 2029 const Row& row = grid_[row_index].row; | 1996 for (auto& grid_cell : grid_[row_index].grid_cells) { |
| 2030 unsigned cols = row.size(); | 1997 const LayoutTableCell* cell = grid_cell.PrimaryCell(); |
| 2031 for (unsigned col_index = 0; col_index < cols; col_index++) { | 1998 if (!cell || grid_cell.InColSpan()) |
| 2032 const CellStruct& cell_struct = CellAt(row_index, col_index); | |
| 2033 const LayoutTableCell* cell = cell_struct.PrimaryCell(); | |
| 2034 if (!cell || cell_struct.in_col_span) | |
| 2035 continue; | 1999 continue; |
| 2036 unsigned row_span = cell->RowSpan(); | 2000 unsigned row_span = cell->RowSpan(); |
| 2037 if (row_span == 1) { | 2001 if (row_span == 1) { |
| 2038 logical_height = | 2002 logical_height = |
| 2039 std::max(logical_height, cell->LogicalHeightForRowSizing()); | 2003 std::max(logical_height, cell->LogicalHeightForRowSizing()); |
| 2040 continue; | 2004 continue; |
| 2041 } | 2005 } |
| 2042 unsigned row_index_for_cell = cell->RowIndex(); | 2006 unsigned row_index_for_cell = cell->RowIndex(); |
| 2043 if (row_index == grid_.size() - 1 || | 2007 if (row_index == grid_.size() - 1 || |
| 2044 (row_span > 1 && row_index - row_index_for_cell == row_span - 1)) { | 2008 (row_span > 1 && row_index - row_index_for_cell == row_span - 1)) { |
| 2045 // This is the last row of the rowspanned cell. Add extra height if | 2009 // This is the last row of the rowspanned cell. Add extra height if |
| 2046 // needed. | 2010 // needed. |
| 2047 if (LayoutTableRow* first_row_for_cell = | 2011 if (LayoutTableRow* first_row_for_cell = grid_[row_index_for_cell].row) { |
| 2048 grid_[row_index_for_cell].row_layout_object) { | |
| 2049 int min_logical_height = cell->LogicalHeightForRowSizing(); | 2012 int min_logical_height = cell->LogicalHeightForRowSizing(); |
| 2050 // Subtract space provided by previous rows. | 2013 // Subtract space provided by previous rows. |
| 2051 min_logical_height -= row_object.LogicalTop().ToInt() - | 2014 min_logical_height -= row_object.LogicalTop().ToInt() - |
| 2052 first_row_for_cell->LogicalTop().ToInt(); | 2015 first_row_for_cell->LogicalTop().ToInt(); |
| 2053 | 2016 |
| 2054 logical_height = std::max(logical_height, min_logical_height); | 2017 logical_height = std::max(logical_height, min_logical_height); |
| 2055 } | 2018 } |
| 2056 } | 2019 } |
| 2057 } | 2020 } |
| 2058 | 2021 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2175 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() | 2138 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() |
| 2176 const { | 2139 const { |
| 2177 // LayoutTableSection paints background from columns. | 2140 // LayoutTableSection paints background from columns. |
| 2178 if (Table()->HasColElements()) | 2141 if (Table()->HasColElements()) |
| 2179 return false; | 2142 return false; |
| 2180 return LayoutTableBoxComponent:: | 2143 return LayoutTableBoxComponent:: |
| 2181 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); | 2144 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); |
| 2182 } | 2145 } |
| 2183 | 2146 |
| 2184 } // namespace blink | 2147 } // namespace blink |
| OLD | NEW |