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

#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/line/root_inline_box.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/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect_outsets.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"

namespace blink {

namespace {

Node* GeneratingNodeForObject(const LayoutBoxModelObject& box_model) {
  Node* node = nullptr;
  const LayoutObject* layout_object = &box_model;
  for (; layout_object && !node; layout_object = layout_object->Parent()) {
    node = layout_object->GeneratingNode();
  }
  return node;
}

LayoutSize LogicalOffsetOnLine(const InlineFlowBox& flow_box) {
  // Compute the offset of the passed flow box when seen as part of an
  // unbroken continuous strip (c.f box-decoration-break: slice.)
  LayoutUnit logical_offset_on_line;
  if (flow_box.IsLeftToRightDirection()) {
    for (const InlineFlowBox* curr = flow_box.PrevForSameLayoutObject(); curr;
         curr = curr->PrevForSameLayoutObject())
      logical_offset_on_line += curr->LogicalWidth();
  } else {
    for (const InlineFlowBox* curr = flow_box.NextForSameLayoutObject(); curr;
         curr = curr->NextForSameLayoutObject())
      logical_offset_on_line += curr->LogicalWidth();
  }
  LayoutSize logical_offset(logical_offset_on_line, LayoutUnit());
  return flow_box.IsHorizontal() ? logical_offset
                                 : logical_offset.TransposedSize();
}

}  // anonymous namespace

BoxModelObjectPainter::BoxModelObjectPainter(const LayoutBoxModelObject& box,
                                             const InlineFlowBox* flow_box)
    : BoxPainterBase(&box.GetDocument(),
                     box.StyleRef(),
                     GeneratingNodeForObject(box)),
      box_model_(box),
      flow_box_(flow_box) {}

void BoxModelObjectPainter::PaintTextClipMask(
    GraphicsContext& context,
    const IntRect& mask_rect,
    const PhysicalOffset& paint_offset,
    bool object_has_multiple_boxes) {
  PaintInfo paint_info(context, CullRect(mask_rect), PaintPhase::kTextClip,
                       kGlobalPaintNormalPhase, 0);
  if (flow_box_) {
    LayoutSize local_offset = ToLayoutSize(flow_box_->Location());
    if (object_has_multiple_boxes &&
        box_model_.StyleRef().BoxDecorationBreak() ==
            EBoxDecorationBreak::kSlice) {
      local_offset -= LogicalOffsetOnLine(*flow_box_);
    }
    // TODO(layout-ng): This looks incorrect in flipped writing mode.
    PhysicalOffset physical_local_offset(local_offset.Width(),
                                         local_offset.Height());
    const RootInlineBox& root = flow_box_->Root();
    flow_box_->Paint(paint_info, paint_offset - physical_local_offset,
                     root.LineTop(), root.LineBottom());
  } else if (auto* layout_block = DynamicTo<LayoutBlock>(box_model_)) {
    layout_block->PaintObject(paint_info, paint_offset);
  } else {
    // We should go through the above path for LayoutInlines.
    DCHECK(!box_model_.IsLayoutInline());
    // Other types of objects don't have anything meaningful to paint for text
    // clip mask.
  }
}

PhysicalRect BoxModelObjectPainter::AdjustRectForScrolledContent(
    const PaintInfo& paint_info,
    const BoxPainterBase::FillLayerInfo& info,
    const PhysicalRect& rect) {
  if (!info.is_clipped_with_local_scrolling)
    return rect;

  const auto& this_box = To<LayoutBox>(box_model_);
  if (BoxDecorationData::IsPaintingScrollingBackground(paint_info, this_box))
    return rect;

  PhysicalRect scrolled_paint_rect = rect;
  GraphicsContext& context = paint_info.context;
  // Clip to the overflow area.
  // TODO(chrishtr): this should be pixel-snapped.
  context.Clip(FloatRect(this_box.OverflowClipRect(rect.offset)));

  // Adjust the paint rect to reflect a scrolled content box with borders at
  // the ends.
  PhysicalOffset offset(this_box.PixelSnappedScrolledContentOffset());
  scrolled_paint_rect.Move(-offset);
  LayoutRectOutsets border = AdjustedBorderOutsets(info);
  scrolled_paint_rect.SetWidth(border.Left() + this_box.ScrollWidth() +
                               border.Right());
  scrolled_paint_rect.SetHeight(this_box.BorderTop() + this_box.ScrollHeight() +
                                this_box.BorderBottom());
  return scrolled_paint_rect;
}

LayoutRectOutsets BoxModelObjectPainter::ComputeBorders() const {
  return box_model_.BorderBoxOutsets();
}

LayoutRectOutsets BoxModelObjectPainter::ComputePadding() const {
  return box_model_.PaddingOutsets();
}

BoxPainterBase::FillLayerInfo BoxModelObjectPainter::GetFillLayerInfo(
    const Color& color,
    const FillLayer& bg_layer,
    BackgroundBleedAvoidance bleed_avoidance,
    bool is_painting_scrolling_background) const {
  PhysicalBoxSides sides_to_include;
  if (flow_box_)
    sides_to_include = flow_box_->SidesToInclude();
  RespectImageOrientationEnum respect_orientation =
      LayoutObject::ShouldRespectImageOrientation(&box_model_);
  if (auto* style_image = bg_layer.GetImage()) {
    respect_orientation =
        style_image->ForceOrientationIfNecessary(respect_orientation);
  }
  return BoxPainterBase::FillLayerInfo(
      box_model_.GetDocument(), box_model_.StyleRef(),
      box_model_.IsScrollContainer(), color, bg_layer, bleed_avoidance,
      respect_orientation, sides_to_include, box_model_.IsLayoutInline(),
      is_painting_scrolling_background);
}

bool BoxModelObjectPainter::IsPaintingScrollingBackground(
    const PaintInfo& paint_info) const {
  if (!box_model_.IsBox())
    return false;

  const auto& this_box = To<LayoutBox>(box_model_);
  return BoxDecorationData::IsPaintingScrollingBackground(paint_info, this_box);
}

}  // namespace blink
