| 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 { |
| 145 if (!backgroundObject) | 146 if (RuntimeEnabledFeatures::newTableCellBackgroundPaintingEnabled() && &back
groundObject != &m_layoutTableCell) { |
| 147 paintParentBackgroundsBehindCell(paintInfo, paintOffset, backgroundObjec
t, type); |
| 146 return; | 148 return; |
| 149 } |
| 147 | 150 |
| 148 if (m_layoutTableCell.style()->visibility() != VISIBLE) | 151 if (m_layoutTableCell.style()->visibility() != VISIBLE) |
| 149 return; | 152 return; |
| 150 | 153 |
| 151 LayoutTable* tableElt = m_layoutTableCell.table(); | 154 LayoutTable* tableElt = m_layoutTableCell.table(); |
| 152 if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells()
== EmptyCellsHide && !m_layoutTableCell.firstChild()) | 155 if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells()
== EmptyCellsHide && !m_layoutTableCell.firstChild()) |
| 153 return; | 156 return; |
| 154 | 157 |
| 155 LayoutRect paintRect = paintBounds(paintOffset, backgroundObject != &m_layou
tTableCell ? AddOffsetFromParent : DoNotAddOffsetFromParent); | 158 LayoutRect paintRect = paintBounds(paintOffset, &backgroundObject != &m_layo
utTableCell ? AddOffsetFromParent : DoNotAddOffsetFromParent); |
| 156 | 159 |
| 157 // Record drawing only if the cell is painting background from containers. | 160 // Record drawing only if the cell is painting background from containers. |
| 158 Optional<LayoutObjectDrawingRecorder> recorder; | 161 Optional<LayoutObjectDrawingRecorder> recorder; |
| 159 if (backgroundObject != &m_layoutTableCell) { | 162 if (&backgroundObject != &m_layoutTableCell) { |
| 160 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.co
ntext, m_layoutTableCell, type)) | 163 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.co
ntext, m_layoutTableCell, type)) |
| 161 return; | 164 return; |
| 162 recorder.emplace(paintInfo.context, m_layoutTableCell, type, paintRect); | 165 recorder.emplace(paintInfo.context, m_layoutTableCell, type, paintRect); |
| 163 } else { | 166 } else { |
| 164 ASSERT(paintRect.location() == paintOffset); | 167 ASSERT(paintRect.location() == paintOffset); |
| 165 } | 168 } |
| 166 | 169 |
| 167 Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor); | 170 Color c = backgroundObject.resolveColor(CSSPropertyBackgroundColor); |
| 168 const FillLayer& bgLayer = backgroundObject->style()->backgroundLayers(); | 171 const FillLayer& bgLayer = backgroundObject.style()->backgroundLayers(); |
| 169 if (bgLayer.hasImage() || c.alpha()) { | 172 if (bgLayer.hasImage() || c.alpha()) { |
| 170 // We have to clip here because the background would paint | 173 // We have to clip here because the background would paint |
| 171 // on top of the borders otherwise. This only matters for cells and row
s. | 174 // on top of the borders otherwise. This only matters for cells and row
s. |
| 172 bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == &
m_layoutTableCell || backgroundObject == m_layoutTableCell.parent()) && tableElt
->collapseBorders(); | 175 bool shouldClip = backgroundObject.hasLayer() && (&backgroundObject == &
m_layoutTableCell || &backgroundObject == m_layoutTableCell.parent()) && tableEl
t->collapseBorders(); |
| 173 GraphicsContextStateSaver stateSaver(paintInfo.context, shouldClip); | 176 GraphicsContextStateSaver stateSaver(paintInfo.context, shouldClip); |
| 174 if (shouldClip) { | 177 if (shouldClip) { |
| 175 LayoutRect clipRect(paintRect.location(), m_layoutTableCell.size()); | 178 LayoutRect clipRect(paintRect.location(), m_layoutTableCell.size()); |
| 176 clipRect.expand(m_layoutTableCell.borderInsets()); | 179 clipRect.expand(m_layoutTableCell.borderInsets()); |
| 177 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); | 180 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); |
| 178 } | 181 } |
| 179 BoxPainter(m_layoutTableCell).paintFillLayers(paintInfo, c, bgLayer, pai
ntRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, backgroundObject); | 182 BoxPainter(m_layoutTableCell).paintFillLayers(paintInfo, c, bgLayer, pai
ntRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, &backgroundObject); |
| 180 } | 183 } |
| 181 } | 184 } |
| 182 | 185 |
| 186 void TableCellPainter::paintParentBackgroundsBehindCell(const PaintInfo& paintIn
fo, const LayoutPoint& paintOffset, const LayoutBox& backgroundObject, DisplayIt
em::Type type) |
| 187 { |
| 188 |
| 189 if (m_layoutTableCell.style()->visibility() != VISIBLE) |
| 190 return; |
| 191 |
| 192 LayoutTable* table = m_layoutTableCell.table(); |
| 193 if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() ==
EmptyCellsHide && !m_layoutTableCell.firstChild()) |
| 194 return; |
| 195 |
| 196 LayoutRect backgroundRect = paintBoundsParent(paintOffset, backgroundObject,
type); |
| 197 |
| 198 LayoutRect cellRect = m_layoutTableCell.frameRect(); |
| 199 cellRect.moveBy(paintOffset); |
| 200 |
| 201 cellRect.setLocation(LayoutPoint(cellRect.pixelSnappedLocation())); |
| 202 cellRect.setSize(LayoutSize(cellRect.pixelSnappedSize())); |
| 203 |
| 204 LayoutRect paintRect = backgroundRect; |
| 205 paintRect.unite(cellRect); |
| 206 |
| 207 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex
t, m_layoutTableCell, type)) { |
| 208 return; |
| 209 } |
| 210 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableCell, t
ype, paintRect); |
| 211 |
| 212 Color color = backgroundObject.resolveColor(CSSPropertyBackgroundColor); |
| 213 const FillLayer& backgroundLayer = backgroundObject.style()->backgroundLayer
s(); |
| 214 |
| 215 // TODO(crbug.com/598489) background image paints incorrectly when rowspan/c
olspan > 1, |
| 216 // and background-image-size is in '%' |
| 217 |
| 218 if (backgroundLayer.hasImage() || color.alpha()) { |
| 219 |
| 220 GraphicsContextStateSaver stateSaver(paintInfo.context, true); |
| 221 LayoutRect clipRect(m_layoutTableCell.location(), m_layoutTableCell.size
()); |
| 222 clipRect.moveBy(paintOffset); |
| 223 paintInfo.context.clip(pixelSnappedIntRect(clipRect)); |
| 224 |
| 225 BoxPainter(backgroundObject).paintFillLayers(paintInfo, color, backgroun
dLayer, paintRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, &backgroundOb
ject); |
| 226 } |
| 227 } |
| 228 |
| 183 void TableCellPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) | 229 void TableCellPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) |
| 184 { | 230 { |
| 185 LayoutTable* table = m_layoutTableCell.table(); | 231 LayoutTable* table = m_layoutTableCell.table(); |
| 186 if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() ==
EmptyCellsHide && !m_layoutTableCell.firstChild()) | 232 if (!table->collapseBorders() && m_layoutTableCell.style()->emptyCells() ==
EmptyCellsHide && !m_layoutTableCell.firstChild()) |
| 187 return; | 233 return; |
| 188 | 234 |
| 189 bool needsToPaintBorder = m_layoutTableCell.styleRef().hasBorderDecoration()
&& !table->collapseBorders(); | 235 bool needsToPaintBorder = m_layoutTableCell.styleRef().hasBorderDecoration()
&& !table->collapseBorders(); |
| 190 if (!m_layoutTableCell.hasBackground() && !m_layoutTableCell.styleRef().boxS
hadow() && !needsToPaintBorder) | 236 if (!m_layoutTableCell.hasBackground() && !m_layoutTableCell.styleRef().boxS
hadow() && !needsToPaintBorder) |
| 191 return; | 237 return; |
| 192 | 238 |
| 193 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex
t, m_layoutTableCell, DisplayItem::BoxDecorationBackground)) | 239 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.contex
t, m_layoutTableCell, DisplayItem::BoxDecorationBackground)) |
| 194 return; | 240 return; |
| 195 | 241 |
| 196 LayoutRect visualOverflowRect = m_layoutTableCell.visualOverflowRect(); | 242 LayoutRect visualOverflowRect = m_layoutTableCell.visualOverflowRect(); |
| 197 visualOverflowRect.moveBy(paintOffset); | 243 visualOverflowRect.moveBy(paintOffset); |
| 198 // TODO(chrishtr): the pixel-snapping here is likely incorrect. | 244 // TODO(chrishtr): the pixel-snapping here is likely incorrect. |
| 199 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableCell, D
isplayItem::BoxDecorationBackground, pixelSnappedIntRect(visualOverflowRect)); | 245 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutTableCell, D
isplayItem::BoxDecorationBackground, pixelSnappedIntRect(visualOverflowRect)); |
| 200 | 246 |
| 201 LayoutRect paintRect = paintBounds(paintOffset, DoNotAddOffsetFromParent); | 247 LayoutRect paintRect = paintBounds(paintOffset, DoNotAddOffsetFromParent); |
| 202 | 248 |
| 203 BoxPainter::paintBoxShadow(paintInfo, paintRect, m_layoutTableCell.styleRef(
), Normal); | 249 BoxPainter::paintBoxShadow(paintInfo, paintRect, m_layoutTableCell.styleRef(
), Normal); |
| 204 | 250 |
| 205 // Paint our cell background. | 251 // Paint our cell background. |
| 206 paintBackgroundsBehindCell(paintInfo, paintOffset, &m_layoutTableCell, Displ
ayItem::BoxDecorationBackground); | 252 paintBackgroundsBehindCell(paintInfo, paintOffset, m_layoutTableCell, Displa
yItem::BoxDecorationBackground); |
| 207 | 253 |
| 208 BoxPainter::paintBoxShadow(paintInfo, paintRect, m_layoutTableCell.styleRef(
), Inset); | 254 BoxPainter::paintBoxShadow(paintInfo, paintRect, m_layoutTableCell.styleRef(
), Inset); |
| 209 | 255 |
| 210 if (!needsToPaintBorder) | 256 if (!needsToPaintBorder) |
| 211 return; | 257 return; |
| 212 | 258 |
| 213 BoxPainter::paintBorder(m_layoutTableCell, paintInfo, paintRect, m_layoutTab
leCell.styleRef()); | 259 BoxPainter::paintBorder(m_layoutTableCell, paintInfo, paintRect, m_layoutTab
leCell.styleRef()); |
| 214 } | 260 } |
| 215 | 261 |
| 216 void TableCellPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset) | 262 void TableCellPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 231 } | 277 } |
| 232 | 278 |
| 233 LayoutRect TableCellPainter::paintBounds(const LayoutPoint& paintOffset, PaintBo
undOffsetBehavior paintBoundOffsetBehavior) | 279 LayoutRect TableCellPainter::paintBounds(const LayoutPoint& paintOffset, PaintBo
undOffsetBehavior paintBoundOffsetBehavior) |
| 234 { | 280 { |
| 235 LayoutPoint adjustedPaintOffset = paintOffset; | 281 LayoutPoint adjustedPaintOffset = paintOffset; |
| 236 if (paintBoundOffsetBehavior == AddOffsetFromParent) | 282 if (paintBoundOffsetBehavior == AddOffsetFromParent) |
| 237 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); | 283 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); |
| 238 return LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell.pixelSna
ppedSize())); | 284 return LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell.pixelSna
ppedSize())); |
| 239 } | 285 } |
| 240 | 286 |
| 287 LayoutRect TableCellPainter::paintBoundsParent(const LayoutPoint& paintOffset, c
onst LayoutBox& backgroundObject, DisplayItem::Type type) |
| 288 { |
| 289 LayoutRect position; |
| 290 switch (type) { |
| 291 case DisplayItem::TableCellBackgroundFromColumnGroup: |
| 292 case DisplayItem::TableCellBackgroundFromColumn: { |
| 293 position = static_cast<const LayoutTableCol&>(backgroundObject).position
ForBackgroundDrawing( |
| 294 m_layoutTableCell.absoluteColumnIndex()); |
| 295 // position is relative to table, must correct for section location |
| 296 LayoutPoint sectionLocation = m_layoutTableCell.section()->location(); |
| 297 position.moveBy(-sectionLocation); |
| 298 position.moveBy(paintOffset); |
| 299 break; |
| 300 } |
| 301 case DisplayItem::TableCellBackgroundFromSection: { |
| 302 position = static_cast<const LayoutTableSection&>(backgroundObject).posi
tionForBackgroundDrawing(); |
| 303 position.moveBy(paintOffset); |
| 304 break; |
| 305 } |
| 306 case DisplayItem::TableCellBackgroundFromRow: { |
| 307 position = static_cast<const LayoutTableRow&>(backgroundObject).position
ForBackgroundDrawing(); |
| 308 position.moveBy(paintOffset); |
| 309 break; |
| 310 } |
| 311 case DisplayItem::BoxDecorationBackground: { |
| 312 LayoutPoint adjustedPaintOffset = paintOffset; |
| 313 adjustedPaintOffset.moveBy(m_layoutTableCell.location()); |
| 314 position = LayoutRect(adjustedPaintOffset, LayoutSize(m_layoutTableCell
.size())); |
| 315 break; |
| 316 } |
| 317 default: |
| 318 ASSERT_NOT_REACHED(); |
| 319 break; |
| 320 } |
| 321 return LayoutRect(position.pixelSnappedLocation(), position.pixelSnappedSize
()); |
| 322 } |
| 323 |
| 241 } // namespace blink | 324 } // namespace blink |
| 242 | 325 |
| OLD | NEW |