OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |