// Copyright 2018 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/ng/ng_fieldset_painter.h"

#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_relative_utils.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/fieldset_paint_info.h"
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/rounded_border_geometry.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.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 {

FieldsetPaintInfo NGFieldsetPainter::CreateFieldsetPaintInfo() const {
  const NGLink* legend = nullptr;
  if (!fieldset_.Children().empty()) {
    const auto& first_child = fieldset_.Children().front();
    if (first_child->IsRenderedLegend())
      legend = &first_child;
  }
  const PhysicalSize fieldset_size(fieldset_.Size());
  const auto& fragment = fieldset_;
  LayoutRectOutsets fieldset_borders = fragment.Borders().ToLayoutRectOutsets();
  const ComputedStyle& style = fieldset_.Style();
  PhysicalRect legend_border_box;
  if (legend) {
    legend_border_box.size = (*legend)->Size();
    // Unapply relative position of the legend.
    // Note that legend->Offset() is the offset after applying
    // position:relative, but the fieldset border painting needs to avoid
    // the legend position with static position.
    //
    // See https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements
    // > * If the element has a rendered legend, then the border is expected to
    // >   not be painted behind the rectangle defined as follows, using the
    // >   writing mode of the fieldset: ...
    // >    ... at its static position (ignoring transforms), ...
    //
    // The following logic produces wrong results for block direction offsets.
    // However we don't need them.
    const WritingDirectionMode writing_direction = style.GetWritingDirection();
    const LogicalSize logical_fieldset_content_size =
        (fieldset_size - PhysicalSize(fieldset_borders.Size()) -
         PhysicalSize(fragment.Padding().HorizontalSum(),
                      fragment.Padding().VerticalSum()))
            .ConvertToLogical(writing_direction.GetWritingMode());
    LogicalOffset relative_offset = ComputeRelativeOffset(
        (*legend)->Style(), writing_direction, logical_fieldset_content_size);
    LogicalOffset legend_logical_offset =
        legend->Offset().ConvertToLogical(writing_direction, fieldset_size,
                                          (*legend)->Size()) -
        relative_offset;
    legend_border_box.offset = legend_logical_offset.ConvertToPhysical(
        writing_direction, fieldset_size, legend_border_box.size);
  }
  return FieldsetPaintInfo(style, fieldset_size, fieldset_borders,
                           legend_border_box);
}

// Paint the fieldset (background, other decorations, and) border, with the
// cutout hole for the legend.
void NGFieldsetPainter::PaintBoxDecorationBackground(
    const PaintInfo& paint_info,
    const PhysicalOffset& paint_offset) {
  GraphicsContext& graphics_context = paint_info.context;
  PhysicalSize fieldset_size(fieldset_.Size());
  PhysicalRect paint_rect(paint_offset, fieldset_size);
  BoxDecorationData box_decoration_data(paint_info, fieldset_);
  // TODO(crbug.com/786475): Fieldset should not scroll.
  DCHECK(!box_decoration_data.IsPaintingScrollingBackground());
  if (!box_decoration_data.ShouldPaint())
    return;

  if (DrawingRecorder::UseCachedDrawingIfPossible(
          graphics_context, *fieldset_.GetLayoutObject(), paint_info.phase))
    return;

  const ComputedStyle& style = fieldset_.Style();
  FieldsetPaintInfo fieldset_paint_info = CreateFieldsetPaintInfo();
  PhysicalRect contracted_rect(paint_rect);
  contracted_rect.Contract(fieldset_paint_info.border_outsets);

  DrawingRecorder recorder(
      graphics_context, *fieldset_.GetLayoutObject(), paint_info.phase,
      NGBoxFragmentPainter(fieldset_).VisualRect(paint_offset));

  NGBoxFragmentPainter fragment_painter(fieldset_);
  if (box_decoration_data.ShouldPaintShadow()) {
    fragment_painter.PaintNormalBoxShadow(paint_info, contracted_rect, style);
  }

  GraphicsContextStateSaver state_saver(graphics_context, false);
  bool needs_end_layer = false;
  if (BleedAvoidanceIsClipping(
          box_decoration_data.GetBackgroundBleedAvoidance())) {
    state_saver.Save();
    FloatRoundedRect border = RoundedBorderGeometry::PixelSnappedRoundedBorder(
        style, contracted_rect, fieldset_.SidesToInclude());
    graphics_context.ClipRoundedRect(border);

    if (box_decoration_data.GetBackgroundBleedAvoidance() ==
        kBackgroundBleedClipLayer) {
      graphics_context.BeginLayer();
      needs_end_layer = true;
    }
  }

  if (box_decoration_data.ShouldPaintBackground()) {
    // TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
    BackgroundImageGeometry geometry(
        *static_cast<const LayoutBoxModelObject*>(fieldset_.GetLayoutObject()));
    fragment_painter.PaintFillLayers(
        paint_info, box_decoration_data.BackgroundColor(),
        style.BackgroundLayers(), contracted_rect, geometry);
  }
  if (box_decoration_data.ShouldPaintShadow()) {
    fragment_painter.PaintInsetBoxShadowWithBorderRect(
        paint_info, contracted_rect, fieldset_.Style());
  }
  if (box_decoration_data.ShouldPaintBorder()) {
    // Create a clipping region around the legend and paint the border as
    // normal.
    PhysicalRect legend_cutout_rect = fieldset_paint_info.legend_cutout_rect;
    legend_cutout_rect.Move(paint_rect.offset);
    graphics_context.ClipOut(PixelSnappedIntRect(legend_cutout_rect));

    const LayoutObject* layout_object = fieldset_.GetLayoutObject();
    Node* node = layout_object->GeneratingNode();
    fragment_painter.PaintBorder(
        *fieldset_.GetLayoutObject(), layout_object->GetDocument(), node,
        paint_info, contracted_rect, fieldset_.Style(),
        box_decoration_data.GetBackgroundBleedAvoidance(),
        fieldset_.SidesToInclude());
  }

  if (needs_end_layer)
    graphics_context.EndLayer();
}

void NGFieldsetPainter::PaintMask(const PaintInfo& paint_info,
                                  const PhysicalOffset& paint_offset) {
  // TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
  const LayoutObject& layout_object = *fieldset_.GetLayoutObject();
  BackgroundImageGeometry geometry(
      static_cast<const LayoutBoxModelObject&>(layout_object));

  NGBoxFragmentPainter ng_box_painter(fieldset_);
  DrawingRecorder recorder(paint_info.context, layout_object, paint_info.phase,
                           ng_box_painter.VisualRect(paint_offset));
  PhysicalRect paint_rect(paint_offset, fieldset_.Size());
  paint_rect.Contract(CreateFieldsetPaintInfo().border_outsets);
  ng_box_painter.PaintMaskImages(paint_info, paint_rect, layout_object,
                                 geometry, fieldset_.SidesToInclude());
}

}  // namespace blink
