| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 boxClipper.emplace(m_layoutTableSection, paintInfo, adjustedPaintOffset, | 101 boxClipper.emplace(m_layoutTableSection, paintInfo, adjustedPaintOffset, |
| 102 ForceContentsClip); | 102 ForceContentsClip); |
| 103 paintObject(paintInfo, adjustedPaintOffset); | 103 paintObject(paintInfo, adjustedPaintOffset); |
| 104 } | 104 } |
| 105 | 105 |
| 106 if (shouldPaintSelfOutline(paintInfo.phase)) | 106 if (shouldPaintSelfOutline(paintInfo.phase)) |
| 107 ObjectPainter(m_layoutTableSection) | 107 ObjectPainter(m_layoutTableSection) |
| 108 .paintOutline(paintInfo, adjustedPaintOffset); | 108 .paintOutline(paintInfo, adjustedPaintOffset); |
| 109 } | 109 } |
| 110 | 110 |
| 111 static inline bool compareCellPositions(LayoutTableCell* elem1, | 111 static inline bool compareCellPositions(const LayoutTableCell* elem1, |
| 112 LayoutTableCell* elem2) { | 112 const LayoutTableCell* elem2) { |
| 113 return elem1->rowIndex() < elem2->rowIndex(); | 113 return elem1->rowIndex() < elem2->rowIndex(); |
| 114 } | 114 } |
| 115 | 115 |
| 116 // This comparison is used only when we have overflowing cells as we have an | 116 // This comparison is used only when we have overflowing cells as we have an |
| 117 // unsorted array to sort. We thus need to sort both on rows and columns to | 117 // unsorted array to sort. We thus need to sort both on rows and columns to |
| 118 // properly issue paint invalidations. | 118 // properly issue paint invalidations. |
| 119 static inline bool compareCellPositionsWithOverflowingCells( | 119 static inline bool compareCellPositionsWithOverflowingCells( |
| 120 LayoutTableCell* elem1, | 120 const LayoutTableCell* elem1, |
| 121 LayoutTableCell* elem2) { | 121 const LayoutTableCell* elem2) { |
| 122 if (elem1->rowIndex() != elem2->rowIndex()) | 122 if (elem1->rowIndex() != elem2->rowIndex()) |
| 123 return elem1->rowIndex() < elem2->rowIndex(); | 123 return elem1->rowIndex() < elem2->rowIndex(); |
| 124 | 124 |
| 125 return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex(); | 125 return elem1->absoluteColumnIndex() < elem2->absoluteColumnIndex(); |
| 126 } | 126 } |
| 127 | 127 |
| 128 void TableSectionPainter::paintCollapsedBorders( | 128 void TableSectionPainter::paintCollapsedBorders( |
| 129 const PaintInfo& paintInfo, | 129 const PaintInfo& paintInfo, |
| 130 const LayoutPoint& paintOffset, | 130 const LayoutPoint& paintOffset, |
| 131 const CollapsedBorderValue& currentBorderValue) { | 131 const CollapsedBorderValue& currentBorderValue) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 localVisualRect.moveBy(-paintOffset); | 188 localVisualRect.moveBy(-paintOffset); |
| 189 | 189 |
| 190 LayoutRect tableAlignedRect = | 190 LayoutRect tableAlignedRect = |
| 191 m_layoutTableSection.logicalRectForWritingModeAndDirection( | 191 m_layoutTableSection.logicalRectForWritingModeAndDirection( |
| 192 localVisualRect); | 192 localVisualRect); |
| 193 | 193 |
| 194 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); | 194 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
| 195 CellSpan dirtiedColumns = | 195 CellSpan dirtiedColumns = |
| 196 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); | 196 m_layoutTableSection.dirtiedEffectiveColumns(tableAlignedRect); |
| 197 | 197 |
| 198 if (dirtiedColumns.start() >= dirtiedColumns.end()) | |
| 199 return; | |
| 200 | |
| 201 PaintInfo paintInfoForDescendants = paintInfo.forDescendants(); | 198 PaintInfo paintInfoForDescendants = paintInfo.forDescendants(); |
| 202 | 199 |
| 203 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { | 200 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { |
| 204 paintBoxShadow(paintInfo, paintOffset, Normal); | 201 paintBoxDecorationBackground(paintInfo, paintOffset, dirtiedRows, |
| 205 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 202 dirtiedColumns); |
| 206 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | |
| 207 if (const LayoutTableCell* cell = | |
| 208 m_layoutTableSection.originatingCellAt(r, c)) { | |
| 209 paintBackgroundsBehindCell(*cell, paintInfoForDescendants, | |
| 210 paintOffset); | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 paintBoxShadow(paintInfo, paintOffset, Inset); | |
| 215 } | 203 } |
| 216 | 204 |
| 217 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) | 205 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) |
| 218 return; | 206 return; |
| 219 | 207 |
| 220 if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) { | 208 if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) { |
| 221 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 209 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 222 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 210 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
| 223 // If a row has a layer, we'll paint row background in TableRowPainter. | 211 // If a row has a layer, we'll paint row background though |
| 212 // TableRowPainter::paint(). |
| 224 if (!row || row->hasSelfPaintingLayer()) | 213 if (!row || row->hasSelfPaintingLayer()) |
| 225 continue; | 214 continue; |
| 226 | 215 TableRowPainter(*row).paintBoxDecorationBackground( |
| 227 TableRowPainter rowPainter(*row); | 216 paintInfoForDescendants, paintOffset, dirtiedColumns); |
| 228 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Normal); | |
| 229 if (row->styleRef().hasBackground()) { | |
| 230 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); | |
| 231 c++) { | |
| 232 if (const LayoutTableCell* cell = | |
| 233 m_layoutTableSection.originatingCellAt(r, c)) { | |
| 234 rowPainter.paintBackgroundBehindCell(*cell, paintInfoForDescendants, | |
| 235 paintOffset); | |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inset); | |
| 240 } | 217 } |
| 241 } | 218 } |
| 242 | 219 |
| 243 const HashSet<LayoutTableCell*>& overflowingCells = | 220 // This is tested after background painting because during background painting |
| 244 m_layoutTableSection.overflowingCells(); | 221 // we need to check validity of the previous background display item based on |
| 222 // dirtyRows and dirtyColumns. |
| 223 if (dirtiedRows.start() >= dirtiedRows.end() || |
| 224 dirtiedColumns.start() >= dirtiedColumns.end()) |
| 225 return; |
| 226 |
| 227 const auto& overflowingCells = m_layoutTableSection.overflowingCells(); |
| 245 if (!m_layoutTableSection.hasMultipleCellLevels() && | 228 if (!m_layoutTableSection.hasMultipleCellLevels() && |
| 246 overflowingCells.isEmpty()) { | 229 overflowingCells.isEmpty()) { |
| 247 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 230 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 248 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 231 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
| 249 // TODO(crbug.com/577282): This painting order is inconsistent with other | 232 // TODO(crbug.com/577282): This painting order is inconsistent with other |
| 250 // outlines. | 233 // outlines. |
| 251 if (row && !row->hasSelfPaintingLayer() && | 234 if (row && !row->hasSelfPaintingLayer() && |
| 252 shouldPaintSelfOutline(paintInfoForDescendants.phase)) | 235 shouldPaintSelfOutline(paintInfoForDescendants.phase)) { |
| 253 TableRowPainter(*row).paintOutline(paintInfoForDescendants, | 236 TableRowPainter(*row).paintOutline(paintInfoForDescendants, |
| 254 paintOffset); | 237 paintOffset); |
| 238 } |
| 255 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 239 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
| 256 if (const LayoutTableCell* cell = | 240 if (const LayoutTableCell* cell = |
| 257 m_layoutTableSection.originatingCellAt(r, c)) | 241 m_layoutTableSection.originatingCellAt(r, c)) |
| 258 paintCell(*cell, paintInfoForDescendants, paintOffset); | 242 paintCell(*cell, paintInfoForDescendants, paintOffset); |
| 259 } | 243 } |
| 260 } | 244 } |
| 261 } else { | 245 } else { |
| 262 // The overflowing cells should be scarce to avoid adding a lot of cells to | 246 // The overflowing cells should be scarce to avoid adding a lot of cells to |
| 263 // the HashSet. | 247 // the HashSet. |
| 264 DCHECK(overflowingCells.size() < | 248 DCHECK(overflowingCells.size() < |
| 265 m_layoutTableSection.numRows() * | 249 m_layoutTableSection.numRows() * |
| 266 m_layoutTableSection.table()->effectiveColumns().size() * | 250 m_layoutTableSection.table()->effectiveColumns().size() * |
| 267 gMaxAllowedOverflowingCellRatioForFastPaintPath); | 251 gMaxAllowedOverflowingCellRatioForFastPaintPath); |
| 268 | 252 |
| 269 // To make sure we properly paint the section, we paint all the overflowing | 253 // To make sure we properly paint the section, we paint all the overflowing |
| 270 // cells that we collected. | 254 // cells that we collected. |
| 271 Vector<LayoutTableCell*> cells; | 255 Vector<const LayoutTableCell*> cells; |
| 272 copyToVector(overflowingCells, cells); | 256 copyToVector(overflowingCells, cells); |
| 273 | 257 |
| 274 HashSet<LayoutTableCell*> spanningCells; | 258 HashSet<const LayoutTableCell*> spanningCells; |
| 275 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 259 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 276 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); | 260 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r); |
| 277 // TODO(crbug.com/577282): This painting order is inconsistent with other | 261 // TODO(crbug.com/577282): This painting order is inconsistent with other |
| 278 // outlines. | 262 // outlines. |
| 279 if (row && !row->hasSelfPaintingLayer() && | 263 if (row && !row->hasSelfPaintingLayer() && |
| 280 shouldPaintSelfOutline(paintInfoForDescendants.phase)) | 264 shouldPaintSelfOutline(paintInfoForDescendants.phase)) { |
| 281 TableRowPainter(*row).paintOutline(paintInfoForDescendants, | 265 TableRowPainter(*row).paintOutline(paintInfoForDescendants, |
| 282 paintOffset); | 266 paintOffset); |
| 267 } |
| 283 unsigned nCols = m_layoutTableSection.numCols(r); | 268 unsigned nCols = m_layoutTableSection.numCols(r); |
| 284 for (unsigned c = dirtiedColumns.start(); | 269 for (unsigned c = dirtiedColumns.start(); |
| 285 c < nCols && c < dirtiedColumns.end(); c++) { | 270 c < nCols && c < dirtiedColumns.end(); c++) { |
| 286 const LayoutTableSection::CellStruct& current = | 271 const auto& cellStruct = m_layoutTableSection.cellAt(r, c); |
| 287 m_layoutTableSection.cellAt(r, c); | 272 for (const auto* cell : cellStruct.cells) { |
| 288 for (LayoutTableCell* cell : current.cells) { | |
| 289 if (overflowingCells.contains(cell)) | 273 if (overflowingCells.contains(cell)) |
| 290 continue; | 274 continue; |
| 291 if (cell->rowSpan() > 1 || cell->colSpan() > 1) { | 275 if (cell->rowSpan() > 1 || cell->colSpan() > 1) { |
| 292 if (!spanningCells.insert(cell).isNewEntry) | 276 if (!spanningCells.insert(cell).isNewEntry) |
| 293 continue; | 277 continue; |
| 294 } | 278 } |
| 295 cells.push_back(cell); | 279 cells.push_back(cell); |
| 296 } | 280 } |
| 297 } | 281 } |
| 298 } | 282 } |
| 299 | 283 |
| 300 // Sort the dirty cells by paint order. | 284 // Sort the dirty cells by paint order. |
| 301 if (!overflowingCells.size()) | 285 if (!overflowingCells.size()) { |
| 302 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); | 286 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); |
| 303 else | 287 } else { |
| 304 std::sort(cells.begin(), cells.end(), | 288 std::sort(cells.begin(), cells.end(), |
| 305 compareCellPositionsWithOverflowingCells); | 289 compareCellPositionsWithOverflowingCells); |
| 290 } |
| 306 | 291 |
| 307 for (const LayoutTableCell* cell : cells) | 292 for (const auto* cell : cells) |
| 308 paintCell(*cell, paintInfoForDescendants, paintOffset); | 293 paintCell(*cell, paintInfoForDescendants, paintOffset); |
| 309 } | 294 } |
| 310 } | 295 } |
| 311 | 296 |
| 297 void TableSectionPainter::paintBoxDecorationBackground( |
| 298 const PaintInfo& paintInfo, |
| 299 const LayoutPoint& paintOffset, |
| 300 const CellSpan& dirtiedRows, |
| 301 const CellSpan& dirtiedColumns) { |
| 302 bool mayHaveBackground = m_layoutTableSection.table()->hasColElements() || |
| 303 m_layoutTableSection.styleRef().hasBackground(); |
| 304 bool hasBoxShadow = m_layoutTableSection.styleRef().boxShadow(); |
| 305 if (!mayHaveBackground && !hasBoxShadow) |
| 306 return; |
| 307 |
| 308 PaintResult paintResult = |
| 309 dirtiedColumns == m_layoutTableSection.fullTableEffectiveColumnSpan() && |
| 310 dirtiedRows == m_layoutTableSection.fullSectionRowSpan() |
| 311 ? FullyPainted |
| 312 : MayBeClippedByPaintDirtyRect; |
| 313 m_layoutTableSection.getMutableForPainting().updatePaintResult( |
| 314 paintResult, paintInfo.cullRect()); |
| 315 |
| 316 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( |
| 317 paintInfo.context, m_layoutTableSection, |
| 318 DisplayItem::kBoxDecorationBackground)) |
| 319 return; |
| 320 |
| 321 LayoutRect bounds = BoxPainter(m_layoutTableSection) |
| 322 .boundsForDrawingRecorder(paintInfo, paintOffset); |
| 323 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection, |
| 324 DisplayItem::kBoxDecorationBackground, |
| 325 bounds); |
| 326 LayoutRect paintRect(paintOffset, m_layoutTableSection.size()); |
| 327 |
| 328 if (hasBoxShadow) { |
| 329 BoxPainter::paintNormalBoxShadow(paintInfo, paintRect, |
| 330 m_layoutTableSection.styleRef()); |
| 331 } |
| 332 |
| 333 if (mayHaveBackground) { |
| 334 PaintInfo paintInfoForCells = paintInfo.forDescendants(); |
| 335 for (auto r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
| 336 for (auto c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
| 337 if (const auto* cell = m_layoutTableSection.originatingCellAt(r, c)) { |
| 338 paintBackgroundsBehindCell(*cell, paintInfoForCells, paintOffset); |
| 339 } |
| 340 } |
| 341 } |
| 342 } |
| 343 |
| 344 if (hasBoxShadow) { |
| 345 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting |
| 346 // paintRect by half widths of collapsed borders. |
| 347 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, |
| 348 m_layoutTableSection.styleRef()); |
| 349 } |
| 350 } |
| 351 |
| 312 void TableSectionPainter::paintBackgroundsBehindCell( | 352 void TableSectionPainter::paintBackgroundsBehindCell( |
| 313 const LayoutTableCell& cell, | 353 const LayoutTableCell& cell, |
| 314 const PaintInfo& paintInfoForCells, | 354 const PaintInfo& paintInfoForCells, |
| 315 const LayoutPoint& paintOffset) { | 355 const LayoutPoint& paintOffset) { |
| 316 LayoutPoint cellPoint = | 356 LayoutPoint cellPoint = |
| 317 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); | 357 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); |
| 318 | 358 |
| 319 // We need to handle painting a stack of backgrounds. This stack (from bottom | 359 // We need to handle painting a stack of backgrounds. This stack (from bottom |
| 320 // to top) consists of the column group, column, row group, row, and then the | 360 // to top) consists of the column group, column, row group, row, and then the |
| 321 // cell. | 361 // cell. |
| 322 | 362 |
| 323 LayoutTable::ColAndColGroup colAndColGroup = | 363 LayoutTable::ColAndColGroup colAndColGroup = |
| 324 m_layoutTableSection.table()->colElementAtAbsoluteColumn( | 364 m_layoutTableSection.table()->colElementAtAbsoluteColumn( |
| 325 cell.absoluteColumnIndex()); | 365 cell.absoluteColumnIndex()); |
| 326 LayoutTableCol* column = colAndColGroup.col; | 366 LayoutTableCol* column = colAndColGroup.col; |
| 327 LayoutTableCol* columnGroup = colAndColGroup.colgroup; | 367 LayoutTableCol* columnGroup = colAndColGroup.colgroup; |
| 328 TableCellPainter tableCellPainter(cell); | 368 TableCellPainter tableCellPainter(cell); |
| 329 | 369 |
| 330 // Column groups and columns first. | 370 // Column groups and columns first. |
| 331 // FIXME: Columns and column groups do not currently support opacity, and they | 371 // FIXME: Columns and column groups do not currently support opacity, and they |
| 332 // are being painted "too late" in the stack, since we have already opened a | 372 // are being painted "too late" in the stack, since we have already opened a |
| 333 // transparency layer (potentially) for the table row group. Note that we | 373 // transparency layer (potentially) for the table row group. Note that we |
| 334 // deliberately ignore whether or not the cell has a layer, since these | 374 // deliberately ignore whether or not the cell has a layer, since these |
| 335 // backgrounds paint "behind" the cell. | 375 // backgrounds paint "behind" the cell. |
| 336 if (columnGroup && columnGroup->styleRef().hasBackground()) | 376 if (columnGroup && columnGroup->styleRef().hasBackground()) { |
| 337 tableCellPainter.paintContainerBackgroundBehindCell( | 377 tableCellPainter.paintContainerBackgroundBehindCell( |
| 338 paintInfoForCells, cellPoint, *columnGroup, | 378 paintInfoForCells, cellPoint, *columnGroup); |
| 339 DisplayItem::kTableCellBackgroundFromColumnGroup); | 379 } |
| 340 if (column && column->styleRef().hasBackground()) | 380 if (column && column->styleRef().hasBackground()) { |
| 341 tableCellPainter.paintContainerBackgroundBehindCell( | 381 tableCellPainter.paintContainerBackgroundBehindCell(paintInfoForCells, |
| 342 paintInfoForCells, cellPoint, *column, | 382 cellPoint, *column); |
| 343 DisplayItem::kTableCellBackgroundFromColumn); | 383 } |
| 344 | 384 |
| 345 // Paint the row group next. | 385 // Paint the row group next. |
| 346 if (m_layoutTableSection.styleRef().hasBackground()) | 386 if (m_layoutTableSection.styleRef().hasBackground()) { |
| 347 tableCellPainter.paintContainerBackgroundBehindCell( | 387 tableCellPainter.paintContainerBackgroundBehindCell( |
| 348 paintInfoForCells, cellPoint, m_layoutTableSection, | 388 paintInfoForCells, cellPoint, m_layoutTableSection); |
| 349 DisplayItem::kTableCellBackgroundFromSection); | 389 } |
| 350 } | 390 } |
| 351 | 391 |
| 352 void TableSectionPainter::paintCell(const LayoutTableCell& cell, | 392 void TableSectionPainter::paintCell(const LayoutTableCell& cell, |
| 353 const PaintInfo& paintInfoForCells, | 393 const PaintInfo& paintInfoForCells, |
| 354 const LayoutPoint& paintOffset) { | 394 const LayoutPoint& paintOffset) { |
| 355 if (!cell.hasSelfPaintingLayer() && !cell.row()->hasSelfPaintingLayer()) { | 395 if (!cell.hasSelfPaintingLayer() && !cell.row()->hasSelfPaintingLayer()) { |
| 356 LayoutPoint cellPoint = | 396 LayoutPoint cellPoint = |
| 357 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); | 397 m_layoutTableSection.flipForWritingModeForChild(&cell, paintOffset); |
| 358 cell.paint(paintInfoForCells, cellPoint); | 398 cell.paint(paintInfoForCells, cellPoint); |
| 359 } | 399 } |
| 360 } | 400 } |
| 361 | 401 |
| 362 void TableSectionPainter::paintBoxShadow(const PaintInfo& paintInfo, | |
| 363 const LayoutPoint& paintOffset, | |
| 364 ShadowStyle shadowStyle) { | |
| 365 DCHECK(shouldPaintSelfBlockBackground(paintInfo.phase)); | |
| 366 if (!m_layoutTableSection.styleRef().boxShadow()) | |
| 367 return; | |
| 368 | |
| 369 DisplayItem::Type type = shadowStyle == Normal | |
| 370 ? DisplayItem::kTableSectionBoxShadowNormal | |
| 371 : DisplayItem::kTableSectionBoxShadowInset; | |
| 372 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( | |
| 373 paintInfo.context, m_layoutTableSection, type)) | |
| 374 return; | |
| 375 | |
| 376 LayoutRect bounds = BoxPainter(m_layoutTableSection) | |
| 377 .boundsForDrawingRecorder(paintInfo, paintOffset); | |
| 378 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection, | |
| 379 type, bounds); | |
| 380 LayoutRect paintRect(paintOffset, m_layoutTableSection.size()); | |
| 381 if (shadowStyle == Normal) { | |
| 382 BoxPainter::paintNormalBoxShadow(paintInfo, paintRect, | |
| 383 m_layoutTableSection.styleRef()); | |
| 384 } else { | |
| 385 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting | |
| 386 // paintRect by half widths of collapsed borders. | |
| 387 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, | |
| 388 m_layoutTableSection.styleRef()); | |
| 389 } | |
| 390 } | |
| 391 | |
| 392 } // namespace blink | 402 } // namespace blink |
| OLD | NEW |