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

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

Issue 2884763003: Combine and simplify LayoutTableSection::DirtiedRows() and DirtiedEffectiveColumns() (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 // 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 void TableSectionPainter::PaintCollapsedBorders( 112 void TableSectionPainter::PaintCollapsedBorders(
118 const PaintInfo& paint_info, 113 const PaintInfo& paint_info,
119 const LayoutPoint& paint_offset, 114 const LayoutPoint& paint_offset,
120 const CollapsedBorderValue& current_border_value) { 115 const CollapsedBorderValue& current_border_value) {
121 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value); 116 PaintCollapsedSectionBorders(paint_info, paint_offset, current_border_value);
122 LayoutTable* table = layout_table_section_.Table(); 117 LayoutTable* table = layout_table_section_.Table();
123 if (table->Header() == layout_table_section_) 118 if (table->Header() == layout_table_section_)
124 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value, 119 PaintRepeatingHeaderGroup(paint_info, paint_offset, current_border_value,
125 kPaintCollapsedBorders); 120 kPaintCollapsedBorders);
126 } 121 }
(...skipping 11 matching lines...) Expand all
138 BoxClipper box_clipper(layout_table_section_, paint_info, 133 BoxClipper box_clipper(layout_table_section_, paint_info,
139 adjusted_paint_offset, kForceContentsClip); 134 adjusted_paint_offset, kForceContentsClip);
140 135
141 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_); 136 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_);
142 local_visual_rect.MoveBy(-adjusted_paint_offset); 137 local_visual_rect.MoveBy(-adjusted_paint_offset);
143 138
144 LayoutRect table_aligned_rect = 139 LayoutRect table_aligned_rect =
145 layout_table_section_.LogicalRectForWritingModeAndDirection( 140 layout_table_section_.LogicalRectForWritingModeAndDirection(
146 local_visual_rect); 141 local_visual_rect);
147 142
148 CellSpan dirtied_rows = layout_table_section_.DirtiedRows(table_aligned_rect); 143 CellSpan dirtied_rows;
149 CellSpan dirtied_columns = 144 CellSpan dirtied_columns;
150 layout_table_section_.DirtiedEffectiveColumns(table_aligned_rect); 145 layout_table_section_.DirtiedRowsAndEffectiveColumns(
146 table_aligned_rect, dirtied_rows, dirtied_columns);
151 147
152 if (dirtied_columns.Start() >= dirtied_columns.end()) 148 if (dirtied_columns.Start() >= dirtied_columns.End())
153 return; 149 return;
154 150
155 // 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
156 // precedence due to cell position is respected. 152 // precedence due to cell position is respected.
157 for (unsigned r = dirtied_rows.end(); r > dirtied_rows.Start(); r--) { 153 for (unsigned r = dirtied_rows.End(); r > dirtied_rows.Start(); r--) {
158 unsigned row = r - 1; 154 unsigned row = r - 1;
159 unsigned n_cols = layout_table_section_.NumEffectiveColumns(row); 155 unsigned n_cols = layout_table_section_.NumEffectiveColumns(row);
160 for (unsigned c = std::min(dirtied_columns.end(), n_cols); 156 for (unsigned c = std::min(dirtied_columns.End(), n_cols);
161 c > dirtied_columns.Start(); c--) { 157 c > dirtied_columns.Start(); c--) {
162 unsigned col = c - 1; 158 unsigned col = c - 1;
163 if (const LayoutTableCell* cell = 159 if (const LayoutTableCell* cell =
164 layout_table_section_.OriginatingCellAt(row, col)) { 160 layout_table_section_.OriginatingCellAt(row, col)) {
165 LayoutPoint cell_point = 161 LayoutPoint cell_point =
166 layout_table_section_.FlipForWritingModeForChild( 162 layout_table_section_.FlipForWritingModeForChild(
167 cell, adjusted_paint_offset); 163 cell, adjusted_paint_offset);
168 TableCellPainter(*cell).PaintCollapsedBorders(paint_info, cell_point, 164 TableCellPainter(*cell).PaintCollapsedBorders(paint_info, cell_point,
169 current_border_value); 165 current_border_value);
170 } 166 }
171 } 167 }
172 } 168 }
173 } 169 }
174 170
175 void TableSectionPainter::PaintObject(const PaintInfo& paint_info, 171 void TableSectionPainter::PaintObject(const PaintInfo& paint_info,
176 const LayoutPoint& paint_offset) { 172 const LayoutPoint& paint_offset) {
177 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_); 173 LayoutRect local_visual_rect = LayoutRect(paint_info.GetCullRect().rect_);
178 local_visual_rect.MoveBy(-paint_offset); 174 local_visual_rect.MoveBy(-paint_offset);
179 175
180 LayoutRect table_aligned_rect = 176 LayoutRect table_aligned_rect =
181 layout_table_section_.LogicalRectForWritingModeAndDirection( 177 layout_table_section_.LogicalRectForWritingModeAndDirection(
182 local_visual_rect); 178 local_visual_rect);
183 179
184 CellSpan dirtied_rows = layout_table_section_.DirtiedRows(table_aligned_rect); 180 CellSpan dirtied_rows;
185 CellSpan dirtied_columns = 181 CellSpan dirtied_columns;
186 layout_table_section_.DirtiedEffectiveColumns(table_aligned_rect); 182 layout_table_section_.DirtiedRowsAndEffectiveColumns(
183 table_aligned_rect, dirtied_rows, dirtied_columns);
187 184
188 PaintInfo paint_info_for_descendants = paint_info.ForDescendants(); 185 PaintInfo paint_info_for_descendants = paint_info.ForDescendants();
189 186
190 if (ShouldPaintSelfBlockBackground(paint_info.phase)) { 187 if (ShouldPaintSelfBlockBackground(paint_info.phase)) {
191 PaintBoxDecorationBackground(paint_info, paint_offset, dirtied_rows, 188 PaintBoxDecorationBackground(paint_info, paint_offset, dirtied_rows,
192 dirtied_columns); 189 dirtied_columns);
193 } 190 }
194 191
195 if (paint_info.phase == kPaintPhaseSelfBlockBackgroundOnly) 192 if (paint_info.phase == kPaintPhaseSelfBlockBackgroundOnly)
196 return; 193 return;
197 194
198 if (ShouldPaintDescendantBlockBackgrounds(paint_info.phase)) { 195 if (ShouldPaintDescendantBlockBackgrounds(paint_info.phase)) {
199 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 196 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
200 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 197 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
201 // 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
202 // TableRowPainter::paint(). 199 // TableRowPainter::paint().
203 if (!row || row->HasSelfPaintingLayer()) 200 if (!row || row->HasSelfPaintingLayer())
204 continue; 201 continue;
205 TableRowPainter(*row).PaintBoxDecorationBackground( 202 TableRowPainter(*row).PaintBoxDecorationBackground(
206 paint_info_for_descendants, paint_offset, dirtied_columns); 203 paint_info_for_descendants, paint_offset, dirtied_columns);
207 } 204 }
208 } 205 }
209 206
210 // This is tested after background painting because during background painting 207 // This is tested after background painting because during background painting
211 // 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
212 // dirtyRows and dirtyColumns. 209 // dirtyRows and dirtyColumns.
213 if (dirtied_rows.Start() >= dirtied_rows.end() || 210 if (dirtied_rows.Start() >= dirtied_rows.End() ||
214 dirtied_columns.Start() >= dirtied_columns.end()) 211 dirtied_columns.Start() >= dirtied_columns.End())
215 return; 212 return;
216 213
217 const auto& overflowing_cells = layout_table_section_.OverflowingCells(); 214 const auto& overflowing_cells = layout_table_section_.OverflowingCells();
218 if (!layout_table_section_.HasMultipleCellLevels() && 215 if (overflowing_cells.IsEmpty()) {
219 overflowing_cells.IsEmpty()) {
220 // This path is for 2 cases: 216 // This path is for 2 cases:
221 // 1. Normal partial paint, without overflowing cells and multiple cell 217 // 1. Normal partial paint, without overflowing cells;
222 // levels;
223 // 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
224 // cells. 219 // cells.
225 // 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
226 // whether dirtied_rows and dirtied_columns cover the whole section. 221 // whether dirtied_rows and dirtied_columns cover the whole section.
227 DCHECK(!layout_table_section_.HasOverflowingCell() || 222 DCHECK(!layout_table_section_.HasOverflowingCell() ||
228 (dirtied_rows == layout_table_section_.FullSectionRowSpan() && 223 (dirtied_rows == layout_table_section_.FullSectionRowSpan() &&
229 dirtied_columns == 224 dirtied_columns ==
230 layout_table_section_.FullTableEffectiveColumnSpan())); 225 layout_table_section_.FullTableEffectiveColumnSpan()));
231 226
232 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 227 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
233 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 228 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
234 // TODO(crbug.com/577282): This painting order is inconsistent with other 229 // TODO(crbug.com/577282): This painting order is inconsistent with other
235 // outlines. 230 // outlines.
236 if (row && !row->HasSelfPaintingLayer() && 231 if (row && !row->HasSelfPaintingLayer() &&
237 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) { 232 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) {
238 TableRowPainter(*row).PaintOutline(paint_info_for_descendants, 233 TableRowPainter(*row).PaintOutline(paint_info_for_descendants,
239 paint_offset); 234 paint_offset);
240 } 235 }
241 for (unsigned c = dirtied_columns.Start(); c < dirtied_columns.end(); 236 for (unsigned c = dirtied_columns.Start(); c < dirtied_columns.End();
242 c++) { 237 c++) {
243 if (const LayoutTableCell* cell = 238 if (const LayoutTableCell* cell =
244 layout_table_section_.OriginatingCellAt(r, c)) 239 layout_table_section_.OriginatingCellAt(r, c))
245 PaintCell(*cell, paint_info_for_descendants, paint_offset); 240 PaintCell(*cell, paint_info_for_descendants, paint_offset);
246 } 241 }
247 } 242 }
248 } else { 243 } else {
249 // This path paints section with multiple cell levels or a reasonable number 244 // This path paints section with a reasonable number of overflowing cells.
250 // of overflowing cells. This is the "partial paint path" for overflowing 245 // This is the "partial paint path" for overflowing cells referred in
251 // cells referred in LayoutTableSection::ComputeOverflowFromDescendants(). 246 // LayoutTableSection::ComputeOverflowFromDescendants().
252 Vector<const LayoutTableCell*> cells; 247 Vector<const LayoutTableCell*> cells;
253 CopyToVector(overflowing_cells, cells); 248 CopyToVector(overflowing_cells, cells);
254 249
255 HashSet<const LayoutTableCell*> spanning_cells; 250 HashSet<const LayoutTableCell*> spanning_cells;
256 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 251 for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
257 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r); 252 const LayoutTableRow* row = layout_table_section_.RowLayoutObjectAt(r);
258 // TODO(crbug.com/577282): This painting order is inconsistent with other 253 // TODO(crbug.com/577282): This painting order is inconsistent with other
259 // outlines. 254 // outlines.
260 if (row && !row->HasSelfPaintingLayer() && 255 if (row && !row->HasSelfPaintingLayer() &&
261 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) { 256 ShouldPaintSelfOutline(paint_info_for_descendants.phase)) {
262 TableRowPainter(*row).PaintOutline(paint_info_for_descendants, 257 TableRowPainter(*row).PaintOutline(paint_info_for_descendants,
263 paint_offset); 258 paint_offset);
264 } 259 }
265 unsigned n_cols = layout_table_section_.NumEffectiveColumns(r); 260 unsigned n_cols = layout_table_section_.NumEffectiveColumns(r);
266 for (unsigned c = dirtied_columns.Start(); 261 for (unsigned c = dirtied_columns.Start();
267 c < n_cols && c < dirtied_columns.end(); c++) { 262 c < n_cols && c < dirtied_columns.End(); c++) {
268 for (const auto* cell : 263 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
269 layout_table_section_.GridCellAt(r, c).Cells()) { 264 if (!overflowing_cells.Contains(cell))
270 if (overflowing_cells.Contains(cell)) 265 cells.push_back(cell);
Xianzhu 2017/05/16 17:18:13 This is simplified because dirtied_columns and dir
271 continue;
272 if (cell->RowSpan() > 1 || cell->ColSpan() > 1) {
273 if (!spanning_cells.insert(cell).is_new_entry)
274 continue;
275 }
276 cells.push_back(cell);
277 } 266 }
278 } 267 }
279 } 268 }
280 269
281 // Sort the dirty cells by paint order. 270 // Sort the dirty cells by paint order.
282 if (!overflowing_cells.size()) { 271 std::sort(cells.begin(), cells.end(), LayoutTableCell::CompareInDOMOrder);
Xianzhu 2017/05/16 17:18:13 Now only one sort method left because we enter thi
283 std::stable_sort(cells.begin(), cells.end(), CompareCellPositions);
284 } else {
285 // This comparison is used only when we have overflowing cells as we have
286 // an unsorted array to sort. We thus need to sort both on rows and
287 // columns to paint in proper order.
288 std::sort(cells.begin(), cells.end(), LayoutTableCell::CompareInDOMOrder);
289 }
290
291 for (const auto* cell : cells) 272 for (const auto* cell : cells)
292 PaintCell(*cell, paint_info_for_descendants, paint_offset); 273 PaintCell(*cell, paint_info_for_descendants, paint_offset);
293 } 274 }
294 } 275 }
295 276
296 void TableSectionPainter::PaintBoxDecorationBackground( 277 void TableSectionPainter::PaintBoxDecorationBackground(
297 const PaintInfo& paint_info, 278 const PaintInfo& paint_info,
298 const LayoutPoint& paint_offset, 279 const LayoutPoint& paint_offset,
299 const CellSpan& dirtied_rows, 280 const CellSpan& dirtied_rows,
300 const CellSpan& dirtied_columns) { 281 const CellSpan& dirtied_columns) {
(...skipping 23 matching lines...) Expand all
324 DisplayItem::kBoxDecorationBackground, bounds); 305 DisplayItem::kBoxDecorationBackground, bounds);
325 LayoutRect paint_rect(paint_offset, layout_table_section_.Size()); 306 LayoutRect paint_rect(paint_offset, layout_table_section_.Size());
326 307
327 if (has_box_shadow) { 308 if (has_box_shadow) {
328 BoxPainter::PaintNormalBoxShadow(paint_info, paint_rect, 309 BoxPainter::PaintNormalBoxShadow(paint_info, paint_rect,
329 layout_table_section_.StyleRef()); 310 layout_table_section_.StyleRef());
330 } 311 }
331 312
332 if (may_have_background) { 313 if (may_have_background) {
333 PaintInfo paint_info_for_cells = paint_info.ForDescendants(); 314 PaintInfo paint_info_for_cells = paint_info.ForDescendants();
334 for (auto r = dirtied_rows.Start(); r < dirtied_rows.end(); r++) { 315 for (auto r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
335 for (auto c = dirtied_columns.Start(); c < dirtied_columns.end(); c++) { 316 for (auto c = dirtied_columns.Start(); c < dirtied_columns.End(); c++) {
336 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) { 317 if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
337 PaintBackgroundsBehindCell(*cell, paint_info_for_cells, paint_offset); 318 PaintBackgroundsBehindCell(*cell, paint_info_for_cells, paint_offset);
338 } 319 }
339 } 320 }
340 } 321 }
341 } 322 }
342 323
343 if (has_box_shadow) { 324 if (has_box_shadow) {
344 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting 325 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting
345 // paintRect by half widths of collapsed borders. 326 // paintRect by half widths of collapsed borders.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 const PaintInfo& paint_info_for_cells, 371 const PaintInfo& paint_info_for_cells,
391 const LayoutPoint& paint_offset) { 372 const LayoutPoint& paint_offset) {
392 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) { 373 if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) {
393 LayoutPoint cell_point = 374 LayoutPoint cell_point =
394 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset); 375 layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset);
395 cell.Paint(paint_info_for_cells, cell_point); 376 cell.Paint(paint_info_for_cells, cell_point);
396 } 377 }
397 } 378 }
398 379
399 } // namespace blink 380 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698