// Copyright 2015 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 "modules/canvas2d/CanvasRenderingContext2DState.h"

#include "core/css/CSSFontSelector.h"
#include "core/css/resolver/FilterOperationResolver.h"
#include "core/css/resolver/StyleBuilder.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/paint/FilterEffectBuilder.h"
#include "core/style/ComputedStyle.h"
#include "core/style/FilterOperation.h"
#include "core/svg/SVGFilterElement.h"
#include "modules/canvas2d/CanvasGradient.h"
#include "modules/canvas2d/CanvasPattern.h"
#include "modules/canvas2d/CanvasRenderingContext2D.h"
#include "modules/canvas2d/CanvasStyle.h"
#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/filters/FilterEffect.h"
#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
#include "platform/graphics/paint/PaintCanvas.h"
#include "platform/graphics/paint/PaintFlags.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
#include <memory>

static const char defaultFont[] = "10px sans-serif";
static const char defaultFilter[] = "none";

namespace blink {

CanvasRenderingContext2DState::CanvasRenderingContext2DState()
    : unrealized_save_count_(0),
      stroke_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)),
      fill_style_(CanvasStyle::CreateFromRGBA(SK_ColorBLACK)),
      shadow_blur_(0),
      shadow_color_(Color::kTransparent),
      global_alpha_(1),
      line_dash_offset_(0),
      unparsed_font_(defaultFont),
      unparsed_filter_(defaultFilter),
      text_align_(kStartTextAlign),
      text_baseline_(kAlphabeticTextBaseline),
      direction_(kDirectionInherit),
      realized_font_(false),
      is_transform_invertible_(true),
      has_clip_(false),
      has_complex_clip_(false),
      fill_style_dirty_(true),
      stroke_style_dirty_(true),
      line_dash_dirty_(false),
      image_smoothing_quality_(kLow_SkFilterQuality) {
  fill_flags_.setStyle(PaintFlags::kFill_Style);
  fill_flags_.setAntiAlias(true);
  image_flags_.setStyle(PaintFlags::kFill_Style);
  image_flags_.setAntiAlias(true);
  stroke_flags_.setStyle(PaintFlags::kStroke_Style);
  stroke_flags_.setStrokeWidth(1);
  stroke_flags_.setStrokeCap(PaintFlags::kButt_Cap);
  stroke_flags_.setStrokeMiter(10);
  stroke_flags_.setStrokeJoin(PaintFlags::kMiter_Join);
  stroke_flags_.setAntiAlias(true);
  SetImageSmoothingEnabled(true);
}

CanvasRenderingContext2DState::CanvasRenderingContext2DState(
    const CanvasRenderingContext2DState& other,
    ClipListCopyMode mode)
    : CSSFontSelectorClient(),
      unrealized_save_count_(other.unrealized_save_count_),
      unparsed_stroke_color_(other.unparsed_stroke_color_),
      unparsed_fill_color_(other.unparsed_fill_color_),
      stroke_style_(other.stroke_style_),
      fill_style_(other.fill_style_),
      stroke_flags_(other.stroke_flags_),
      fill_flags_(other.fill_flags_),
      image_flags_(other.image_flags_),
      shadow_offset_(other.shadow_offset_),
      shadow_blur_(other.shadow_blur_),
      shadow_color_(other.shadow_color_),
      empty_draw_looper_(other.empty_draw_looper_),
      shadow_only_draw_looper_(other.shadow_only_draw_looper_),
      shadow_and_foreground_draw_looper_(
          other.shadow_and_foreground_draw_looper_),
      shadow_only_image_filter_(other.shadow_only_image_filter_),
      shadow_and_foreground_image_filter_(
          other.shadow_and_foreground_image_filter_),
      global_alpha_(other.global_alpha_),
      transform_(other.transform_),
      line_dash_(other.line_dash_),
      line_dash_offset_(other.line_dash_offset_),
      unparsed_font_(other.unparsed_font_),
      font_(other.font_),
      font_for_filter_(other.font_for_filter_),
      unparsed_filter_(other.unparsed_filter_),
      filter_value_(other.filter_value_),
      resolved_filter_(other.resolved_filter_),
      text_align_(other.text_align_),
      text_baseline_(other.text_baseline_),
      direction_(other.direction_),
      realized_font_(other.realized_font_),
      is_transform_invertible_(other.is_transform_invertible_),
      has_clip_(other.has_clip_),
      has_complex_clip_(other.has_complex_clip_),
      fill_style_dirty_(other.fill_style_dirty_),
      stroke_style_dirty_(other.stroke_style_dirty_),
      line_dash_dirty_(other.line_dash_dirty_),
      image_smoothing_enabled_(other.image_smoothing_enabled_),
      image_smoothing_quality_(other.image_smoothing_quality_) {
  if (mode == kCopyClipList) {
    clip_list_ = other.clip_list_;
  }
  if (realized_font_)
    static_cast<CSSFontSelector*>(font_.GetFontSelector())
        ->RegisterForInvalidationCallbacks(this);
}

