// Copyright (c) 2012 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 UI_GFX_CANVAS_H_
#define UI_GFX_CANVAS_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string16.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/skia_paint_canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/text_constants.h"

namespace cc {
class SkottieWrapper;
}  // namespace cc

namespace gfx {

class Rect;
class RectF;
class FontList;
class Point;
class PointF;
class Size;
class Transform;
class Vector2d;

// Canvas is a PaintCanvas wrapper that provides a number of methods for
// common operations used throughout an application built using ui/gfx.
//
// All methods that take integer arguments (as is used throughout views)
// end with Int. If you need to use methods provided by PaintCanvas, you'll
// need to do a conversion. In particular you'll need to use |SkIntToScalar()|,
// or if converting from a scalar to an integer |SkScalarRound()|.
//
// A handful of methods in this class are overloaded providing an additional
// argument of type SkBlendMode. SkBlendMode specifies how the
// source and destination colors are combined. Unless otherwise specified,
// the variant that does not take a SkBlendMode uses a transfer mode
// of kSrcOver_Mode.
class GFX_EXPORT Canvas {
 public:
  enum {
    // Specifies the alignment for text rendered with the DrawStringRect method.
    TEXT_ALIGN_LEFT = 1 << 0,
    TEXT_ALIGN_CENTER = 1 << 1,
    TEXT_ALIGN_RIGHT = 1 << 2,
    TEXT_ALIGN_TO_HEAD = 1 << 3,

    // Specifies the text consists of multiple lines.
    MULTI_LINE = 1 << 4,

    // By default DrawStringRect does not process the prefix ('&') character
    // specially. That is, the string "&foo" is rendered as "&foo". When
    // rendering text from a resource that uses the prefix character for
    // mnemonics, the prefix should be processed and can be rendered as an
    // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX).
    SHOW_PREFIX = 1 << 5,
    HIDE_PREFIX = 1 << 6,

    // Prevent ellipsizing
    NO_ELLIPSIS = 1 << 7,

    // Specifies if words can be split by new lines.
    // This only works with MULTI_LINE.
    CHARACTER_BREAKABLE = 1 << 8,

    // Instructs DrawStringRect() to not use subpixel rendering.  This is useful
    // when rendering text onto a fully- or partially-transparent background
    // that will later be blended with another image.
    NO_SUBPIXEL_RENDERING = 1 << 9,
  };

  // Creates an empty canvas with image_scale of 1x.
  Canvas();

  // Creates canvas with provided DIP |size| and |image_scale|.
  // If this canvas is not opaque, it's explicitly cleared to transparent before
  // being returned.
  Canvas(const Size& size, float image_scale, bool is_opaque);

  // Creates a Canvas backed by an |sk_canvas| with |image_scale_|.
  // |sk_canvas| is assumed to be already scaled based on |image_scale|
  // so no additional scaling is applied.
  // Note: the caller must ensure that sk_canvas outlives this object, or until
  // RecreateBackingCanvas is called.
  Canvas(cc::PaintCanvas* sk_canvas, float image_scale);

  virtual ~Canvas();

  // Recreates the backing platform canvas with DIP |size| and |image_scale_|.
  // If the canvas is not opaque, it is explicitly cleared.
  // This method is public so that canvas_skia_paint can recreate the platform
  // canvas after having initialized the canvas.
  // TODO(pkotwicz): Push the image_scale into skia::PlatformCanvas such that
  // this method can be private.
  void RecreateBackingCanvas(const Size& size,
                             float image_scale,
                             bool is_opaque);

  // Compute the size required to draw some text with the provided fonts.
  // Attempts to fit the text with the provided width and height. Increases
  // height and then width as needed to make the text fit. This method
  // supports multiple lines. On Skia only a line_height can be specified and
  // specifying a 0 value for it will cause the default height to be used.
  static void SizeStringInt(const base::string16& text,
                            const FontList& font_list,
                            int* width,
                            int* height,
                            int line_height,
                            int flags);

  // This is same as SizeStringInt except that fractional size is returned.
  // See comment in GetStringWidthF for its usage.
  static void SizeStringFloat(const base::string16& text,
                              const FontList& font_list,
                              float* width,
                              float* height,
                              int line_height,
                              int flags);

  // Returns the number of horizontal pixels needed to display the specified
  // |text| with |font_list|.
  static int GetStringWidth(const base::string16& text,
                            const FontList& font_list);

