blob: dd2e76467c69a58679f0fa2678d0148cd6750837 [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"
15#include "ui/gfx/native_widget_types.h"
16
17class SkBitmap;
18
19namespace ui {
20class Transform;
21}
[email protected]36df22b2011-02-24 21:47:5622
[email protected]267c03d2011-02-02 23:03:0723namespace gfx {
24
[email protected]3127f6632012-03-17 00:14:0625class Brush;
26class Rect;
27class Font;
28class Point;
[email protected]0834e1b12012-04-11 02:23:5629class ShadowValue;
[email protected]3127f6632012-03-17 00:14:0630class Size;
31
32// Canvas is a SkCanvas wrapper that provides a number of methods for
33// common operations used throughout an application built using ui/gfx.
34//
35// All methods that take integer arguments (as is used throughout views)
36// end with Int. If you need to use methods provided by SkCanvas, you'll
37// need to do a conversion. In particular you'll need to use |SkIntToScalar()|,
38// or if converting from a scalar to an integer |SkScalarRound()|.
39//
40// A handful of methods in this class are overloaded providing an additional
41// argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the
42// source and destination colors are combined. Unless otherwise specified,
43// the variant that does not take a SkXfermode::Mode uses a transfer mode
44// of kSrcOver_Mode.
45class UI_EXPORT Canvas {
[email protected]267c03d2011-02-02 23:03:0746 public:
[email protected]3127f6632012-03-17 00:14:0647 enum TruncateFadeMode {
48 TruncateFadeTail,
49 TruncateFadeHead,
50 TruncateFadeHeadAndTail,
51 };
52
53 // Specifies the alignment for text rendered with the DrawStringInt method.
54 enum {
55 TEXT_ALIGN_LEFT = 1 << 0,
56 TEXT_ALIGN_CENTER = 1 << 1,
57 TEXT_ALIGN_RIGHT = 1 << 2 ,
58 TEXT_VALIGN_TOP = 1 << 3,
59 TEXT_VALIGN_MIDDLE = 1 << 4,
60 TEXT_VALIGN_BOTTOM = 1 << 5,
61
62 // Specifies the text consists of multiple lines.
63 MULTI_LINE = 1 << 6,
64
65 // By default DrawStringInt does not process the prefix ('&') character
66 // specially. That is, the string "&foo" is rendered as "&foo". When
67 // rendering text from a resource that uses the prefix character for
68 // mnemonics, the prefix should be processed and can be rendered as an
69 // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX).
70 SHOW_PREFIX = 1 << 7,
71 HIDE_PREFIX = 1 << 8,
72
73 // Prevent ellipsizing
74 NO_ELLIPSIS = 1 << 9,
75
76 // Specifies if words can be split by new lines.
77 // This only works with MULTI_LINE.
78 CHARACTER_BREAK = 1 << 10,
79
80 // Instructs DrawStringInt() to render the text using RTL directionality.
81 // In most cases, passing this flag is not necessary because information
82 // about the text directionality is going to be embedded within the string
83 // in the form of special Unicode characters. However, we don't insert
84 // directionality characters into strings if the locale is LTR because some
85 // platforms (for example, an English Windows XP with no RTL fonts
86 // installed) don't support these characters. Thus, this flag should be
87 // used to render text using RTL directionality when the locale is LTR.
88 FORCE_RTL_DIRECTIONALITY = 1 << 11,
89
90 // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right.
91 // See FORCE_RTL_DIRECTIONALITY for details.
92 FORCE_LTR_DIRECTIONALITY = 1 << 12,
93
94 // Instructs DrawStringInt() to not use subpixel rendering. This is useful
95 // when rendering text onto a fully- or partially-transparent background
96 // that will later be blended with another image.
97 NO_SUBPIXEL_RENDERING = 1 << 13,
98 };
99
100 // Creates an empty canvas.
[email protected]94a0d2582012-03-09 00:30:59101 Canvas();
[email protected]267c03d2011-02-02 23:03:07102
[email protected]3127f6632012-03-17 00:14:06103 // If this canvas is not opaque, it's explicitly cleared to transparent before
104 // being returned.
105 Canvas(const gfx::Size& size, bool is_opaque);
106
107 // Constructs a canvas the size of the provided |bitmap|, and draws the
108 // bitmap into it.
109 Canvas(const SkBitmap& bitmap, bool is_opaque);
110
[email protected]94a0d2582012-03-09 00:30:59111 explicit Canvas(SkCanvas* canvas);
[email protected]267c03d2011-02-02 23:03:07112
[email protected]3127f6632012-03-17 00:14:06113 virtual ~Canvas();
[email protected]267c03d2011-02-02 23:03:07114
[email protected]3127f6632012-03-17 00:14:06115 // Compute the size required to draw some text with the provided font.
116 // Attempts to fit the text with the provided width and height. Increases
117 // height and then width as needed to make the text fit. This method
118 // supports multiple lines.
119 static void SizeStringInt(const string16& text,
120 const gfx::Font& font,
121 int* width, int* height,
122 int flags);
123
124 // Returns the number of horizontal pixels needed to display the specified
125 // |text| with |font|.
126 static int GetStringWidth(const string16& text, const gfx::Font& font);
127
128 // Returns the default text alignment to be used when drawing text on a
129 // gfx::Canvas based on the directionality of the system locale language.
130 // This function is used by gfx::Canvas::DrawStringInt when the text alignment
131 // is not specified.
132 //
133 // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or
134 // gfx::Canvas::TEXT_ALIGN_RIGHT.
135 static int DefaultCanvasTextAlignment();
136
137 // Draws text with a 1-pixel halo around it of the given color.
138 // On Windows, it allows ClearType to be drawn to an otherwise transparenct
139 // bitmap for drag images. Drag images have only 1-bit of transparency, so
140 // we don't do any fancy blurring.
141 // On Linux, text with halo is created by stroking it with 2px |halo_color|
142 // then filling it with |text_color|.
143 // On Mac, NOTIMPLEMENTED.
144 // TODO(dhollowa): Skia-native implementation is underway. Cut over to
145 // that when ready. http::/crbug.com/109946
146 void DrawStringWithHalo(const string16& text,
147 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42148 SkColor text_color,
149 SkColor halo_color,
[email protected]3127f6632012-03-17 00:14:06150 int x, int y, int w, int h,
151 int flags);
152
153 // Extracts a bitmap from the contents of this canvas.
154 SkBitmap ExtractBitmap() const;
155
156 // Draws a dashed rectangle of the specified color.
157 void DrawDashedRect(const gfx::Rect& rect, SkColor color);
158
159 // Saves a copy of the drawing state onto a stack, operating on this copy
160 // until a balanced call to Restore() is made.
161 void Save();
162
163 // As with Save(), except draws to a layer that is blended with the canvas
164 // at the specified alpha once Restore() is called.
165 // |layer_bounds| are the bounds of the layer relative to the current
166 // transform.
167 void SaveLayerAlpha(uint8 alpha);
168 void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds);
169
170 // Restores the drawing state after a call to Save*(). It is an error to
171 // call Restore() more times than Save*().
172 void Restore() ;
173
[email protected]ffdd1fd2012-04-09 23:24:41174 // Adds |rect| to the current clip. Returns true if the resulting clip is
175 // non-empty.
[email protected]3127f6632012-03-17 00:14:06176 bool ClipRect(const gfx::Rect& rect);
177
[email protected]ffdd1fd2012-04-09 23:24:41178 // Adds |path| to the current clip. Returns true if the resulting clip is
179 // non-empty.
180 bool ClipPath(const SkPath& path);
181
182 // Returns the bounds of the current clip (in local coordinates) in the
183 // |bounds| parameter, and returns true if it is non empty.
184 bool GetClipBounds(gfx::Rect* bounds);
185
[email protected]3127f6632012-03-17 00:14:06186 void Translate(const gfx::Point& point);
187
188 void Scale(int x_scale, int y_scale);
189
[email protected]ffdd1fd2012-04-09 23:24:41190 // Fills the entire canvas' bitmap (restricted to current clip) with
191 // specified |color| using a transfer mode of SkXfermode::kSrcOver_Mode.
192 void DrawColor(SkColor color);
193
194 // Fills the entire canvas' bitmap (restricted to current clip) with
195 // specified |color| and |mode|.
196 void DrawColor(SkColor color, SkXfermode::Mode mode);
197
[email protected]3127f6632012-03-17 00:14:06198 // Fills |rect| with |color| using a transfer mode of
199 // SkXfermode::kSrcOver_Mode.
[email protected]1b81ff22012-03-24 22:04:42200 void FillRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06201
202 // Fills |rect| with the specified |color| and |mode|.
[email protected]1b81ff22012-03-24 22:04:42203 void FillRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06204
[email protected]3127f6632012-03-17 00:14:06205 // Draws a single pixel rect in the specified region with the specified
206 // color, using a transfer mode of SkXfermode::kSrcOver_Mode.
207 //
208 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42209 void DrawRect(const gfx::Rect& rect, SkColor color);
[email protected]3127f6632012-03-17 00:14:06210
211 // Draws a single pixel rect in the specified region with the specified
212 // color and transfer mode.
213 //
214 // NOTE: if you need a single pixel line, use DrawLine.
[email protected]1b81ff22012-03-24 22:04:42215 void DrawRect(const gfx::Rect& rect, SkColor color, SkXfermode::Mode mode);
[email protected]3127f6632012-03-17 00:14:06216
[email protected]ffdd1fd2012-04-09 23:24:41217 // Draws the given rectangle with the given |paint| parameters.
[email protected]3127f6632012-03-17 00:14:06218 void DrawRect(const gfx::Rect& rect, const SkPaint& paint);
219
[email protected]ffdd1fd2012-04-09 23:24:41220 // Draw the given point with the given |paint| parameters.
221 void DrawPoint(const gfx::Point& p, const SkPaint& paint);
222
[email protected]3127f6632012-03-17 00:14:06223 // Draws a single pixel line with the specified color.
[email protected]1b81ff22012-03-24 22:04:42224 void DrawLine(const gfx::Point& p1, const gfx::Point& p2, SkColor color);
[email protected]3127f6632012-03-17 00:14:06225
[email protected]ffdd1fd2012-04-09 23:24:41226 // Draws a line with the given |paint| parameters.
227 void DrawLine(const gfx::Point& p1,
228 const gfx::Point& p2,
229 const SkPaint& paint);
230
231 // Draws a circle with the given |paint| parameters.
232 void DrawCircle(const gfx::Point& center_point,
233 int radius,
234 const SkPaint& paint);
235
236 // Draws the given rectangle with rounded corners of |radius| using the
237 // given |paint| parameters.
238 void DrawRoundRect(const gfx::Rect& rect, int radius, const SkPaint& paint);
239
240 // Draws the given path using the given |paint| parameters.
241 void DrawPath(const SkPath& path, const SkPaint& paint);
242
[email protected]3127f6632012-03-17 00:14:06243 // Draws a bitmap with the origin at the specified location. The upper left
244 // corner of the bitmap is rendered at the specified location.
245 void DrawBitmapInt(const SkBitmap& bitmap, int x, int y);
246
247 // Draws a bitmap with the origin at the specified location, using the
248 // specified paint. The upper left corner of the bitmap is rendered at the
249 // specified location.
250 void DrawBitmapInt(const SkBitmap& bitmap,
251 int x, int y,
252 const SkPaint& paint);
253
254 // Draws a portion of a bitmap in the specified location. The src parameters
255 // correspond to the region of the bitmap to draw in the region defined
256 // by the dest coordinates.
257 //
258 // If the width or height of the source differs from that of the destination,
259 // the bitmap will be scaled. When scaling down, it is highly recommended
260 // that you call buildMipMap(false) on your bitmap to ensure that it has
261 // a mipmap, which will result in much higher-quality output. Set |filter|
262 // to use filtering for bitmaps, otherwise the nearest-neighbor algorithm
263 // is used for resampling.
264 //
265 // An optional custom SkPaint can be provided.
266 void DrawBitmapInt(const SkBitmap& bitmap,
267 int src_x, int src_y, int src_w, int src_h,
268 int dest_x, int dest_y, int dest_w, int dest_h,
269 bool filter);
270 void DrawBitmapInt(const SkBitmap& bitmap,
271 int src_x, int src_y, int src_w, int src_h,
272 int dest_x, int dest_y, int dest_w, int dest_h,
273 bool filter,
274 const SkPaint& paint);
275
276 // Draws text with the specified color, font and location. The text is
277 // aligned to the left, vertically centered, clipped to the region. If the
278 // text is too big, it is truncated and '...' is added to the end.
279 void DrawStringInt(const string16& text,
280 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42281 SkColor color,
[email protected]3127f6632012-03-17 00:14:06282 int x, int y, int w, int h);
283 void DrawStringInt(const string16& text,
284 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42285 SkColor color,
[email protected]3127f6632012-03-17 00:14:06286 const gfx::Rect& display_rect);
287
288 // Draws text with the specified color, font and location. The last argument
289 // specifies flags for how the text should be rendered. It can be one of
290 // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT.
291 void DrawStringInt(const string16& text,
292 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42293 SkColor color,
[email protected]3127f6632012-03-17 00:14:06294 int x, int y, int w, int h,
295 int flags);
296
[email protected]0834e1b12012-04-11 02:23:56297 // Similar to above DrawStringInt method but with text shadows support.
298 // Currently it's only implemented for canvas skia.
299 void DrawStringWithShadows(const string16& text,
300 const gfx::Font& font,
301 SkColor color,
302 const gfx::Rect& text_bounds,
303 int flags,
304 const std::vector<ShadowValue>& shadows);
305
[email protected]3127f6632012-03-17 00:14:06306 // Draws a dotted gray rectangle used for focus purposes.
307 void DrawFocusRect(const gfx::Rect& rect);
308
309 // Tiles the image in the specified region.
310 void TileImageInt(const SkBitmap& bitmap,
311 int x, int y, int w, int h);
312 void TileImageInt(const SkBitmap& bitmap,
313 int src_x, int src_y,
314 int dest_x, int dest_y, int w, int h);
315
316 // Returns a native drawing context for platform specific drawing routines to
317 // use. Must be balanced by a call to EndPlatformPaint().
318 NativeDrawingContext BeginPlatformPaint();
319
320 // Signifies the end of platform drawing using the native drawing context
321 // returned by BeginPlatformPaint().
322 void EndPlatformPaint();
323
324 // Apply transformation on the canvas.
325 void Transform(const ui::Transform& transform);
326
327#if defined(OS_WIN)
328 // Draws the given string with the beginning and/or the end using a fade
329 // gradient. When truncating the head
330 // |desired_characters_to_truncate_from_head| specifies the maximum number of
331 // characters that can be truncated.
332 void DrawFadeTruncatingString(
333 const string16& text,
334 TruncateFadeMode truncate_mode,
335 size_t desired_characters_to_truncate_from_head,
336 const gfx::Font& font,
[email protected]1b81ff22012-03-24 22:04:42337 SkColor color,
[email protected]3127f6632012-03-17 00:14:06338 const gfx::Rect& display_rect);
339#endif
340
341 skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); }
342 SkCanvas* sk_canvas() const { return canvas_; }
343
344 private:
345 // Test whether the provided rectangle intersects the current clip rect.
346 bool IntersectsClipRectInt(int x, int y, int w, int h);
[email protected]0834e1b12012-04-11 02:23:56347 bool IntersectsClipRect(const gfx::Rect& rect);
[email protected]3127f6632012-03-17 00:14:06348
349#if defined(OS_WIN)
350 // Draws text with the specified color, font and location. The text is
351 // aligned to the left, vertically centered, clipped to the region. If the
352 // text is too big, it is truncated and '...' is added to the end.
353 void DrawStringInt(const string16& text,
354 HFONT font,
[email protected]1b81ff22012-03-24 22:04:42355 SkColor color,
[email protected]0834e1b12012-04-11 02:23:56356 const gfx::Rect& text_bounds,
[email protected]3127f6632012-03-17 00:14:06357 int flags);
358#endif
359
360 scoped_ptr<skia::PlatformCanvas> owned_canvas_;
361 SkCanvas* canvas_;
362
363 DISALLOW_COPY_AND_ASSIGN(Canvas);
[email protected]267c03d2011-02-02 23:03:07364};
365
[email protected]7fe28392011-10-27 00:16:05366} // namespace gfx
[email protected]267c03d2011-02-02 23:03:07367
368#endif // UI_GFX_CANVAS_H_