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

Unified Diff: Source/core/paint/TableCellPainter.cpp

Issue 724483002: Move painting code from RenderTableCell to TableCellPainter. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/paint/TableCellPainter.h ('k') | Source/core/paint/TableRowPainter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/paint/TableCellPainter.cpp
diff --git a/Source/core/paint/TableCellPainter.cpp b/Source/core/paint/TableCellPainter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7892579c7b8cb5838f9d7c265f9e3b74a732a9e4
--- /dev/null
+++ b/Source/core/paint/TableCellPainter.cpp
@@ -0,0 +1,254 @@
+// 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
+
« no previous file with comments | « Source/core/paint/TableCellPainter.h ('k') | Source/core/paint/TableRowPainter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698