Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: third_party/WebKit/Source/core/paint/TableSectionPainter.cpp

Issue 1963313002: Implement box-shadow for table section and row (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/BoxPainter.h"
13 #include "core/paint/LayoutObjectDrawingRecorder.h" 14 #include "core/paint/LayoutObjectDrawingRecorder.h"
14 #include "core/paint/ObjectPainter.h" 15 #include "core/paint/ObjectPainter.h"
15 #include "core/paint/PaintInfo.h" 16 #include "core/paint/PaintInfo.h"
16 #include "core/paint/TableCellPainter.h" 17 #include "core/paint/TableCellPainter.h"
17 #include "core/paint/TableRowPainter.h" 18 #include "core/paint/TableRowPainter.h"
18 #include <algorithm> 19 #include <algorithm>
19 20
20 namespace blink { 21 namespace blink {
21 22
23 inline const LayoutTableCell* TableSectionPainter::primaryCellToPaint(unsigned r ow, unsigned column, const CellSpan& dirtiedRows, const CellSpan& dirtiedColumns ) const
24 {
25 ASSERT(row >= dirtiedRows.start() && row < dirtiedRows.end());
26 ASSERT(column >= dirtiedColumns.start() && column < dirtiedColumns.end());
27
28 const LayoutTableCell* cell = m_layoutTableSection.primaryCellAt(row, column );
29 if (!cell)
30 return nullptr;
31 if (row > dirtiedRows.start() && m_layoutTableSection.primaryCellAt(row - 1, column) == cell)
32 return nullptr;
33 if (column > dirtiedColumns.start() && m_layoutTableSection.primaryCellAt(ro w, column - 1) == cell)
34 return nullptr;
35 return cell;
36 }
37
22 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p aintOffset) 38 void TableSectionPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& p aintOffset)
23 { 39 {
24 ASSERT(!m_layoutTableSection.needsLayout()); 40 ASSERT(!m_layoutTableSection.needsLayout());
25 // avoid crashing on bugs that cause us to paint with dirty layout 41 // avoid crashing on bugs that cause us to paint with dirty layout
26 if (m_layoutTableSection.needsLayout()) 42 if (m_layoutTableSection.needsLayout())
27 return; 43 return;
28 44
29 unsigned totalRows = m_layoutTableSection.numRows(); 45 unsigned totalRows = m_layoutTableSection.numRows();
30 unsigned totalCols = m_layoutTableSection.table()->numEffectiveColumns(); 46 unsigned totalCols = m_layoutTableSection.table()->numEffectiveColumns();
31 47
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 localPaintInvalidationRect.moveBy(-paintOffset); 117 localPaintInvalidationRect.moveBy(-paintOffset);
102 118
103 LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingMode AndDirection(localPaintInvalidationRect); 119 LayoutRect tableAlignedRect = m_layoutTableSection.logicalRectForWritingMode AndDirection(localPaintInvalidationRect);
104 120
105 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect); 121 CellSpan dirtiedRows = m_layoutTableSection.dirtiedRows(tableAlignedRect);
106 CellSpan dirtiedColumns = m_layoutTableSection.dirtiedEffectiveColumns(table AlignedRect); 122 CellSpan dirtiedColumns = m_layoutTableSection.dirtiedEffectiveColumns(table AlignedRect);
107 123
108 if (dirtiedColumns.start() >= dirtiedColumns.end()) 124 if (dirtiedColumns.start() >= dirtiedColumns.end())
109 return; 125 return;
110 126
111 PaintInfo paintInfoForCells = paintInfo.forDescendants(); 127 PaintInfo paintInfoForDescendants = paintInfo.forDescendants();
112 const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.ove rflowingCells(); 128
113 if (!m_layoutTableSection.hasMultipleCellLevels() && !overflowingCells.size( )) { 129 if (shouldPaintSelfBlockBackground(paintInfo.phase)) {
114 // Draw the dirty cells in the order that they appear. 130 paintBoxShadow(paintInfo, paintOffset, Normal);
131 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
132 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
133 if (const LayoutTableCell* cell = primaryCellToPaint(r, c, dirti edRows, dirtiedColumns))
134 paintBackgroundsBehindCell(*cell, paintInfoForDescendants, p aintOffset);
135 }
136 }
137 paintBoxShadow(paintInfo, paintOffset, Inset);
138 }
139
140 if (paintInfo.phase == PaintPhaseSelfBlockBackgroundOnly)
141 return;
142
143 if (shouldPaintDescendantBlockBackgrounds(paintInfo.phase)) {
115 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { 144 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
116 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); 145 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r );
117 // TODO(wangxianzhu): This painting order is inconsistent with other outlines. crbug.com/577282. 146 // If a row has a layer, we'll paint row background in TableRowPaint er.
118 if (row && !row->hasSelfPaintingLayer()) 147 if (!row || row->hasSelfPaintingLayer())
119 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); 148 continue;
149
150 TableRowPainter rowPainter(*row);
151 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Norm al);
152 if (row->hasBackground()) {
153 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end (); c++) {
154 if (const LayoutTableCell* cell = primaryCellToPaint(r, c, d irtiedRows, dirtiedColumns))
155 rowPainter.paintBackgroundBehindCell(*cell, paintInfoFor Descendants, paintOffset);
156 }
157 }
158 rowPainter.paintBoxShadow(paintInfoForDescendants, paintOffset, Inse t);
159 }
160 }
161
162 const HashSet<LayoutTableCell*>& overflowingCells = m_layoutTableSection.ove rflowingCells();
163 if (!m_layoutTableSection.hasMultipleCellLevels() && overflowingCells.isEmpt y()) {
164 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
165 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r );
166 // TODO(crbug.com/577282): This painting order is inconsistent with other outlines.
167 if (row && !row->hasSelfPaintingLayer() && shouldPaintSelfOutline(pa intInfoForDescendants.phase))
168 TableRowPainter(*row).paintOutline(paintInfoForDescendants, pain tOffset);
120 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { 169 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
121 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); 170 if (const LayoutTableCell * cell = primaryCellToPaint(r, c, dirt iedRows, dirtiedColumns))
122 const LayoutTableCell* cell = current.primaryCell(); 171 paintCell(*cell, paintInfoForDescendants, paintOffset);
123 if (!cell || (r > dirtiedRows.start() && m_layoutTableSection.pr imaryCellAt(r - 1, c) == cell) || (c > dirtiedColumns.start() && m_layoutTableSe ction.primaryCellAt(r, c - 1) == cell))
124 continue;
125 paintCell(*cell, paintInfo.phase, paintInfoForCells, paintOffset );
126 } 172 }
127 } 173 }
128 } else { 174 } else {
129 // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet. 175 // The overflowing cells should be scarce to avoid adding a lot of cells to the HashSet.
130 #if ENABLE(ASSERT) 176 ASSERT(overflowingCells.size() < m_layoutTableSection.numRows() * m_layo utTableSection.table()->effectiveColumns().size() * gMaxAllowedOverflowingCellRa tioForFastPaintPath);
131 unsigned totalRows = m_layoutTableSection.numRows();
132 unsigned totalCols = m_layoutTableSection.table()->effectiveColumns().si ze();
133 ASSERT(overflowingCells.size() < totalRows * totalCols * gMaxAllowedOver flowingCellRatioForFastPaintPath);
134 #endif
135 177
136 // To make sure we properly paint invalidate the section, we paint inval idated all the overflowing cells that we collected. 178 // To make sure we properly paint the section, we paint all the overflow ing cells that we collected.
137 Vector<LayoutTableCell*> cells; 179 Vector<LayoutTableCell*> cells;
138 copyToVector(overflowingCells, cells); 180 copyToVector(overflowingCells, cells);
139 181
140 HashSet<LayoutTableCell*> spanningCells; 182 HashSet<LayoutTableCell*> spanningCells;
141
142 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) { 183 for (unsigned r = dirtiedRows.start(); r < dirtiedRows.end(); r++) {
143 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r ); 184 const LayoutTableRow* row = m_layoutTableSection.rowLayoutObjectAt(r );
144 // TODO(wangxianzhu): This painting order is inconsistent with other outlines. crbug.com/577282. 185 // TODO(crbug.com/577282): This painting order is inconsistent with other outlines.
145 if (row && !row->hasSelfPaintingLayer()) 186 if (row && !row->hasSelfPaintingLayer() && shouldPaintSelfOutline(pa intInfoForDescendants.phase))
146 TableRowPainter(*row).paintOutlineForRowIfNeeded(paintInfo, pain tOffset); 187 TableRowPainter(*row).paintOutline(paintInfoForDescendants, pain tOffset);
147 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) { 188 for (unsigned c = dirtiedColumns.start(); c < dirtiedColumns.end(); c++) {
148 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c); 189 const LayoutTableSection::CellStruct& current = m_layoutTableSec tion.cellAt(r, c);
149 if (!current.hasCells()) 190 for (LayoutTableCell* cell : current.cells) {
150 continue; 191 if (overflowingCells.contains(cell))
151 for (unsigned i = 0; i < current.cells.size(); ++i) {
152 if (overflowingCells.contains(current.cells[i]))
153 continue; 192 continue;
154 193 if (cell->rowSpan() > 1 || cell->colSpan() > 1) {
155 if (current.cells[i]->rowSpan() > 1 || current.cells[i]->col Span() > 1) { 194 if (!spanningCells.add(cell).isNewEntry)
156 if (!spanningCells.add(current.cells[i]).isNewEntry)
157 continue; 195 continue;
158 } 196 }
159 197 cells.append(cell);
160 cells.append(current.cells[i]);
161 } 198 }
162 } 199 }
163 } 200 }
164 201
165 // Sort the dirty cells by paint order. 202 // Sort the dirty cells by paint order.
166 if (!overflowingCells.size()) 203 if (!overflowingCells.size())
167 std::stable_sort(cells.begin(), cells.end(), compareCellPositions); 204 std::stable_sort(cells.begin(), cells.end(), compareCellPositions);
168 else 205 else
169 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl owingCells); 206 std::sort(cells.begin(), cells.end(), compareCellPositionsWithOverfl owingCells);
170 207
171 for (unsigned i = 0; i < cells.size(); ++i) 208 for (const LayoutTableCell* cell : cells)
172 paintCell(*cells[i], paintInfo.phase, paintInfoForCells, paintOffset ); 209 paintCell(*cell, paintInfoForDescendants, paintOffset);
173 } 210 }
174 } 211 }
175 212
176 void TableSectionPainter::paintCell(const LayoutTableCell& cell, PaintPhase orig inalPaintPhase, const PaintInfo& paintInfoForCells, const LayoutPoint& paintOffs et) 213 void TableSectionPainter::paintBackgroundsBehindCell(const LayoutTableCell& cell , const PaintInfo& paintInfoForCells, const LayoutPoint& paintOffset)
177 { 214 {
178 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel l, paintOffset); 215 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild(&cel l, paintOffset);
179 const LayoutTableRow* row = toLayoutTableRow(cell.parent());
180 216
181 if (!BlockPainter(cell).intersectsPaintRect(paintInfoForCells, paintOffset + cell.location())) 217 // We need to handle painting a stack of backgrounds. This stack (from botto m to top) consists of
chrishtr 2016/05/14 18:03:46 Why is this code gone?
218 // the column group, column, row group, row, and then the cell.
219
220 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table()->c olElementAtAbsoluteColumn(cell.absoluteColumnIndex());
221 LayoutTableCol* column = colAndColGroup.col;
222 LayoutTableCol* columnGroup = colAndColGroup.colgroup;
223 TableCellPainter tableCellPainter(cell);
224
225 // Column groups and columns first.
226 // FIXME: Columns and column groups do not currently support opacity, and th ey are being painted "too late" in
227 // the stack, since we have already opened a transparency layer (potentially ) for the table row group.
228 // Note that we deliberately ignore whether or not the cell has a layer, sin ce these backgrounds paint "behind" the
229 // cell.
230 if (columnGroup && columnGroup->hasBackground())
231 tableCellPainter.paintContainerBackgroundBehindCell(paintInfoForCells, c ellPoint, *columnGroup, DisplayItem::TableCellBackgroundFromColumnGroup);
232 if (column && column->hasBackground())
233 tableCellPainter.paintContainerBackgroundBehindCell(paintInfoForCells, c ellPoint, *column, DisplayItem::TableCellBackgroundFromColumn);
234
235 // Paint the row group next.
236 if (m_layoutTableSection.hasBackground())
237 tableCellPainter.paintContainerBackgroundBehindCell(paintInfoForCells, c ellPoint, m_layoutTableSection, DisplayItem::TableCellBackgroundFromSection);
238 }
239
240 void TableSectionPainter::paintCell(const LayoutTableCell& cell, const PaintInfo & paintInfoForCells, const LayoutPoint& paintOffset)
241 {
242 if (!cell.hasSelfPaintingLayer() && !cell.row()->hasSelfPaintingLayer()) {
243 LayoutPoint cellPoint = m_layoutTableSection.flipForWritingModeForChild( &cell, paintOffset);
244 cell.paint(paintInfoForCells, cellPoint);
245 }
246 }
247
248 void TableSectionPainter::paintBoxShadow(const PaintInfo& paintInfo, const Layou tPoint& paintOffset, ShadowStyle shadowStyle)
249 {
250 ASSERT(shouldPaintSelfBlockBackground(paintInfo.phase));
251 if (!m_layoutTableSection.styleRef().boxShadow())
182 return; 252 return;
183 253
184 if (shouldPaintSelfBlockBackground(originalPaintPhase)) { 254 DisplayItem::Type type = shadowStyle == Normal ? DisplayItem::TableSectionBo xShadowNormal : DisplayItem::TableSectionBoxShadowInset;
185 // We need to handle painting a stack of backgrounds. This stack (from b ottom to top) consists of 255 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex t, m_layoutTableSection, type))
186 // the column group, column, row group, row, and then the cell. 256 return;
187 257
188 LayoutTable::ColAndColGroup colAndColGroup = m_layoutTableSection.table( )->colElementAtAbsoluteColumn(cell.absoluteColumnIndex()); 258 LayoutRect bounds = BoxPainter(m_layoutTableSection).boundsForDrawingRecorde r(paintOffset);
189 LayoutTableCol* column = colAndColGroup.col; 259 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableSection , type, bounds);
190 LayoutTableCol* columnGroup = colAndColGroup.colgroup; 260 BoxPainter::paintBoxShadow(paintInfo, LayoutRect(paintOffset, m_layoutTableS ection.size()), m_layoutTableSection.styleRef(), shadowStyle);
191 TableCellPainter tableCellPainter(cell);
192
193 // Column groups and columns first.
194 // FIXME: Columns and column groups do not currently support opacity, an d they are being painted "too late" in
195 // the stack, since we have already opened a transparency layer (potenti ally) for the table row group.
196 // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the
197 // cell.
198 if (columnGroup && columnGroup->hasBackground())
199 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP oint, columnGroup, DisplayItem::TableCellBackgroundFromColumnGroup);
200 if (column && column->hasBackground())
201 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP oint, column, DisplayItem::TableCellBackgroundFromColumn);
202
203 // Paint the row group next.
204 if (m_layoutTableSection.hasBackground())
205 tableCellPainter.paintBackgroundsBehindCell(paintInfoForCells, cellP oint, &m_layoutTableSection, DisplayItem::TableCellBackgroundFromSection);
206 }
207
208 if (shouldPaintDescendantBlockBackgrounds(originalPaintPhase)) {
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
210 // painting the row background for the cell.
211 if (row->hasBackground() && !row->hasSelfPaintingLayer())
212 TableCellPainter(cell).paintBackgroundsBehindCell(paintInfoForCells, cellPoint, row, DisplayItem::TableCellBackgroundFromRow);
213 }
214
215 if (originalPaintPhase != PaintPhaseSelfBlockBackgroundOnly && !cell.hasSelf PaintingLayer() && !row->hasSelfPaintingLayer())
216 cell.paint(paintInfoForCells, cellPoint);
217 } 261 }
218 262
219 } // namespace blink 263 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698