CanvasRenderingContext2DState::~CanvasRenderingContext2DState() {}

void CanvasRenderingContext2DState::FontsNeedUpdate(
    CSSFontSelector* font_selector) {
  DCHECK_EQ(font_selector, font_.GetFontSelector());
  DCHECK(realized_font_);

  font_.Update(font_selector);
  // FIXME: We only really need to invalidate the resolved filter if the font
  // update above changed anything and the filter uses font-dependent units.
  resolved_filter_.reset();
}

DEFINE_TRACE(CanvasRenderingContext2DState) {
  visitor->Trace(stroke_style_);
  visitor->Trace(fill_style_);
  visitor->Trace(filter_value_);
  CSSFontSelectorClient::Trace(visitor);
}

void CanvasRenderingContext2DState::SetLineDashOffset(double offset) {
  line_dash_offset_ = offset;
  line_dash_dirty_ = true;
}

void CanvasRenderingContext2DState::SetLineDash(const Vector<double>& dash) {
  line_dash_ = dash;
  // Spec requires the concatenation of two copies the dash list when the
  // number of elements is odd
  if (dash.size() % 2)
    line_dash_.AppendVector(dash);

  line_dash_dirty_ = true;
}

static bool HasANonZeroElement(const Vector<double>& line_dash) {
  for (size_t i = 0; i < line_dash.size(); i++) {
    if (line_dash[i] != 0.0)
      return true;
  }
  return false;
}

void CanvasRenderingContext2DState::UpdateLineDash() const {
  if (!line_dash_dirty_)
    return;

  if (!HasANonZeroElement(line_dash_)) {
    stroke_flags_.setPathEffect(0);
  } else {
    Vector<float> line_dash(line_dash_.size());
    std::copy(line_dash_.begin(), line_dash_.end(), line_dash.begin());
    stroke_flags_.setPathEffect(SkDashPathEffect::Make(
        line_dash.data(), line_dash.size(), line_dash_offset_));
  }

  line_dash_dirty_ = false;
}

void CanvasRenderingContext2DState::SetStrokeStyle(CanvasStyle* style) {
  stroke_style_ = style;
  stroke_style_dirty_ = true;
}

void CanvasRenderingContext2DState::SetFillStyle(CanvasStyle* style) {
  fill_style_ = style;
  fill_style_dirty_ = true;
}

void CanvasRenderingContext2DState::UpdateStrokeStyle() const {
  if (!stroke_style_dirty_)
    return;

  int clamped_alpha = ClampedAlphaForBlending(global_alpha_);
  DCHECK(stroke_style_);
  stroke_style_->ApplyToFlags(stroke_flags_);
  stroke_flags_.setColor(
      ScaleAlpha(stroke_style_->PaintColor(), clamped_alpha));
  stroke_style_dirty_ = false;
}

