Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2884533002: Extract LayoutTableSection::CellStruct to a standalone class TableGridCell (Closed)
Patch Set: - Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698