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

Side by Side Diff: third_party/WebKit/Source/core/paint/TableSectionPainter.cpp

Issue 2884763003: Combine and simplify LayoutTableSection::DirtiedRows() and DirtiedEffectiveColumns() (Closed)
Patch Set: Rebase on origin/master 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/TableSectionPainter.h" 5 #include "core/paint/TableSectionPainter.h"
6 6
7 #include "core/layout/LayoutTableCell.h" 7 #include "core/layout/LayoutTableCell.h"
8 #include "core/layout/LayoutTableCol.h" 8 #include "core/layout/LayoutTableCol.h"
9 #include "core/layout/LayoutTableRow.h" 9 #include "core/layout/LayoutTableRow.h"
10 #include "core/paint/BoxClipper.h" 10 #include "core/paint/BoxClipper.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 box_clipper.emplace(layout_table_section_, paint_info, 102 box_clipper.emplace(layout_table_section_, paint_info,
103 adjusted_paint_offset, kForceContentsClip); 103 adjusted_paint_offset, kForceContentsClip);
104 PaintObject(paint_info, adjusted_paint_offset); 104 PaintObject(paint_info, adjusted_paint_offset);
105 } 105 }
106 106
107 if (ShouldPaintSelfOutline(paint_info.phase)) 107 if (ShouldPaintSelfOutline(paint_info.phase))
108 ObjectPainter(layout_table_section_) 108 ObjectPainter(layout_table_section_)
109 .PaintOutline(paint_info, adjusted_paint_offset); 109 .PaintOutline(paint_info, adjusted_paint_offset);
110 } 110 }
111 111
112 static inline bool CompareCellPositions(const LayoutTableCell* elem1,
113 const LayoutTableCell* elem2) {
114 return elem1->RowIndex() < elem2->RowIndex();
115 }
116
117 // This comparison is used only when we have overflowing cells as we have an
118 // unsorted array to sort. We thus need to sort both on rows and columns to
119 // paint in proper order.
120 static inline bool CompareCellPositionsWithOverflowingCells(
121 const LayoutTableCell* elem1,
122 const LayoutTableCell* elem2) {
123 if (elem1->RowIndex() != elem2->RowIndex())
124 return elem1->RowIndex() < elem2->RowIndex();
125
126 return elem1->AbsoluteColumnIndex() < elem2->AbsoluteColumnIndex();
127 }
128
129 void TableSectionPainter::PaintCollapsedBorders( 112 void TableSectionPainter::PaintCollapsedBorders(
130 const PaintInfo& paint_info, 113 const PaintInfo& paint_info,
131 const LayoutPoint& paint_offset, 114 const LayoutPoint& paint_offset,
132 const CollapsedBorderValue& current_border_value) { 115 const CollapsedBorderValue& current_border_value) {
133 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value); 116 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value);
134 LayoutTable* table = layout_table_section_.Table(); 117 LayoutTable* table = layout_table_section_.Table();
135 if (table->Header() == layout_table_section_) 118 if (table->Header() == layout_table_section_)
136 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value, 119 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value,
137 kPaintCollapsedBorders); 120 kPaintCollapsedBorders);
138 } 121 }
(...skipping 11 matching lines...) Expand all
150 BoxClipper box_clipper(layout_table_section_, paint_info, 133 BoxClipper box_clipper(layout_table_section_, paint_info,
151 adjusted_paint_offset, kForceContentsClip); 134 adjusted_paint_offset, kForceContentsClip);
152 135
153 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_); 136 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_);
154 local_visual_rect.MoveBy(-adjusted_paint_offset); 137 local_visual_rect.MoveBy(-adjusted_paint_offset);
155 138
156 LayoutRect table_aligned_rect = 139 LayoutRect table_aligned_rect =
157 layout_table_section_.LogicalRectForWritingModeAndDirection( 140 layout_table_section_.LogicalRectForWritingModeAndDirection(
158 local_visual_rect); 141 local_visual_rect);
159 142
160 CellSpan dirtied_rows = layout_table_section_.DirtiedRows(table_aligned_rect); 143 CellSpan dirtied_rows;
161 CellSpan dirtied_columns = 144 CellSpan dirtied_columns;
162 layout_table_section_.DirtiedEffectiveColumns(table_aligned_rect); 145 layout_table_section_.DirtiedRowsAndEffectiveColumns(
146 table_aligned_rect, dirtied_rows, dirtied_columns);
163 147
164 if (dirtied_columns.Start() >= dirtied_columns.end()) 148 if (dirtied_columns.Start() >= dirtied_columns.End())
165 return; 149 return;
166 150
167 // Collapsed borders are painted from the bottom right to the top left so that 151 // Collapsed borders are painted from the bottom right to the top left so that
168 // precedence due to cell position is respected. 152 // precedence due to cell position is respected.
169 for (unsigned r = dirtied_rows.end(); r > dirtied_rows.Start(); r--) { 153 for (unsigned r = dirtied_rows.End(); r > dirtied_rows.Start(); r--) {
170 unsigned row = r - 1; 154 unsigned row = r - 1;
171 unsigned n_cols = layout_table_section_.NumCols(row); 155 unsigned n_cols = layout_table_section_.NumCols(row);
172 for (unsigned c = std::min(dirtied_columns.end(), n_cols); 156 for (unsigned c = std::min(dirtied_columns.End(), n_cols);
173 c > dirtied_columns.Start(); c--) { 157 c > dirtied_columns.Start(); c--) {
174 unsigned col = c - 1; 158 unsigned col = c - 1;
175 if (const LayoutTableCell* cell = 159 if (const LayoutTableCell* cell =
176 layout_table_section_.OriginatingCellAt(row, col)) { 160 layout_table_section_.OriginatingCellAt(row, col)) {
177 LayoutPoint cell_point = 161 LayoutPoint cell_point =
178 layout_table_section_.FlipForWritingModeForChild( 162 layout_table_section_.FlipForWritingModeForChild(
179 cell, adjusted_paint_offset); 163 cell, adjusted_paint_offset);
180 TableCellPainter(*cell).PaintCollapsedBorders(paint_info, cell_point, 164 TableCellPainter(*cell).PaintCollapsedBorders(paint_info, cell_point,
181 current_border_value); 165 current_border_value);
182 } 166 }
183 } 167 }
184 } 168 }
185 } 169 }
186 170
187 void TableSectionPainter::PaintObject(const PaintInfo& paint_info, 171 void TableSectionPainter::PaintObject(const PaintInfo& paint_info,
188 const LayoutPoint& paint_offset) { 172 const LayoutPoint& paint_offset) {
189 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_); 173 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_);
190 local_visual_rect.MoveBy(-paint_offset); 174 local_visual_rect.MoveBy(-paint_offset);
191 175
192 LayoutRect table_aligned_rect = 176 LayoutRect table_aligned_rect =
193 layout_table_section_.LogicalRectForWritingModeAndDirection( 177 layout_table_section_.LogicalRectForWritingModeAndDirection(
194 local_visual_rect); 178 local_visual_rect);
195 179
196 CellSpan dirtied_rows = layout_table_section_.DirtiedRows(table_aligned_rect); 180 CellSpan dirtied_rows;
197 CellSpan dirtied_columns = 181 CellSpan dirtied_columns;
198 layout_table_section_.DirtiedEffectiveColumns(table_aligned_rect); 182 layout_table_section_.DirtiedRowsAndEffectiveColumns(
183 table_aligned_rect, dirtied_rows, dirtied_columns);
199 184
200 PaintInfo paint_info_for_descendants = paint_info.ForDescendants(); 185 PaintInfo paint_info_for_descendants = paint_info.ForDescendants();
201 186
202 if (ShouldPaintSelfBlockBackground(paint_info.phase)) { 187 if (ShouldPaintSelfBlockBackground(paint_info.phase)) {
203 PaintBoxDecorationBackground(paint_info, paint_offset, dirtied_rows, 188 PaintBoxDecorationBackground(paint_info, paint_offset, dirtied_rows,
204 dirtied_columns); 189 dirtied_columns);
205 } 190 }
206 191
207 if (paint_info.phase == kPaintPhaseSelfBlockBackgroundOnly) 192 if (paint_info.phase == kPaintPhaseSelfBlockBackgroundOnly)
208 return; 193 return;
209 194
210 if (ShouldPaintDescendantBlockBackgrounds(paint_info.phase)) { 195 if (ShouldPaintDescendantBlockBackgrounds(paint_info.phase)) {
211 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 196 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
212 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 197 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
213 // If a row has a layer, we'll paint row background though 198 // If a row has a layer, we'll paint row background though
214 // TableRowPainter::paint(). 199 // TableRowPainter::paint().
215 if (!row || row->HasSelfPaintingLayer()) 200 if (!row || row->HasSelfPaintingLayer())
216 continue; 201 continue;
217 TableRowPainter(*row).PaintBoxDecorationBackground( 202 TableRowPainter(*row).PaintBoxDecorationBackground(
218 paint_info_for_descendants, paint_offset, dirtied_columns); 203 paint_info_for_descendants, paint_offset, dirtied_columns);
219 } 204 }
220 } 205 }
221 206
222 // This is tested after background painting because during background painting 207 // This is tested after background painting because during background painting
223 // we need to check validity of the previous background display item based on 208 // we need to check validity of the previous background display item based on
224 // dirtyRows and dirtyColumns. 209 // dirtyRows and dirtyColumns.
225 if (dirtied_rows.Start() >= dirtied_rows.end() || 210 if (dirtied_rows.Start() >= dirtied_rows.End() ||
226 dirtied_columns.Start() >= dirtied_columns.end()) 211 dirtied_columns.Start() >= dirtied_columns.End())
227 return; 212 return;
228 213
229 const auto& overflowing_cells = layout_table_section_.OverflowingCells(); 214 const auto& overflowing_cells = layout_table_section_.OverflowingCells();
230 if (!layout_table_section_.HasMultipleCellLevels() && 215 if (overflowing_cells.IsEmpty()) {
231 overflowing_cells.IsEmpty()) {
232 // This path is for 2 cases: 216 // This path is for 2 cases:
233 // 1. Normal partial paint, without overflowing cells and multiple cell 217 // 1. Normal partial paint, without overflowing cells;
234 // levels;
235 // 2. Full paint, for small sections or big sections with many overflowing 218 // 2. Full paint, for small sections or big sections with many overflowing
236 // cells. 219 // cells.
237 // The difference between the normal partial paint and full paint is that 220 // The difference between the normal partial paint and full paint is that
238 // whether dirtied_rows and dirtied_columns cover the whole section. 221 // whether dirtied_rows and dirtied_columns cover the whole section.
239 DCHECK(!layout_table_section_.HasOverflowingCell() || 222 DCHECK(!layout_table_section_.HasOverflowingCell() ||
240 (dirtied_rows == layout_table_section_.FullSectionRowSpan() && 223 (dirtied_rows == layout_table_section_.FullSectionRowSpan() &&
241 dirtied_columns == 224 dirtied_columns ==
242 layout_table_section_.FullTableEffectiveColumnSpan())); 225 layout_table_section_.FullTableEffectiveColumnSpan()));
243 226
244 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 227 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
245 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 228 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
246 // TODO(crbug.com/577282): This painting order is inconsistent with other 229 // TODO(crbug.com/577282): This painting order is inconsistent with other
247 // outlines. 230 // outlines.
248 if (row && !row->HasSelfPaintingLayer() && 231 if (row && !row->HasSelfPaintingLayer() &&
249 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) { 232 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) {
250 TableRowPainter(*row).PaintOutline(paint_info_for_descendants, 233 TableRowPainter(*row).PaintOutline(paint_info_for_descendants,
251 paint_offset); 234 paint_offset);
252 } 235 }
253 for (unsigned c = dirtied_columns.Start(); c < dirtied_columns.end(); 236 for (unsigned c = dirtied_columns.Start(); c < dirtied_columns.End();
254 c++) { 237 c++) {
255 if (const LayoutTableCell* cell = 238 if (const LayoutTableCell* cell =
256 layout_table_section_.OriginatingCellAt(r, c)) 239 layout_table_section_.OriginatingCellAt(r, c))
257 PaintCell(*cell, paint_info_for_descendants, paint_offset); 240 PaintCell(*cell, paint_info_for_descendants, paint_offset);
258 } 241 }
259 } 242 }
260 } else { 243 } else {
261 // This path paints section with multiple cell levels or a reasonable number 244 // This path paints section with a reasonable number of overflowing cells.
262 // of overflowing cells. This is the "partial paint path" for overflowing 245 // This is the "partial paint path" for overflowing cells referred in
263 // cells referred in LayoutTableSection::ComputeOverflowFromDescendants(). 246 // LayoutTableSection::ComputeOverflowFromDescendants().
264 Vector<const LayoutTableCell*> cells; 247 Vector<const LayoutTableCell*> cells;
265 CopyToVector(overflowing_cells, cells); 248 CopyToVector(overflowing_cells, cells);
266 249
267 HashSet<const LayoutTableCell*> spanning_cells; 250 HashSet<const LayoutTableCell*> spanning_cells;
268 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 251 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
269 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 252 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
270 // TODO(crbug.com/577282): This painting order is inconsistent with other 253 // TODO(crbug.com/577282): This painting order is inconsistent with other
271 // outlines. 254 // outlines.
272 if (row && !row->HasSelfPaintingLayer() && 255 if (row && !row->HasSelfPaintingLayer() &&
273 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) { 256 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) {
274 TableRowPainter(*row).PaintOutline(paint_info_for_descendants, 257 TableRowPainter(*row).PaintOutline(paint_info_for_descendants,
275 paint_offset); 258 paint_offset);
276 } 259 }
277 unsigned n_cols = layout_table_section_.NumCols(r); 260 unsigned n_cols = layout_table_section_.NumCols(r);
278 for (unsigned c = dirtied_columns.Start(); 261 for (unsigned c = dirtied_columns.Start();
279 c < n_cols && c < dirtied_columns.end(); c++) { 262 c < n_cols && c < dirtied_columns.End(); c++) {
280 for (const auto* cell : 263 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
281 layout_table_section_.GridCellAt(r, c).Cells()) { 264 if (!overflowing_cells.Contains(cell))
282 if (overflowing_cells.Contains(cell)) 265 cells.push_back(cell);
283 continue;
284 if (cell->RowSpan() > 1 || cell->ColSpan() > 1) {
285 if (!spanning_cells.insert(cell).is_new_entry)
286 continue;
287 }
288 cells.push_back(cell);
289 } 266 }
290 } 267 }
291 } 268 }
292 269
293 // Sort the dirty cells by paint order. 270 // Sort the dirty cells by paint order.
294 if (!overflowing_cells.size()) { 271 std::sort(cells.begin(), cells.end(), LayoutTableCell::CompareInDOMOrder);
295 std::stable_sort(cells.begin(), cells.end(), CompareCellPositions);
296 } else {
297 std::sort(cells.begin(), cells.end(),
298 CompareCellPositionsWithOverflowingCells);
299 }
300
301 for (const auto* cell : cells) 272 for (const auto* cell : cells)
302 PaintCell(*cell, paint_info_for_descendants, paint_offset); 273 PaintCell(*cell, paint_info_for_descendants, paint_offset);
303 } 274 }
304 } 275 }
305 276
306 void TableSectionPainter::PaintBoxDecorationBackground( 277 void TableSectionPainter::PaintBoxDecorationBackground(
307 const PaintInfo& paint_info, 278 const PaintInfo& paint_info,
308 const LayoutPoint& paint_offset, 279 const LayoutPoint& paint_offset,
309 const CellSpan& dirtied_rows, 280 const CellSpan& dirtied_rows,
310 const CellSpan& dirtied_columns) { 281 const CellSpan& dirtied_columns) {
(...skipping 23 matching lines...) Expand all
334 DisplayItem::kBoxDecorationBackground, bounds); 305 DisplayItem::kBoxDecorationBackground, bounds);
335 LayoutRect paint_rect(paint_offset, layout_table_section_.Size()); 306 LayoutRect paint_rect(paint_offset, layout_table_section_.Size());
336 307
337 if (has_box_shadow) { 308 if (has_box_shadow) {
338 BoxPainter::PaintNormalBoxShadow(paint_info, paint_rect, 309 BoxPainter::PaintNormalBoxShadow(paint_info, paint_rect,
339 layout_table_section_.StyleRef()); 310 layout_table_section_.StyleRef());
340 } 311 }
341 312
342 if (may_have_background) { 313 if (may_have_background) {
343 PaintInfo paint_info_for_cells = paint_info.ForDescendants(); 314 PaintInfo paint_info_for_cells = paint_info.ForDescendants();
344 for (auto r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 315 for (auto r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
345 for (auto c = dirtied_columns.Start(); c < dirtied_columns.end(); c++) { 316 for (auto c = dirtied_columns.Start(); c < dirtied_columns.End(); c++) {
346 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) { 317 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
347 PaintBackgroundsBehindCell(*cell, paint_info_for_cells, paint_offset); 318 PaintBackgroundsBehindCell(*cell, paint_info_for_cells, paint_offset);
348 } 319 }
349 } 320 }
350 } 321 }
351 } 322 }
352 323
353 if (has_box_shadow) { 324 if (has_box_shadow) {
354 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting 325 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting
355 // paintRect by half widths of collapsed borders. 326 // paintRect by half widths of collapsed borders.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 const PaintInfo& paint_info_for_cells, 373 const PaintInfo& paint_info_for_cells,
403 const LayoutPoint& paint_offset) { 374 const LayoutPoint& paint_offset) {
404 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { 375 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) {
405 LayoutPoint cell_point = 376 LayoutPoint cell_point =
406 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); 377 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset);
407 cell.Paint(paint_info_for_cells, cell_point); 378 cell.Paint(paint_info_for_cells, cell_point);
408 } 379 }
409 } 380 }
410 381
411 } // namespace blink 382 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698