  // This is same as GetStringWidth except that fractional width is returned.
  // Use this method for the scenario that multiple string widths need to be
  // summed up. This is because GetStringWidth returns the ceiled width and
  // adding multiple ceiled widths could cause more precision loss for certain
  // platform like Mac where the fractional width is used.
  static float GetStringWidthF(const base::string16& text,
                               const FontList& font_list);

  // Returns the default text alignment to be used when drawing text on a
  // Canvas based on the directionality of the system locale language.
  // This function is used by Canvas::DrawStringRect when the text alignment
  // is not specified.
  //
  // This function returns either Canvas::TEXT_ALIGN_LEFT or
  // Canvas::TEXT_ALIGN_RIGHT.
  static int DefaultCanvasTextAlignment();

  // Unscales by the image scale factor (aka device scale factor), and returns
  // that factor.  This is useful when callers want to draw directly in the
  // native scale.
  float UndoDeviceScaleFactor();

  // Saves a copy of the drawing state onto a stack, operating on this copy
  // until a balanced call to Restore() is made.
  void Save();

  // As with Save(), except draws to a layer that is blended with the canvas
  // at the specified alpha once Restore() is called.
  // |layer_bounds| are the bounds of the layer relative to the current
  // transform.
  void SaveLayerAlpha(uint8_t alpha);
  void SaveLayerAlpha(uint8_t alpha, const Rect& layer_bounds);

  // Like SaveLayerAlpha but draws the layer with an arbitrary set of
  // PaintFlags once Restore() is called.
  void SaveLayerWithFlags(const cc::PaintFlags& flags);

  // Restores the drawing state after a call to Save*(). It is an error to
  // call Restore() more times than Save*().
  void Restore();

  // Applies |rect| to the current clip using the specified region |op|.
  void ClipRect(const Rect& rect, SkClipOp op = SkClipOp::kIntersect);
  void ClipRect(const RectF& rect, SkClipOp op = SkClipOp::kIntersect);

  // Adds |path| to the current clip. |do_anti_alias| is true if the clip
  // should be antialiased.
  void ClipPath(const SkPath& path, bool do_anti_alias);

  // Returns the bounds of the current clip (in local coordinates) in the
  // |bounds| parameter, and returns true if it is non empty.
  bool GetClipBounds(Rect* bounds);

  void Translate(const Vector2d& offset);

  void Scale(float x_scale, float y_scale);

  // Fills the entire canvas' bitmap (restricted to current clip) with
  // specified |color| using a transfer mode of SkBlendMode::kSrcOver.
  void DrawColor(SkColor color);

  // Fills the entire canvas' bitmap (restricted to current clip) with
  // specified |color| and |mode|.
  void DrawColor(SkColor color, SkBlendMode mode);

  // Fills |rect| with |color| using a transfer mode of
  // SkBlendMode::kSrcOver.
  void FillRect(const Rect& rect, SkColor color);

  // Fills |rect| with the specified |color| and |mode|.
  void FillRect(const Rect& rect, SkColor color, SkBlendMode mode);

  // Draws a single pixel rect in the specified region with the specified
  // color, using a transfer mode of SkBlendMode::kSrcOver.
  //
  // NOTE: if you need a single pixel line, use DrawLine.
  void DrawRect(const RectF& rect, SkColor color);

  // Draws a single pixel rect in the specified region with the specified
  // color and transfer mode.
  //
  // NOTE: if you need a single pixel line, use DrawLine.
  void DrawRect(const RectF& rect, SkColor color, SkBlendMode mode);

  // Draws the given rectangle with the given |flags| parameters.
  // DEPRECATED in favor of the RectF version below.
  // TODO(funkysidd): Remove this (http://crbug.com/553726)
  void DrawRect(const Rect& rect, const cc::PaintFlags& flags);

  // Draws the given rectangle with the given |flags| parameters.
  void DrawRect(const RectF& rect, const cc::PaintFlags& flags);

  // Draws a single pixel line with the specified color.
  // DEPRECATED in favor of the RectF version below.
  // TODO(funkysidd): Remove this (http://crbug.com/553726)
  void DrawLine(const Point& p1, const Point& p2, SkColor color);

  // Draws a single dip line with the specified color.
  void DrawLine(const PointF& p1, const PointF& p2, SkColor color);

