| 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" |
| 11 #include "core/paint/BoxPainter.h" | 11 #include "core/paint/BoxPainter.h" |
| 12 #include "core/paint/LayoutObjectDrawingRecorder.h" | 12 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 13 #include "core/paint/ObjectPainter.h" | 13 #include "core/paint/ObjectPainter.h" |
| 14 #include "core/paint/PaintInfo.h" | 14 #include "core/paint/PaintInfo.h" |
| 15 #include "core/paint/TableCellPainter.h" | 15 #include "core/paint/TableCellPainter.h" |
| 16 #include "core/paint/TableRowPainter.h" | 16 #include "core/paint/TableRowPainter.h" |
| 17 #include <algorithm> | 17 #include <algorithm> |
| 18 | 18 |
| 19 namespace blink { | 19 namespace blink { |
| 20 | 20 |
| 21 inline const LayoutTableCell* TableSectionPainter::primaryCellToPaint( | |
| 22 unsigned row, | |
| 23 unsigned column, | |
| 24 const CellSpan& dirtiedRows, | |
| 25 const CellSpan& dirtiedColumns) const { | |
| 26 DCHECK(row >= dirtiedRows.start() && row < dirtiedRows.end()); | |
| 27 DCHECK(column >= dirtiedColumns.start() && column < dirtiedColumns.end()); | |
| 28 | |
| 29 const LayoutTableCell* cell = m_layoutTableSection.primaryCellAt(row, column); | |
| 30 if (!cell) | |
| 31 return nullptr; | |
| 32 // We have painted (row, column) when painting (row - 1, column). | |
| 33 if (row > dirtiedRows.start() && | |
| 34 m_layoutTableSection.primaryCellAt(row - 1, column) == cell) | |
| 35 return nullptr; | |
| 36 // We have painted (row, column) when painting (row, column -1). | |
| 37 if (column > dirtiedColumns.start() && | |
| 38 m_layoutTableSection.primaryCellAt(row, column - 1) == cell) | |
| 39 return nullptr; | |
| 40 return cell; | |
| 41 } | |
| 42 | |
| 43 void TableSectionPainter::paintRepeatingHeaderGroup( | 21 void TableSectionPainter::paintRepeatingHeaderGroup( |
| 44 const PaintInfo& paintInfo, | 22 const PaintInfo& paintInfo, |
| 45 const LayoutPoint& paintOffset, | 23 const LayoutPoint& paintOffset, |
| 46 const CollapsedBorderValue& currentBorderValue, | 24 const CollapsedBorderValue& currentBorderValue, |
| 47 ItemToPaint itemToPaint) { | 25 ItemToPaint itemToPaint) { |
| 48 if (!m_layoutTableSection.isRepeatingHeaderGroup()) | 26 if (!m_layoutTableSection.isRepeatingHeaderGroup()) |
| 49 return; | 27 return; |
| 50 | 28 |
| 51 LayoutTable* table = m_layoutTableSection.table(); | 29 LayoutTable* table = m_layoutTableSection.table(); |
| 52 LayoutPoint paginationOffset = paintOffset; | 30 LayoutPoint paginationOffset = paintOffset; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 return; | 164 return; |
| 187 | 165 |
| 188 // Collapsed borders are painted from the bottom right to the top left so that | 166 // Collapsed borders are painted from the bottom right to the top left so that |
| 189 // precedence due to cell position is respected. | 167 // precedence due to cell position is respected. |
| 190 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { | 168 for (unsigned r = dirtiedRows.end(); r > dirtiedRows.start(); r--) { |
| 191 unsigned row = r - 1; | 169 unsigned row = r - 1; |
| 192 unsigned nCols = m_layoutTableSection.numCols(row); | 170 unsigned nCols = m_layoutTableSection.numCols(row); |
| 193 for (unsigned c = std::min(dirtiedColumns.end(), nCols); | 171 for (unsigned c = std::min(dirtiedColumns.end(), nCols); |
| 194 c > dirtiedColumns.start(); c--) { | 172 c > dirtiedColumns.start(); c--) { |
| 195 unsigned col = c - 1; | 173 unsigned col = c - 1; |
| 196 const LayoutTableCell* cell = | 174 if (const LayoutTableCell* cell = |
| 197 m_layoutTableSection.primaryCellAt(row, col); | 175 m_layoutTableSection.originatingCellAt(row, col)) { |
| 198 if (!cell || (row > dirtiedRows.start() && | 176 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild( |
| 199 m_layoutTableSection.primaryCellAt(row - 1, col) == cell) || | 177 cell, adjustedPaintOffset); |
| 200 (col > dirtiedColumns.start() && | 178 TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint, |
| 201 m_layoutTableSection.primaryCellAt(row, col - 1) == cell)) | 179 currentBorderValue); |
| 202 continue; | 180 } |
| 203 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild( | |
| 204 cell, adjustedPaintOffset); | |
| 205 TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint, | |
| 206 currentBorderValue); | |
| 207 } | 181 } |
| 208 } | 182 } |
| 209 } | 183 } |
| 210 | 184 |
| 211 void TableSectionPainter::paintObject(const PaintInfo& paintInfo, | 185 void TableSectionPainter::paintObject(const PaintInfo& paintInfo, |
| 212 const LayoutPoint& paintOffset) { | 186 const LayoutPoint& paintOffset) { |
| 213 LayoutRect localVisualRect = LayoutRect(paintInfo.cullRect().m_rect); | 187 LayoutRect localVisualRect = LayoutRect(paintInfo.cullRect().m_rect); |
| 214 localVisualRect.moveBy(-paintOffset); | 188 localVisualRect.moveBy(-paintOffset); |
| 215 | 189 |
| 216 LayoutRect tableAlignedRect = | 190 LayoutRect tableAlignedRect = |
| 217 m_layoutTableSection.logicalRectForWritingModeAndDirection( | 191 m_layoutTableSection.logicalRectForWritingModeAndDirection( |
| 218 localVisualRect); | 192 localVisualRect); |
| 219 | 193 |
| 220 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); | 194 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
| 221 CellSpan dirtiedColumns = | 195 CellSpan dirtiedColumns = |
| 222 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); | 196 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); |
| 223 | 197 |
| 224 if (dirtiedColumns.start() >= dirtiedColumns.end()) | 198 if (dirtiedColumns.start() >= dirtiedColumns.end()) |
| 225 return; | 199 return; |
| 226 | 200 |
| 227 PaintInfo paintInfoForDescendants = paintInfo.forDescendants(); | 201 PaintInfo paintInfoForDescendants = paintInfo.forDescendants(); |
| 228 | 202 |
| 229 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { | 203 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { |
| 230 paintBoxShadow(paintInfo, paintOffset, Normal); | 204 paintBoxShadow(paintInfo, paintOffset, Normal); |
| 231 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 205 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 232 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 206 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
| 233 if (const LayoutTableCell* cell = | 207 if (const LayoutTableCell* cell = |
| 234 primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns)) | 208 m_layoutTableSection.originatingCellAt(r, c)) { |
| 235 paintBackgroundsBehindCell(*cell, paintInfoForDescendants, | 209 paintBackgroundsBehindCell(*cell, paintInfoForDescendants, |
| 236 paintOffset); | 210 paintOffset); |
| 211 } |
| 237 } | 212 } |
| 238 } | 213 } |
| 239 paintBoxShadow(paintInfo, paintOffset, Inset); | 214 paintBoxShadow(paintInfo, paintOffset, Inset); |
| 240 } | 215 } |
| 241 | 216 |
| 242 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) | 217 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) |
| 243 return; | 218 return; |
| 244 | 219 |
| 245 if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) { | 220 if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) { |
| 246 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 221 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 247 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 222 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
| 248 // If a row has a layer, we'll paint row background in TableRowPainter. | 223 // If a row has a layer, we'll paint row background in TableRowPainter. |
| 249 if (!row || row->hasSelfPaintingLayer()) | 224 if (!row || row->hasSelfPaintingLayer()) |
| 250 continue; | 225 continue; |
| 251 | 226 |
| 252 TableRowPainter rowPainter(*row); | 227 TableRowPainter rowPainter(*row); |
| 253 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Normal); | 228 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Normal); |
| 254 if (row->styleRef().hasBackground()) { | 229 if (row->styleRef().hasBackground()) { |
| 255 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); | 230 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); |
| 256 c++) { | 231 c++) { |
| 257 if (const LayoutTableCell* cell = | 232 if (const LayoutTableCell* cell = |
| 258 primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns)) | 233 m_layoutTableSection.originatingCellAt(r, c)) { |
| 259 rowPainter.paintBackgroundBehindCell(*cell, paintInfoForDescendants, | 234 rowPainter.paintBackgroundBehindCell(*cell, paintInfoForDescendants, |
| 260 paintOffset); | 235 paintOffset); |
| 236 } |
| 261 } | 237 } |
| 262 } | 238 } |
| 263 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset); | 239 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset); |
| 264 } | 240 } |
| 265 } | 241 } |
| 266 | 242 |
| 267 const HashSet<LayoutTableCell*>& overflowingCells = | 243 const HashSet<LayoutTableCell*>& overflowingCells = |
| 268 m_layoutTableSection.overflowingCells(); | 244 m_layoutTableSection.overflowingCells(); |
| 269 if (!m_layoutTableSection.hasMultipleCellLevels() && | 245 if (!m_layoutTableSection.hasMultipleCellLevels() && |
| 270 overflowingCells.isEmpty()) { | 246 overflowingCells.isEmpty()) { |
| 271 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 247 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 272 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 248 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
| 273 // TODO(crbug.com/577282): This painting order is inconsistent with other | 249 // TODO(crbug.com/577282): This painting order is inconsistent with other |
| 274 // outlines. | 250 // outlines. |
| 275 if (row && !row->hasSelfPaintingLayer() && | 251 if (row && !row->hasSelfPaintingLayer() && |
| 276 shouldPaintSelfOutline(paintInfoForDescendants.phase)) | 252 shouldPaintSelfOutline(paintInfoForDescendants.phase)) |
| 277 TableRowPainter(*row).paintOutline(paintInfoForDescendants, | 253 TableRowPainter(*row).paintOutline(paintInfoForDescendants, |
| 278 paintOffset); | 254 paintOffset); |
| 279 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 255 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
| 280 if (const LayoutTableCell* cell = | 256 if (const LayoutTableCell* cell = |
| 281 primaryCellToPaint(r, c, dirtiedRows, dirtiedColumns)) | 257 m_layoutTableSection.originatingCellAt(r, c)) |
| 282 paintCell(*cell, paintInfoForDescendants, paintOffset); | 258 paintCell(*cell, paintInfoForDescendants, paintOffset); |
| 283 } | 259 } |
| 284 } | 260 } |
| 285 } else { | 261 } else { |
| 286 // The overflowing cells should be scarce to avoid adding a lot of cells to | 262 // The overflowing cells should be scarce to avoid adding a lot of cells to |
| 287 // the HashSet. | 263 // the HashSet. |
| 288 DCHECK(overflowingCells.size() < | 264 DCHECK(overflowingCells.size() < |
| 289 m_layoutTableSection.numRows() * | 265 m_layoutTableSection.numRows() * |
| 290 m_layoutTableSection.table()->effectiveColumns().size() * | 266 m_layoutTableSection.table()->effectiveColumns().size() * |
| 291 gMaxAllowedOverflowingCellRatioForFastPaintPath); | 267 gMaxAllowedOverflowingCellRatioForFastPaintPath); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 m_layoutTableSection.styleRef()); | 383 m_layoutTableSection.styleRef()); |
| 408 } else { | 384 } else { |
| 409 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting | 385 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting |
| 410 // paintRect by half widths of collapsed borders. | 386 // paintRect by half widths of collapsed borders. |
| 411 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, | 387 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, |
| 412 m_layoutTableSection.styleRef()); | 388 m_layoutTableSection.styleRef()); |
| 413 } | 389 } |
| 414 } | 390 } |
| 415 | 391 |
| 416 } // namespace blink | 392 } // namespace blink |
| OLD | NEW |