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

#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_shape.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/layout/svg/svg_marker_data.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/paint/scoped_svg_paint_state.h"
#include "third_party/blink/renderer/core/paint/svg_container_painter.h"
#include "third_party/blink/renderer/core/paint/svg_model_object_painter.h"
#include "third_party/blink/renderer/core/paint/svg_object_painter.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"

namespace blink {

static base::Optional<AffineTransform> SetupNonScalingStrokeContext(
    const LayoutSVGShape& layout_svg_shape,
    GraphicsContextStateSaver& state_saver) {
  const AffineTransform& non_scaling_stroke_transform =
      layout_svg_shape.NonScalingStrokeTransform();
  if (!non_scaling_stroke_transform.IsInvertible())
    return base::nullopt;
  state_saver.Save();
  state_saver.Context().ConcatCTM(non_scaling_stroke_transform.Inverse());
  return non_scaling_stroke_transform;
}

static SkPathFillType FillRuleFromStyle(const PaintInfo& paint_info,
                                        const ComputedStyle& style) {
  return WebCoreWindRuleToSkFillType(paint_info.IsRenderingClipPathAsMaskImage()
                                         ? style.ClipRule()
                                         : style.FillRule());
}

void SVGShapePainter::Paint(const PaintInfo& paint_info) {
  if (paint_info.phase != PaintPhase::kForeground ||
      layout_svg_shape_.StyleRef().Visibility() != EVisibility::kVisible ||
      layout_svg_shape_.IsShapeEmpty())
    return;

  if (SVGModelObjectPainter::CanUseCullRect(layout_svg_shape_.StyleRef())) {
    if (!paint_info.GetCullRect().IntersectsTransformed(
            layout_svg_shape_.LocalSVGTransform(),
            layout_svg_shape_.VisualRectInLocalSVGCoordinates()))
      return;
  }
  // Shapes cannot have children so do not call TransformCullRect.

  ScopedSVGTransformState transform_state(paint_info, layout_svg_shape_);
  {
    ScopedSVGPaintState paint_state(layout_svg_shape_, paint_info);
    SVGModelObjectPainter::RecordHitTestData(layout_svg_shape_, paint_info);
    if (!DrawingRecorder::UseCachedDrawingIfPossible(
            paint_info.context, layout_svg_shape_, paint_info.phase)) {
      SVGDrawingRecorder recorder(paint_info.context, layout_svg_shape_,
                                  paint_info.phase);
      const ComputedStyle& style = layout_svg_shape_.StyleRef();

      bool should_anti_alias =
          style.ShapeRendering() != EShapeRendering::kCrispedges &&
          style.ShapeRendering() != EShapeRendering::kOptimizespeed;

      for (int i = 0; i < 3; i++) {
        switch (style.PaintOrderType(i)) {
          case PT_FILL: {
            PaintFlags fill_flags;
            if (!SVGObjectPainter(layout_svg_shape_)
                     .PreparePaint(paint_info, style, kApplyToFillMode,
                                   fill_flags))
              break;
            fill_flags.setAntiAlias(should_anti_alias);
            FillShape(paint_info.context, fill_flags,
                      FillRuleFromStyle(paint_info, style));
            break;
          }
          case PT_STROKE:
            if (style.HasVisibleStroke()) {
              GraphicsContextStateSaver state_saver(paint_info.context, false);
              base::Optional<AffineTransform> non_scaling_transform;

              if (layout_svg_shape_.HasNonScalingStroke()) {
                // Non-scaling stroke needs to reset the transform back to the
                // host transform.
                non_scaling_transform = SetupNonScalingStrokeContext(
                    layout_svg_shape_, state_saver);
                if (!non_scaling_transform)
                  return;
              }

              PaintFlags stroke_flags;
              if (!SVGObjectPainter(layout_svg_shape_)
                       .PreparePaint(
                           paint_info, style, kApplyToStrokeMode, stroke_flags,
                           base::OptionalOrNullptr(non_scaling_transform)))
                break;
              stroke_flags.setAntiAlias(should_anti_alias);

              StrokeData stroke_data;
              SVGLayoutSupport::ApplyStrokeStyleToStrokeData(
                  stroke_data, style, layout_svg_shape_,
                  layout_svg_shape_.DashScaleFactor());
              stroke_data.SetupPaint(&stroke_flags);

              StrokeShape(paint_info.context, stroke_flags);
            }
            break;
          case PT_MARKERS:
            PaintMarkers(paint_info);
            break;
          default:
            NOTREACHED();
            break;
        }
      }
    }
  }

  SVGModelObjectPainter(layout_svg_shape_).PaintOutline(paint_info);
}

class PathWithTemporaryWindingRule {
 public:
  PathWithTemporaryWindingRule(Path& path, SkPathFillType fill_type)
      : path_(const_cast<SkPath&>(path.GetSkPath())) {
    saved_fill_type_ = path_.getFillType();
    path_.setFillType(fill_type);
  }
  ~PathWithTemporaryWindingRule() { path_.setFillType(saved_fill_type_); }

