blob: 3ec0d178dd2c403107b6d065cda8b6046e3541ac [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 "core/paint/FieldsetPainter.h"
#include "core/layout/LayoutFieldset.h"
#include "core/paint/BoxDecorationData.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/LayoutObjectDrawingRecorder.h"
#include "core/paint/PaintInfo.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
namespace blink {
void FieldsetPainter::paintBoxDecorationBackground(
const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) {
LayoutRect paintRect(paintOffset, m_layoutFieldset.size());
LayoutBox* legend = m_layoutFieldset.findInFlowLegend();
if (!legend)
return BoxPainter(m_layoutFieldset)
.paintBoxDecorationBackground(paintInfo, paintOffset);
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
paintInfo.context, m_layoutFieldset, paintInfo.phase))
return;
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
if (m_layoutFieldset.style()->isHorizontalWritingMode()) {
LayoutUnit yOff =
(legend->location().y() > 0)
? LayoutUnit()
: (legend->size().height() - m_layoutFieldset.borderTop()) / 2;
paintRect.setHeight(paintRect.height() - yOff);
paintRect.setY(paintRect.y() + yOff);
} else {
LayoutUnit xOff =
(legend->location().x() > 0)
? LayoutUnit()
: (legend->size().width() - m_layoutFieldset.borderLeft()) / 2;
paintRect.setWidth(paintRect.width() - xOff);
paintRect.setX(paintRect.x() + xOff);
}
LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutFieldset,
paintInfo.phase, paintRect);
BoxDecorationData boxDecorationData(m_layoutFieldset);
if (boxDecorationData.bleedAvoidance == BackgroundBleedNone) {
BoxPainter::paintNormalBoxShadow(paintInfo, paintRect,
m_layoutFieldset.styleRef());
}
BoxPainter(m_layoutFieldset)
.paintFillLayers(paintInfo, boxDecorationData.backgroundColor,
m_layoutFieldset.style()->backgroundLayers(), paintRect);
BoxPainter::paintInsetBoxShadow(paintInfo, paintRect,
m_layoutFieldset.styleRef());
if (!boxDecorationData.hasBorderDecoration)
return;
// Create a clipping region around the legend and paint the border as normal
GraphicsContext& graphicsContext = paintInfo.context;
GraphicsContextStateSaver stateSaver(graphicsContext);
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
if (m_layoutFieldset.style()->isHorizontalWritingMode()) {
LayoutUnit clipTop = paintRect.y();
LayoutUnit clipHeight =
max(static_cast<LayoutUnit>(m_layoutFieldset.style()->borderTopWidth()),
legend->size().height() -
((legend->size().height() - m_layoutFieldset.borderTop()) / 2));
graphicsContext.clipOut(
pixelSnappedIntRect(paintRect.x() + legend->location().x(), clipTop,
legend->size().width(), clipHeight));
} else {
LayoutUnit clipLeft = paintRect.x();
LayoutUnit clipWidth = max(
static_cast<LayoutUnit>(m_layoutFieldset.style()->borderLeftWidth()),
legend->size().width());
graphicsContext.clipOut(
pixelSnappedIntRect(clipLeft, paintRect.y() + legend->location().y(),
clipWidth, legend->size().height()));
}
BoxPainter::paintBorder(m_layoutFieldset, paintInfo, paintRect,
m_layoutFieldset.styleRef());
}
void FieldsetPainter::paintMask(const PaintInfo& paintInfo,
const LayoutPoint& paintOffset) {
if (m_layoutFieldset.style()->visibility() != EVisibility::kVisible ||
paintInfo.phase != PaintPhaseMask)
return;
LayoutRect paintRect = LayoutRect(paintOffset, m_layoutFieldset.size());
LayoutBox* legend = m_layoutFieldset.findInFlowLegend();
if (!legend)
return BoxPainter(m_layoutFieldset).paintMask(paintInfo, paintOffset);
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
paintInfo.context, m_layoutFieldset, paintInfo.phase))
return;
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
if (m_layoutFieldset.style()->isHorizontalWritingMode()) {
LayoutUnit yOff =
(legend->location().y() > LayoutUnit())
? LayoutUnit()
: (legend->size().height() - m_layoutFieldset.borderTop()) / 2;
paintRect.expand(LayoutUnit(), -yOff);
paintRect.move(LayoutUnit(), yOff);
} else {
LayoutUnit xOff =
(legend->location().x() > LayoutUnit())
? LayoutUnit()
: (legend->size().width() - m_layoutFieldset.borderLeft()) / 2;
paintRect.expand(-xOff, LayoutUnit());
paintRect.move(xOff, LayoutUnit());
}
LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutFieldset,
paintInfo.phase, paintRect);
BoxPainter(m_layoutFieldset).paintMaskImages(paintInfo, paintRect);
}
} // namespace blink