// 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/box_painter.h"

#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/background_bleed_avoidance.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.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_base.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/nine_piece_image_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/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/scoped_paint_state.h"
#include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h"
#include "third_party/blink/renderer/core/paint/theme_painter.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/geometry/length_functions.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/hit_test_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h"

namespace blink {

void BoxPainter::Paint(const PaintInfo& paint_info) {
  // Default implementation. Just pass paint through to the children.
  ScopedPaintState paint_state(layout_box_, paint_info);
  PaintChildren(paint_state.GetPaintInfo());
}

void BoxPainter::PaintChildren(const PaintInfo& paint_info) {
  PaintInfo child_info(paint_info);
  for (LayoutObject* child = layout_box_.SlowFirstChild(); child;
       child = child->NextSibling()) {
    if (child->IsSVGForeignObject()) {
      SVGForeignObjectPainter(ToLayoutSVGForeignObject(*child))
          .PaintLayer(paint_info);
    } else {
      child->Paint(child_info);
    }
  }
}

void BoxPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info,
                                              const LayoutPoint& paint_offset) {
  LayoutRect paint_rect;
  const DisplayItemClient* background_client = nullptr;
  base::Optional<ScopedBoxContentsPaintState> contents_paint_state;
  if (BoxModelObjectPainter::IsPaintingScrollingBackground(&layout_box_,
                                                           paint_info)) {
    // For the case where we are painting the background into the scrolling
    // contents layer of a composited scroller we need to include the entire
    // overflow rect.
    paint_rect = layout_box_.PhysicalLayoutOverflowRect();
    contents_paint_state.emplace(paint_info, paint_offset, layout_box_);
    paint_rect.MoveBy(contents_paint_state->PaintOffset());

    // The background painting code assumes that the borders are part of the
    // paint_rect so we expand the paint_rect by the border size when painting
    // the background into the scrolling contents layer.
    paint_rect.Expand(layout_box_.BorderBoxOutsets());

    background_client = &layout_box_.GetScrollableArea()
                             ->GetScrollingBackgroundDisplayItemClient();
  } else {
    paint_rect = layout_box_.BorderBoxRect();
    paint_rect.MoveBy(paint_offset);
    background_client = &layout_box_;
  }

  // Paint the background if we're visible and this block has a box decoration
  // (background, border, appearance, or box shadow).
  const ComputedStyle& style = layout_box_.StyleRef();
  if (style.Visibility() == EVisibility::kVisible &&
      layout_box_.HasBoxDecorationBackground()) {
    PaintBoxDecorationBackgroundWithRect(
        contents_paint_state ? contents_paint_state->GetPaintInfo()
                             : paint_info,
        paint_rect, *background_client);
  }

  if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    RecordHitTestData(paint_info, paint_rect, *background_client);
}

bool BoxPainter::BackgroundIsKnownToBeOpaque(const PaintInfo& paint_info) {
  LayoutRect bounds = BoxModelObjectPainter::IsPaintingScrollingBackground(
                          &layout_box_, paint_info)
                          ? layout_box_.LayoutOverflowRect()
                          : layout_box_.SelfVisualOverflowRect();
  return layout_box_.BackgroundIsKnownToBeOpaqueInRect(bounds);
}