  // Draws a line with the given |flags| parameters.
  // DEPRECATED in favor of the RectF version below.
  // TODO(funkysidd): Remove this (http://crbug.com/553726)
  void DrawLine(const Point& p1, const Point& p2, const cc::PaintFlags& flags);

  // Draws a line with the given |flags| parameters.
  void DrawLine(const PointF& p1,
                const PointF& p2,
                const cc::PaintFlags& flags);

  // Draws a line that's a single DIP. At fractional scale factors, this is
  // floored to the nearest integral number of pixels.
  void DrawSharpLine(PointF p1, PointF p2, SkColor color);

  // As above, but draws a single pixel at all scale factors.
  void Draw1pxLine(PointF p1, PointF p2, SkColor color);

  // Draws a circle with the given |flags| parameters.
  // DEPRECATED in favor of the RectF version below.
  // TODO(funkysidd): Remove this (http://crbug.com/553726)
  void DrawCircle(const Point& center_point,
                  int radius,
                  const cc::PaintFlags& flags);

  // Draws a circle with the given |flags| parameters.
  void DrawCircle(const PointF& center_point,
                  float radius,
                  const cc::PaintFlags& flags);

  // Draws the given rectangle with rounded corners of |radius| using the
  // given |flags| parameters. DEPRECATED in favor of the RectF version below.
  // TODO(mgiuca): Remove this (http://crbug.com/553726).
  void DrawRoundRect(const Rect& rect, int radius, const cc::PaintFlags& flags);

  // Draws the given rectangle with rounded corners of |radius| using the
  // given |flags| parameters.
  void DrawRoundRect(const RectF& rect,
                     float radius,
                     const cc::PaintFlags& flags);

  // Draws the given path using the given |flags| parameters.
  void DrawPath(const SkPath& path, const cc::PaintFlags& flags);

  // Draws an image with the origin at the specified location. The upper left
  // corner of the bitmap is rendered at the specified location.
  // Parameters are specified relative to current canvas scale not in pixels.
  // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1.
  void DrawImageInt(const ImageSkia&, int x, int y);

  // Helper for DrawImageInt(..., flags) that constructs a temporary flags and
  // calls flags.setAlpha(alpha).
  void DrawImageInt(const ImageSkia&, int x, int y, uint8_t alpha);

  // Draws an image with the origin at the specified location, using the
  // specified flags. The upper left corner of the bitmap is rendered at the
  // specified location.
  // Parameters are specified relative to current canvas scale not in pixels.
  // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
  void DrawImageInt(const ImageSkia& image,
                    int x,
                    int y,
                    const cc::PaintFlags& flags);

  // Draws a portion of an image in the specified location. The src parameters
  // correspond to the region of the bitmap to draw in the region defined
  // by the dest coordinates.
  //
  // If the width or height of the source differs from that of the destination,
  // the image will be scaled. When scaling down, a mipmap will be generated.
  // Set |filter| to use filtering for images, otherwise the nearest-neighbor
  // algorithm is used for resampling.
  //
  // An optional custom cc::PaintFlags can be provided.
  // Parameters are specified relative to current canvas scale not in pixels.
  // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
  void DrawImageInt(const ImageSkia& image,
                    int src_x,
                    int src_y,
                    int src_w,
                    int src_h,
                    int dest_x,
                    int dest_y,
                    int dest_w,
                    int dest_h,
                    bool filter);
  void DrawImageInt(const ImageSkia& image,
                    int src_x,
                    int src_y,
                    int src_w,
                    int src_h,
                    int dest_x,
                    int dest_y,
                    int dest_w,
                    int dest_h,
                    bool filter,
                    const cc::PaintFlags& flags);

  // Same as the DrawImageInt functions above. Difference being this does not
  // do any scaling, i.e. it does not scale the output by the device scale
  // factor (the internal image_scale_). It takes an ImageSkiaRep instead of
  // an ImageSkia as the caller chooses the exact scale/pixel representation to
  // use, which will not be scaled while drawing it into the canvas.
  void DrawImageIntInPixel(const ImageSkiaRep& image_rep,
                           int dest_x,
                           int dest_y,
                           int dest_w,
                           int dest_h,
                           bool filter,
                           const cc::PaintFlags& flags);

  // Draws an |image| with the top left corner at |x| and |y|, clipped to
  // |path|.
  // Parameters are specified relative to current canvas scale not in pixels.
  // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1.
  void DrawImageInPath(const ImageSkia& image,
                       int x,
                       int y,
                       const SkPath& path,
                       const cc::PaintFlags& flags);

