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/LayoutTable.h" | 7 #include "core/layout/LayoutTable.h" |
8 #include "core/layout/LayoutTableCell.h" | 8 #include "core/layout/LayoutTableCell.h" |
9 #include "core/layout/LayoutTableCol.h" | 9 #include "core/layout/LayoutTableCol.h" |
10 #include "core/layout/LayoutTableRow.h" | 10 #include "core/layout/LayoutTableRow.h" |
11 #include "core/paint/BlockPainter.h" | 11 #include "core/paint/BlockPainter.h" |
12 #include "core/paint/BoxClipper.h" | 12 #include "core/paint/BoxClipper.h" |
13 #include "core/paint/LayoutObjectDrawingRecorder.h" | 13 #include "core/paint/LayoutObjectDrawingRecorder.h" |
14 #include "core/paint/ObjectPainter.h" | 14 #include "core/paint/ObjectPainter.h" |
15 #include "core/paint/PaintInfo.h" | 15 #include "core/paint/PaintInfo.h" |
16 #include "core/paint/TableCellPainter.h" | 16 #include "core/paint/TableCellPainter.h" |
17 #include "core/paint/TableRowPainter.h" | 17 #include "core/paint/TableRowPainter.h" |
18 #include <algorithm> | 18 #include <algorithm> |
19 | 19 |
20 namespace blink { | 20 namespace blink { |
21 | 21 |
22 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p aintOffset) | 22 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p aintOffset) |
23 { | 23 { |
24 ASSERT(!m_layoutTableSection.needsLayout()); | 24 ASSERT(!m_layoutTableSection.needsLayout()); |
25 // avoid crashing on bugs that cause us to paint with dirty layout | 25 // avoid crashing on bugs that cause us to paint with dirty layout |
26 if (m_layoutTableSection.needsLayout()) | 26 if (m_layoutTableSection.needsLayout()) |
27 return; | 27 return; |
28 | 28 |
29 // Table sections don't paint self background. The cells paint table section 's background | |
30 // behind them when needed during PaintPhaseBlockBackground or PaintPhaseDes cendantBlockBackgroundOnly. | |
31 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly) | |
32 return; | |
33 | |
29 unsigned totalRows = m_layoutTableSection.numRows(); | 34 unsigned totalRows = m_layoutTableSection.numRows(); |
30 unsigned totalCols = m_layoutTableSection.table()->columns().size(); | 35 unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
31 | 36 |
32 if (!totalRows || !totalCols) | 37 if (!totalRows || !totalCols) |
33 return; | 38 return; |
34 | 39 |
35 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableSection.locatio n(); | 40 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutTableSection.locatio n(); |
36 { | 41 |
42 if (paintInfo.phase != PaintPhaseSelfOutlineOnly) { | |
37 BoxClipper boxClipper(m_layoutTableSection, paintInfo, adjustedPaintOffs et, ForceContentsClip); | 43 BoxClipper boxClipper(m_layoutTableSection, paintInfo, adjustedPaintOffs et, ForceContentsClip); |
38 paintObject(paintInfo, adjustedPaintOffset); | 44 paintObject(paintInfo, adjustedPaintOffset); |
39 } | 45 } |
40 | 46 |
pdr.
2016/01/14 19:56:45
else?
Xianzhu
2016/01/15 01:05:33
No. PaintPhaseOutline needs to execute both the ab
| |
41 if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSe lfOutline) && m_layoutTableSection.style()->visibility() == VISIBLE) | 47 if (shouldPaintSelfOutline(paintInfo.phase)) |
42 ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, adjustedPain tOffset); | 48 ObjectPainter(m_layoutTableSection).paintOutline(paintInfo, adjustedPain tOffset); |
43 } | 49 } |
44 | 50 |
45 static inline bool compareCellPositions(LayoutTableCell* elem1, LayoutTableCell* elem2) | 51 static inline bool compareCellPositions(LayoutTableCell* elem1, LayoutTableCell* elem2) |
46 { | 52 { |
47 return elem1->rowIndex() < elem2->rowIndex(); | 53 return elem1->rowIndex() < elem2->rowIndex(); |
48 } | 54 } |
49 | 55 |
50 // This comparison is used only when we have overflowing cells as we have an uns orted array to sort. We thus need | 56 // This comparison is used only when we have overflowing cells as we have an uns orted array to sort. We thus need |
51 // to sort both on rows and columns to properly issue paint invalidations. | 57 // to sort both on rows and columns to properly issue paint invalidations. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 localPaintInvalidationRect.moveBy(-paintOffset); | 104 localPaintInvalidationRect.moveBy(-paintOffset); |
99 | 105 |
100 LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingMode AndDirection(localPaintInvalidationRect); | 106 LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingMode AndDirection(localPaintInvalidationRect); |
101 | 107 |
102 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); | 108 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); |
103 CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRe ct); | 109 CellSpan dirtiedColumns = m_layoutTableSection.dirtiedColumns(tableAlignedRe ct); |
104 | 110 |
105 if (dirtiedColumns.start() >= dirtiedColumns.end()) | 111 if (dirtiedColumns.start() >= dirtiedColumns.end()) |
106 return; | 112 return; |
107 | 113 |
114 PaintInfo paintInfoForCells = paintInfo.forDescendants(); | |
108 const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.ove rflowingCells(); | 115 const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.ove rflowingCells(); |
109 if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size( )) { | 116 if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size( )) { |
110 // Draw the dirty cells in the order that they appear. | 117 // Draw the dirty cells in the order that they appear. |
111 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 118 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
112 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); | 119 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); |
120 // TODO(wangxianzhu): This painting order is inconsistent with other outlines. crbug.com/577282. | |
113 if (row && !row->hasSelfPaintingLayer()) | 121 if (row && !row->hasSelfPaintingLayer()) |
114 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); | 122 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); |
115 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 123 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
116 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); | 124 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); |
117 const LayoutTableCell* cell = current.primaryCell(); | 125 const LayoutTableCell* cell = current.primaryCell(); |
118 if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.pr imaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSe ction.primaryCellAt(r, c - 1) == cell)) | 126 if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.pr imaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSe ction.primaryCellAt(r, c - 1) == cell)) |
119 continue; | 127 continue; |
120 paintCell(*cell, paintInfo, paintOffset); | 128 paintCell(*cell, paintInfoForCells, paintOffset); |
121 } | 129 } |
122 } | 130 } |
123 } else { | 131 } else { |
124 // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet. | 132 // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet. |
125 #if ENABLE(ASSERT) | 133 #if ENABLE(ASSERT) |
126 unsigned totalRows = m_layoutTableSection.numRows(); | 134 unsigned totalRows = m_layoutTableSection.numRows(); |
127 unsigned totalCols = m_layoutTableSection.table()->columns().size(); | 135 unsigned totalCols = m_layoutTableSection.table()->columns().size(); |
128 ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOver flowingCellRatioForFastPaintPath); | 136 ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOver flowingCellRatioForFastPaintPath); |
129 #endif | 137 #endif |
130 | 138 |
131 // To make sure we properly paint invalidate the section, we paint inval idated all the overflowing cells that we collected. | 139 // To make sure we properly paint invalidate the section, we paint inval idated all the overflowing cells that we collected. |
132 Vector<LayoutTableCell*> cells; | 140 Vector<LayoutTableCell*> cells; |
133 copyToVector(overflowingCells, cells); | 141 copyToVector(overflowingCells, cells); |
134 | 142 |
135 HashSet<LayoutTableCell*> spanningCells; | 143 HashSet<LayoutTableCell*> spanningCells; |
136 | 144 |
137 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { | 145 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { |
138 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); | 146 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); |
147 // TODO(wangxianzhu): This painting order is inconsistent with other outlines. crbug.com/577282. | |
139 if (row && !row->hasSelfPaintingLayer()) | 148 if (row && !row->hasSelfPaintingLayer()) |
140 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); | 149 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); |
141 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { | 150 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { |
142 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); | 151 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); |
143 if (!current.hasCells()) | 152 if (!current.hasCells()) |
144 continue; | 153 continue; |
145 for (unsigned i = 0; i < current.cells.size(); ++i) { | 154 for (unsigned i = 0; i < current.cells.size(); ++i) { |
146 if (overflowingCells.contains(current.cells[i])) | 155 if (overflowingCells.contains(current.cells[i])) |
147 continue; | 156 continue; |
148 | 157 |
149 if (current.cells[i]->rowSpan() > 1 || current.cells[i]->col Span() > 1) { | 158 if (current.cells[i]->rowSpan() > 1 || current.cells[i]->col Span() > 1) { |
150 if (!spanningCells.add(current.cells[i]).isNewEntry) | 159 if (!spanningCells.add(current.cells[i]).isNewEntry) |
151 continue; | 160 continue; |
152 } | 161 } |
153 | 162 |
154 cells.append(current.cells[i]); | 163 cells.append(current.cells[i]); |
155 } | 164 } |
156 } | 165 } |
157 } | 166 } |
158 | 167 |
159 // Sort the dirty cells by paint order. | 168 // Sort the dirty cells by paint order. |
160 if (!overflowingCells.size()) | 169 if (!overflowingCells.size()) |
161 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); | 170 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); |
162 else | 171 else |
163 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl owingCells); | 172 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl owingCells); |
164 | 173 |
165 for (unsigned i = 0; i < cells.size(); ++i) | 174 for (unsigned i = 0; i < cells.size(); ++i) |
166 paintCell(*cells[i], paintInfo, paintOffset); | 175 paintCell(*cells[i], paintInfoForCells, paintOffset); |
167 } | 176 } |
168 } | 177 } |
169 | 178 |
170 void TableSectionPainter::paintCell(const LayoutTableCell& cell, const PaintInfo & paintInfo, const LayoutPoint& paintOffset) | 179 void TableSectionPainter::paintCell(const LayoutTableCell& cell, const PaintInfo & paintInfo, const LayoutPoint& paintOffset) |
171 { | 180 { |
172 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel l, paintOffset); | 181 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel l, paintOffset); |
173 PaintPhase paintPhase = paintInfo.phase; | 182 PaintPhase paintPhase = paintInfo.phase; |
174 const LayoutTableRow* row = toLayoutTableRow(cell.parent()); | 183 const LayoutTableRow* row = toLayoutTableRow(cell.parent()); |
175 | 184 |
176 if ((paintPhase == PaintPhaseSelfBlockBackground || paintPhase == PaintPhase BlockBackground) | 185 if (shouldPaintSelfBlockBackground(paintPhase) |
177 && BlockPainter(cell).intersectsPaintRect(paintInfo, paintOffset)) { | 186 && BlockPainter(cell).intersectsPaintRect(paintInfo, paintOffset)) { |
178 // We need to handle painting a stack of backgrounds. This stack (from b ottom to top) consists of | 187 // We need to handle painting a stack of backgrounds. This stack (from b ottom to top) consists of |
179 // the column group, column, row group, row, and then the cell. | 188 // the column group, column, row group, row, and then the cell. |
180 | 189 |
181 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table( )->colElement(cell.col()); | 190 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table( )->colElement(cell.col()); |
182 LayoutTableCol* column = colAndColGroup.col; | 191 LayoutTableCol* column = colAndColGroup.col; |
183 LayoutTableCol* columnGroup = colAndColGroup.colgroup; | 192 LayoutTableCol* columnGroup = colAndColGroup.colgroup; |
184 TableCellPainter tableCellPainter(cell); | 193 TableCellPainter tableCellPainter(cell); |
185 | 194 |
186 // Column groups and columns first. | 195 // Column groups and columns first. |
(...skipping 13 matching lines...) Expand all Loading... | |
200 // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for | 209 // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for |
201 // painting the row background for the cell. | 210 // painting the row background for the cell. |
202 if (row->hasBackground() && !row->hasSelfPaintingLayer()) | 211 if (row->hasBackground() && !row->hasSelfPaintingLayer()) |
203 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, ro w, DisplayItem::TableCellBackgroundFromRow); | 212 tableCellPainter.paintBackgroundsBehindCell(paintInfo, cellPoint, ro w, DisplayItem::TableCellBackgroundFromRow); |
204 } | 213 } |
205 if ((!cell.hasSelfPaintingLayer() && !row->hasSelfPaintingLayer())) | 214 if ((!cell.hasSelfPaintingLayer() && !row->hasSelfPaintingLayer())) |
206 cell.paint(paintInfo, cellPoint); | 215 cell.paint(paintInfo, cellPoint); |
207 } | 216 } |
208 | 217 |
209 } // namespace blink | 218 } // namespace blink |
OLD | NEW |