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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableCol.cpp

Issue 1676933004: Table cell background painting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: colgroup paint bug125336 fix Created 4 years, 10 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 /* 1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
8 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 8 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 103
104 bool LayoutTableCol::canHaveChildren() const 104 bool LayoutTableCol::canHaveChildren() const
105 { 105 {
106 // Cols cannot have children. This is actually necessary to fix a bug 106 // Cols cannot have children. This is actually necessary to fix a bug
107 // with libraries.uc.edu, which makes a <p> be a table-column. 107 // with libraries.uc.edu, which makes a <p> be a table-column.
108 return isTableColumnGroup(); 108 return isTableColumnGroup();
109 } 109 }
110 110
111 LayoutRect LayoutTableCol::clippedOverflowRectForPaintInvalidation(const LayoutB oxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintIn validationState) const 111 LayoutRect LayoutTableCol::clippedOverflowRectForPaintInvalidation(const LayoutB oxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintIn validationState) const
112 { 112 {
113 // For now, just paint invalidate the whole table. 113 LayoutRect r = positionByCellSpan();
114 // FIXME: Find a better way to do this, e.g., need to paint invalidate all t he cells that we 114 mapToVisibleRectInAncestorSpace(paintInvalidationContainer, r, paintInvalida tionState);
115 // might have propagated a background color or borders into. 115 return r;
116 // FIXME: check for paintInvalidationContainer each time here?
117
118 LayoutTable* parentTable = table();
119 if (!parentTable)
120 return LayoutRect();
121 return parentTable->clippedOverflowRectForPaintInvalidation(paintInvalidatio nContainer, paintInvalidationState);
122 } 116 }
123 117
124 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*) 118 void LayoutTableCol::imageChanged(WrappedImagePtr, const IntRect*)
125 { 119 {
126 // FIXME: Issue paint invalidation of only the rect the image paints in. 120 // FIXME: Issue paint invalidation of only the rect the image paints in.
127 setShouldDoFullPaintInvalidation(); 121 // INVALIDATE ALL THE CHILDREN
122
123 // This does not work, background does not paint
124 // table()->setShouldDoFullPaintInvalidation(PaintInvalidationFull);
125 // This ends up with nothing being painted at all
126 // setShouldDoFullPaintInvalidation();
Xianzhu 2016/02/23 22:58:27 Why doesn't the logic in LayoutTable::invalidatePa
atotic1 2016/03/15 16:50:47 We do not call invalidatePaintOfSubtreesIfNeeded f
127 Vector<LayoutTableCell*> cells = getColumnCells();
128 for (auto c = cells.begin(); c != cells.end(); c++)
129 (*c)->setShouldDoFullPaintInvalidation();
128 } 130 }
129 131
130 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits() 132 void LayoutTableCol::clearPreferredLogicalWidthsDirtyBits()
131 { 133 {
132 clearPreferredLogicalWidthsDirty(); 134 clearPreferredLogicalWidthsDirty();
133 135
134 for (LayoutObject* child = firstChild(); child; child = child->nextSibling() ) 136 for (LayoutObject* child = firstChild(); child; child = child->nextSibling() )
135 child->clearPreferredLogicalWidthsDirty(); 137 child->clearPreferredLogicalWidthsDirty();
136 } 138 }
137 139
138 LayoutTable* LayoutTableCol::table() const 140 LayoutTable* LayoutTableCol::table() const
139 { 141 {
140 LayoutObject* table = parent(); 142 LayoutObject* table = parent();
141 if (table && !table->isTable()) 143 if (table && !table->isTable())
142 table = table->parent(); 144 table = table->parent();
143 return table && table->isTable() ? toLayoutTable(table) : nullptr; 145 return table && table->isTable() ? toLayoutTable(table) : nullptr;
144 } 146 }
145 147
146 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const 148 LayoutTableCol* LayoutTableCol::enclosingColumnGroup() const
147 { 149 {
148 if (!parent()->isLayoutTableCol()) 150 if (!parent()->isLayoutTableCol())
149 return nullptr; 151 return nullptr;
150 152
151 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent()); 153 LayoutTableCol* parentColumnGroup = toLayoutTableCol(parent());
152 ASSERT(parentColumnGroup->isTableColumnGroup()); 154 ASSERT(parentColumnGroup->isTableColumnGroup());
153 ASSERT(isTableColumn()); 155 ASSERT(isTableColumn());
154 return parentColumnGroup; 156 return parentColumnGroup;
155 } 157 }
156 158
159 LayoutTableCol * LayoutTableCol::lastColumnInGroup() const
160 {
161 ASSERT(this->isTableColumnGroup());
162
163 LayoutTableCol * endCol = 0;
164 LayoutTableCol * currentCol = this->nextColumn();
165 // if column has children, traverse the children to find last
166 if (this->firstChild()) {
167 while (currentCol && currentCol->enclosingColumnGroup() == this) {
168 endCol = currentCol;
169 currentCol = currentCol->nextColumn();
170 }
171 } else { // otherwise, if we have span, use that to find next child
172 auto span = this->span();
173 endCol = currentCol;
174 while (--span > 0 && currentCol) {
175 currentCol = currentCol->nextColumn();
176 endCol = currentCol;
177 }
178 }
179 return endCol;
180 }
181
157 LayoutTableCol* LayoutTableCol::nextColumn() const 182 LayoutTableCol* LayoutTableCol::nextColumn() const
158 { 183 {
159 // If |this| is a column-group, the next column is the colgroup's first chil d column. 184 // If |this| is a column-group, the next column is the colgroup's first chil d column.
160 if (LayoutObject* firstChild = this->firstChild()) 185 if (LayoutObject* firstChild = this->firstChild())
161 return toLayoutTableCol(firstChild); 186 return toLayoutTableCol(firstChild);
162 187
163 // Otherwise it's the next column along. 188 // Otherwise it's the next column along.
164 LayoutObject* next = nextSibling(); 189 LayoutObject* next = nextSibling();
165 190
166 // Failing that, the child is the last column in a column-group, so the next column is the next column/column-group after its column-group. 191 // Failing that, the child is the last column in a column-group, so the next column is the next column/column-group after its column-group.
167 if (!next && parent()->isLayoutTableCol()) 192
168 next = parent()->nextSibling(); 193 auto p = parent();
194 if (!next && p && p->isLayoutTableCol())
Xianzhu 2016/02/23 22:58:27 Can parent() be null?
atotic1 2016/03/15 16:50:47 Yes, seen it live when restoring from history.
195 next = p->nextSibling();
169 196
170 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { } 197 for (; next && !next->isLayoutTableCol(); next = next->nextSibling()) { }
171 198
172 return toLayoutTableCol(next); 199 return toLayoutTableCol(next);
173 } 200 }
174 201
175 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa bleCell*) const 202 const BorderValue& LayoutTableCol::borderAdjoiningCellStartBorder(const LayoutTa bleCell*) const
176 { 203 {
177 return style()->borderStart(); 204 return style()->borderStart();
178 } 205 }
179 206
180 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl eCell*) const 207 const BorderValue& LayoutTableCol::borderAdjoiningCellEndBorder(const LayoutTabl eCell*) const
181 { 208 {
182 return style()->borderEnd(); 209 return style()->borderEnd();
183 } 210 }
184 211
185 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe ll* cell) const 212 const BorderValue& LayoutTableCol::borderAdjoiningCellBefore(const LayoutTableCe ll* cell) const
186 { 213 {
187 ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()).inner mostColOrColGroup() == this); 214 ASSERT_UNUSED(cell, table()->colElement(cell->col() + cell->colSpan()).inner mostColOrColGroup() == this);
188 return style()->borderStart(); 215 return style()->borderStart();
189 } 216 }
190 217
191 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel l* cell) const 218 const BorderValue& LayoutTableCol::borderAdjoiningCellAfter(const LayoutTableCel l* cell) const
192 { 219 {
193 ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1).innermostColOrColGr oup() == this); 220 ASSERT_UNUSED(cell, table()->colElement(cell->col() - 1).innermostColOrColGr oup() == this);
194 return style()->borderEnd(); 221 return style()->borderEnd();
195 } 222 }
196 223
224 // computes col/colgroup position that only spans cells
225 LayoutRect LayoutTableCol::positionByCellSpan() const
226 {
227
228 LayoutTable * myTable = table();
229 LayoutRect position;
230
231 if (!myTable)
232 return position;
233
234 LayoutTableSection* topSection = myTable->topNonEmptySection();
235 LayoutTableSection* bottomSection = myTable->bottomNonEmptySection();
236 if (!topSection || !bottomSection)
237 return position;
238
239 unsigned startColumnIndex;
240 unsigned endColumnIndex;
241
242 if (isTableColumnGroup()) {
243 // colgroup position
244 LayoutTableCol * startColumn = nextColumn();
245 LayoutTableCol * endColumn = lastColumnInGroup();
246
247 if (startColumn && endColumn) {
248 startColumnIndex = myTable->colElementToCol(startColumn);
249 endColumnIndex = myTable->colElementToCol(endColumn);
250 } else {
251 return position;
252 }
253 } else {
254 // col position
255 startColumnIndex = myTable->colElementToCol(this);
256 endColumnIndex = std::min(startColumnIndex + span() - 1, bottomSection-> numColumns() - 1);
257 }
258
259 position = topSection->positionOfIdealCell(0, startColumnIndex);
260 position.moveBy(topSection->location());
261 LayoutRect bottomPosition = bottomSection->positionOfIdealCell(bottomSection ->numRows() - 1, endColumnIndex);
262 bottomPosition.moveBy(bottomSection->location());
263 position.unite(bottomPosition);
264 return position;
265 }
266
267 // returns indexes to all columns that span this column
268 Vector<unsigned> LayoutTableCol::getColumnIndexes() const
269 {
270 LayoutTable * myTable = table();
271 Vector<unsigned> indexes;
272 if (isTableColumn()) {
273 unsigned idx = myTable->colElementToCol(this);
274 auto span = this->span();
275 while (span--)
276 indexes.append(idx++);
277 } else {
278 // isTableColumnGroup
279 LayoutTableCol* currentCol = nullptr;
280 auto lastCol = lastColumnInGroup();
281 do {
282 currentCol = currentCol ? currentCol->nextColumn() : nextColumn();
283 if (currentCol) {
284 auto colIndexes = currentCol->getColumnIndexes();
285 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++)
286 indexes.append(*c);
287 }
288 } while (currentCol && currentCol != lastCol);
289 }
290 return indexes;
291 }
292
293 // returns all cells inside a column
294 Vector<LayoutTableCell*> LayoutTableCol::getColumnCells() const
295 {
296 // enumerate all the columns we need
297 LayoutTable * myTable = table();
298 Vector<LayoutTableCell*> cells;
299
300 if (!myTable) // can't do this before table is laid out
301 return cells;
302
303 auto colIndexes = getColumnIndexes();
304 auto section = myTable->topSection();
305 // Get all cells from all columns
306 while (section) {
307 for (auto c = colIndexes.begin(); c != colIndexes.end(); c++) {
308 for (unsigned r = 0; r < section->numRows(); r++) {
309 LayoutTableCell * cell = section->primaryCellAt(r, *c);
310 if (cell && cell->hasCol() && cell->col() == *c)
311 cells.append(cell);
312 }
313 }
314 section = myTable->sectionBelow(section, SkipEmptySections);
315 }
316 return cells;
317 }
318
197 } // namespace blink 319 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698