blob: 4691cd91965d332ed1f8c2886e558d2bb71b5830 [file] [log] [blame]
// 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/TablePainter.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/DrawingRecorder.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderBoxClipper.h"
#include "core/rendering/RenderTable.h"
#include "core/rendering/RenderTableSection.h"
#include "core/rendering/style/CollapsedBorderValue.h"
namespace blink {
void TablePainter::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, &m_renderTable);
LayoutPoint adjustedPaintOffset = paintOffset + m_renderTable.location();
if (!m_renderTable.isDocumentElement()) {
LayoutRect overflowBox = m_renderTable.visualOverflowRect();
m_renderTable.flipForWritingMode(overflowBox);
overflowBox.moveBy(adjustedPaintOffset);
if (!overflowBox.intersects(paintInfo.rect))
return;
}
RenderBoxClipper boxClipper(m_renderTable, paintInfo, adjustedPaintOffset, ForceContentsClip);
paintObject(paintInfo, adjustedPaintOffset);
}
void TablePainter::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
PaintPhase paintPhase = paintInfo.phase;
if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && m_renderTable.hasBoxDecorationBackground() && m_renderTable.style()->visibility() == VISIBLE)
paintBoxDecorationBackground(paintInfo, paintOffset);
if (paintPhase == PaintPhaseMask) {
m_renderTable.paintMask(paintInfo, paintOffset);
return;
}
// We're done. We don't bother painting any children.
if (paintPhase == PaintPhaseBlockBackground)
return;
// We don't paint our own background, but we do let the kids paint their backgrounds.
if (paintPhase == PaintPhaseChildBlockBackgrounds)
paintPhase = PaintPhaseChildBlockBackground;
PaintInfo info(paintInfo);
info.phase = paintPhase;
info.updatePaintingRootForChildren(&m_renderTable);
for (RenderObject* child = m_renderTable.firstChild(); child; child = child->nextSibling()) {
if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
LayoutPoint childPoint = m_renderTable.flipForWritingModeForChild(toRenderBox(child), paintOffset);
child->paint(info, childPoint);
}
}
if (m_renderTable.collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && m_renderTable.style()->visibility() == VISIBLE) {
m_renderTable.recalcCollapsedBorders();
// Using our cached sorted styles, we then do individual passes,
// painting each style of border from lowest precedence to highest precedence.
info.phase = PaintPhaseCollapsedTableBorders;
RenderTable::CollapsedBorderValues collapsedBorders = m_renderTable.collapsedBorders();
size_t count = collapsedBorders.size();
for (size_t i = 0; i < count; ++i) {
// FIXME: pass this value into children rather than storing temporarily on the RenderTable object.
m_renderTable.setCurrentBorderValue(&collapsedBorders[i]);
for (RenderTableSection* section = m_renderTable.bottomSection(); section; section = m_renderTable.sectionAbove(section)) {
LayoutPoint childPoint = m_renderTable.flipForWritingModeForChild(section, paintOffset);
section->paint(info, childPoint);
}
}
m_renderTable.setCurrentBorderValue(0);
}
// Paint outline.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_renderTable.style()->hasOutline() && m_renderTable.style()->visibility() == VISIBLE)
m_renderTable.paintOutline(paintInfo, LayoutRect(paintOffset, m_renderTable.size()));
}
void TablePainter::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (!paintInfo.shouldPaintWithinRoot(&m_renderTable))
return;
LayoutRect rect(paintOffset, m_renderTable.size());
m_renderTable.subtractCaptionRect(rect);
BoxPainter(m_renderTable).paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, rect);
}
void TablePainter::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (m_renderTable.style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
LayoutRect rect(paintOffset, m_renderTable.size());
m_renderTable.subtractCaptionRect(rect);
DrawingRecorder recorder(paintInfo.context, &m_renderTable, paintInfo.phase, pixelSnappedIntRect(rect));
BoxPainter(m_renderTable).paintMaskImages(paintInfo, rect);
}
} // namespace blink