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

#include "base/optional.h"
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_container.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.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/scoped_svg_paint_state.h"
#include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h"
#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"

namespace blink {

void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
  // Spec: groups w/o children still may render filter content.
  if (!layout_svg_container_.FirstChild() &&
      !layout_svg_container_.SelfWillPaint())
    return;

  // Spec: An empty viewBox on the <svg> element disables rendering.
  DCHECK(layout_svg_container_.GetElement());
  auto* svg_svg_element =
      DynamicTo<SVGSVGElement>(*layout_svg_container_.GetElement());
  if (svg_svg_element && svg_svg_element->HasEmptyViewBox())
    return;

  if (SVGModelObjectPainter(layout_svg_container_)
          .CullRectSkipsPainting(paint_info)) {
    return;
  }

  // We do not apply cull rect optimizations across transforms for two reasons:
  //   1) Performance: We can optimize transform changes by not repainting.
  //   2) Complexity: Difficulty updating clips when ancestor transforms change.
  // This is why we use an infinite cull rect if there is a transform. Non-svg
  // content, does this in PaintLayerPainter::PaintSingleFragment.
  PaintInfo paint_info_before_filtering(paint_info);
  if (layout_svg_container_.StyleRef().HasTransform()) {
    paint_info_before_filtering.ApplyInfiniteCullRect();
  } else if (const auto* properties =
                 layout_svg_container_.FirstFragment().PaintProperties()) {
    if (const auto* transform = properties->Transform())
      paint_info_before_filtering.TransformCullRect(*transform);
  }

  ScopedSVGTransformState transform_state(
      paint_info_before_filtering, layout_svg_container_,
      layout_svg_container_.LocalToSVGParentTransform());
  {
    base::Optional<ScopedPaintChunkProperties> scoped_paint_chunk_properties;
    if (layout_svg_container_.IsSVGViewportContainer() &&
        SVGLayoutSupport::IsOverflowHidden(layout_svg_container_)) {
      const auto* fragment =
          paint_info_before_filtering.FragmentToPaint(layout_svg_container_);
      if (!fragment)
        return;
      const auto* properties = fragment->PaintProperties();
      // TODO(crbug.com/814815): The condition should be a DCHECK, but for now
      // we may paint the object for filters during PrePaint before the
      // properties are ready.
      if (properties && properties->OverflowClip()) {
        scoped_paint_chunk_properties.emplace(
            paint_info_before_filtering.context.GetPaintController(),
            *properties->OverflowClip(), layout_svg_container_,
            paint_info_before_filtering.DisplayItemTypeForClipping());
      }
    }

    ScopedSVGPaintState paint_state(layout_svg_container_,
                                    paint_info_before_filtering);
    bool continue_rendering = true;
    if (paint_state.GetPaintInfo().phase == PaintPhase::kForeground)
      continue_rendering = paint_state.ApplyEffects();

    if (continue_rendering) {
      for (LayoutObject* child = layout_svg_container_.FirstChild(); child;
           child = child->NextSibling()) {
        if (auto* foreign_object = DynamicTo<LayoutSVGForeignObject>(*child)) {
          SVGForeignObjectPainter(*foreign_object)
              .PaintLayer(paint_state.GetPaintInfo());
        } else {
          child->Paint(paint_state.GetPaintInfo());
        }
      }
    }
  }

  SVGModelObjectPainter(layout_svg_container_)
      .PaintOutline(paint_info_before_filtering);

  if (paint_info_before_filtering.ShouldAddUrlMetadata() &&
      paint_info_before_filtering.phase == PaintPhase::kForeground) {
    ObjectPainter(layout_svg_container_)
        .AddURLRectIfNeeded(paint_info_before_filtering, PhysicalOffset());
  }
}

}  // namespace blink