  const SkPath& GetSkPath() const { return path_; }

 private:
  SkPath& path_;
  SkPathFillType saved_fill_type_;
};

void SVGShapePainter::FillShape(GraphicsContext& context,
                                const PaintFlags& flags,
                                SkPathFillType fill_type) {
  switch (layout_svg_shape_.GeometryCodePath()) {
    case kRectGeometryFastPath:
      context.DrawRect(layout_svg_shape_.ObjectBoundingBox(), flags,
                       DarkModeFilter::ElementRole::kSVG);
      break;
    case kEllipseGeometryFastPath:
      context.DrawOval(layout_svg_shape_.ObjectBoundingBox(), flags,
                       DarkModeFilter::ElementRole::kSVG);
      break;
    default: {
      PathWithTemporaryWindingRule path_with_winding(
          layout_svg_shape_.GetPath(), fill_type);
      context.DrawPath(path_with_winding.GetSkPath(), flags,
                       DarkModeFilter::ElementRole::kSVG);
    }
  }
  PaintTiming& timing = PaintTiming::From(
      layout_svg_shape_.GetElement()->GetDocument().TopDocument());
  timing.MarkFirstContentfulPaint();
}

void SVGShapePainter::StrokeShape(GraphicsContext& context,
                                  const PaintFlags& flags) {
  DCHECK(layout_svg_shape_.StyleRef().HasVisibleStroke());

  switch (layout_svg_shape_.GeometryCodePath()) {
    case kRectGeometryFastPath:
      context.DrawRect(layout_svg_shape_.ObjectBoundingBox(), flags,
                       DarkModeFilter::ElementRole::kSVG);
      break;
    case kEllipseGeometryFastPath:
      context.DrawOval(layout_svg_shape_.ObjectBoundingBox(), flags,
                       DarkModeFilter::ElementRole::kSVG);
      break;
    default:
      DCHECK(layout_svg_shape_.HasPath());
      const Path* use_path = &layout_svg_shape_.GetPath();
      if (layout_svg_shape_.HasNonScalingStroke())
        use_path = &layout_svg_shape_.NonScalingStrokePath();
      context.DrawPath(use_path->GetSkPath(), flags,
                       DarkModeFilter::ElementRole::kSVG);
  }
  PaintTiming& timing = PaintTiming::From(
      layout_svg_shape_.GetElement()->GetDocument().TopDocument());
  timing.MarkFirstContentfulPaint();
}

void SVGShapePainter::PaintMarkers(const PaintInfo& paint_info) {
  const Vector<MarkerPosition>* marker_positions =
      layout_svg_shape_.MarkerPositions();
  if (!marker_positions || marker_positions->IsEmpty())
    return;
  SVGResourceClient* client = SVGResources::GetClient(layout_svg_shape_);
  const ComputedStyle& style = layout_svg_shape_.StyleRef();
  auto* marker_start = GetSVGResourceAsType<LayoutSVGResourceMarker>(
      *client, style.MarkerStartResource());
  auto* marker_mid = GetSVGResourceAsType<LayoutSVGResourceMarker>(
      *client, style.MarkerMidResource());
  auto* marker_end = GetSVGResourceAsType<LayoutSVGResourceMarker>(
      *client, style.MarkerEndResource());
  if (!marker_start && !marker_mid && !marker_end)
    return;

  const float stroke_width = layout_svg_shape_.StrokeWidthForMarkerUnits();

  for (const MarkerPosition& marker_position : *marker_positions) {
    if (LayoutSVGResourceMarker* marker = marker_position.SelectMarker(
            marker_start, marker_mid, marker_end)) {
      PaintMarker(paint_info, *marker, marker_position, stroke_width);
    }
  }
}

void SVGShapePainter::PaintMarker(const PaintInfo& paint_info,
                                  LayoutSVGResourceMarker& marker,
                                  const MarkerPosition& position,
                                  float stroke_width) {
  marker.ClearInvalidationMask();

  if (!marker.ShouldPaint())
    return;

  AffineTransform transform =
      marker.MarkerTransformation(position, stroke_width);

  cc::PaintCanvas* canvas = paint_info.context.Canvas();

  canvas->save();
  canvas->concat(AffineTransformToSkMatrix(transform));
  if (SVGLayoutSupport::IsOverflowHidden(marker))
    canvas->clipRect(marker.Viewport());

  PaintRecordBuilder builder(paint_info.context);
  PaintInfo marker_paint_info(builder.Context(), paint_info);
  // It's expensive to track the transformed paint cull rect for each
  // marker so just disable culling. The shape paint call will already
  // be culled if it is outside the paint info cull rect.
  marker_paint_info.ApplyInfiniteCullRect();

  SVGContainerPainter(marker).Paint(marker_paint_info);
  builder.EndRecording(*canvas);

  canvas->restore();
}

}  // namespace blink
