| // 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 <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/strings/string16.h" |
| #include "skia/ext/platform_canvas.h" |
| #include "skia/ext/refptr.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/native_widget_types.h" |
| #include "ui/gfx/shadow_value.h" |
| |
| namespace gfx { |
| |
| class Rect; |
| class Font; |
| class FontList; |
| class Point; |
| class Size; |
| class Transform; |
| |
| // Canvas is a SkCanvas 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 SkCanvas, 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 SkXfermode::Mode. SkXfermode::Mode specifies how the |
| // source and destination colors are combined. Unless otherwise specified, |
| // the variant that does not take a SkXfermode::Mode uses a transfer mode |
| // of kSrcOver_Mode. |
| class GFX_EXPORT Canvas { |
| public: |
| enum TruncateFadeMode { |
| TruncateFadeTail, |
| TruncateFadeHead, |
| }; |
| |
| // Specifies the alignment for text rendered with the DrawStringInt method. |
| enum { |
| TEXT_ALIGN_LEFT = 1 << 0, |
| TEXT_ALIGN_CENTER = 1 << 1, |
| TEXT_ALIGN_RIGHT = 1 << 2, |
| |
| // Specifies the text consists of multiple lines. |
| MULTI_LINE = 1 << 3, |
| |
| // By default DrawStringInt 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 << 4, |
| HIDE_PREFIX = 1 << 5, |
| |
| // Prevent ellipsizing |
| NO_ELLIPSIS = 1 << 6, |
| |
| // Specifies if words can be split by new lines. |
| // This only works with MULTI_LINE. |
| CHARACTER_BREAK = 1 << 7, |
| |
| // Instructs DrawStringInt() to render the text using RTL directionality. |
| // In most cases, passing this flag is not necessary because information |
| // about the text directionality is going to be embedded within the string |
| // in the form of special Unicode characters. However, we don't insert |
| // directionality characters into strings if the locale is LTR because some |
| // platforms (for example, an English Windows XP with no RTL fonts |
| // installed) don't support these characters. Thus, this flag should be |
| // used to render text using RTL directionality when the locale is LTR. |
| FORCE_RTL_DIRECTIONALITY = 1 << 8, |
| |
| // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right. |
| // See FORCE_RTL_DIRECTIONALITY for details. |
| FORCE_LTR_DIRECTIONALITY = 1 << 9, |
| |
| // Instructs DrawStringInt() 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 << 10, |
| }; |
| |
| // 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); |
| |
| // Constructs a canvas with the size and the image_scale of the provided |
| // |image_rep|, and draws the |image_rep| into it. |
| Canvas(const ImageSkiaRep& image_rep, bool is_opaque); |
| |
| virtual ~Canvas(); |
| |
| // 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. |
| static Canvas* CreateCanvasWithoutScaling(SkCanvas* sk_canvas, |
| float image_scale); |
| |
| // 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); |
| // Obsolete version. Use the above version which takes FontList. |
| static void SizeStringInt(const base::string16& text, |
| const Font& font, |
| 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); |
| // Obsolete version. Use the above version which takes FontList. |
| static int GetStringWidth(const base::string16& text, const Font& font); |
| |
| // 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 fractioal 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::DrawStringInt when the text alignment |
| // is not specified. |
| // |
| // This function returns either Canvas::TEXT_ALIGN_LEFT or |
| // Canvas::TEXT_ALIGN_RIGHT. |
| static int DefaultCanvasTextAlignment(); |
| |
| // Draws text with a 1-pixel halo around it of the given color. |
| // On Windows, it allows ClearType to be drawn to an otherwise transparent |
| // bitmap for drag images. Drag images have only 1-bit of transparency, so |
| // we don't do any fancy blurring. |
| // On Linux, text with halo is created by stroking it with 2px |halo_color| |
| // then filling it with |text_color|. |
| // On Mac, NOTIMPLEMENTED. |
| // TODO(dhollowa): Skia-native implementation is underway. Cut over to |
| // that when ready. http::/crbug.com/109946 |
| void DrawStringRectWithHalo(const base::string16& text, |
| const FontList& font_list, |
| SkColor text_color, |
| SkColor halo_color, |
| const Rect& display_rect, |
| int flags); |
| // Obsolete version. Use the above version which takes FontList. |
| void DrawStringWithHalo(const base::string16& text, |
| const Font& font, |
| SkColor text_color, |
| SkColor halo_color, |
| int x, |
| int y, |
| int w, |
| int h, |
| int flags); |
| |
| // Extracts an ImageSkiaRep from the contents of this canvas. |
| ImageSkiaRep ExtractImageRep() const; |
| |
| // Draws a dashed rectangle of the specified color. |
| void DrawDashedRect(const Rect& rect, SkColor color); |
| |
| // 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 alpha); |
| void SaveLayerAlpha(uint8 alpha, const Rect& layer_bounds); |
| |
| // Restores the drawing state after a call to Save*(). It is an error to |
| // call Restore() more times than Save*(). |
| void Restore(); |
| |
| // Adds |rect| to the current clip. Returns true if the resulting clip is |
| // non-empty. |
| bool ClipRect(const Rect& rect); |
| |
| // Adds |path| to the current clip. Returns true if the resulting clip is |
| // non-empty. |
| bool ClipPath(const SkPath& path); |
| |
| // 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(int x_scale, int y_scale); |
| |
| // Fills the entire canvas' bitmap (restricted to current clip) with |
| // specified |color| using a transfer mode of SkXfermode::kSrcOver_Mode. |
| void DrawColor(SkColor color); |
| |
| // Fills the entire canvas' bitmap (restricted to current clip) with |
| // specified |color| and |mode|. |
| void DrawColor(SkColor color, SkXfermode::Mode mode); |
| |
| // Fills |rect| with |color| using a transfer mode of |
| // SkXfermode::kSrcOver_Mode. |
| void FillRect(const Rect& rect, SkColor color); |
| |
| // Fills |rect| with the specified |color| and |mode|. |
| void FillRect(const Rect& rect, SkColor color, SkXfermode::Mode mode); |
| |
| // Draws a single pixel rect in the specified region with the specified |
| // color, using a transfer mode of SkXfermode::kSrcOver_Mode. |
| // |
| // NOTE: if you need a single pixel line, use DrawLine. |
| void DrawRect(const Rect& 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 Rect& rect, SkColor color, SkXfermode::Mode mode); |
| |
| // Draws the given rectangle with the given |paint| parameters. |
| void DrawRect(const Rect& rect, const SkPaint& paint); |
| |
| // Draw the given point with the given |paint| parameters. |
| void DrawPoint(const Point& p, const SkPaint& paint); |
| |
| // Draws a single pixel line with the specified color. |
| void DrawLine(const Point& p1, const Point& p2, SkColor color); |
| |
| // Draws a line with the given |paint| parameters. |
| void DrawLine(const Point& p1, const Point& p2, const SkPaint& paint); |
| |
| // Draws a circle with the given |paint| parameters. |
| void DrawCircle(const Point& center_point, |
| int radius, |
| const SkPaint& paint); |
| |
| // Draws the given rectangle with rounded corners of |radius| using the |
| // given |paint| parameters. |
| void DrawRoundRect(const Rect& rect, int radius, const SkPaint& paint); |
| |
| // Draws the given path using the given |paint| parameters. |
| void DrawPath(const SkPath& path, const SkPaint& paint); |
| |
| // 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(..., paint) that constructs a temporary paint and |
| // calls paint.setAlpha(alpha). |
| void DrawImageInt(const ImageSkia&, int x, int y, uint8 alpha); |
| |
| // Draws an image with the origin at the specified location, using the |
| // specified paint. 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 SkPaint& paint); |
| |
| // 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 SkPaint 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 SkPaint& paint); |
| |
| // 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 SkPaint& paint); |
| |
| // 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); |
| // Obsolete versions. Use the above versions which take FontList. |
| void DrawStringInt(const base::string16& text, |
| const Font& font, |
| SkColor color, |
| int x, |
| int y, |
| int w, |
| int h); |
| void DrawStringInt(const base::string16& text, |
| const Font& font, |
| 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); |
| // Obsolete version. Use the above version which takes FontList. |
| void DrawStringInt(const base::string16& text, |
| const Font& font, |
| SkColor color, |
| int x, |
| int y, |
| int w, |
| int h, |
| int flags); |
| |
| // Similar to above DrawStringInt method but with text shadows support. |
| // Currently it's only implemented for canvas skia. Specifying a 0 line_height |
| // will cause the default height to be used. |
| void DrawStringRectWithShadows(const base::string16& text, |
| const FontList& font_list, |
| SkColor color, |
| const Rect& text_bounds, |
| int line_height, |
| int flags, |
| const ShadowValues& shadows); |
| // Obsolete version. Use the above version which takes FontList. |
| void DrawStringWithShadows(const base::string16& text, |
| const Font& font, |
| SkColor color, |
| const Rect& text_bounds, |
| int line_height, |
| int flags, |
| const ShadowValues& shadows); |
| |
| // Draws a dotted gray rectangle used for focus purposes. |
| void DrawFocusRect(const Rect& rect); |
| |
| // 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); |
| void TileImageInt(const ImageSkia& image, |
| int src_x, |
| int src_y, |
| float tile_scale_x, |
| float tile_scale_y, |
| int dest_x, |
| int dest_y, |
| int w, |
| int h); |
| |
| // Returns a native drawing context for platform specific drawing routines to |
| // use. Must be balanced by a call to EndPlatformPaint(). |
| NativeDrawingContext BeginPlatformPaint(); |
| |
| // Signifies the end of platform drawing using the native drawing context |
| // returned by BeginPlatformPaint(). |
| void EndPlatformPaint(); |
| |
| // Apply transformation on the canvas. |
| void Transform(const Transform& transform); |
| |
| // Draws the given string with the beginning or the end using a fade gradient. |
| void DrawFadeTruncatingStringRect( |
| const base::string16& text, |
| TruncateFadeMode truncate_mode, |
| const FontList& font_list, |
| SkColor color, |
| const Rect& display_rect); |
| void DrawFadeTruncatingStringRectWithFlags( |
| const base::string16& text, |
| TruncateFadeMode truncate_mode, |
| const FontList& font_list, |
| SkColor color, |
| const Rect& display_rect, |
| int flags); |
| |
| skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); } |
| SkCanvas* sk_canvas() const { return canvas_; } |
| float image_scale() const { return image_scale_; } |
| |
| private: |
| Canvas(SkCanvas* canvas, float image_scale); |
| |
| // Test whether the provided rectangle intersects the current clip rect. |
| bool IntersectsClipRectInt(int x, int y, int w, int h); |
| bool IntersectsClipRect(const Rect& rect); |
| |
| // Returns the image rep which best matches the canvas |image_scale_|. |
| // Returns a null image rep if |image| contains no image reps. |
| // Builds mip map for returned image rep if necessary. |
| // |
| // An optional additional user defined scale can be provided. |
| const ImageSkiaRep& GetImageRepToPaint(const ImageSkia& image) const; |
| const ImageSkiaRep& GetImageRepToPaint( |
| const ImageSkia& image, |
| float user_defined_scale_factor_x, |
| float user_defined_scale_factor_y) const; |
| |
| // 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_; |
| |
| skia::RefPtr<skia::PlatformCanvas> owned_canvas_; |
| SkCanvas* canvas_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Canvas); |
| }; |
| |
| } // namespace gfx |
| |
| #endif // UI_GFX_CANVAS_H_ |