// 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 "base/optional.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/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/core/paint/paint_info.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_paint_context.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 bool SetupNonScalingStrokeContext(
    AffineTransform& stroke_transform,
    GraphicsContextStateSaver& state_saver) {
  if (!stroke_transform.IsInvertible())
    return false;

  state_saver.Save();
  state_saver.Context().ConcatCTM(stroke_transform.Inverse());
  return true;
}

static SkPath::FillType FillRuleFromStyle(const PaintInfo& paint_info,
                                          const SVGComputedStyle& svg_style) {
  return WebCoreWindRuleToSkFillType(paint_info.IsRenderingClipPathAsMaskImage()
                                         ? svg_style.ClipRule()
                                         : svg_style.FillRule());
}

void SVGShapePainter::RecordHitTestData(const PaintInfo& paint_info) {
  // 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;

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

  auto rect = LayoutRect(layout_svg_shape_.VisualRectInLocalSVGCoordinates());
  HitTestData::RecordTouchActionRect(paint_info.context, layout_svg_shape_,
                                     TouchActionRect(rect, touch_action));
}

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;

  PaintInfo paint_info_before_filtering(paint_info);

  if (SVGModelObjectPainter(layout_svg_shape_)
          .CullRectSkipsPainting(paint_info_before_filtering)) {
    return;
  }
  // Shapes cannot have children so do not call UpdateCullRect.

  SVGTransformContext transform_context(paint_info_before_filtering,
                                        layout_svg_shape_,
                                        layout_svg_shape_.LocalSVGTransform());
  {
    SVGPaintContext paint_context(layout_svg_shape_,
                                  paint_info_before_filtering);
    if (paint_context.ApplyClipMaskAndFilterIfNecessary() &&
        !DrawingRecorder::UseCachedDrawingIfPossible(
            paint_context.GetPaintInfo().context, layout_svg_shape_,
            paint_context.GetPaintInfo().phase)) {
      if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
        RecordHitTestData(paint_info);
      DrawingRecorder recorder(paint_context.GetPaintInfo().context,
                               layout_svg_shape_,
                               paint_context.GetPaintInfo().phase);
      const SVGComputedStyle& svg_style =
          layout_svg_shape_.StyleRef().SvgStyle();

      bool should_anti_alias = svg_style.ShapeRendering() != SR_CRISPEDGES &&
                               svg_style.ShapeRendering() != SR_OPTIMIZESPEED;

      for (int i = 0; i < 3; i++) {
        switch (svg_style.PaintOrderType(i)) {
          case PT_FILL: {
            PaintFlags fill_flags;
            if (!SVGPaintContext::PaintForLayoutObject(
                    paint_context.GetPaintInfo(), layout_svg_shape_.StyleRef(),
                    layout_svg_shape_, kApplyToFillMode, fill_flags))
              break;
            fill_flags.setAntiAlias(should_anti_alias);
            FillShape(
                paint_context.GetPaintInfo().context, fill_flags,
                FillRuleFromStyle(paint_context.GetPaintInfo(), svg_style));
            break;
          }
          case PT_STROKE:
            if (svg_style.HasVisibleStroke()) {
              GraphicsContextStateSaver state_saver(
                  paint_context.GetPaintInfo().context, false);
              AffineTransform non_scaling_transform;
              const AffineTransform* additional_paint_server_transform =
                  nullptr;

              if (layout_svg_shape_.HasNonScalingStroke()) {
                non_scaling_transform =
                    layout_svg_shape_.NonScalingStrokeTransform();
                if (!SetupNonScalingStrokeContext(non_scaling_transform,
                                                  state_saver))
                  return;

                // Non-scaling stroke needs to reset the transform back to the
                // host transform.
                additional_paint_server_transform = &non_scaling_transform;
              }

              PaintFlags stroke_flags;
              if (!SVGPaintContext::PaintForLayoutObject(
                      paint_context.GetPaintInfo(),
                      layout_svg_shape_.StyleRef(), layout_svg_shape_,
                      kApplyToStrokeMode, stroke_flags,
                      additional_paint_server_transform))
                break;
              stroke_flags.setAntiAlias(should_anti_alias);

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

              StrokeShape(paint_context.GetPaintInfo().context, stroke_flags);
            }
            break;
          case PT_MARKERS:
            PaintMarkers(paint_context.GetPaintInfo(),
                         layout_svg_shape_.VisualRectInLocalSVGCoordinates());
            break;
          default:
            NOTREACHED();
            break;
        }
      }
    }
  }

  SVGModelObjectPainter(layout_svg_shape_)
      .PaintOutline(paint_info_before_filtering);
}

class PathWithTemporaryWindingRule {
 public:
  PathWithTemporaryWindingRule(Path& path, SkPath::FillType 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_;
  SkPath::FillType saved_fill_type_;
};

void SVGShapePainter::FillShape(GraphicsContext& context,
                                const PaintFlags& flags,
                                SkPath::FillType fill_type) {
  switch (layout_svg_shape_.GeometryCodePath()) {
    case kRectGeometryFastPath:
      context.DrawRect(layout_svg_shape_.ObjectBoundingBox(), flags);
      break;
    case kEllipseGeometryFastPath:
      context.DrawOval(layout_svg_shape_.ObjectBoundingBox(), flags);
      break;
    default: {
      PathWithTemporaryWindingRule path_with_winding(
          layout_svg_shape_.GetPath(), fill_type);
      context.DrawPath(path_with_winding.GetSkPath(), flags);
    }
  }
}

void SVGShapePainter::StrokeShape(GraphicsContext& context,
                                  const PaintFlags& flags) {
  if (!layout_svg_shape_.StyleRef().SvgStyle().HasVisibleStroke())
    return;

  switch (layout_svg_shape_.GeometryCodePath()) {
    case kRectGeometryFastPath:
      context.DrawRect(layout_svg_shape_.ObjectBoundingBox(), flags);
      break;
    case kEllipseGeometryFastPath:
      context.DrawOval(layout_svg_shape_.ObjectBoundingBox(), flags);
      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);
  }
}

void SVGShapePainter::PaintMarkers(const PaintInfo& paint_info,
                                   const FloatRect& bounding_box) {
  const Vector<MarkerPosition>* marker_positions =
      layout_svg_shape_.MarkerPositions();
  if (!marker_positions || marker_positions->IsEmpty())
    return;

  SVGResources* resources =
      SVGResourcesCache::CachedResourcesForLayoutObject(layout_svg_shape_);
  if (!resources)
    return;

  LayoutSVGResourceMarker* marker_start = resources->MarkerStart();
  LayoutSVGResourceMarker* marker_mid = resources->MarkerMid();
  LayoutSVGResourceMarker* marker_end = resources->MarkerEnd();
  if (!marker_start && !marker_mid && !marker_end)
    return;

  float stroke_width = layout_svg_shape_.StrokeWidth();

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

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

  AffineTransform transform = marker.MarkerTransformation(
      position.origin, position.angle, 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(nullptr, &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.cull_rect_ = CullRect(LayoutRect::InfiniteIntRect());

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

  canvas->restore();
}

}  // namespace blink