void CanvasRenderingContext2DState::UpdateFillStyle() const {
  if (!fill_style_dirty_)
    return;

  int clamped_alpha = ClampedAlphaForBlending(global_alpha_);
  DCHECK(fill_style_);
  fill_style_->ApplyToFlags(fill_flags_);
  fill_flags_.setColor(ScaleAlpha(fill_style_->PaintColor(), clamped_alpha));
  fill_style_dirty_ = false;
}

CanvasStyle* CanvasRenderingContext2DState::Style(PaintType paint_type) const {
  switch (paint_type) {
    case kFillPaintType:
      return FillStyle();
    case kStrokePaintType:
      return StrokeStyle();
    case kImagePaintType:
      return nullptr;
  }
  NOTREACHED();
  return nullptr;
}

void CanvasRenderingContext2DState::SetShouldAntialias(bool should_antialias) {
  fill_flags_.setAntiAlias(should_antialias);
  stroke_flags_.setAntiAlias(should_antialias);
  image_flags_.setAntiAlias(should_antialias);
}

bool CanvasRenderingContext2DState::ShouldAntialias() const {
  DCHECK(fill_flags_.isAntiAlias() == stroke_flags_.isAntiAlias() &&
         fill_flags_.isAntiAlias() == image_flags_.isAntiAlias());
  return fill_flags_.isAntiAlias();
}

void CanvasRenderingContext2DState::SetGlobalAlpha(double alpha) {
  global_alpha_ = alpha;
  stroke_style_dirty_ = true;
  fill_style_dirty_ = true;
  int image_alpha = ClampedAlphaForBlending(alpha);
  image_flags_.setAlpha(image_alpha > 255 ? 255 : image_alpha);
}

void CanvasRenderingContext2DState::ClipPath(
    const SkPath& path,
    AntiAliasingMode anti_aliasing_mode) {
  clip_list_.ClipPath(path, anti_aliasing_mode,
                      AffineTransformToSkMatrix(transform_));
  has_clip_ = true;
  if (!path.isRect(0))
    has_complex_clip_ = true;
}

void CanvasRenderingContext2DState::SetFont(const Font& font,
                                            CSSFontSelector* selector) {
  font_ = font;
  font_.Update(selector);
  realized_font_ = true;
  selector->RegisterForInvalidationCallbacks(this);
}

const Font& CanvasRenderingContext2DState::GetFont() const {
  DCHECK(realized_font_);
  return font_;
}

void CanvasRenderingContext2DState::SetTransform(
    const AffineTransform& transform) {
  is_transform_invertible_ = transform.IsInvertible();
  transform_ = transform;
}

void CanvasRenderingContext2DState::ResetTransform() {
  transform_.MakeIdentity();
  is_transform_invertible_ = true;
}

sk_sp<SkImageFilter> CanvasRenderingContext2DState::GetFilterForOffscreenCanvas(
    IntSize canvas_size) const {
  if (!filter_value_)
    return nullptr;

  if (resolved_filter_)
    return resolved_filter_;

  FilterOperations operations =
      FilterOperationResolver::CreateOffscreenFilterOperations(*filter_value_);

  // We can't reuse m_fillFlags and m_strokeFlags for the filter, since these
  // incorporate the global alpha, which isn't applicable here.
  PaintFlags fill_flags_for_filter;
  fill_style_->ApplyToFlags(fill_flags_for_filter);
  fill_flags_for_filter.setColor(fill_style_->PaintColor());
  PaintFlags stroke_flags_for_filter;
  stroke_style_->ApplyToFlags(stroke_flags_for_filter);
  stroke_flags_for_filter.setColor(stroke_style_->PaintColor());

  FilterEffectBuilder filter_effect_builder(
      FloatRect((FloatPoint()), FloatSize(canvas_size)),
      1.0f,  // Deliberately ignore zoom on the canvas element.
      &fill_flags_for_filter, &stroke_flags_for_filter);

  FilterEffect* last_effect =
      filter_effect_builder.BuildFilterEffect(operations);
  if (last_effect) {
    resolved_filter_ =
        SkiaImageFilterBuilder::Build(last_effect, kInterpolationSpaceSRGB);
  }

  return resolved_filter_;
}

