Chromium Code Reviews| 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/TableCellPainter.h" | 5 #include "core/paint/TableCellPainter.h" |
| 6 | 6 |
| 7 #include "core/layout/LayoutTableCell.h" | 7 #include "core/layout/LayoutTableCell.h" |
| 8 #include "core/layout/LayoutTableCol.h" | |
| 8 #include "core/paint/BlockPainter.h" | 9 #include "core/paint/BlockPainter.h" |
| 9 #include "core/paint/BoxPainter.h" | 10 #include "core/paint/BoxPainter.h" |
| 10 #include "core/paint/LayoutObjectDrawingRecorder.h" | 11 #include "core/paint/LayoutObjectDrawingRecorder.h" |
| 11 #include "core/paint/PaintInfo.h" | 12 #include "core/paint/PaintInfo.h" |
| 12 #include "platform/graphics/GraphicsContextStateSaver.h" | 13 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 13 | 14 |
| 14 namespace blink { | 15 namespace blink { |
| 15 | 16 |
| 16 inline const CollapsedBorderValue* TableCellPainter::cachedCollapsedLeftBorder(c onst ComputedStyle& styleForCellFlow) const | 17 inline const CollapsedBorderValue* TableCellPainter::cachedCollapsedLeftBorder(c onst ComputedStyle& styleForCellFlow) const |
| 17 { | 18 { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 if (displayItemType & DisplayItem::TableCollapsedBorderLeft) { | 134 if (displayItemType & DisplayItem::TableCollapsedBorderLeft) { |
| 134 ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borde rRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), BSLeft, | 135 ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.x(), borde rRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), BSLeft, |
| 135 leftBorderValue->color().resolve(cellColor), collapsedBorderStyle(le ftBorderValue->style()), 0, 0, true); | 136 leftBorderValue->color().resolve(cellColor), collapsedBorderStyle(le ftBorderValue->style()), 0, 0, true); |
| 136 } | 137 } |
| 137 if (displayItemType & DisplayItem::TableCollapsedBorderRight) { | 138 if (displayItemType & DisplayItem::TableCollapsedBorderRight) { |
| 138 ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.maxX() - r ightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), BSRight, | 139 ObjectPainter::drawLineForBoxSide(graphicsContext, borderRect.maxX() - r ightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), BSRight, |
| 139 rightBorderValue->color().resolve(cellColor), collapsedBorderStyle(r ightBorderValue->style()), 0, 0, true); | 140 rightBorderValue->color().resolve(cellColor), collapsedBorderStyle(r ightBorderValue->style()), 0, 0, true); |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 | 143 |
| 143 void TableCellPainter::paintBackgroundsBehindCell(const PaintInfo& paintInfo, co nst LayoutPoint& paintOffset, const LayoutObject* backgroundObject, DisplayItem: :Type type) | 144 void TableCellPainter::paintBackgroundsBehindCell(const PaintInfo& paintInfo, co nst LayoutPoint& paintOffset, const LayoutBox* backgroundObject, DisplayItem::Ty pe type) |
| 144 { | 145 { |
| 146 if (RuntimeEnabledFeatures::newTableCellBackgroundPaintingEnabled() && backg roundObject != &m_layoutTableCell) { | |
| 147 paintParentBackgroundsBehindCell(paintInfo, paintOffset, backgroundObjec t, type); | |
| 148 return; | |
| 149 } | |
| 150 | |
| 145 if (!backgroundObject) | 151 if (!backgroundObject) |
| 146 return; | 152 return; |
| 147 | 153 |
| 148 if (m_layoutTableCell.style()->visibility() != VISIBLE) | 154 if (m_layoutTableCell.style()->visibility() != VISIBLE) |
| 149 return; | 155 return; |
| 150 | 156 |
| 151 LayoutTable* tableElt = m_layoutTableCell.table(); | 157 LayoutTable* tableElt = m_layoutTableCell.table(); |
| 152 if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) | 158 if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) |
| 153 return; | 159 return; |
| 154 | 160 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 173 GraphicsContextStateSaver stateSaver(paintInfo.context, shouldClip); | 179 GraphicsContextStateSaver stateSaver(paintInfo.context, shouldClip); |
| 174 if (shouldClip) { | 180 if (shouldClip) { |
| 175 LayoutRect clipRect(paintRect.location(), m_layoutTableCell.size()); | 181 LayoutRect clipRect(paintRect.location(), m_layoutTableCell.size()); |
| 176 clipRect.expand(m_layoutTableCell.borderInsets()); | 182 clipRect.expand(m_layoutTableCell.borderInsets()); |
| 177 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); | 183 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); |
| 178 } | 184 } |
| 179 BoxPainter(m_layoutTableCell).paintFillLayers(paintInfo, c, bgLayer, pai ntRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, backgroundObject); | 185 BoxPainter(m_layoutTableCell).paintFillLayers(paintInfo, c, bgLayer, pai ntRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, backgroundObject); |
| 180 } | 186 } |
| 181 } | 187 } |
| 182 | 188 |
| 189 void TableCellPainter::paintParentBackgroundsBehindCell(const PaintInfo& paintIn fo, const LayoutPoint& paintOffset, const LayoutBox* backgroundObject, DisplayIt em::Type type) | |
| 190 { | |
| 191 if (!backgroundObject) | |
| 192 return; | |
| 193 | |
| 194 if (m_layoutTableCell.style()->visibility() != VISIBLE) | |
| 195 return; | |
| 196 | |
| 197 LayoutTable* tableElt = m_layoutTableCell.table(); | |
|
Xianzhu
2016/03/28 00:44:43
s/tableElt/table/
atotic1
2016/03/29 17:05:17
Done.
| |
| 198 if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) | |
| 199 return; | |
| 200 | |
| 201 LayoutRect backgroundRect = paintBoundsParent(paintOffset, backgroundObject, type); | |
| 202 | |
| 203 LayoutRect cellRect = m_layoutTableCell.frameRect(); | |
| 204 cellRect.moveBy(paintOffset); | |
| 205 | |
| 206 cellRect.setLocation(LayoutPoint(cellRect.pixelSnappedLocation())); | |
| 207 cellRect.setSize(LayoutSize(cellRect.pixelSnappedSize())); | |
| 208 | |
| 209 // We paint background LTR, top->bottom. | |
| 210 // This makes code much simpler, but is not spec-conformant. | |
| 211 // The spec-conformant code would have to handle all writing-mode | |
| 212 // painting directions correctly. | |
|
Xianzhu
2016/03/28 00:44:42
Convert the above to a TODO, and reference a bug.
atotic1
2016/03/29 17:05:17
Done.
| |
| 213 | |
| 214 if (backgroundRect.x() > cellRect.x()) | |
| 215 backgroundRect.setX(cellRect.x()); | |
| 216 if (backgroundRect.y() > cellRect.y()) | |
| 217 backgroundRect.setY(cellRect.y()); | |
|
Xianzhu
2016/03/28 00:44:43
Why does this happen?
atotic1
2016/03/29 17:05:17
This happens when table is vertical. I've reworked
| |
| 218 | |
| 219 Optional<LayoutObjectDrawingRecorder> recorder; | |
|
Xianzhu
2016/03/28 00:44:42
This recorder doesn't need to be optional. You can
atotic1
2016/03/29 17:05:17
Done.
| |
| 220 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex t, m_layoutTableCell, type)) { | |
| 221 return; | |
| 222 } | |
| 223 recorder.emplace(paintInfo.context, m_layoutTableCell, type, cellRect); | |
| 224 | |
| 225 Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor); | |
|
Xianzhu
2016/03/28 00:44:42
s/c/color/
atotic1
2016/03/29 17:05:17
Done.
| |
| 226 const FillLayer& bgLayer = backgroundObject->style()->backgroundLayers(); | |
|
Xianzhu
2016/03/28 00:44:43
s/bgLayer/backgroundLayer/
atotic1
2016/03/29 17:05:17
Done.
| |
| 227 FillLayer bgAdjustedLayer(bgLayer); | |
|
Xianzhu
2016/03/28 00:44:42
Not used?
atotic1
2016/03/29 17:05:17
Done.
| |
| 228 | |
| 229 if (bgLayer.hasImage() || c.alpha()) { | |
| 230 | |
| 231 GraphicsContextStateSaver stateSaver(paintInfo.context, true); | |
| 232 LayoutRect clipRect(m_layoutTableCell.location(), m_layoutTableCell.size ()); | |
| 233 clipRect.moveBy(paintOffset); | |
| 234 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); | |
| 235 | |
| 236 // If cell is larger than background, we might have to paint multiple ti mes. | |
| 237 LayoutUnit colExtraPixels = std::max(LayoutUnit(0), cellRect.maxX() - ba ckgroundRect.maxX()); | |
| 238 unsigned colRepeat = 1 + (colExtraPixels / backgroundRect.width()) + (co lExtraPixels % backgroundRect.width() != 0); | |
| 239 LayoutUnit rowExtraPixels = std::max(LayoutUnit(0), cellRect.maxY() - ba ckgroundRect.maxY()); | |
| 240 unsigned rowRepeat = 1 + (rowExtraPixels / backgroundRect.height()) + (r owExtraPixels % backgroundRect.height() != 0); | |
| 241 for (unsigned row = 0; row < rowRepeat; row++) { | |
| 242 for (unsigned col = 0; col < colRepeat; col++) { | |
| 243 LayoutRect paintRect = backgroundRect; | |
| 244 paintRect.move(col * paintRect.width(), row * paintRect.height() ); | |
| 245 BoxPainter(*backgroundObject).paintFillLayers(paintInfo, c, bgLa yer, paintRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, backgroundObject ); | |
| 246 } | |
| 247 } | |
|
Xianzhu
2016/03/28 00:44:43
The following case is broken with the code:
<!DOC
atotic1
2016/03/28 20:45:33
You are correct in that we fail this test case. My
Xianzhu
2016/03/28 21:26:04
Because the background bug has been there for a lo
| |
| 248 } | |
| 249 } | |
| 250 | |
| 183 void TableCellPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) | 251 void TableCellPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
| 184 { | 252 { |
| 185 LayoutTable* table = m_layoutTableCell.table(); | 253 LayoutTable* table = m_layoutTableCell.table(); |
| 186 if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) | 254 if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) |
| 187 return; | 255 return; |
| 188 | 256 |
| 189 bool needsToPaintBorder = m_layoutTableCell.styleRef().hasBorderDecoration() && !table->collapseBorders(); | 257 bool needsToPaintBorder = m_layoutTableCell.styleRef().hasBorderDecoration() && !table->collapseBorders(); |
| 190 if (!m_layoutTableCell.hasBackground() && !m_layoutTableCell.styleRef().boxS hadow() && !needsToPaintBorder) | 258 if (!m_layoutTableCell.hasBackground() && !m_layoutTableCell.styleRef().boxS hadow() && !needsToPaintBorder) |
| 191 return; | 259 return; |
| 192 | 260 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 } | 299 } |
| 232 | 300 |
| 233 LayoutRect TableCellPainter::paintBounds(const LayoutPoint& paintOffset, PaintBo undOffsetBehavior paintBoundOffsetBehavior) | 301 LayoutRect TableCellPainter::paintBounds(const LayoutPoint& paintOffset, PaintBo undOffsetBehavior paintBoundOffsetBehavior) |
| 234 { | 302 { |
| 235 LayoutPoint adjustedPaintOffset = paintOffset; | 303 LayoutPoint adjustedPaintOffset = paintOffset; |
| 236 if (paintBoundOffsetBehavior == AddOffsetFromParent) | 304 if (paintBoundOffsetBehavior == AddOffsetFromParent) |
| 237 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); | 305 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); |
| 238 return LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell.pixelSna ppedSize())); | 306 return LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell.pixelSna ppedSize())); |
| 239 } | 307 } |
| 240 | 308 |
| 309 LayoutRect TableCellPainter::paintBoundsParent(const LayoutPoint& paintOffset, c onst LayoutBox* backgroundObject, DisplayItem::Type type) | |
| 310 { | |
| 311 LayoutRect position; | |
| 312 switch (type) { | |
| 313 case DisplayItem::TableCellBackgroundFromColumnGroup: | |
| 314 case DisplayItem::TableCellBackgroundFromColumn: | |
| 315 { | |
|
Xianzhu
2016/03/28 00:44:43
Put '{' at the end of the previous line.
atotic1
2016/03/29 17:05:17
Done.
| |
| 316 position = static_cast<const LayoutTableCol*>(backgroundObject)->positio nByCellSpan( | |
| 317 m_layoutTableCell.absoluteColumnIndex()); | |
| 318 // position is relative to table, must correct for section location | |
| 319 LayoutPoint sectionLocation = m_layoutTableCell.section()->location(); | |
| 320 position.moveBy(-sectionLocation); | |
| 321 position.moveBy(paintOffset); | |
| 322 } | |
|
Xianzhu
2016/03/28 00:44:43
Put break inside of '}' and align '}' with 'case'.
atotic1
2016/03/29 17:05:17
Done.
| |
| 323 break; | |
| 324 case DisplayItem::TableCellBackgroundFromSection: | |
|
Xianzhu
2016/03/28 00:44:42
We know TableCellSection's paint bounds in TableCe
atotic1
2016/03/29 17:05:17
How do we know TableSection bounds inside TableCel
| |
| 325 position = static_cast<const LayoutTableSection*>(backgroundObject)->pos itionByCellSpan(); | |
| 326 position.moveBy(paintOffset); | |
| 327 break; | |
| 328 case DisplayItem::TableCellBackgroundFromRow: | |
| 329 position = static_cast<const LayoutTableRow*>(backgroundObject)->positio nByCellSpan(); | |
| 330 position.moveBy(paintOffset); | |
| 331 break; | |
|
Xianzhu
2016/03/28 00:44:42
Ditto.
| |
| 332 case DisplayItem::BoxDecorationBackground: { | |
| 333 LayoutPoint adjustedPaintOffset = paintOffset; | |
| 334 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); | |
| 335 position = LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell .pixelSnappedSize())); | |
| 336 } | |
| 337 break; | |
| 338 default: | |
| 339 ASSERT(false); | |
|
Xianzhu
2016/03/28 00:44:42
ASSERT_NOT_REACHED();
atotic1
2016/03/29 17:05:17
Done.
| |
| 340 break; | |
| 341 } | |
| 342 return LayoutRect(position.pixelSnappedLocation(), position.pixelSnappedSize ()); | |
| 343 } | |
| 344 | |
| 241 } // namespace blink | 345 } // namespace blink |
| 242 | 346 |
| OLD | NEW |