OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // 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 | |
8 #include <vector> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/strings/string16.h" | |
13 #include "skia/ext/platform_canvas.h" | |
14 #include "skia/ext/refptr.h" | |
15 #include "ui/gfx/image/image_skia.h" | |
16 #include "ui/gfx/native_widget_types.h" | |
17 #include "ui/gfx/shadow_value.h" | |
18 #include "ui/gfx/text_constants.h" | |
19 | |
20 namespace gfx { | |
21 | |
22 class Rect; | |
23 class FontList; | |
24 class Point; | |
25 class Size; | |
26 class Transform; | |
27 | |
28 // Canvas is a SkCanvas wrapper that provides a number of methods for | |
29 // common operations used throughout an application built using ui/gfx. | |
30 // | |
31 // All methods that take integer arguments (as is used throughout views) | |
32 // end with Int. If you need to use methods provided by SkCanvas, you'll | |
33 // need to do a conversion. In particular you'll need to use |SkIntToScalar()|, | |
34 // or if converting from a scalar to an integer |SkScalarRound()|. | |
35 // | |
36 // A handful of methods in this class are overloaded providing an additional | |
37 // argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the | |
38 // source and destination colors are combined. Unless otherwise specified, | |
39 // the variant that does not take a SkXfermode::Mode uses a transfer mode | |
40 // of kSrcOver_Mode. | |
41 class GFX_EXPORT Canvas { | |
42 public: | |
43 // Specifies the alignment for text rendered with the DrawStringRect method. | |
44 enum { | |
45 TEXT_ALIGN_LEFT = 1 << 0, | |
46 TEXT_ALIGN_CENTER = 1 << 1, | |
47 TEXT_ALIGN_RIGHT = 1 << 2, | |
48 | |
49 // Specifies the text consists of multiple lines. | |
50 MULTI_LINE = 1 << 3, | |
51 | |
52 // By default DrawStringRect does not process the prefix ('&') character | |
53 // specially. That is, the string "&foo" is rendered as "&foo". When | |
54 // rendering text from a resource that uses the prefix character for | |
55 // mnemonics, the prefix should be processed and can be rendered as an | |
56 // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX). | |
57 SHOW_PREFIX = 1 << 4, | |
58 HIDE_PREFIX = 1 << 5, | |
59 | |
60 // Prevent ellipsizing | |
61 NO_ELLIPSIS = 1 << 6, | |
62 | |
63 // Specifies if words can be split by new lines. | |
64 // This only works with MULTI_LINE. | |
65 CHARACTER_BREAK = 1 << 7, | |
66 | |
67 // Instructs DrawStringRect() to render the text using RTL directionality. | |
68 // In most cases, passing this flag is not necessary because information | |
69 // about the text directionality is going to be embedded within the string | |
70 // in the form of special Unicode characters. However, we don't insert | |
71 // directionality characters into strings if the locale is LTR because some | |
72 // platforms (for example, an English Windows XP with no RTL fonts | |
73 // installed) don't support these characters. Thus, this flag should be | |
74 // used to render text using RTL directionality when the locale is LTR. | |
75 FORCE_RTL_DIRECTIONALITY = 1 << 8, | |
76 | |
77 // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right. | |
78 // See FORCE_RTL_DIRECTIONALITY for details. | |
79 FORCE_LTR_DIRECTIONALITY = 1 << 9, | |
80 | |
81 // Instructs DrawStringRect() to not use subpixel rendering. This is useful | |
82 // when rendering text onto a fully- or partially-transparent background | |
83 // that will later be blended with another image. | |
84 NO_SUBPIXEL_RENDERING = 1 << 10, | |
85 }; | |
86 | |
87 // Creates an empty canvas with image_scale of 1x. | |
88 Canvas(); | |
89 | |
90 // Creates canvas with provided DIP |size| and |image_scale|. | |
91 // If this canvas is not opaque, it's explicitly cleared to transparent before | |
92 // being returned. | |
93 Canvas(const Size& size, float image_scale, bool is_opaque); | |
94 | |
95 // Constructs a canvas with the size and the image_scale of the provided | |
96 // |image_rep|, and draws the |image_rep| into it. | |
97 Canvas(const ImageSkiaRep& image_rep, bool is_opaque); | |
98 | |
99 virtual ~Canvas(); | |
100 | |
101 // Creates a Canvas backed by an |sk_canvas| with |image_scale_|. | |
102 // |sk_canvas| is assumed to be already scaled based on |image_scale| | |
103 // so no additional scaling is applied. | |
104 static Canvas* CreateCanvasWithoutScaling(SkCanvas* sk_canvas, | |
105 float image_scale); | |
106 | |
107 // Recreates the backing platform canvas with DIP |size| and |image_scale_|. | |
108 // If the canvas is not opaque, it is explicitly cleared. | |
109 // This method is public so that canvas_skia_paint can recreate the platform | |
110 // canvas after having initialized the canvas. | |
111 // TODO(pkotwicz): Push the image_scale into skia::PlatformCanvas such that | |
112 // this method can be private. | |
113 void RecreateBackingCanvas(const Size& size, | |
114 float image_scale, | |
115 bool is_opaque); | |
116 | |
117 // Compute the size required to draw some text with the provided fonts. | |
118 // Attempts to fit the text with the provided width and height. Increases | |
119 // height and then width as needed to make the text fit. This method | |
120 // supports multiple lines. On Skia only a line_height can be specified and | |
121 // specifying a 0 value for it will cause the default height to be used. | |
122 static void SizeStringInt(const base::string16& text, | |
123 const FontList& font_list, | |
124 int* width, | |
125 int* height, | |
126 int line_height, | |
127 int flags); | |
128 | |
129 // This is same as SizeStringInt except that fractional size is returned. | |
130 // See comment in GetStringWidthF for its usage. | |
131 static void SizeStringFloat(const base::string16& text, | |
132 const FontList& font_list, | |
133 float* width, | |
134 float* height, | |
135 int line_height, | |
136 int flags); | |
137 | |
138 // Returns the number of horizontal pixels needed to display the specified | |
139 // |text| with |font_list|. | |
140 static int GetStringWidth(const base::string16& text, | |
141 const FontList& font_list); | |
142 | |
143 // This is same as GetStringWidth except that fractional width is returned. | |
144 // Use this method for the scenario that multiple string widths need to be | |
145 // summed up. This is because GetStringWidth returns the ceiled width and | |
146 // adding multiple ceiled widths could cause more precision loss for certain | |
147 // platform like Mac where the fractioal width is used. | |
148 static float GetStringWidthF(const base::string16& text, | |
149 const FontList& font_list); | |
150 | |
151 // Returns the default text alignment to be used when drawing text on a | |
152 // Canvas based on the directionality of the system locale language. | |
153 // This function is used by Canvas::DrawStringRect when the text alignment | |
154 // is not specified. | |
155 // | |
156 // This function returns either Canvas::TEXT_ALIGN_LEFT or | |
157 // Canvas::TEXT_ALIGN_RIGHT. | |
158 static int DefaultCanvasTextAlignment(); | |
159 | |
160 // Draws text with a 1-pixel halo around it of the given color. | |
161 // On Windows, it allows ClearType to be drawn to an otherwise transparent | |
162 // bitmap for drag images. Drag images have only 1-bit of transparency, so | |
163 // we don't do any fancy blurring. | |
164 // On Linux, text with halo is created by stroking it with 2px |halo_color| | |
165 // then filling it with |text_color|. | |
166 // On Mac, NOTIMPLEMENTED. | |
167 // TODO(dhollowa): Skia-native implementation is underway. Cut over to | |
168 // that when ready. http::/crbug.com/109946 | |
169 void DrawStringRectWithHalo(const base::string16& text, | |
170 const FontList& font_list, | |
171 SkColor text_color, | |
172 SkColor halo_color, | |
173 const Rect& display_rect, | |
174 int flags); | |
175 | |
176 // Extracts an ImageSkiaRep from the contents of this canvas. | |
177 ImageSkiaRep ExtractImageRep() const; | |
178 | |
179 // Draws a dashed rectangle of the specified color. | |
180 void DrawDashedRect(const Rect& rect, SkColor color); | |
181 | |
182 // Saves a copy of the drawing state onto a stack, operating on this copy | |
183 // until a balanced call to Restore() is made. | |
184 void Save(); | |
185 | |
186 // As with Save(), except draws to a layer that is blended with the canvas | |
187 // at the specified alpha once Restore() is called. | |
188 // |layer_bounds| are the bounds of the layer relative to the current | |
189 // transform. | |
190 void SaveLayerAlpha(uint8 alpha); | |
191 void SaveLayerAlpha(uint8 alpha, const Rect& layer_bounds); | |
192 | |
193 // Restores the drawing state after a call to Save*(). It is an error to | |
194 // call Restore() more times than Save*(). | |
195 void Restore(); | |
196 | |
197 // Adds |rect| to the current clip. | |
198 void ClipRect(const Rect& rect); | |
199 | |
200 // Adds |path| to the current clip. |do_anti_alias| is true if the clip | |
201 // should be antialiased. | |
202 void ClipPath(const SkPath& path, bool do_anti_alias); | |
203 | |
204 // Returns true if the current clip is empty. | |
205 bool IsClipEmpty() const; | |
206 | |
207 // Returns the bounds of the current clip (in local coordinates) in the | |
208 // |bounds| parameter, and returns true if it is non empty. | |
209 bool GetClipBounds(Rect* bounds); | |
210 | |
211 void Translate(const Vector2d& offset); | |
212 | |
213 void Scale(int x_scale, int y_scale); | |
214 | |
215 // Fills the entire canvas' bitmap (restricted to current clip) with | |
216 // specified |color| using a transfer mode of SkXfermode::kSrcOver_Mode. | |
217 void DrawColor(SkColor color); | |
218 | |
219 // Fills the entire canvas' bitmap (restricted to current clip) with | |
220 // specified |color| and |mode|. | |
221 void DrawColor(SkColor color, SkXfermode::Mode mode); | |
222 | |
223 // Fills |rect| with |color| using a transfer mode of | |
224 // SkXfermode::kSrcOver_Mode. | |
225 void FillRect(const Rect& rect, SkColor color); | |
226 | |
227 // Fills |rect| with the specified |color| and |mode|. | |
228 void FillRect(const Rect& rect, SkColor color, SkXfermode::Mode mode); | |
229 | |
230 // Draws a single pixel rect in the specified region with the specified | |
231 // color, using a transfer mode of SkXfermode::kSrcOver_Mode. | |
232 // | |
233 // NOTE: if you need a single pixel line, use DrawLine. | |
234 void DrawRect(const Rect& rect, SkColor color); | |
235 | |
236 // Draws a single pixel rect in the specified region with the specified | |
237 // color and transfer mode. | |
238 // | |
239 // NOTE: if you need a single pixel line, use DrawLine. | |
240 void DrawRect(const Rect& rect, SkColor color, SkXfermode::Mode mode); | |
241 | |
242 // Draws the given rectangle with the given |paint| parameters. | |
243 void DrawRect(const Rect& rect, const SkPaint& paint); | |
244 | |
245 // Draw the given point with the given |paint| parameters. | |
246 void DrawPoint(const Point& p, const SkPaint& paint); | |
247 | |
248 // Draws a single pixel line with the specified color. | |
249 void DrawLine(const Point& p1, const Point& p2, SkColor color); | |
250 | |
251 // Draws a line with the given |paint| parameters. | |
252 void DrawLine(const Point& p1, const Point& p2, const SkPaint& paint); | |
253 | |
254 // Draws a circle with the given |paint| parameters. | |
255 void DrawCircle(const Point& center_point, | |
256 int radius, | |
257 const SkPaint& paint); | |
258 | |
259 // Draws the given rectangle with rounded corners of |radius| using the | |
260 // given |paint| parameters. | |
261 void DrawRoundRect(const Rect& rect, int radius, const SkPaint& paint); | |
262 | |
263 // Draws the given path using the given |paint| parameters. | |
264 void DrawPath(const SkPath& path, const SkPaint& paint); | |
265 | |
266 // Draws an image with the origin at the specified location. The upper left | |
267 // corner of the bitmap is rendered at the specified location. | |
268 // Parameters are specified relative to current canvas scale not in pixels. | |
269 // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1. | |
270 void DrawImageInt(const ImageSkia&, int x, int y); | |
271 | |
272 // Helper for DrawImageInt(..., paint) that constructs a temporary paint and | |
273 // calls paint.setAlpha(alpha). | |
274 void DrawImageInt(const ImageSkia&, int x, int y, uint8 alpha); | |
275 | |
276 // Draws an image with the origin at the specified location, using the | |
277 // specified paint. The upper left corner of the bitmap is rendered at the | |
278 // specified location. | |
279 // Parameters are specified relative to current canvas scale not in pixels. | |
280 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. | |
281 void DrawImageInt(const ImageSkia& image, | |
282 int x, | |
283 int y, | |
284 const SkPaint& paint); | |
285 | |
286 // Draws a portion of an image in the specified location. The src parameters | |
287 // correspond to the region of the bitmap to draw in the region defined | |
288 // by the dest coordinates. | |
289 // | |
290 // If the width or height of the source differs from that of the destination, | |
291 // the image will be scaled. When scaling down, a mipmap will be generated. | |
292 // Set |filter| to use filtering for images, otherwise the nearest-neighbor | |
293 // algorithm is used for resampling. | |
294 // | |
295 // An optional custom SkPaint can be provided. | |
296 // Parameters are specified relative to current canvas scale not in pixels. | |
297 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. | |
298 void DrawImageInt(const ImageSkia& image, | |
299 int src_x, | |
300 int src_y, | |
301 int src_w, | |
302 int src_h, | |
303 int dest_x, | |
304 int dest_y, | |
305 int dest_w, | |
306 int dest_h, | |
307 bool filter); | |
308 void DrawImageInt(const ImageSkia& image, | |
309 int src_x, | |
310 int src_y, | |
311 int src_w, | |
312 int src_h, | |
313 int dest_x, | |
314 int dest_y, | |
315 int dest_w, | |
316 int dest_h, | |
317 bool filter, | |
318 const SkPaint& paint); | |
319 | |
320 // Same as the DrawImageInt functions above. Difference being this does not | |
321 // do any scaling, i.e. it assumes that the source/destination/image, etc are | |
322 // in pixels. It does translate the destination rectangle to ensure that the | |
323 // image is displayed at the correct pixel coordinates. | |
324 void DrawImageIntInPixel(const ImageSkia& image, | |
325 int src_x, | |
326 int src_y, | |
327 int src_w, | |
328 int src_h, | |
329 int dest_x, | |
330 int dest_y, | |
331 int dest_w, | |
332 int dest_h, | |
333 bool filter, | |
334 const SkPaint& paint); | |
335 | |
336 // Draws an |image| with the top left corner at |x| and |y|, clipped to | |
337 // |path|. | |
338 // Parameters are specified relative to current canvas scale not in pixels. | |
339 // Thus, x is 2 pixels if canvas scale = 2 & |x| = 1. | |
340 void DrawImageInPath(const ImageSkia& image, | |
341 int x, | |
342 int y, | |
343 const SkPath& path, | |
344 const SkPaint& paint); | |
345 | |
346 // Draws text with the specified color, fonts and location. The text is | |
347 // aligned to the left, vertically centered, clipped to the region. If the | |
348 // text is too big, it is truncated and '...' is added to the end. | |
349 void DrawStringRect(const base::string16& text, | |
350 const FontList& font_list, | |
351 SkColor color, | |
352 const Rect& display_rect); | |
353 | |
354 // Draws text with the specified color, fonts and location. The last argument | |
355 // specifies flags for how the text should be rendered. It can be one of | |
356 // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT. | |
357 void DrawStringRectWithFlags(const base::string16& text, | |
358 const FontList& font_list, | |
359 SkColor color, | |
360 const Rect& display_rect, | |
361 int flags); | |
362 | |
363 // Similar to above DrawStringRect method but with text shadows support. | |
364 // Currently it's only implemented for canvas skia. Specifying a 0 line_height | |
365 // will cause the default height to be used. | |
366 void DrawStringRectWithShadows(const base::string16& text, | |
367 const FontList& font_list, | |
368 SkColor color, | |
369 const Rect& text_bounds, | |
370 int line_height, | |
371 int flags, | |
372 const ShadowValues& shadows); | |
373 | |
374 // Draws a dotted gray rectangle used for focus purposes. | |
375 void DrawFocusRect(const Rect& rect); | |
376 | |
377 // Draws a |rect| in the specified region with the specified |color| with a | |
378 // with of one logical pixel which might be more device pixels. | |
379 void DrawSolidFocusRect(const Rect& rect, SkColor color); | |
380 | |
381 // Tiles the image in the specified region. | |
382 // Parameters are specified relative to current canvas scale not in pixels. | |
383 // Thus, |x| is 2 pixels if canvas scale = 2 & |x| = 1. | |
384 void TileImageInt(const ImageSkia& image, | |
385 int x, | |
386 int y, | |
387 int w, | |
388 int h); | |
389 void TileImageInt(const ImageSkia& image, | |
390 int src_x, | |
391 int src_y, | |
392 int dest_x, | |
393 int dest_y, | |
394 int w, | |
395 int h); | |
396 void TileImageInt(const ImageSkia& image, | |
397 int src_x, | |
398 int src_y, | |
399 float tile_scale_x, | |
400 float tile_scale_y, | |
401 int dest_x, | |
402 int dest_y, | |
403 int w, | |
404 int h); | |
405 | |
406 // Returns a native drawing context for platform specific drawing routines to | |
407 // use. Must be balanced by a call to EndPlatformPaint(). | |
408 NativeDrawingContext BeginPlatformPaint(); | |
409 | |
410 // Signifies the end of platform drawing using the native drawing context | |
411 // returned by BeginPlatformPaint(). | |
412 void EndPlatformPaint(); | |
413 | |
414 // Apply transformation on the canvas. | |
415 void Transform(const Transform& transform); | |
416 | |
417 // Draws the given string with a fade gradient at the end. | |
418 void DrawFadedString(const base::string16& text, | |
419 const FontList& font_list, | |
420 SkColor color, | |
421 const Rect& display_rect, | |
422 int flags); | |
423 | |
424 skia::PlatformCanvas* platform_canvas() { return owned_canvas_.get(); } | |
425 SkCanvas* sk_canvas() { return canvas_; } | |
426 float image_scale() const { return image_scale_; } | |
427 | |
428 private: | |
429 Canvas(SkCanvas* canvas, float image_scale); | |
430 | |
431 // Test whether the provided rectangle intersects the current clip rect. | |
432 bool IntersectsClipRectInt(int x, int y, int w, int h); | |
433 bool IntersectsClipRect(const Rect& rect); | |
434 | |
435 // Helper for the DrawImageInt functions declared above. The |pixel| | |
436 // parameter if true indicates that the bounds and the image are to | |
437 // be assumed to be in pixels, i.e. no scaling needs to be performed. | |
438 void DrawImageIntHelper(const ImageSkia& image, | |
439 int src_x, | |
440 int src_y, | |
441 int src_w, | |
442 int src_h, | |
443 int dest_x, | |
444 int dest_y, | |
445 int dest_w, | |
446 int dest_h, | |
447 bool filter, | |
448 const SkPaint& paint, | |
449 float image_scale, | |
450 bool pixel); | |
451 | |
452 // The device scale factor at which drawing on this canvas occurs. | |
453 // An additional scale can be applied via Canvas::Scale(). However, | |
454 // Canvas::Scale() does not affect |image_scale_|. | |
455 float image_scale_; | |
456 | |
457 skia::RefPtr<skia::PlatformCanvas> owned_canvas_; | |
458 SkCanvas* canvas_; | |
459 | |
460 DISALLOW_COPY_AND_ASSIGN(Canvas); | |
461 }; | |
462 | |
463 } // namespace gfx | |
464 | |
465 #endif // UI_GFX_CANVAS_H_ | |
OLD | NEW |