void BoxPainter::PaintBoxDecorationBackgroundWithRect(
    const PaintInfo& paint_info,
    const LayoutRect& paint_rect,
    const DisplayItemClient& background_client) {
  bool painting_scrolling_background =
      BoxModelObjectPainter::IsPaintingScrollingBackground(&layout_box_,
                                                           paint_info);
  const ComputedStyle& style = layout_box_.StyleRef();

  base::Optional<DisplayItemCacheSkipper> cache_skipper;
  // Disable cache in under-invalidation checking mode for MediaSliderPart
  // because we always paint using the latest data (buffered ranges, current
  // time and duration) which may be different from the cached data, and for
  // delayed-invalidation object because it may change before it's actually
  // invalidated. Note that we still report harmless under-invalidation of
  // non-delayed-invalidation animated background, which should be ignored.
  if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() &&
      (style.Appearance() == kMediaSliderPart ||
       layout_box_.ShouldDelayFullPaintInvalidation())) {
    cache_skipper.emplace(paint_info.context);
  }

  if (DrawingRecorder::UseCachedDrawingIfPossible(
          paint_info.context, background_client,
          DisplayItem::kBoxDecorationBackground))
    return;

  DrawingRecorder recorder(paint_info.context, background_client,
                           DisplayItem::kBoxDecorationBackground);
  BoxDecorationData box_decoration_data(layout_box_);
  GraphicsContextStateSaver state_saver(paint_info.context, false);

  if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
      LayoutRect(EnclosingIntRect(paint_rect)) == paint_rect &&
      BackgroundIsKnownToBeOpaque(paint_info))
    recorder.SetKnownToBeOpaque();

  const auto skip_background = layout_box_.BackgroundTransfersToView() ||
                               (paint_info.SkipRootBackground() &&
                                paint_info.PaintContainer() == &layout_box_);

  bool needs_end_layer = false;
  if (!painting_scrolling_background) {
    // FIXME: Should eventually give the theme control over whether the box
    // shadow should paint, since controls could have custom shadows of their
    // own.
    BoxPainterBase::PaintNormalBoxShadow(paint_info, paint_rect, style, true,
                                         true, skip_background);

    if (BleedAvoidanceIsClipping(box_decoration_data.bleed_avoidance)) {
      state_saver.Save();
      FloatRoundedRect border = style.GetRoundedBorderFor(paint_rect);
      paint_info.context.ClipRoundedRect(border);

      if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer) {
        paint_info.context.BeginLayer();
        needs_end_layer = true;
      }
    }
  }

  // If we have a native theme appearance, paint that before painting our
  // background.  The theme will tell us whether or not we should also paint the
  // CSS background.
  IntRect snapped_paint_rect(PixelSnappedIntRect(paint_rect));
  ThemePainter& theme_painter = LayoutTheme::GetTheme().Painter();
  bool theme_painted =
      box_decoration_data.has_appearance &&
      !theme_painter.Paint(layout_box_, paint_info, snapped_paint_rect);
  if (!theme_painted && !skip_background) {
    PaintBackground(paint_info, paint_rect,
                    box_decoration_data.background_color,
                    box_decoration_data.bleed_avoidance);

    if (box_decoration_data.has_appearance) {
      theme_painter.PaintDecorations(layout_box_.GetNode(),
                                     layout_box_.GetDocument(), style,
                                     paint_info, snapped_paint_rect);
    }
  }

  if (!painting_scrolling_background) {
    BoxPainterBase::PaintInsetBoxShadowWithBorderRect(paint_info, paint_rect,
                                                      style);

    // The theme will tell us whether or not we should also paint the CSS
    // border.
    if (box_decoration_data.has_border_decoration &&
        (!box_decoration_data.has_appearance ||
         (!theme_painted &&
          LayoutTheme::GetTheme().Painter().PaintBorderOnly(
              layout_box_.GetNode(), style, paint_info, snapped_paint_rect))) &&
        !(layout_box_.IsTable() &&
          ToLayoutTable(&layout_box_)->ShouldCollapseBorders())) {
      BoxPainterBase::PaintBorder(
          layout_box_, layout_box_.GetDocument(), layout_box_.GeneratingNode(),
          paint_info, paint_rect, style, box_decoration_data.bleed_avoidance);
    }
  }

  if (needs_end_layer)
    paint_info.context.EndLayer();
}

void BoxPainter::PaintBackground(const PaintInfo& paint_info,
                                 const LayoutRect& paint_rect,
                                 const Color& background_color,
                                 BackgroundBleedAvoidance bleed_avoidance) {
  if (layout_box_.BackgroundTransfersToView())
    return;
  if (layout_box_.BackgroundIsKnownToBeObscured())
    return;
  BackgroundImageGeometry geometry(layout_box_);
  BoxModelObjectPainter box_model_painter(layout_box_);
  box_model_painter.PaintFillLayers(paint_info, background_color,
                                    layout_box_.StyleRef().BackgroundLayers(),
                                    paint_rect, geometry, bleed_avoidance);
}

void BoxPainter::PaintMask(const PaintInfo& paint_info,
                           const LayoutPoint& paint_offset) {
  DCHECK_EQ(PaintPhase::kMask, paint_info.phase);

  if (!layout_box_.HasMask() ||
      layout_box_.StyleRef().Visibility() != EVisibility::kVisible)
    return;

  if (DrawingRecorder::UseCachedDrawingIfPossible(
          paint_info.context, layout_box_, paint_info.phase))
    return;

  DrawingRecorder recorder(paint_info.context, layout_box_, paint_info.phase);
  LayoutRect paint_rect = LayoutRect(paint_offset, layout_box_.Size());
  PaintMaskImages(paint_info, paint_rect);
}

void BoxPainter::PaintMaskImages(const PaintInfo& paint_info,
                                 const LayoutRect& paint_rect) {
  // For mask images legacy layout painting handles multi-line boxes by giving
  // the full width of the element, not the current line box, thereby clipping
  // the offending edges.
  bool include_logical_left_edge = true;
  bool include_logical_right_edge = true;

  BackgroundImageGeometry geometry(layout_box_);
  BoxModelObjectPainter painter(layout_box_);
  painter.PaintMaskImages(paint_info, paint_rect, layout_box_, geometry,
                          include_logical_left_edge,
                          include_logical_right_edge);
}

void BoxPainter::RecordHitTestData(const PaintInfo& paint_info,
                                   const LayoutRect& paint_rect,
                                   const DisplayItemClient& background_client) {
  // Hit test display items are only needed for compositing. This flag is used
  // for for printing and drag images which do not need hit testing.
  if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
    return;

  // If an object is not visible, it does not participate in hit testing.
  if (layout_box_.StyleRef().Visibility() != EVisibility::kVisible)
    return;

  auto touch_action = layout_box_.EffectiveWhitelistedTouchAction();
  if (touch_action == TouchAction::kTouchActionAuto)
    return;

  HitTestDisplayItem::Record(paint_info.context, background_client,
                             HitTestRect(paint_rect, touch_action));
}

}  // namespace blink