sk_sp<SkImageFilter> CanvasRenderingContext2DState::GetFilter(
    Element* style_resolution_host,
    IntSize canvas_size,
    CanvasRenderingContext2D* context) const {
  if (!filter_value_)
    return nullptr;

  // StyleResolverState cannot be used in frame-less documents.
  if (!style_resolution_host->GetDocument().GetFrame())
    return nullptr;

  if (!resolved_filter_) {
    // Update the filter value to the proper base URL if needed.
    if (filter_value_->MayContainUrl())
      filter_value_->ReResolveUrl(style_resolution_host->GetDocument());

    RefPtr<ComputedStyle> filter_style = ComputedStyle::Create();
    // Must set font in case the filter uses any font-relative units (em, ex)
    filter_style->SetFont(font_for_filter_);

    StyleResolverState resolver_state(style_resolution_host->GetDocument(),
                                      style_resolution_host, filter_style.Get(),
                                      filter_style.Get());
    resolver_state.SetStyle(filter_style);

    StyleBuilder::ApplyProperty(CSSPropertyFilter, resolver_state,
                                *filter_value_);
    resolver_state.LoadPendingResources();

    // We can't reuse m_fillFlags and m_strokeFlags for the filter, since these
    // incorporate the global alpha, which isn't applicable here.
    PaintFlags fill_flags_for_filter;
    fill_style_->ApplyToFlags(fill_flags_for_filter);
    fill_flags_for_filter.setColor(fill_style_->PaintColor());
    PaintFlags stroke_flags_for_filter;
    stroke_style_->ApplyToFlags(stroke_flags_for_filter);
    stroke_flags_for_filter.setColor(stroke_style_->PaintColor());

    FilterEffectBuilder filter_effect_builder(
        style_resolution_host,
        FloatRect((FloatPoint()), FloatSize(canvas_size)),
        1.0f,  // Deliberately ignore zoom on the canvas element.
        &fill_flags_for_filter, &stroke_flags_for_filter);

    if (FilterEffect* last_effect =
            filter_effect_builder.BuildFilterEffect(filter_style->Filter())) {
      resolved_filter_ =
          SkiaImageFilterBuilder::Build(last_effect, kInterpolationSpaceSRGB);
      if (resolved_filter_) {
        context->UpdateFilterReferences(filter_style->Filter());
        if (last_effect->OriginTainted())
          context->SetOriginTainted();
      }
    }
  }

  return resolved_filter_;
}

bool CanvasRenderingContext2DState::HasFilterForOffscreenCanvas(
    IntSize canvas_size) const {
  // Checking for a non-null m_filterValue isn't sufficient, since this value
  // might refer to a non-existent filter.
  return !!GetFilterForOffscreenCanvas(canvas_size);
}

bool CanvasRenderingContext2DState::HasFilter(
    Element* style_resolution_host,
    IntSize canvas_size,
    CanvasRenderingContext2D* context) const {
  // Checking for a non-null m_filterValue isn't sufficient, since this value
  // might refer to a non-existent filter.
  return !!GetFilter(style_resolution_host, canvas_size, context);
}

void CanvasRenderingContext2DState::ClearResolvedFilter() const {
  resolved_filter_.reset();
}

SkDrawLooper* CanvasRenderingContext2DState::EmptyDrawLooper() const {
  if (!empty_draw_looper_)
    empty_draw_looper_ = DrawLooperBuilder().DetachDrawLooper();

  return empty_draw_looper_.get();
}

SkDrawLooper* CanvasRenderingContext2DState::ShadowOnlyDrawLooper() const {
  if (!shadow_only_draw_looper_) {
    DrawLooperBuilder draw_looper_builder;
    draw_looper_builder.AddShadow(shadow_offset_, shadow_blur_, shadow_color_,
                                  DrawLooperBuilder::kShadowIgnoresTransforms,
                                  DrawLooperBuilder::kShadowRespectsAlpha);
    shadow_only_draw_looper_ = draw_looper_builder.DetachDrawLooper();
  }
  return shadow_only_draw_looper_.get();
}

SkDrawLooper* CanvasRenderingContext2DState::ShadowAndForegroundDrawLooper()
    const {
  if (!shadow_and_foreground_draw_looper_) {
    DrawLooperBuilder draw_looper_builder;
    draw_looper_builder.AddShadow(shadow_offset_, shadow_blur_, shadow_color_,
                                  DrawLooperBuilder::kShadowIgnoresTransforms,
                                  DrawLooperBuilder::kShadowRespectsAlpha);
    draw_looper_builder.AddUnmodifiedContent();
    shadow_and_foreground_draw_looper_ = draw_looper_builder.DetachDrawLooper();
  }
  return shadow_and_foreground_draw_looper_.get();
}

sk_sp<SkImageFilter> CanvasRenderingContext2DState::ShadowOnlyImageFilter()
    const {
  if (!shadow_only_image_filter_) {
    double sigma = SkBlurRadiusToSigma(shadow_blur_);
    shadow_only_image_filter_ = SkDropShadowImageFilter::Make(
        shadow_offset_.Width(), shadow_offset_.Height(), sigma, sigma,
        shadow_color_, SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode,
        nullptr);
  }
  return shadow_only_image_filter_;
}

sk_sp<SkImageFilter>
CanvasRenderingContext2DState::ShadowAndForegroundImageFilter() const {
  if (!shadow_and_foreground_image_filter_) {
    double sigma = SkBlurRadiusToSigma(shadow_blur_);
    shadow_and_foreground_image_filter_ = SkDropShadowImageFilter::Make(
        shadow_offset_.Width(), shadow_offset_.Height(), sigma, sigma,
        shadow_color_,
        SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr);
  }
  return shadow_and_foreground_image_filter_;
}

void CanvasRenderingContext2DState::ShadowParameterChanged() {
  shadow_only_draw_looper_.reset();
  shadow_and_foreground_draw_looper_.reset();
  shadow_only_image_filter_.reset();
  shadow_and_foreground_image_filter_.reset();
}

void CanvasRenderingContext2DState::SetShadowOffsetX(double x) {
  shadow_offset_.SetWidth(x);
  ShadowParameterChanged();
}

void CanvasRenderingContext2DState::SetShadowOffsetY(double y) {
  shadow_offset_.SetHeight(y);
  ShadowParameterChanged();
}

void CanvasRenderingContext2DState::SetShadowBlur(double shadow_blur) {
  shadow_blur_ = shadow_blur;
  ShadowParameterChanged();
}

void CanvasRenderingContext2DState::SetShadowColor(SkColor shadow_color) {
  shadow_color_ = shadow_color;
  ShadowParameterChanged();
}

void CanvasRenderingContext2DState::SetFilter(const CSSValue* filter_value) {
  filter_value_ = filter_value;
  resolved_filter_.reset();
}

void CanvasRenderingContext2DState::SetGlobalComposite(SkBlendMode mode) {
  stroke_flags_.setBlendMode(mode);
  fill_flags_.setBlendMode(mode);
  image_flags_.setBlendMode(mode);
}

SkBlendMode CanvasRenderingContext2DState::GlobalComposite() const {
  return stroke_flags_.getBlendMode();
}

void CanvasRenderingContext2DState::SetImageSmoothingEnabled(bool enabled) {
  image_smoothing_enabled_ = enabled;
  UpdateFilterQuality();
}

bool CanvasRenderingContext2DState::ImageSmoothingEnabled() const {
  return image_smoothing_enabled_;
}

void CanvasRenderingContext2DState::SetImageSmoothingQuality(
    const String& quality_string) {
  if (quality_string == "low") {
    image_smoothing_quality_ = kLow_SkFilterQuality;
  } else if (quality_string == "medium") {
    image_smoothing_quality_ = kMedium_SkFilterQuality;
  } else if (quality_string == "high") {
    image_smoothing_quality_ = kHigh_SkFilterQuality;
  } else {
    return;
  }
  UpdateFilterQuality();
}

String CanvasRenderingContext2DState::ImageSmoothingQuality() const {
  switch (image_smoothing_quality_) {
    case kLow_SkFilterQuality:
      return "low";
    case kMedium_SkFilterQuality:
      return "medium";
    case kHigh_SkFilterQuality:
      return "high";
    default:
      NOTREACHED();
      return "low";
  }
}

void CanvasRenderingContext2DState::UpdateFilterQuality() const {
  if (!image_smoothing_enabled_) {
    UpdateFilterQualityWithSkFilterQuality(kNone_SkFilterQuality);
  } else {
    UpdateFilterQualityWithSkFilterQuality(image_smoothing_quality_);
  }
}

void CanvasRenderingContext2DState::UpdateFilterQualityWithSkFilterQuality(
    const SkFilterQuality& filter_quality) const {
  stroke_flags_.setFilterQuality(filter_quality);
  fill_flags_.setFilterQuality(filter_quality);
  image_flags_.setFilterQuality(filter_quality);
}

bool CanvasRenderingContext2DState::ShouldDrawShadows() const {
  return AlphaChannel(shadow_color_) &&
         (shadow_blur_ || !shadow_offset_.IsZero());
}

const PaintFlags* CanvasRenderingContext2DState::GetFlags(
    PaintType paint_type,
    ShadowMode shadow_mode,
    ImageType image_type) const {
  PaintFlags* flags;
  switch (paint_type) {
    case kStrokePaintType:
      UpdateLineDash();
      UpdateStrokeStyle();
      flags = &stroke_flags_;
      break;
    default:
      NOTREACHED();
    // no break on purpose: flags needs to be assigned to avoid compiler warning
    // about uninitialized variable.
    case kFillPaintType:
      UpdateFillStyle();
      flags = &fill_flags_;
      break;
    case kImagePaintType:
      flags = &image_flags_;
      break;
  }

  if ((!ShouldDrawShadows() && shadow_mode == kDrawShadowAndForeground) ||
      shadow_mode == kDrawForegroundOnly) {
    flags->setLooper(0);
    flags->setImageFilter(0);
    return flags;
  }

  if (!ShouldDrawShadows() && shadow_mode == kDrawShadowOnly) {
    flags->setLooper(sk_ref_sp(EmptyDrawLooper()));  // draw nothing
    flags->setImageFilter(0);
    return flags;
  }

  if (shadow_mode == kDrawShadowOnly) {
    if (image_type == kNonOpaqueImage || filter_value_) {
      flags->setLooper(0);
      flags->setImageFilter(ShadowOnlyImageFilter());
      return flags;
    }
    flags->setLooper(sk_ref_sp(ShadowOnlyDrawLooper()));
    flags->setImageFilter(0);
    return flags;
  }

  DCHECK(shadow_mode == kDrawShadowAndForeground);
  if (image_type == kNonOpaqueImage) {
    flags->setLooper(0);
    flags->setImageFilter(ShadowAndForegroundImageFilter());
    return flags;
  }
  flags->setLooper(sk_ref_sp(ShadowAndForegroundDrawLooper()));
  flags->setImageFilter(0);
  return flags;
}

}  // namespace blink
