blob: 8b039fe4baaed920f21e09f88e64d6a28346de58 [file] [log] [blame]
[email protected]fa8cfb02012-01-13 00:27:411// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]267c03d2011-02-02 23:03:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_GFX_CANVAS_H_
6#define UI_GFX_CANVAS_H_
[email protected]267c03d2011-02-02 23:03:077
[email protected]0834e1b12012-04-11 02:23:568#include <vector>
9
[email protected]3127f6632012-03-17 00:14:0610#include "base/basictypes.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/string16.h"
13#include "skia/ext/platform_canvas.h"
[email protected]35d53342012-05-16 21:30:1214#include "ui/gfx/image/image_skia.h"
[email protected]3127f6632012-03-17 00:14:0615#include "ui/gfx/native_widget_types.h"
[email protected]25650682012-05-29 23:09:1916#include "ui/gfx/shadow_value.h"
[email protected]3127f6632012-03-17 00:14:0617
18class SkBitmap;
19
20namespace ui {
21class Transform;
22}
[email protected]36df22b2011-02-24 21:47:5623
[email protected]267c03d2011-02-02 23:03:0724namespace gfx {
25
[email protected]3127f6632012-03-17 00:14:0626class Rect;
27class Font;
28class Point;
29class Size;
30
31// Canvas is a SkCanvas wrapper that provides a number of methods for
32// common operations used throughout an application built using ui/gfx.
33//
34// All methods that take integer arguments (as is used throughout views)
35// end with Int. If you need to use methods provided by SkCanvas, you'll
36// need to do a conversion. In particular you'll need to use |SkIntToScalar()|,
37// or if converting from a scalar to an integer |SkScalarRound()|.
38//
39// A handful of methods in this class are overloaded providing an additional
40// argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the
41// source and destination colors are combined. Unless otherwise specified,
42// the variant that does not take a SkXfermode::Mode uses a transfer mode
43// of kSrcOver_Mode.
44class UI_EXPORT Canvas {
[email protected]267c03d2011-02-02 23:03:0745 public:
[email protected]3127f6632012-03-17 00:14:0646 enum TruncateFadeMode {
47 TruncateFadeTail,
48 TruncateFadeHead,
49 TruncateFadeHeadAndTail,
50 };
51
52 // Specifies the alignment for text rendered with the DrawStringInt method.
53 enum {
54 TEXT_ALIGN_LEFT = 1 << 0,
55 TEXT_ALIGN_CENTER = 1 << 1,
56 TEXT_ALIGN_RIGHT = 1 << 2 ,
57 TEXT_VALIGN_TOP = 1 << 3,
58 TEXT_VALIGN_MIDDLE = 1 << 4,
59 TEXT_VALIGN_BOTTOM = 1 << 5,
60
61 // Specifies the text consists of multiple lines.
62 MULTI_LINE = 1 << 6,
63
64 // By default DrawStringInt does not process the prefix ('&') character
65 // specially. That is, the string "&foo" is rendered as "&foo". When
66 // rendering text from a resource that uses the prefix character for
67 // mnemonics, the prefix should be processed and can be rendered as an
68 // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX).
69 SHOW_PREFIX = 1 << 7,
70 HIDE_PREFIX = 1 << 8,
71
72 // Prevent ellipsizing
73 NO_ELLIPSIS = 1 << 9,
74
75 // Specifies if words can be split by new lines.
76 // This only works with MULTI_LINE.
77 CHARACTER_BREAK = 1 << 10,
78
79 // Instructs DrawStringInt() to render the text using RTL directionality.
80 // In most cases, passing this flag is not necessary because information
81 // about the text directionality is going to be embedded within the string
82 // in the form of special Unicode characters. However, we don't insert
83 // directionality characters into strings if the locale is LTR because some
84 // platforms (for example, an English Windows XP with no RTL fonts
85 // installed) don't support these characters. Thus, this flag should be
86 // used to render text using RTL directionality when the locale is LTR.
87 FORCE_RTL_DIRECTIONALITY = 1 << 11,
88
89 // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right.
90 // See FORCE_RTL_DIRECTIONALITY for details.
91 FORCE_LTR_DIRECTIONALITY = 1 << 12,
92
93 // Instructs DrawStringInt() to not use subpixel rendering. This is useful
94 // when rendering text onto a fully- or partially-transparent background
95 // that will later be blended with another image.
96 NO_SUBPIXEL_RENDERING = 1 << 13,
97 };
98
[email protected]3b2591a2012-06-27 17:58:4199 // Creates an empty canvas with scale factor of 1x.
[email protected]94a0d2582012-03-09 00:30:59100 Canvas();
[email protected]267c03d2011-02-02 23:03:07101
[email protected]3b2591a2012-06-27 17:58:41102 // Creates canvas with provided DIP |size| and |scale_factor|.
103 // If this canvas is not opaque, it's explicitly cleared to transparent before
104 // being returned.
105 Canvas(const gfx::Size& size,
106 ui::ScaleFactor scale_factor,
107 bool is_opaque);
[email protected]3127f6632012-03-17 00:14:06108
[email protected]3b2591a2012-06-27 17:58:41109 // Constructs a canvas with the size and the scale factor of the
110 // provided |image_rep|, and draws the |image_rep| into it.
111 Canvas(const gfx::ImageSkiaRep& image_rep, bool is_opaque);
112
[email protected]57047da2012-07-23 20:55:08113 virtual ~Canvas();
[email protected]f7fc60212012-07-23 20:27:08114
[email protected]de13f352012-07-24 16:51:16115 // Creates a gfx::Canvas backed by an |sk_canvas| with |scale_factor|.
116 // |sk_canvas| is assumed to be already scaled based on |scale_factor|
117 // so no additional scaling is applied.
118 static Canvas* CreateCanvasWithoutScaling(SkCanvas* sk_canvas,
119 ui::ScaleFactor scale_factor);
120
[email protected]3b2591a2012-06-27 17:58:41121 // Recreates the backing platform canvas with DIP |size| and |scale_factor|.
122 // If the canvas is not opaque, it is explicitly cleared.
123 // This method is public so that canvas_skia_paint can recreate the platform
124 // canvas after having initialized the canvas.
125 // TODO(pkotwicz): Push the scale factor into skia::PlatformCanvas such that
126 // this method can be private.
127 void RecreateBackingCanvas(const gfx::Size& size,
128 ui::ScaleFactor scale_factor,
129 bool is_opaque);
130
[email protected]3127f6632012-03-17 00:14:06131 // Compute the size required to draw some text with the provided font.
132 // Attempts to fit the text with the provided width and height. Increases
133 // height and then width as needed to make the text fit. This method
134 // supports multiple lines.
135 static void SizeStringInt(const string16& text,
136 const gfx::Font& font,
137 int* width, int* height,
138 int flags);
139
140 // Returns the number of horizontal pixels needed to display the specified
141 // |text| with |font|.
142 static int GetStringWidth(const string16& text, const gfx::Font& font);
143
144 // Returns the default text alignment to be used when drawing text on a
145 // gfx::Canvas based on the directionality of the system locale language.
146 // This function is used by gfx::Canvas::DrawStringInt when the text alignment
147 // is not specified.
148 //
149 // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or
150 // gfx::Canvas::TEXT_ALIGN_RIGHT.
151 static int DefaultCanvasTextAlignment();
152
153 // Draws text with a 1-pixel halo around it of the given color.
154 // On Windows, it allows ClearType to be drawn to an otherwise transparenct
155 // bitmap for drag images. Drag images have only 1-bit of transparency, so
156 // we don't do any fancy blurring.
157 // On Linux, text with halo is created by stroking it with 2px |halo_color|
158 // then filling it with |text_color|.
159 // On Mac, NOTIMPLEMENTED.
160 // TODO(dhollowa): Skia-native implementation is underway. Cut over to
161 // that when ready. http::/crbug.com/109946
162 void DrawStringWithHalo(const string16& text,
163 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42164 SkColor text_color,
165 SkColor halo_color,
[email protected]3127f6632012-03-17 00:14:06166 int x, int y, int w, int h,
167 int flags);
168
[email protected]3b2591a2012-06-27 17:58:41169 // Extracts an ImageSkiaRep from the contents of this canvas.
[email protected]de13f352012-07-24 16:51:16170 gfx::ImageSkiaRep ExtractImageRep() const;
[email protected]3b2591a2012-06-27 17:58:41171
[email protected]3127f6632012-03-17 00:14:06172 // Draws a dashed rectangle of the specified color.
173 void DrawDashedRect(const gfx::Rect& rect, SkColor color);
174
175 // Saves a copy of the drawing state onto a stack, operating on this copy
176 // until a balanced call to Restore() is made.
177 void Save();
178
179 // As with Save(), except draws to a layer that is blended with the canvas
180 // at the specified alpha once Restore() is called.
181 // |layer_bounds| are the bounds of the layer relative to the current
182 // transform.
183 void SaveLayerAlpha(uint8 alpha);
184 void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds);
185
186 // Restores the drawing state after a call to Save*(). It is an error to
187 // call Restore() more times than Save*().
188 void Restore() ;
189
[email protected]ffdd1fd2012-04-09 23:24:41190 // Adds |rect| to the current clip. Returns true if the resulting clip is
191 // non-empty.
[email protected]3127f6632012-03-17 00:14:06192 bool ClipRect(const gfx::Rect& rect);
193
[email protected]ffdd1fd2012-04-09 23:24:41194 // Adds |path| to the current clip. Returns true if the resulting clip is
195 // non-empty.
196 bool ClipPath(const SkPath& path);
197
198 // Returns the bounds of the current clip (in local coordinates) in the
199 // |bounds| parameter, and returns true if it is non empty.
200 bool GetClipBounds(gfx::Rect* bounds);
201
[email protected]3127f6632012-03-17 00:14:06202 void Translate(const gfx::Point& point);
203
204 void Scale(int x_scale, int y_scale);
205
[email protected]ffdd1fd2012-04-09 23:24:41206 // Fills the entire canvas' bitmap (restricted to current clip) with
207 // specified |color| using a transfer mode of SkXfermode::kSrcOver_Mode.
208 void DrawColor(SkColor color);
209
210 // Fills the entire canvas' bitmap (restricted to current clip) with
211 // specified |color| and |mode|.
212 void DrawColor(SkColor color, SkXfermode::Mode mode);
213
[email protected]3127f6632012-03-17 00:14:06214 // Fills |rect| with |color| using a transfer mode of
215 // SkXfermode::kSrcOver_Mode.
[email protected]1b81ff22012-03-24 22:04:42216 void FillRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06217
218 // Fills |rect| with the specified |color| and |mode|.
[email protected]1b81ff22012-03-24 22:04:42219 void FillRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06220
[email protected]3127f6632012-03-17 00:14:06221 // Draws a single pixel rect in the specified region with the specified
222 // color, using a transfer mode of SkXfermode::kSrcOver_Mode.
223 //
224 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42225 void DrawRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06226
227 // Draws a single pixel rect in the specified region with the specified
228 // color and transfer mode.
229 //
230 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42231 void DrawRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06232
[email protected]ffdd1fd2012-04-09 23:24:41233 // Draws the given rectangle with the given |paint| parameters.
[email protected]3127f6632012-03-17 00:14:06234 void DrawRect(const gfx::Rect& rect, const SkPaint& paint);
235
[email protected]ffdd1fd2012-04-09 23:24:41236 // Draw the given point with the given |paint| parameters.
237 void DrawPoint(const gfx::Point& p, const SkPaint& paint);
238
[email protected]3127f6632012-03-17 00:14:06239 // Draws a single pixel line with the specified color.
[email protected]1b81ff22012-03-24 22:04:42240 void DrawLine(const gfx::Point& p1, const gfx::Point& p2, SkColor color);
[email protected]3127f6632012-03-17 00:14:06241
[email protected]ffdd1fd2012-04-09 23:24:41242 // Draws a line with the given |paint| parameters.
243 void DrawLine(const gfx::Point& p1,
244 const gfx::Point& p2,
245 const SkPaint& paint);
246
247 // Draws a circle with the given |paint| parameters.
248 void DrawCircle(const gfx::Point& center_point,
249 int radius,
250 const SkPaint& paint);
251
252 // Draws the given rectangle with rounded corners of |radius| using the
253 // given |paint| parameters.
254 void DrawRoundRect(const gfx::Rect& rect, int radius, const SkPaint& paint);
255
256 // Draws the given path using the given |paint| parameters.
257 void DrawPath(const SkPath& path, const SkPaint& paint);
258
[email protected]35d53342012-05-16 21:30:12259 // Draws an image with the origin at the specified location. The upper left
[email protected]3127f6632012-03-17 00:14:06260 // corner of the bitmap is rendered at the specified location.
[email protected]35d53342012-05-16 21:30:12261 // Parameters are specified relative to current canvas scale not in pixels.
[email protected]8232da6b2012-07-02 19:41:15262 // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1.
[email protected]243cac7d2012-06-07 13:29:20263 void DrawImageInt(const gfx::ImageSkia&, int x, int y);
[email protected]3127f6632012-03-17 00:14:06264
[email protected]2885cb32012-10-03 19:41:11265 // Helper for DrawImageInt(..., paint) that constructs a temporary paint and
266 // calls paint.setAlpha(alpha).
267 void DrawImageInt(const gfx::ImageSkia&, int x, int y, uint8 alpha);
268
[email protected]35d53342012-05-16 21:30:12269 // Draws an image with the origin at the specified location, using the
[email protected]3127f6632012-03-17 00:14:06270 // specified paint. The upper left corner of the bitmap is rendered at the
271 // specified location.
[email protected]35d53342012-05-16 21:30:12272 // Parameters are specified relative to current canvas scale not in pixels.
273 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
[email protected]243cac7d2012-06-07 13:29:20274 void DrawImageInt(const gfx::ImageSkia& image,
275 int x, int y,
276 const SkPaint& paint);
[email protected]3127f6632012-03-17 00:14:06277
[email protected]35d53342012-05-16 21:30:12278 // Draws a portion of an image in the specified location. The src parameters
[email protected]3127f6632012-03-17 00:14:06279 // correspond to the region of the bitmap to draw in the region defined
280 // by the dest coordinates.
281 //
282 // If the width or height of the source differs from that of the destination,
[email protected]35d53342012-05-16 21:30:12283 // the image will be scaled. When scaling down, a mipmap will be generated.
284 // Set |filter| to use filtering for images, otherwise the nearest-neighbor
285 // algorithm is used for resampling.
[email protected]3127f6632012-03-17 00:14:06286 //
287 // An optional custom SkPaint can be provided.
[email protected]35d53342012-05-16 21:30:12288 // Parameters are specified relative to current canvas scale not in pixels.
289 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
[email protected]243cac7d2012-06-07 13:29:20290 void DrawImageInt(const gfx::ImageSkia& image,
291 int src_x, int src_y, int src_w, int src_h,
292 int dest_x, int dest_y, int dest_w, int dest_h,
293 bool filter);
294 void DrawImageInt(const gfx::ImageSkia& image,
295 int src_x, int src_y, int src_w, int src_h,
296 int dest_x, int dest_y, int dest_w, int dest_h,
297 bool filter,
298 const SkPaint& paint);
[email protected]3127f6632012-03-17 00:14:06299
[email protected]8232da6b2012-07-02 19:41:15300 // Draws an |image| with the top left corner at |x| and |y|, clipped to
301 // |path|.
302 // Parameters are specified relative to current canvas scale not in pixels.
303 // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1.
304 void DrawImageInPath(const gfx::ImageSkia& image,
305 int x,
306 int y,
307 const SkPath& path,
308 const SkPaint& paint);
309
[email protected]3127f6632012-03-17 00:14:06310 // Draws text with the specified color, font and location. The text is
311 // aligned to the left, vertically centered, clipped to the region. If the
312 // text is too big, it is truncated and '...' is added to the end.
313 void DrawStringInt(const string16& text,
314 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42315 SkColor color,
[email protected]3127f6632012-03-17 00:14:06316 int x, int y, int w, int h);
317 void DrawStringInt(const string16& text,
318 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42319 SkColor color,
[email protected]3127f6632012-03-17 00:14:06320 const gfx::Rect& display_rect);
321
322 // Draws text with the specified color, font and location. The last argument
323 // specifies flags for how the text should be rendered. It can be one of
324 // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT.
325 void DrawStringInt(const string16& text,
326 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42327 SkColor color,
[email protected]3127f6632012-03-17 00:14:06328 int x, int y, int w, int h,
329 int flags);
330
[email protected]0834e1b12012-04-11 02:23:56331 // Similar to above DrawStringInt method but with text shadows support.
332 // Currently it's only implemented for canvas skia.
333 void DrawStringWithShadows(const string16& text,
334 const gfx::Font& font,
335 SkColor color,
336 const gfx::Rect& text_bounds,
337 int flags,
[email protected]25650682012-05-29 23:09:19338 const ShadowValues& shadows);
[email protected]0834e1b12012-04-11 02:23:56339
[email protected]3127f6632012-03-17 00:14:06340 // Draws a dotted gray rectangle used for focus purposes.
341 void DrawFocusRect(const gfx::Rect& rect);
342
343 // Tiles the image in the specified region.
[email protected]35d53342012-05-16 21:30:12344 // Parameters are specified relative to current canvas scale not in pixels.
345 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
346 void TileImageInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06347 int x, int y, int w, int h);
[email protected]35d53342012-05-16 21:30:12348 void TileImageInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06349 int src_x, int src_y,
350 int dest_x, int dest_y, int w, int h);
[email protected]2a3115e2012-05-25 23:27:04351 void TileImageInt(const gfx::ImageSkia& image,
352 int src_x, int src_y,
353 float tile_scale_x, float tile_scale_y,
354 int dest_x, int dest_y, int w, int h);
[email protected]3127f6632012-03-17 00:14:06355
356 // Returns a native drawing context for platform specific drawing routines to
357 // use. Must be balanced by a call to EndPlatformPaint().
358 NativeDrawingContext BeginPlatformPaint();
359
360 // Signifies the end of platform drawing using the native drawing context
361 // returned by BeginPlatformPaint().
362 void EndPlatformPaint();
363
364 // Apply transformation on the canvas.
365 void Transform(const ui::Transform& transform);
366
[email protected]3127f6632012-03-17 00:14:06367 // Draws the given string with the beginning and/or the end using a fade
368 // gradient. When truncating the head
369 // |desired_characters_to_truncate_from_head| specifies the maximum number of
370 // characters that can be truncated.
371 void DrawFadeTruncatingString(
372 const string16& text,
373 TruncateFadeMode truncate_mode,
374 size_t desired_characters_to_truncate_from_head,
375 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42376 SkColor color,
[email protected]3127f6632012-03-17 00:14:06377 const gfx::Rect& display_rect);
[email protected]3127f6632012-03-17 00:14:06378
379 skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); }
380 SkCanvas* sk_canvas() const { return canvas_; }
[email protected]3b2591a2012-06-27 17:58:41381 ui::ScaleFactor scale_factor() const { return scale_factor_; }
[email protected]3127f6632012-03-17 00:14:06382
383 private:
[email protected]de13f352012-07-24 16:51:16384 Canvas(SkCanvas* canvas, ui::ScaleFactor scale_factor);
385
[email protected]3127f6632012-03-17 00:14:06386 // Test whether the provided rectangle intersects the current clip rect.
387 bool IntersectsClipRectInt(int x, int y, int w, int h);
[email protected]0834e1b12012-04-11 02:23:56388 bool IntersectsClipRect(const gfx::Rect& rect);
[email protected]3127f6632012-03-17 00:14:06389
[email protected]8232da6b2012-07-02 19:41:15390 // Returns the image rep which best matches the canvas |scale_factor_|.
391 // Returns a null image rep if |image| contains no image reps.
392 // Builds mip map for returned image rep if necessary.
[email protected]35d53342012-05-16 21:30:12393 //
394 // An optional additional user defined scale can be provided.
[email protected]8232da6b2012-07-02 19:41:15395 const gfx::ImageSkiaRep& GetImageRepToPaint(
396 const gfx::ImageSkia& image) const;
397 const gfx::ImageSkiaRep& GetImageRepToPaint(
398 const gfx::ImageSkia& image,
399 float user_defined_scale_factor_x,
400 float user_defined_scale_factor_y) const;
[email protected]35d53342012-05-16 21:30:12401
[email protected]3b2591a2012-06-27 17:58:41402 // The device scale factor at which drawing on this canvas occurs.
403 // An additional scale can be applied via Canvas::Scale(). However,
404 // Canvas::Scale() does not affect |scale_factor_|.
405 ui::ScaleFactor scale_factor_;
406
[email protected]de13f352012-07-24 16:51:16407 scoped_ptr<skia::PlatformCanvas> owned_canvas_;
408 SkCanvas* canvas_;
409
[email protected]3127f6632012-03-17 00:14:06410 DISALLOW_COPY_AND_ASSIGN(Canvas);
[email protected]267c03d2011-02-02 23:03:07411};
412
[email protected]7fe28392011-10-27 00:16:05413} // namespace gfx
[email protected]267c03d2011-02-02 23:03:07414
415#endif // UI_GFX_CANVAS_H_