blob: 69f402be1fd22bdb0c743e226421c497fc60e03d [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_
7#pragma once
8
[email protected]0834e1b12012-04-11 02:23:569#include <vector>
10
[email protected]3127f6632012-03-17 00:14:0611#include "base/basictypes.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/string16.h"
14#include "skia/ext/platform_canvas.h"
[email protected]35d53342012-05-16 21:30:1215#include "ui/gfx/image/image_skia.h"
[email protected]3127f6632012-03-17 00:14:0616#include "ui/gfx/native_widget_types.h"
17
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 Brush;
27class Rect;
28class Font;
29class Point;
[email protected]0834e1b12012-04-11 02:23:5630class ShadowValue;
[email protected]3127f6632012-03-17 00:14:0631class Size;
32
33// Canvas is a SkCanvas wrapper that provides a number of methods for
34// common operations used throughout an application built using ui/gfx.
35//
36// All methods that take integer arguments (as is used throughout views)
37// end with Int. If you need to use methods provided by SkCanvas, you'll
38// need to do a conversion. In particular you'll need to use |SkIntToScalar()|,
39// or if converting from a scalar to an integer |SkScalarRound()|.
40//
41// A handful of methods in this class are overloaded providing an additional
42// argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the
43// source and destination colors are combined. Unless otherwise specified,
44// the variant that does not take a SkXfermode::Mode uses a transfer mode
45// of kSrcOver_Mode.
46class UI_EXPORT Canvas {
[email protected]267c03d2011-02-02 23:03:0747 public:
[email protected]3127f6632012-03-17 00:14:0648 enum TruncateFadeMode {
49 TruncateFadeTail,
50 TruncateFadeHead,
51 TruncateFadeHeadAndTail,
52 };
53
54 // Specifies the alignment for text rendered with the DrawStringInt method.
55 enum {
56 TEXT_ALIGN_LEFT = 1 << 0,
57 TEXT_ALIGN_CENTER = 1 << 1,
58 TEXT_ALIGN_RIGHT = 1 << 2 ,
59 TEXT_VALIGN_TOP = 1 << 3,
60 TEXT_VALIGN_MIDDLE = 1 << 4,
61 TEXT_VALIGN_BOTTOM = 1 << 5,
62
63 // Specifies the text consists of multiple lines.
64 MULTI_LINE = 1 << 6,
65
66 // By default DrawStringInt does not process the prefix ('&') character
67 // specially. That is, the string "&foo" is rendered as "&foo". When
68 // rendering text from a resource that uses the prefix character for
69 // mnemonics, the prefix should be processed and can be rendered as an
70 // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX).
71 SHOW_PREFIX = 1 << 7,
72 HIDE_PREFIX = 1 << 8,
73
74 // Prevent ellipsizing
75 NO_ELLIPSIS = 1 << 9,
76
77 // Specifies if words can be split by new lines.
78 // This only works with MULTI_LINE.
79 CHARACTER_BREAK = 1 << 10,
80
81 // Instructs DrawStringInt() to render the text using RTL directionality.
82 // In most cases, passing this flag is not necessary because information
83 // about the text directionality is going to be embedded within the string
84 // in the form of special Unicode characters. However, we don't insert
85 // directionality characters into strings if the locale is LTR because some
86 // platforms (for example, an English Windows XP with no RTL fonts
87 // installed) don't support these characters. Thus, this flag should be
88 // used to render text using RTL directionality when the locale is LTR.
89 FORCE_RTL_DIRECTIONALITY = 1 << 11,
90
91 // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right.
92 // See FORCE_RTL_DIRECTIONALITY for details.
93 FORCE_LTR_DIRECTIONALITY = 1 << 12,
94
95 // Instructs DrawStringInt() to not use subpixel rendering. This is useful
96 // when rendering text onto a fully- or partially-transparent background
97 // that will later be blended with another image.
98 NO_SUBPIXEL_RENDERING = 1 << 13,
99 };
100
101 // Creates an empty canvas.
[email protected]94a0d2582012-03-09 00:30:59102 Canvas();
[email protected]267c03d2011-02-02 23:03:07103
[email protected]3127f6632012-03-17 00:14:06104 // If this canvas is not opaque, it's explicitly cleared to transparent before
105 // being returned.
106 Canvas(const gfx::Size& size, bool is_opaque);
107
108 // Constructs a canvas the size of the provided |bitmap|, and draws the
109 // bitmap into it.
110 Canvas(const SkBitmap& bitmap, bool is_opaque);
111
[email protected]94a0d2582012-03-09 00:30:59112 explicit Canvas(SkCanvas* canvas);
[email protected]267c03d2011-02-02 23:03:07113
[email protected]3127f6632012-03-17 00:14:06114 virtual ~Canvas();
[email protected]267c03d2011-02-02 23:03:07115
[email protected]3127f6632012-03-17 00:14:06116 // Compute the size required to draw some text with the provided font.
117 // Attempts to fit the text with the provided width and height. Increases
118 // height and then width as needed to make the text fit. This method
119 // supports multiple lines.
120 static void SizeStringInt(const string16& text,
121 const gfx::Font& font,
122 int* width, int* height,
123 int flags);
124
125 // Returns the number of horizontal pixels needed to display the specified
126 // |text| with |font|.
127 static int GetStringWidth(const string16& text, const gfx::Font& font);
128
129 // Returns the default text alignment to be used when drawing text on a
130 // gfx::Canvas based on the directionality of the system locale language.
131 // This function is used by gfx::Canvas::DrawStringInt when the text alignment
132 // is not specified.
133 //
134 // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or
135 // gfx::Canvas::TEXT_ALIGN_RIGHT.
136 static int DefaultCanvasTextAlignment();
137
138 // Draws text with a 1-pixel halo around it of the given color.
139 // On Windows, it allows ClearType to be drawn to an otherwise transparenct
140 // bitmap for drag images. Drag images have only 1-bit of transparency, so
141 // we don't do any fancy blurring.
142 // On Linux, text with halo is created by stroking it with 2px |halo_color|
143 // then filling it with |text_color|.
144 // On Mac, NOTIMPLEMENTED.
145 // TODO(dhollowa): Skia-native implementation is underway. Cut over to
146 // that when ready. http::/crbug.com/109946
147 void DrawStringWithHalo(const string16& text,
148 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42149 SkColor text_color,
150 SkColor halo_color,
[email protected]3127f6632012-03-17 00:14:06151 int x, int y, int w, int h,
152 int flags);
153
154 // Extracts a bitmap from the contents of this canvas.
155 SkBitmap ExtractBitmap() const;
156
157 // Draws a dashed rectangle of the specified color.
158 void DrawDashedRect(const gfx::Rect& rect, SkColor color);
159
160 // Saves a copy of the drawing state onto a stack, operating on this copy
161 // until a balanced call to Restore() is made.
162 void Save();
163
164 // As with Save(), except draws to a layer that is blended with the canvas
165 // at the specified alpha once Restore() is called.
166 // |layer_bounds| are the bounds of the layer relative to the current
167 // transform.
168 void SaveLayerAlpha(uint8 alpha);
169 void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds);
170
171 // Restores the drawing state after a call to Save*(). It is an error to
172 // call Restore() more times than Save*().
173 void Restore() ;
174
[email protected]ffdd1fd2012-04-09 23:24:41175 // Adds |rect| to the current clip. Returns true if the resulting clip is
176 // non-empty.
[email protected]3127f6632012-03-17 00:14:06177 bool ClipRect(const gfx::Rect& rect);
178
[email protected]ffdd1fd2012-04-09 23:24:41179 // Adds |path| to the current clip. Returns true if the resulting clip is
180 // non-empty.
181 bool ClipPath(const SkPath& path);
182
183 // Returns the bounds of the current clip (in local coordinates) in the
184 // |bounds| parameter, and returns true if it is non empty.
185 bool GetClipBounds(gfx::Rect* bounds);
186
[email protected]3127f6632012-03-17 00:14:06187 void Translate(const gfx::Point& point);
188
189 void Scale(int x_scale, int y_scale);
190
[email protected]ffdd1fd2012-04-09 23:24:41191 // Fills the entire canvas' bitmap (restricted to current clip) with
192 // specified |color| using a transfer mode of SkXfermode::kSrcOver_Mode.
193 void DrawColor(SkColor color);
194
195 // Fills the entire canvas' bitmap (restricted to current clip) with
196 // specified |color| and |mode|.
197 void DrawColor(SkColor color, SkXfermode::Mode mode);
198
[email protected]3127f6632012-03-17 00:14:06199 // Fills |rect| with |color| using a transfer mode of
200 // SkXfermode::kSrcOver_Mode.
[email protected]1b81ff22012-03-24 22:04:42201 void FillRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06202
203 // Fills |rect| with the specified |color| and |mode|.
[email protected]1b81ff22012-03-24 22:04:42204 void FillRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06205
[email protected]3127f6632012-03-17 00:14:06206 // Draws a single pixel rect in the specified region with the specified
207 // color, using a transfer mode of SkXfermode::kSrcOver_Mode.
208 //
209 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42210 void DrawRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06211
212 // Draws a single pixel rect in the specified region with the specified
213 // color and transfer mode.
214 //
215 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42216 void DrawRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06217
[email protected]ffdd1fd2012-04-09 23:24:41218 // Draws the given rectangle with the given |paint| parameters.
[email protected]3127f6632012-03-17 00:14:06219 void DrawRect(const gfx::Rect& rect, const SkPaint& paint);
220
[email protected]ffdd1fd2012-04-09 23:24:41221 // Draw the given point with the given |paint| parameters.
222 void DrawPoint(const gfx::Point& p, const SkPaint& paint);
223
[email protected]3127f6632012-03-17 00:14:06224 // Draws a single pixel line with the specified color.
[email protected]1b81ff22012-03-24 22:04:42225 void DrawLine(const gfx::Point& p1, const gfx::Point& p2, SkColor color);
[email protected]3127f6632012-03-17 00:14:06226
[email protected]ffdd1fd2012-04-09 23:24:41227 // Draws a line with the given |paint| parameters.
228 void DrawLine(const gfx::Point& p1,
229 const gfx::Point& p2,
230 const SkPaint& paint);
231
232 // Draws a circle with the given |paint| parameters.
233 void DrawCircle(const gfx::Point& center_point,
234 int radius,
235 const SkPaint& paint);
236
237 // Draws the given rectangle with rounded corners of |radius| using the
238 // given |paint| parameters.
239 void DrawRoundRect(const gfx::Rect& rect, int radius, const SkPaint& paint);
240
241 // Draws the given path using the given |paint| parameters.
242 void DrawPath(const SkPath& path, const SkPaint& paint);
243
[email protected]35d53342012-05-16 21:30:12244 // Draws an image with the origin at the specified location. The upper left
[email protected]3127f6632012-03-17 00:14:06245 // corner of the bitmap is rendered at the specified location.
[email protected]35d53342012-05-16 21:30:12246 // Parameters are specified relative to current canvas scale not in pixels.
247 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
248 void DrawBitmapInt(const gfx::ImageSkia&, int x, int y);
[email protected]3127f6632012-03-17 00:14:06249
[email protected]35d53342012-05-16 21:30:12250 // Draws an image with the origin at the specified location, using the
[email protected]3127f6632012-03-17 00:14:06251 // specified paint. The upper left corner of the bitmap is rendered at the
252 // specified location.
[email protected]35d53342012-05-16 21:30:12253 // Parameters are specified relative to current canvas scale not in pixels.
254 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
255 void DrawBitmapInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06256 int x, int y,
257 const SkPaint& paint);
258
[email protected]35d53342012-05-16 21:30:12259 // Draws a portion of an image in the specified location. The src parameters
[email protected]3127f6632012-03-17 00:14:06260 // correspond to the region of the bitmap to draw in the region defined
261 // by the dest coordinates.
262 //
263 // If the width or height of the source differs from that of the destination,
[email protected]35d53342012-05-16 21:30:12264 // the image will be scaled. When scaling down, a mipmap will be generated.
265 // Set |filter| to use filtering for images, otherwise the nearest-neighbor
266 // algorithm is used for resampling.
[email protected]3127f6632012-03-17 00:14:06267 //
268 // An optional custom SkPaint can be provided.
[email protected]35d53342012-05-16 21:30:12269 // Parameters are specified relative to current canvas scale not in pixels.
270 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
271 void DrawBitmapInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06272 int src_x, int src_y, int src_w, int src_h,
273 int dest_x, int dest_y, int dest_w, int dest_h,
274 bool filter);
[email protected]35d53342012-05-16 21:30:12275 void DrawBitmapInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06276 int src_x, int src_y, int src_w, int src_h,
277 int dest_x, int dest_y, int dest_w, int dest_h,
278 bool filter,
279 const SkPaint& paint);
280
281 // Draws text with the specified color, font and location. The text is
282 // aligned to the left, vertically centered, clipped to the region. If the
283 // text is too big, it is truncated and '...' is added to the end.
284 void DrawStringInt(const string16& text,
285 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42286 SkColor color,
[email protected]3127f6632012-03-17 00:14:06287 int x, int y, int w, int h);
288 void DrawStringInt(const string16& text,
289 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42290 SkColor color,
[email protected]3127f6632012-03-17 00:14:06291 const gfx::Rect& display_rect);
292
293 // Draws text with the specified color, font and location. The last argument
294 // specifies flags for how the text should be rendered. It can be one of
295 // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT.
296 void DrawStringInt(const string16& text,
297 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42298 SkColor color,
[email protected]3127f6632012-03-17 00:14:06299 int x, int y, int w, int h,
300 int flags);
301
[email protected]0834e1b12012-04-11 02:23:56302 // Similar to above DrawStringInt method but with text shadows support.
303 // Currently it's only implemented for canvas skia.
304 void DrawStringWithShadows(const string16& text,
305 const gfx::Font& font,
306 SkColor color,
307 const gfx::Rect& text_bounds,
308 int flags,
309 const std::vector<ShadowValue>& shadows);
310
[email protected]3127f6632012-03-17 00:14:06311 // Draws a dotted gray rectangle used for focus purposes.
312 void DrawFocusRect(const gfx::Rect& rect);
313
314 // Tiles the image in the specified region.
[email protected]35d53342012-05-16 21:30:12315 // Parameters are specified relative to current canvas scale not in pixels.
316 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1.
317 void TileImageInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06318 int x, int y, int w, int h);
[email protected]35d53342012-05-16 21:30:12319 void TileImageInt(const gfx::ImageSkia& image,
[email protected]3127f6632012-03-17 00:14:06320 int src_x, int src_y,
321 int dest_x, int dest_y, int w, int h);
322
323 // Returns a native drawing context for platform specific drawing routines to
324 // use. Must be balanced by a call to EndPlatformPaint().
325 NativeDrawingContext BeginPlatformPaint();
326
327 // Signifies the end of platform drawing using the native drawing context
328 // returned by BeginPlatformPaint().
329 void EndPlatformPaint();
330
331 // Apply transformation on the canvas.
332 void Transform(const ui::Transform& transform);
333
334#if defined(OS_WIN)
335 // Draws the given string with the beginning and/or the end using a fade
336 // gradient. When truncating the head
337 // |desired_characters_to_truncate_from_head| specifies the maximum number of
338 // characters that can be truncated.
339 void DrawFadeTruncatingString(
340 const string16& text,
341 TruncateFadeMode truncate_mode,
342 size_t desired_characters_to_truncate_from_head,
343 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42344 SkColor color,
[email protected]3127f6632012-03-17 00:14:06345 const gfx::Rect& display_rect);
346#endif
347
348 skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); }
349 SkCanvas* sk_canvas() const { return canvas_; }
350
351 private:
352 // Test whether the provided rectangle intersects the current clip rect.
353 bool IntersectsClipRectInt(int x, int y, int w, int h);
[email protected]0834e1b12012-04-11 02:23:56354 bool IntersectsClipRect(const gfx::Rect& rect);
[email protected]3127f6632012-03-17 00:14:06355
[email protected]35d53342012-05-16 21:30:12356 // Returns the bitmap whose density best matches the current canvas scale.
357 // Returns a null bitmap if |image| contains no bitmaps.
358 // |bitmap_scale_factor| is set to the scale factor of the returned bitmap.
359 // Builds mip map for returned bitmap if necessary.
360 //
361 // An optional additional user defined scale can be provided.
362 const SkBitmap& GetBitmapToPaint(const gfx::ImageSkia& image,
363 float* bitmap_scale_factor) const;
364 const SkBitmap& GetBitmapToPaint(const gfx::ImageSkia& image,
365 float user_defined_scale_factor_x,
366 float user_defined_scale_factor_y,
367 float* bitmap_scale_factor) const;
368
[email protected]3127f6632012-03-17 00:14:06369#if defined(OS_WIN)
370 // Draws text with the specified color, font and location. The text is
371 // aligned to the left, vertically centered, clipped to the region. If the
372 // text is too big, it is truncated and '...' is added to the end.
373 void DrawStringInt(const string16& text,
374 HFONT font,
[email protected]1b81ff22012-03-24 22:04:42375 SkColor color,
[email protected]0834e1b12012-04-11 02:23:56376 const gfx::Rect& text_bounds,
[email protected]3127f6632012-03-17 00:14:06377 int flags);
378#endif
379
380 scoped_ptr<skia::PlatformCanvas> owned_canvas_;
381 SkCanvas* canvas_;
382
383 DISALLOW_COPY_AND_ASSIGN(Canvas);
[email protected]267c03d2011-02-02 23:03:07384};
385
[email protected]7fe28392011-10-27 00:16:05386} // namespace gfx
[email protected]267c03d2011-02-02 23:03:07387
388#endif // UI_GFX_CANVAS_H_