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