blob: 744ebe0f011391ab0d647d96d48ecfbe257c4c5b [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 "third_party/blink/renderer/core/paint/fieldset_painter.h"
#include "third_party/blink/renderer/core/layout/layout_fieldset.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_decoration_data.h"
#include "third_party/blink/renderer/core/paint/box_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/fieldset_paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
namespace blink {
namespace {
FieldsetPaintInfo CreateFieldsetPaintInfo(const LayoutBox& fieldset,
const LayoutBox& legend) {
LayoutRectOutsets fieldset_borders(
fieldset.BorderTop(), fieldset.BorderRight(),
LayoutUnit(), // bottom border will always be left alone.
fieldset.BorderLeft());
return FieldsetPaintInfo(fieldset.StyleRef(), fieldset.Size(),
fieldset_borders, legend.FrameRect());
}
} // anonymous namespace
void FieldsetPainter::PaintBoxDecorationBackground(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
LayoutRect paint_rect(paint_offset, layout_fieldset_.Size());
LayoutBox* legend = layout_fieldset_.FindInFlowLegend();
if (!legend)
return BoxPainter(layout_fieldset_)
.PaintBoxDecorationBackground(paint_info, paint_offset);
if (!DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, layout_fieldset_, paint_info.phase)) {
FieldsetPaintInfo fieldset_paint_info =
CreateFieldsetPaintInfo(layout_fieldset_, *legend);
paint_rect.Contract(fieldset_paint_info.border_outsets);
DrawingRecorder recorder(paint_info.context, layout_fieldset_,
paint_info.phase);
BoxDecorationData box_decoration_data(layout_fieldset_);
BoxPainterBase::PaintNormalBoxShadow(paint_info, paint_rect,
layout_fieldset_.StyleRef());
BackgroundImageGeometry geometry(layout_fieldset_);
BoxModelObjectPainter(layout_fieldset_)
.PaintFillLayers(paint_info, box_decoration_data.background_color,
layout_fieldset_.StyleRef().BackgroundLayers(),
paint_rect, geometry);
BoxPainterBase::PaintInsetBoxShadowWithBorderRect(
paint_info, paint_rect, layout_fieldset_.StyleRef());
if (box_decoration_data.has_border_decoration) {
// Create a clipping region around the legend and paint the border as
// normal
GraphicsContext& graphics_context = paint_info.context;
GraphicsContextStateSaver state_saver(graphics_context);
LayoutRect legend_cutout_rect = fieldset_paint_info.legend_cutout_rect;
legend_cutout_rect.MoveBy(paint_offset);
graphics_context.ClipOut(PixelSnappedIntRect(legend_cutout_rect));
Node* node = nullptr;
const LayoutObject* layout_object = &layout_fieldset_;
for (; layout_object && !node; layout_object = layout_object->Parent())
node = layout_object->GeneratingNode();
BoxPainterBase::PaintBorder(
layout_fieldset_, layout_fieldset_.GetDocument(), node, paint_info,
paint_rect, layout_fieldset_.StyleRef());
}
}
if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) {
BoxPainter(layout_fieldset_)
.RecordHitTestData(paint_info, paint_rect, layout_fieldset_);
}
}
void FieldsetPainter::PaintMask(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
if (layout_fieldset_.StyleRef().Visibility() != EVisibility::kVisible ||
paint_info.phase != PaintPhase::kMask)
return;
LayoutRect paint_rect = LayoutRect(paint_offset, layout_fieldset_.Size());
LayoutBox* legend = layout_fieldset_.FindInFlowLegend();
if (!legend)
return BoxPainter(layout_fieldset_).PaintMask(paint_info, paint_offset);
if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, layout_fieldset_, paint_info.phase))
return;
FieldsetPaintInfo fieldset_paint_info =
CreateFieldsetPaintInfo(layout_fieldset_, *legend);
paint_rect.Contract(fieldset_paint_info.border_outsets);
DrawingRecorder recorder(paint_info.context, layout_fieldset_,
paint_info.phase);
BoxPainter(layout_fieldset_).PaintMaskImages(paint_info, paint_rect);
}
} // namespace blink