Commit 7a10493b authored by chrishtr@chromium.org's avatar chrishtr@chromium.org

Move painting code from RenderTableCell to TableCellPainter.

BUG=412088

Review URL: https://codereview.chromium.org/724483002

git-svn-id: svn://svn.chromium.org/blink/trunk@185329 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 16a50c6d
...@@ -1508,6 +1508,8 @@ ...@@ -1508,6 +1508,8 @@
'paint/SVGShapePainter.h', 'paint/SVGShapePainter.h',
'paint/SVGTextPainter.cpp', 'paint/SVGTextPainter.cpp',
'paint/SVGTextPainter.h', 'paint/SVGTextPainter.h',
'paint/TableCellPainter.cpp',
'paint/TableCellPainter.h',
'paint/TablePainter.cpp', 'paint/TablePainter.cpp',
'paint/TablePainter.h', 'paint/TablePainter.h',
'paint/TableRowPainter.cpp', 'paint/TableRowPainter.cpp',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/paint/TableCellPainter.h"
#include "core/paint/BlockPainter.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/DrawingRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCell.h"
namespace blink {
inline CollapsedBorderValue TableCellPainter::cachedCollapsedLeftBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode()) {
return styleForCellFlow->isLeftToRightDirection() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSStart)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSEnd);
}
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSAfter)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSBefore);
}
inline CollapsedBorderValue TableCellPainter::cachedCollapsedRightBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode()) {
return styleForCellFlow->isLeftToRightDirection() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSEnd)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSStart);
}
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSBefore)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSAfter);
}
inline CollapsedBorderValue TableCellPainter::cachedCollapsedTopBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode())
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSAfter) : m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSBefore);
return styleForCellFlow->isLeftToRightDirection() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSStart) : m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSEnd);
}
inline CollapsedBorderValue TableCellPainter::cachedCollapsedBottomBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode()) {
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSBefore)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSAfter);
}
return styleForCellFlow->isLeftToRightDirection() ? m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSEnd)
: m_renderTableCell.section()->cachedCollapsedBorder(&m_renderTableCell, CBSStart);
}
void TableCellPainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase != PaintPhaseCollapsedTableBorders);
BlockPainter(m_renderTableCell).paint(paintInfo, paintOffset);
}
struct CollapsedBorder {
CollapsedBorderValue borderValue;
BoxSide side;
bool shouldPaint;
int x1;
int y1;
int x2;
int y2;
EBorderStyle style;
};
class CollapsedBorders {
public:
CollapsedBorders()
: m_count(0)
{
}
void addBorder(const CollapsedBorderValue& borderValue, BoxSide borderSide, bool shouldPaint, int x1, int y1, int x2, int y2, EBorderStyle borderStyle)
{
if (borderValue.exists() && shouldPaint) {
m_borders[m_count].borderValue = borderValue;
m_borders[m_count].side = borderSide;
m_borders[m_count].shouldPaint = shouldPaint;
m_borders[m_count].x1 = x1;
m_borders[m_count].x2 = x2;
m_borders[m_count].y1 = y1;
m_borders[m_count].y2 = y2;
m_borders[m_count].style = borderStyle;
m_count++;
}
}
CollapsedBorder* nextBorder()
{
for (unsigned i = 0; i < m_count; i++) {
if (m_borders[i].borderValue.exists() && m_borders[i].shouldPaint) {
m_borders[i].shouldPaint = false;
return &m_borders[i];
}
}
return 0;
}
CollapsedBorder m_borders[4];
unsigned m_count;
};
static EBorderStyle collapsedBorderStyle(EBorderStyle style)
{
if (style == OUTSET)
return GROOVE;
if (style == INSET)
return RIDGE;
return style;
}
void TableCellPainter::paintCollapsedBorders(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase == PaintPhaseCollapsedTableBorders);
if (!paintInfo.shouldPaintWithinRoot(&m_renderTableCell) || m_renderTableCell.style()->visibility() != VISIBLE)
return;
LayoutRect paintRect = LayoutRect(paintOffset + m_renderTableCell.location(), m_renderTableCell.pixelSnappedSize());
if (paintRect.y() - m_renderTableCell.table()->outerBorderTop() >= paintInfo.rect.maxY())
return;
if (paintRect.maxY() + m_renderTableCell.table()->outerBorderBottom() <= paintInfo.rect.y())
return;
if (!m_renderTableCell.table()->currentBorderValue())
return;
const RenderStyle* styleForCellFlow = m_renderTableCell.styleForCellFlow();
CollapsedBorderValue leftVal = cachedCollapsedLeftBorder(styleForCellFlow);
CollapsedBorderValue rightVal = cachedCollapsedRightBorder(styleForCellFlow);
CollapsedBorderValue topVal = cachedCollapsedTopBorder(styleForCellFlow);
CollapsedBorderValue bottomVal = cachedCollapsedBottomBorder(styleForCellFlow);
// Adjust our x/y/width/height so that we paint the collapsed borders at the correct location.
int topWidth = topVal.width();
int bottomWidth = bottomVal.width();
int leftWidth = leftVal.width();
int rightWidth = rightVal.width();
IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2,
paintRect.y() - topWidth / 2,
paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2,
paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2);
EBorderStyle topStyle = collapsedBorderStyle(topVal.style());
EBorderStyle bottomStyle = collapsedBorderStyle(bottomVal.style());
EBorderStyle leftStyle = collapsedBorderStyle(leftVal.style());
EBorderStyle rightStyle = collapsedBorderStyle(rightVal.style());
bool renderTop = topStyle > BHIDDEN && !topVal.isTransparent();
bool renderBottom = bottomStyle > BHIDDEN && !bottomVal.isTransparent();
bool renderLeft = leftStyle > BHIDDEN && !leftVal.isTransparent();
bool renderRight = rightStyle > BHIDDEN && !rightVal.isTransparent();
// We never paint diagonals at the joins. We simply let the border with the highest
// precedence paint on top of borders with lower precedence.
CollapsedBorders borders;
borders.addBorder(topVal, BSTop, renderTop, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, topStyle);
borders.addBorder(bottomVal, BSBottom, renderBottom, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), bottomStyle);
borders.addBorder(leftVal, BSLeft, renderLeft, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), leftStyle);
borders.addBorder(rightVal, BSRight, renderRight, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), rightStyle);
GraphicsContext* graphicsContext = paintInfo.context;
bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext);
for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) {
if (border->borderValue.isSameIgnoringColor(*m_renderTableCell.table()->currentBorderValue())) {
ObjectPainter::drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
border->borderValue.color().resolve(m_renderTableCell.style()->visitedDependentColor(CSSPropertyColor)), border->style, 0, 0, antialias);
}
}
}
void TableCellPainter::paintBackgroundsBehindCell(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderObject* backgroundObject)
{
if (!paintInfo.shouldPaintWithinRoot(&m_renderTableCell))
return;
if (!backgroundObject)
return;
if (m_renderTableCell.style()->visibility() != VISIBLE)
return;
RenderTable* tableElt = m_renderTableCell.table();
if (!tableElt->collapseBorders() && m_renderTableCell.style()->emptyCells() == HIDE && !m_renderTableCell.firstChild())
return;
LayoutPoint adjustedPaintOffset = paintOffset;
if (backgroundObject != &m_renderTableCell)
adjustedPaintOffset.moveBy(m_renderTableCell.location());
Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor);
const FillLayer& bgLayer = backgroundObject->style()->backgroundLayers();
if (bgLayer.hasImage() || c.alpha()) {
// We have to clip here because the background would paint
// on top of the borders otherwise. This only matters for cells and rows.
bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == &m_renderTableCell || backgroundObject == m_renderTableCell.parent()) && tableElt->collapseBorders();
GraphicsContextStateSaver stateSaver(*paintInfo.context, shouldClip);
if (shouldClip) {
LayoutRect clipRect(adjustedPaintOffset.x() + m_renderTableCell.borderLeft(), adjustedPaintOffset.y() + m_renderTableCell.borderTop(),
m_renderTableCell.width() - m_renderTableCell.borderLeft() - m_renderTableCell.borderRight(),
m_renderTableCell.height() - m_renderTableCell.borderTop() - m_renderTableCell.borderBottom());
paintInfo.context->clip(clipRect);
}
BoxPainter(m_renderTableCell).paintFillLayers(paintInfo, c, bgLayer, LayoutRect(adjustedPaintOffset, m_renderTableCell.pixelSnappedSize()), BackgroundBleedNone, CompositeSourceOver, backgroundObject);
}
}
void TableCellPainter::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (!paintInfo.shouldPaintWithinRoot(&m_renderTableCell))
return;
RenderTable* tableElt = m_renderTableCell.table();
if (!tableElt->collapseBorders() && m_renderTableCell.style()->emptyCells() == HIDE && !m_renderTableCell.firstChild())
return;
LayoutRect paintRect = LayoutRect(paintOffset, m_renderTableCell.pixelSnappedSize());
DrawingRecorder recorder(paintInfo.context, &m_renderTableCell, paintInfo.phase, pixelSnappedIntRect(paintRect));
BoxPainter::paintBoxShadow(paintInfo, paintRect, m_renderTableCell.style(), Normal);
// Paint our cell background.
paintBackgroundsBehindCell(paintInfo, paintOffset, &m_renderTableCell);
BoxPainter::paintBoxShadow(paintInfo, paintRect, m_renderTableCell.style(), Inset);
if (!m_renderTableCell.style()->hasBorder() || tableElt->collapseBorders())
return;
BoxPainter::paintBorder(m_renderTableCell, paintInfo, paintRect, m_renderTableCell.style());
}
void TableCellPainter::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (m_renderTableCell.style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
RenderTable* tableElt = m_renderTableCell.table();
if (!tableElt->collapseBorders() && m_renderTableCell.style()->emptyCells() == HIDE && !m_renderTableCell.firstChild())
return;
BoxPainter(m_renderTableCell).paintMaskImages(paintInfo, LayoutRect(paintOffset, m_renderTableCell.pixelSnappedSize()));
}
} // namespace blink
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TableCellPainter_h
#define TableCellPainter_h
#include "core/rendering/style/CollapsedBorderValue.h"
namespace blink {
struct PaintInfo;
class LayoutPoint;
class RenderObject;
class RenderStyle;
class RenderTableCell;
class TableCellPainter {
public:
TableCellPainter(RenderTableCell& renderTableCell) : m_renderTableCell(renderTableCell) { }
void paint(PaintInfo&, const LayoutPoint&);
void paintCollapsedBorders(PaintInfo&, const LayoutPoint&);
void paintBackgroundsBehindCell(PaintInfo&, const LayoutPoint&, RenderObject* backgroundObject);
void paintBoxDecorationBackground(PaintInfo&, const LayoutPoint& paintOffset);
void paintMask(PaintInfo&, const LayoutPoint& paintOffset);
private:
CollapsedBorderValue cachedCollapsedLeftBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedRightBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedTopBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedBottomBorder(const RenderStyle*) const;
RenderTableCell& m_renderTableCell;
};
} // namespace blink
#endif // TableCellPainter_h
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "core/paint/TableRowPainter.h" #include "core/paint/TableRowPainter.h"
#include "core/paint/ObjectPainter.h" #include "core/paint/ObjectPainter.h"
#include "core/paint/TableCellPainter.h"
#include "core/rendering/GraphicsContextAnnotator.h" #include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/PaintInfo.h" #include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCell.h" #include "core/rendering/RenderTableCell.h"
...@@ -22,7 +23,7 @@ void TableRowPainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset ...@@ -22,7 +23,7 @@ void TableRowPainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset
for (RenderTableCell* cell = m_renderTableRow.firstCell(); cell; cell = cell->nextCell()) { for (RenderTableCell* cell = m_renderTableRow.firstCell(); cell; cell = cell->nextCell()) {
// Paint the row background behind the cell. // Paint the row background behind the cell.
if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground)
cell->paintBackgroundsBehindCell(paintInfo, paintOffset, &m_renderTableRow); TableCellPainter(*cell).paintBackgroundsBehindCell(paintInfo, paintOffset, &m_renderTableRow);
if (!cell->hasSelfPaintingLayer()) if (!cell->hasSelfPaintingLayer())
cell->paint(paintInfo, paintOffset); cell->paint(paintInfo, paintOffset);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "core/paint/TableSectionPainter.h" #include "core/paint/TableSectionPainter.h"
#include "core/paint/ObjectPainter.h" #include "core/paint/ObjectPainter.h"
#include "core/paint/TableCellPainter.h"
#include "core/paint/TableRowPainter.h" #include "core/paint/TableRowPainter.h"
#include "core/rendering/GraphicsContextAnnotator.h" #include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/PaintInfo.h" #include "core/rendering/PaintInfo.h"
...@@ -83,7 +84,7 @@ void TableSectionPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& p ...@@ -83,7 +84,7 @@ void TableSectionPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& p
if (!cell || (row > dirtiedRows.start() && m_renderTableSection.primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && m_renderTableSection.primaryCellAt(row, col - 1) == cell)) if (!cell || (row > dirtiedRows.start() && m_renderTableSection.primaryCellAt(row - 1, col) == cell) || (col > dirtiedColumns.start() && m_renderTableSection.primaryCellAt(row, col - 1) == cell))
continue; continue;
LayoutPoint cellPoint = m_renderTableSection.flipForWritingModeForChild(cell, paintOffset); LayoutPoint cellPoint = m_renderTableSection.flipForWritingModeForChild(cell, paintOffset);
cell->paintCollapsedBorders(paintInfo, cellPoint); TableCellPainter(*cell).paintCollapsedBorders(paintInfo, cellPoint);
} }
} }
} else { } else {
...@@ -146,7 +147,7 @@ void TableSectionPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& p ...@@ -146,7 +147,7 @@ void TableSectionPainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& p
if (paintInfo.phase == PaintPhaseCollapsedTableBorders) { if (paintInfo.phase == PaintPhaseCollapsedTableBorders) {
for (unsigned i = cells.size(); i > 0; --i) { for (unsigned i = cells.size(); i > 0; --i) {
LayoutPoint cellPoint = m_renderTableSection.flipForWritingModeForChild(cells[i - 1], paintOffset); LayoutPoint cellPoint = m_renderTableSection.flipForWritingModeForChild(cells[i - 1], paintOffset);
cells[i - 1]->paintCollapsedBorders(paintInfo, cellPoint); TableCellPainter(*cells[i - 1]).paintCollapsedBorders(paintInfo, cellPoint);
} }
} else { } else {
for (unsigned i = 0; i < cells.size(); ++i) for (unsigned i = 0; i < cells.size(); ++i)
...@@ -173,16 +174,16 @@ void TableSectionPainter::paintCell(RenderTableCell* cell, PaintInfo& paintInfo, ...@@ -173,16 +174,16 @@ void TableSectionPainter::paintCell(RenderTableCell* cell, PaintInfo& paintInfo,
// the stack, since we have already opened a transparency layer (potentially) for the table row group. // the stack, since we have already opened a transparency layer (potentially) for the table row group.
// Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the
// cell. // cell.
cell->paintBackgroundsBehindCell(paintInfo, cellPoint, columnGroup); TableCellPainter(*cell).paintBackgroundsBehindCell(paintInfo, cellPoint, columnGroup);
cell->paintBackgroundsBehindCell(paintInfo, cellPoint, column); TableCellPainter(*cell).paintBackgroundsBehindCell(paintInfo, cellPoint, column);
// Paint the row group next. // Paint the row group next.
cell->paintBackgroundsBehindCell(paintInfo, cellPoint, &m_renderTableSection); TableCellPainter(*cell).paintBackgroundsBehindCell(paintInfo, cellPoint, &m_renderTableSection);
// Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for
// painting the row background for the cell. // painting the row background for the cell.
if (!row->hasSelfPaintingLayer()) if (!row->hasSelfPaintingLayer())
cell->paintBackgroundsBehindCell(paintInfo, cellPoint, row); TableCellPainter(*cell).paintBackgroundsBehindCell(paintInfo, cellPoint, row);
} }
if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer())) if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()))
cell->paint(paintInfo, cellPoint); cell->paint(paintInfo, cellPoint);
......
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
#include "core/HTMLNames.h" #include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h" #include "core/css/StylePropertySet.h"
#include "core/html/HTMLTableCellElement.h" #include "core/html/HTMLTableCellElement.h"
#include "core/paint/BoxPainter.h" #include "core/paint/TableCellPainter.h"
#include "core/paint/DrawingRecorder.h"
#include "core/rendering/PaintInfo.h" #include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCol.h" #include "core/rendering/RenderTableCol.h"
#include "core/rendering/RenderView.h" #include "core/rendering/RenderView.h"
...@@ -854,34 +853,6 @@ CollapsedBorderValue RenderTableCell::computeCollapsedAfterBorder(IncludeBorderC ...@@ -854,34 +853,6 @@ CollapsedBorderValue RenderTableCell::computeCollapsedAfterBorder(IncludeBorderC
return result; return result;
} }
inline CollapsedBorderValue RenderTableCell::cachedCollapsedLeftBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode())
return styleForCellFlow->isLeftToRightDirection() ? section()->cachedCollapsedBorder(this, CBSStart) : section()->cachedCollapsedBorder(this, CBSEnd);
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? section()->cachedCollapsedBorder(this, CBSAfter) : section()->cachedCollapsedBorder(this, CBSBefore);
}
inline CollapsedBorderValue RenderTableCell::cachedCollapsedRightBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode())
return styleForCellFlow->isLeftToRightDirection() ? section()->cachedCollapsedBorder(this, CBSEnd) : section()->cachedCollapsedBorder(this, CBSStart);
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? section()->cachedCollapsedBorder(this, CBSBefore) : section()->cachedCollapsedBorder(this, CBSAfter);
}
inline CollapsedBorderValue RenderTableCell::cachedCollapsedTopBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode())
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? section()->cachedCollapsedBorder(this, CBSAfter) : section()->cachedCollapsedBorder(this, CBSBefore);
return styleForCellFlow->isLeftToRightDirection() ? section()->cachedCollapsedBorder(this, CBSStart) : section()->cachedCollapsedBorder(this, CBSEnd);
}
inline CollapsedBorderValue RenderTableCell::cachedCollapsedBottomBorder(const RenderStyle* styleForCellFlow) const
{
if (styleForCellFlow->isHorizontalWritingMode())
return styleForCellFlow->slowIsFlippedBlocksWritingMode() ? section()->cachedCollapsedBorder(this, CBSBefore) : section()->cachedCollapsedBorder(this, CBSAfter);
return styleForCellFlow->isLeftToRightDirection() ? section()->cachedCollapsedBorder(this, CBSEnd) : section()->cachedCollapsedBorder(this, CBSStart);
}
int RenderTableCell::borderLeft() const int RenderTableCell::borderLeft() const
{ {
return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlockFlow::borderLeft(); return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlockFlow::borderLeft();
...@@ -990,69 +961,9 @@ int RenderTableCell::borderHalfAfter(bool outer) const ...@@ -990,69 +961,9 @@ int RenderTableCell::borderHalfAfter(bool outer) const
void RenderTableCell::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) void RenderTableCell::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{ {
ASSERT(paintInfo.phase != PaintPhaseCollapsedTableBorders); TableCellPainter(*this).paint(paintInfo, paintOffset);
RenderBlock::paint(paintInfo, paintOffset);
}
static EBorderStyle collapsedBorderStyle(EBorderStyle style)
{
if (style == OUTSET)
return GROOVE;
if (style == INSET)
return RIDGE;
return style;
} }
struct CollapsedBorder {
CollapsedBorderValue borderValue;
BoxSide side;
bool shouldPaint;
int x1;
int y1;
int x2;
int y2;
EBorderStyle style;
};
class CollapsedBorders {
public:
CollapsedBorders()
: m_count(0)
{
}
void addBorder(const CollapsedBorderValue& borderValue, BoxSide borderSide, bool shouldPaint,
int x1, int y1, int x2, int y2, EBorderStyle borderStyle)
{
if (borderValue.exists() && shouldPaint) {
m_borders[m_count].borderValue = borderValue;
m_borders[m_count].side = borderSide;
m_borders[m_count].shouldPaint = shouldPaint;
m_borders[m_count].x1 = x1;
m_borders[m_count].x2 = x2;
m_borders[m_count].y1 = y1;
m_borders[m_count].y2 = y2;
m_borders[m_count].style = borderStyle;
m_count++;
}
}
CollapsedBorder* nextBorder()
{
for (unsigned i = 0; i < m_count; i++) {
if (m_borders[i].borderValue.exists() && m_borders[i].shouldPaint) {
m_borders[i].shouldPaint = false;
return &m_borders[i];
}
}
return 0;
}
CollapsedBorder m_borders[4];
unsigned m_count;
};
static void addBorderStyle(RenderTable::CollapsedBorderValues& borderValues, static void addBorderStyle(RenderTable::CollapsedBorderValues& borderValues,
CollapsedBorderValue borderValue) CollapsedBorderValue borderValue)
{ {
...@@ -1088,139 +999,14 @@ void RenderTableCell::sortBorderValues(RenderTable::CollapsedBorderValues& borde ...@@ -1088,139 +999,14 @@ void RenderTableCell::sortBorderValues(RenderTable::CollapsedBorderValues& borde
compareBorderValuesForQSort); compareBorderValuesForQSort);
} }
void RenderTableCell::paintCollapsedBorders(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase == PaintPhaseCollapsedTableBorders);
if (!paintInfo.shouldPaintWithinRoot(this) || style()->visibility() != VISIBLE)
return;
LayoutRect paintRect = LayoutRect(paintOffset + location(), pixelSnappedSize());
if (paintRect.y() - table()->outerBorderTop() >= paintInfo.rect.maxY())
return;
if (paintRect.maxY() + table()->outerBorderBottom() <= paintInfo.rect.y())
return;
if (!table()->currentBorderValue())
return;
const RenderStyle* styleForCellFlow = this->styleForCellFlow();
CollapsedBorderValue leftVal = cachedCollapsedLeftBorder(styleForCellFlow);
CollapsedBorderValue rightVal = cachedCollapsedRightBorder(styleForCellFlow);
CollapsedBorderValue topVal = cachedCollapsedTopBorder(styleForCellFlow);
CollapsedBorderValue bottomVal = cachedCollapsedBottomBorder(styleForCellFlow);
// Adjust our x/y/width/height so that we paint the collapsed borders at the correct location.
int topWidth = topVal.width();
int bottomWidth = bottomVal.width();
int leftWidth = leftVal.width();
int rightWidth = rightVal.width();
IntRect borderRect = pixelSnappedIntRect(paintRect.x() - leftWidth / 2,
paintRect.y() - topWidth / 2,
paintRect.width() + leftWidth / 2 + (rightWidth + 1) / 2,
paintRect.height() + topWidth / 2 + (bottomWidth + 1) / 2);
EBorderStyle topStyle = collapsedBorderStyle(topVal.style());
EBorderStyle bottomStyle = collapsedBorderStyle(bottomVal.style());
EBorderStyle leftStyle = collapsedBorderStyle(leftVal.style());
EBorderStyle rightStyle = collapsedBorderStyle(rightVal.style());
bool renderTop = topStyle > BHIDDEN && !topVal.isTransparent();
bool renderBottom = bottomStyle > BHIDDEN && !bottomVal.isTransparent();
bool renderLeft = leftStyle > BHIDDEN && !leftVal.isTransparent();
bool renderRight = rightStyle > BHIDDEN && !rightVal.isTransparent();
// We never paint diagonals at the joins. We simply let the border with the highest
// precedence paint on top of borders with lower precedence.
CollapsedBorders borders;
borders.addBorder(topVal, BSTop, renderTop, borderRect.x(), borderRect.y(), borderRect.maxX(), borderRect.y() + topWidth, topStyle);
borders.addBorder(bottomVal, BSBottom, renderBottom, borderRect.x(), borderRect.maxY() - bottomWidth, borderRect.maxX(), borderRect.maxY(), bottomStyle);
borders.addBorder(leftVal, BSLeft, renderLeft, borderRect.x(), borderRect.y(), borderRect.x() + leftWidth, borderRect.maxY(), leftStyle);
borders.addBorder(rightVal, BSRight, renderRight, borderRect.maxX() - rightWidth, borderRect.y(), borderRect.maxX(), borderRect.maxY(), rightStyle);
GraphicsContext* graphicsContext = paintInfo.context;
bool antialias = BoxPainter::shouldAntialiasLines(graphicsContext);
for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) {
if (border->borderValue.isSameIgnoringColor(*table()->currentBorderValue())) {
ObjectPainter::drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
border->borderValue.color().resolve(style()->visitedDependentColor(CSSPropertyColor)), border->style, 0, 0, antialias);
}
}
}
void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderObject* backgroundObject)
{
if (!paintInfo.shouldPaintWithinRoot(this))
return;
if (!backgroundObject)
return;
if (style()->visibility() != VISIBLE)
return;
RenderTable* tableElt = table();
if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
return;
LayoutPoint adjustedPaintOffset = paintOffset;
if (backgroundObject != this)
adjustedPaintOffset.moveBy(location());
Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor);
const FillLayer& bgLayer = backgroundObject->style()->backgroundLayers();
if (bgLayer.hasImage() || c.alpha()) {
// We have to clip here because the background would paint
// on top of the borders otherwise. This only matters for cells and rows.
bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == this || backgroundObject == parent()) && tableElt->collapseBorders();
GraphicsContextStateSaver stateSaver(*paintInfo.context, shouldClip);
if (shouldClip) {
LayoutRect clipRect(adjustedPaintOffset.x() + borderLeft(), adjustedPaintOffset.y() + borderTop(),
width() - borderLeft() - borderRight(), height() - borderTop() - borderBottom());
paintInfo.context->clip(clipRect);
}
BoxPainter(*this).paintFillLayers(paintInfo, c, bgLayer, LayoutRect(adjustedPaintOffset, pixelSnappedSize()), BackgroundBleedNone, CompositeSourceOver, backgroundObject);
}
}
void RenderTableCell::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset) void RenderTableCell::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{ {
if (!paintInfo.shouldPaintWithinRoot(this)) TableCellPainter(*this).paintBoxDecorationBackground(paintInfo, paintOffset);
return;
RenderTable* tableElt = table();
if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
return;
LayoutRect paintRect = LayoutRect(paintOffset, pixelSnappedSize());
DrawingRecorder recorder(paintInfo.context, this, paintInfo.phase, pixelSnappedIntRect(paintRect));
BoxPainter::paintBoxShadow(paintInfo, paintRect, style(), Normal);
// Paint our cell background.
paintBackgroundsBehindCell(paintInfo, paintOffset, this);
BoxPainter::paintBoxShadow(paintInfo, paintRect, style(), Inset);
if (!style()->hasBorder() || tableElt->collapseBorders())
return;
BoxPainter::paintBorder(*this, paintInfo, paintRect, style());
} }
void RenderTableCell::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset) void RenderTableCell::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{ {
if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) TableCellPainter(*this).paintMask(paintInfo, paintOffset);
return;
RenderTable* tableElt = table();
if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
return;
BoxPainter(*this).paintMaskImages(paintInfo, LayoutRect(paintOffset, pixelSnappedSize()));
} }
bool RenderTableCell::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const bool RenderTableCell::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const
......
...@@ -128,9 +128,6 @@ public: ...@@ -128,9 +128,6 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&) override; virtual void paint(PaintInfo&, const LayoutPoint&) override;
void paintCollapsedBorders(PaintInfo&, const LayoutPoint&);
void paintBackgroundsBehindCell(PaintInfo&, const LayoutPoint&, RenderObject* backgroundObject);
LayoutUnit cellBaselinePosition() const; LayoutUnit cellBaselinePosition() const;
bool isBaselineAligned() const bool isBaselineAligned() const
{ {
...@@ -263,11 +260,6 @@ private: ...@@ -263,11 +260,6 @@ private:
CollapsedBorderValue collapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue collapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
CollapsedBorderValue collapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue collapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
CollapsedBorderValue cachedCollapsedLeftBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedRightBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedTopBorder(const RenderStyle*) const;
CollapsedBorderValue cachedCollapsedBottomBorder(const RenderStyle*) const;
CollapsedBorderValue computeCollapsedStartBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue computeCollapsedStartBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
CollapsedBorderValue computeCollapsedEndBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue computeCollapsedEndBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
CollapsedBorderValue computeCollapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const; CollapsedBorderValue computeCollapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment