// Copyright (c) 2013 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.

#ifndef SKIA_EXT_ANALYSIS_CANVAS_H_
#define SKIA_EXT_ANALYSIS_CANVAS_H_

#include <stddef.h>
#include <stdint.h>

#include "base/compiler_specific.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"

namespace skia {

// Does not render anything, but gathers statistics about a region
// (specified as a clip rectangle) of an SkPicture as the picture is
// played back through it.
// To use: play a picture into the canvas, and then check result.
class SK_API AnalysisCanvas : public SkCanvas, public SkPicture::AbortCallback {
 public:
  AnalysisCanvas(int width, int height);
  ~AnalysisCanvas() override;

  // Returns true when a SkColor can be used to represent result.
  bool GetColorIfSolid(SkColor* color) const;

  void SetForceNotSolid(bool flag);
  void SetForceNotTransparent(bool flag);

  // SkPicture::AbortCallback override.
  bool abort() override;

  // SkCanvas overrides.
  void onDrawPaint(const SkPaint& paint) override;
  void onDrawPoints(PointMode,
                  size_t count,
                  const SkPoint pts[],
                  const SkPaint&) override;
  void onDrawOval(const SkRect&, const SkPaint&) override;
  void onDrawRect(const SkRect&, const SkPaint&) override;
  void onDrawRRect(const SkRRect&, const SkPaint&) override;
  void onDrawPath(const SkPath& path, const SkPaint&) override;
  void onDrawBitmap(const SkBitmap&,
                    SkScalar left,
                    SkScalar top,
                    const SkPaint* paint = NULL) override;
  void onDrawBitmapRect(const SkBitmap&,
                        const SkRect* src,
                        const SkRect& dst,
                        const SkPaint* paint,
                        SrcRectConstraint) override;
  void onDrawBitmapNine(const SkBitmap& bitmap,
                        const SkIRect& center,
                        const SkRect& dst,
                        const SkPaint* paint = NULL) override;
  void onDrawImage(const SkImage*,
                    SkScalar left,
                    SkScalar top,
                    const SkPaint* paint = NULL) override;
  void onDrawImageRect(const SkImage*,
                       const SkRect* src,
                       const SkRect& dst,
                       const SkPaint* paint,
                       SrcRectConstraint) override;
  void onDrawVertices(VertexMode,
                      int vertexCount,
                      const SkPoint vertices[],
                      const SkPoint texs[],
                      const SkColor colors[],
                      SkXfermode*,
                      const uint16_t indices[],
                      int indexCount,
                      const SkPaint&) override;

 protected:
  void willSave() override;
  SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
  void willRestore() override;

  void onClipRect(const SkRect& rect,
                  SkRegion::Op op,
                  ClipEdgeStyle edge_style) override;
  void onClipRRect(const SkRRect& rrect,
                   SkRegion::Op op,
                   ClipEdgeStyle edge_style) override;
  void onClipPath(const SkPath& path,
                  SkRegion::Op op,
                  ClipEdgeStyle edge_style) override;
  void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override;

  void onDrawText(const void* text,
                  size_t byteLength,
                  SkScalar x,
                  SkScalar y,
                  const SkPaint&) override;
  void onDrawPosText(const void* text,
                     size_t byteLength,
                     const SkPoint pos[],
                     const SkPaint&) override;
  void onDrawPosTextH(const void* text,
                      size_t byteLength,
                      const SkScalar xpos[],
                      SkScalar constY,
                      const SkPaint&) override;
  void onDrawTextOnPath(const void* text,
                        size_t byteLength,
                        const SkPath& path,
                        const SkMatrix* matrix,
                        const SkPaint&) override;
  void onDrawTextBlob(const SkTextBlob* blob,
                      SkScalar x,
                      SkScalar y,
                      const SkPaint& paint) override;
  void onDrawDRRect(const SkRRect& outer,
                    const SkRRect& inner,
                    const SkPaint&) override;

  void OnComplexClip();

 private:
  typedef SkCanvas INHERITED;

  int saved_stack_size_;
  int force_not_solid_stack_level_;
  int force_not_transparent_stack_level_;

  bool is_forced_not_solid_;
  bool is_forced_not_transparent_;
  bool is_solid_color_;
  SkColor color_;
  bool is_transparent_;
  int draw_op_count_;
};

}  // namespace skia

#endif  // SKIA_EXT_ANALYSIS_CANVAS_H_