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/TableRowPainter.h" | 5 #include "core/paint/TableRowPainter.h" |
6 | 6 |
7 #include "core/layout/LayoutTableCell.h" | 7 #include "core/layout/LayoutTableCell.h" |
8 #include "core/layout/LayoutTableRow.h" | 8 #include "core/layout/LayoutTableRow.h" |
9 #include "core/paint/BoxPainter.h" | 9 #include "core/paint/BoxPainter.h" |
10 #include "core/paint/LayoutObjectDrawingRecorder.h" | 10 #include "core/paint/LayoutObjectDrawingRecorder.h" |
11 #include "core/paint/ObjectPainter.h" | 11 #include "core/paint/ObjectPainter.h" |
12 #include "core/paint/PaintInfo.h" | 12 #include "core/paint/PaintInfo.h" |
13 #include "core/paint/TableCellPainter.h" | 13 #include "core/paint/TableCellPainter.h" |
14 | 14 |
15 namespace blink { | 15 namespace blink { |
16 | 16 |
17 void TableRowPainter::paint(const PaintInfo& paintInfo, | 17 void TableRowPainter::paint(const PaintInfo& paintInfo, |
18 const LayoutPoint& paintOffset) { | 18 const LayoutPoint& paintOffset) { |
19 ObjectPainter(m_layoutTableRow).checkPaintOffset(paintInfo, paintOffset); | 19 ObjectPainter(m_layoutTableRow).checkPaintOffset(paintInfo, paintOffset); |
20 DCHECK(m_layoutTableRow.hasSelfPaintingLayer()); | 20 DCHECK(m_layoutTableRow.hasSelfPaintingLayer()); |
21 | 21 |
22 // TODO(crbug.com/577282): This painting order is inconsistent with other | 22 // TODO(crbug.com/577282): This painting order is inconsistent with other |
23 // outlines. | 23 // outlines. |
24 if (shouldPaintSelfOutline(paintInfo.phase)) | 24 if (shouldPaintSelfOutline(paintInfo.phase)) |
25 paintOutline(paintInfo, paintOffset); | 25 paintOutline(paintInfo, paintOffset); |
26 if (paintInfo.phase == PaintPhaseSelfOutlineOnly) | 26 if (paintInfo.phase == PaintPhaseSelfOutlineOnly) |
27 return; | 27 return; |
28 | 28 |
29 PaintInfo paintInfoForCells = paintInfo.forDescendants(); | |
30 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { | 29 if (shouldPaintSelfBlockBackground(paintInfo.phase)) { |
31 paintBoxShadow(paintInfo, paintOffset, Normal); | 30 const auto* section = m_layoutTableRow.section(); |
32 if (m_layoutTableRow.styleRef().hasBackground()) { | 31 LayoutRect cullRect = LayoutRect(paintInfo.cullRect().m_rect); |
33 // Paint row background of behind the cells. | 32 cullRect.moveBy(m_layoutTableRow.physicalLocation(section)); |
34 for (LayoutTableCell* cell = m_layoutTableRow.firstCell(); cell; | 33 LayoutRect logicalRectInSection = |
35 cell = cell->nextCell()) | 34 section->logicalRectForWritingModeAndDirection(cullRect); |
36 TableCellPainter(*cell).paintContainerBackgroundBehindCell( | 35 CellSpan dirtiedColumns = |
37 paintInfoForCells, paintOffset, m_layoutTableRow, | 36 section->dirtiedEffectiveColumns(logicalRectInSection); |
38 DisplayItem::kTableCellBackgroundFromRow); | 37 paintBoxDecorationBackground(paintInfo, paintOffset, dirtiedColumns); |
39 } | |
40 paintBoxShadow(paintInfo, paintOffset, Inset); | |
41 } | 38 } |
42 | 39 |
43 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) | 40 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) |
44 return; | 41 return; |
45 | 42 |
| 43 PaintInfo paintInfoForCells = paintInfo.forDescendants(); |
46 for (LayoutTableCell* cell = m_layoutTableRow.firstCell(); cell; | 44 for (LayoutTableCell* cell = m_layoutTableRow.firstCell(); cell; |
47 cell = cell->nextCell()) { | 45 cell = cell->nextCell()) { |
48 if (!cell->hasSelfPaintingLayer()) | 46 if (!cell->hasSelfPaintingLayer()) |
49 cell->paint(paintInfoForCells, paintOffset); | 47 cell->paint(paintInfoForCells, paintOffset); |
50 } | 48 } |
51 } | 49 } |
52 | 50 |
53 void TableRowPainter::paintOutline(const PaintInfo& paintInfo, | 51 void TableRowPainter::paintOutline(const PaintInfo& paintInfo, |
54 const LayoutPoint& paintOffset) { | 52 const LayoutPoint& paintOffset) { |
55 DCHECK(shouldPaintSelfOutline(paintInfo.phase)); | 53 DCHECK(shouldPaintSelfOutline(paintInfo.phase)); |
56 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location(); | 54 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location(); |
57 ObjectPainter(m_layoutTableRow).paintOutline(paintInfo, adjustedPaintOffset); | 55 ObjectPainter(m_layoutTableRow).paintOutline(paintInfo, adjustedPaintOffset); |
58 } | 56 } |
59 | 57 |
60 void TableRowPainter::paintBoxShadow(const PaintInfo& paintInfo, | 58 void TableRowPainter::paintBoxDecorationBackground( |
61 const LayoutPoint& paintOffset, | 59 const PaintInfo& paintInfo, |
62 ShadowStyle shadowStyle) { | 60 const LayoutPoint& paintOffset, |
63 DCHECK(shouldPaintSelfBlockBackground(paintInfo.phase)); | 61 const CellSpan& dirtiedColumns) { |
64 if (!m_layoutTableRow.styleRef().boxShadow()) | 62 bool hasBackground = m_layoutTableRow.styleRef().hasBackground(); |
| 63 bool hasBoxShadow = m_layoutTableRow.styleRef().boxShadow(); |
| 64 if (!hasBackground && !hasBoxShadow) |
65 return; | 65 return; |
66 | 66 |
67 DisplayItem::Type type = shadowStyle == Normal | 67 const auto* section = m_layoutTableRow.section(); |
68 ? DisplayItem::kTableRowBoxShadowNormal | 68 PaintResult paintResult = |
69 : DisplayItem::kTableRowBoxShadowInset; | 69 dirtiedColumns == section->fullTableEffectiveColumnSpan() |
| 70 ? FullyPainted |
| 71 : MayBeClippedByPaintDirtyRect; |
| 72 m_layoutTableRow.getMutableForPainting().updatePaintResult( |
| 73 paintResult, paintInfo.cullRect()); |
| 74 |
70 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( | 75 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( |
71 paintInfo.context, m_layoutTableRow, type)) | 76 paintInfo.context, m_layoutTableRow, |
| 77 DisplayItem::kBoxDecorationBackground)) |
72 return; | 78 return; |
73 | 79 |
74 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location(); | 80 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableRow.location(); |
75 LayoutRect bounds = | 81 LayoutRect bounds = |
76 BoxPainter(m_layoutTableRow) | 82 BoxPainter(m_layoutTableRow) |
77 .boundsForDrawingRecorder(paintInfo, adjustedPaintOffset); | 83 .boundsForDrawingRecorder(paintInfo, adjustedPaintOffset); |
78 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableRow, | 84 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableRow, |
79 type, bounds); | 85 DisplayItem::kBoxDecorationBackground, |
| 86 bounds); |
80 LayoutRect paintRect(adjustedPaintOffset, m_layoutTableRow.size()); | 87 LayoutRect paintRect(adjustedPaintOffset, m_layoutTableRow.size()); |
81 if (shadowStyle == Normal) { | 88 |
| 89 if (hasBoxShadow) { |
82 BoxPainter::paintNormalBoxShadow(paintInfo, paintRect, | 90 BoxPainter::paintNormalBoxShadow(paintInfo, paintRect, |
83 m_layoutTableRow.styleRef()); | 91 m_layoutTableRow.styleRef()); |
84 } else { | 92 } |
| 93 |
| 94 if (hasBackground) { |
| 95 PaintInfo paintInfoForCells = paintInfo.forDescendants(); |
| 96 for (auto c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
| 97 if (const auto* cell = |
| 98 section->originatingCellAt(m_layoutTableRow.rowIndex(), c)) |
| 99 paintBackgroundBehindCell(*cell, paintInfoForCells, paintOffset); |
| 100 } |
| 101 } |
| 102 |
| 103 if (hasBoxShadow) { |
85 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting | 104 // TODO(wangxianzhu): Calculate the inset shadow bounds by insetting |
86 // paintRect by half widths of collapsed borders. | 105 // paintRect by half widths of collapsed borders. |
87 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, | 106 BoxPainter::paintInsetBoxShadow(paintInfo, paintRect, |
88 m_layoutTableRow.styleRef()); | 107 m_layoutTableRow.styleRef()); |
89 } | 108 } |
90 } | 109 } |
91 | 110 |
92 void TableRowPainter::paintBackgroundBehindCell( | 111 void TableRowPainter::paintBackgroundBehindCell( |
93 const LayoutTableCell& cell, | 112 const LayoutTableCell& cell, |
94 const PaintInfo& paintInfo, | 113 const PaintInfo& paintInfo, |
95 const LayoutPoint& paintOffset) { | 114 const LayoutPoint& paintOffset) { |
96 DCHECK(m_layoutTableRow.styleRef().hasBackground() && | 115 DCHECK(m_layoutTableRow.styleRef().hasBackground()); |
97 !m_layoutTableRow.hasSelfPaintingLayer()); | 116 LayoutPoint cellPoint = paintOffset; |
98 LayoutPoint cellPoint = | 117 // If the row is self painting, paintOffset is in row's coordinates, so |
99 m_layoutTableRow.section()->flipForWritingModeForChild(&cell, | 118 // doesn't need to flip in section's blocks direction. A row doesn't have |
100 paintOffset); | 119 // flipped blocks direction. |
| 120 if (!m_layoutTableRow.hasSelfPaintingLayer()) { |
| 121 cellPoint = m_layoutTableRow.section()->flipForWritingModeForChild( |
| 122 &cell, cellPoint); |
| 123 } |
101 TableCellPainter(cell).paintContainerBackgroundBehindCell( | 124 TableCellPainter(cell).paintContainerBackgroundBehindCell( |
102 paintInfo, cellPoint, m_layoutTableRow, | 125 paintInfo, cellPoint, m_layoutTableRow); |
103 DisplayItem::kTableCellBackgroundFromRow); | |
104 } | 126 } |
105 | 127 |
106 } // namespace blink | 128 } // namespace blink |
OLD | NEW |