  // Draws the frame of the |skottie| animation specified by the normalized time
  // instant t [0->first frame .. 1->last frame] onto the region corresponded by
  // |dst| in the canvas.
  void DrawSkottie(scoped_refptr<cc::SkottieWrapper> skottie,
                   const Rect& dst,
                   float t);

  // Draws text with the specified color, fonts and location. The text is
  // aligned to the left, vertically centered, clipped to the region. If the
  // text is too big, it is truncated and '...' is added to the end.
  void DrawStringRect(const base::string16& text,
                      const FontList& font_list,
                      SkColor color,
                      const Rect& display_rect);

  // Draws text with the specified color, fonts and location. The last argument
  // specifies flags for how the text should be rendered. It can be one of
  // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT.
  void DrawStringRectWithFlags(const base::string16& text,
                               const FontList& font_list,
                               SkColor color,
                               const Rect& display_rect,
                               int flags);

  // Draws a |rect| in the specified region with the specified |color|. The
  // width of the stroke is |thickness| dip, but the actual pixel width will be
  // floored to ensure an integral value.
  void DrawSolidFocusRect(RectF rect, SkColor color, int thickness);

  // Tiles the image in the specified region.
  // Parameters are specified relative to current canvas scale not in pixels.
  // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
  void TileImageInt(const ImageSkia& image,
                    int x,
                    int y,
                    int w,
                    int h);
  void TileImageInt(const ImageSkia& image,
                    int src_x,
                    int src_y,
                    int dest_x,
                    int dest_y,
                    int w,
                    int h,
                    float tile_scale = 1.0f,
                    SkTileMode tile_mode_x = SkTileMode::kRepeat,
                    SkTileMode tile_mode_y = SkTileMode::kRepeat,
                    cc::PaintFlags* flags = nullptr);

  // Helper for TileImageInt().  Initializes |flags| for tiling |image| with the
  // given parameters.  Returns false if the provided image does not have a
  // representation for the current scale.
  bool InitPaintFlagsForTiling(const ImageSkia& image,
                               int src_x,
                               int src_y,
                               float tile_scale_x,
                               float tile_scale_y,
                               int dest_x,
                               int dest_y,
                               SkTileMode tile_mode_x,
                               SkTileMode tile_mode_y,
                               cc::PaintFlags* flags);

  // Apply transformation on the canvas.
  void Transform(const Transform& transform);

  // Note that writing to this bitmap will modify pixels stored in this canvas.
  SkBitmap GetBitmap() const;

  // TODO(enne): rename sk_canvas members and interface.
  cc::PaintCanvas* sk_canvas() { return canvas_; }
  float image_scale() const { return image_scale_; }

 private:
  // Tests whether the provided rectangle intersects the current clip rect.
  bool IntersectsClipRect(const SkRect& rect);

  // Helper for the DrawImageInt functions declared above. The
  // |remove_image_scale| parameter indicates if the scale of the |image_rep|
  // should be removed when drawing the image, to avoid double-scaling it.
  void DrawImageIntHelper(const ImageSkiaRep& image_rep,
                          int src_x,
                          int src_y,
                          int src_w,
                          int src_h,
                          int dest_x,
                          int dest_y,
                          int dest_w,
                          int dest_h,
                          bool filter,
                          const cc::PaintFlags& flags,
                          bool remove_image_scale);
  cc::PaintCanvas* CreateOwnedCanvas(const Size& size, bool is_opaque);

  // The device scale factor at which drawing on this canvas occurs.
  // An additional scale can be applied via Canvas::Scale(). However,
  // Canvas::Scale() does not affect |image_scale_|.
  float image_scale_;

  // canvas_ is our active canvas object. Sometimes we are also the owner,
  // in which case bitmap_ and owned_canvas_ will be set. Other times we are
  // just borrowing someone else's canvas, in which case canvas_ will point
  // there but bitmap_ and owned_canvas_ will not exist.
  base::Optional<SkBitmap> bitmap_;
  base::Optional<cc::SkiaPaintCanvas> owned_canvas_;
  cc::PaintCanvas* canvas_;

  DISALLOW_COPY_AND_ASSIGN(Canvas);
};

}  // namespace gfx

#endif  // UI_GFX_CANVAS_H_
