blob: 4c216426938e675f5756fb4c42cba1d4c43712aa [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]3127f6632012-03-17 00:14:069#include "base/basictypes.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/string16.h"
12#include "skia/ext/platform_canvas.h"
13#include "ui/gfx/native_widget_types.h"
14
15class SkBitmap;
16
17namespace ui {
18class Transform;
19}
[email protected]36df22b2011-02-24 21:47:5620
[email protected]267c03d2011-02-02 23:03:0721namespace gfx {
22
[email protected]3127f6632012-03-17 00:14:0623class Brush;
24class Rect;
25class Font;
26class Point;
27class Size;
28
29// Canvas is a SkCanvas wrapper that provides a number of methods for
30// common operations used throughout an application built using ui/gfx.
31//
32// All methods that take integer arguments (as is used throughout views)
33// end with Int. If you need to use methods provided by SkCanvas, you'll
34// need to do a conversion. In particular you'll need to use |SkIntToScalar()|,
35// or if converting from a scalar to an integer |SkScalarRound()|.
36//
37// A handful of methods in this class are overloaded providing an additional
38// argument of type SkXfermode::Mode. SkXfermode::Mode specifies how the
39// source and destination colors are combined. Unless otherwise specified,
40// the variant that does not take a SkXfermode::Mode uses a transfer mode
41// of kSrcOver_Mode.
42class UI_EXPORT Canvas {
[email protected]267c03d2011-02-02 23:03:0743 public:
[email protected]3127f6632012-03-17 00:14:0644 enum TruncateFadeMode {
45 TruncateFadeTail,
46 TruncateFadeHead,
47 TruncateFadeHeadAndTail,
48 };
49
50 // Specifies the alignment for text rendered with the DrawStringInt method.
51 enum {
52 TEXT_ALIGN_LEFT = 1 << 0,
53 TEXT_ALIGN_CENTER = 1 << 1,
54 TEXT_ALIGN_RIGHT = 1 << 2 ,
55 TEXT_VALIGN_TOP = 1 << 3,
56 TEXT_VALIGN_MIDDLE = 1 << 4,
57 TEXT_VALIGN_BOTTOM = 1 << 5,
58
59 // Specifies the text consists of multiple lines.
60 MULTI_LINE = 1 << 6,
61
62 // By default DrawStringInt does not process the prefix ('&') character
63 // specially. That is, the string "&foo" is rendered as "&foo". When
64 // rendering text from a resource that uses the prefix character for
65 // mnemonics, the prefix should be processed and can be rendered as an
66 // underline (SHOW_PREFIX), or not rendered at all (HIDE_PREFIX).
67 SHOW_PREFIX = 1 << 7,
68 HIDE_PREFIX = 1 << 8,
69
70 // Prevent ellipsizing
71 NO_ELLIPSIS = 1 << 9,
72
73 // Specifies if words can be split by new lines.
74 // This only works with MULTI_LINE.
75 CHARACTER_BREAK = 1 << 10,
76
77 // Instructs DrawStringInt() to render the text using RTL directionality.
78 // In most cases, passing this flag is not necessary because information
79 // about the text directionality is going to be embedded within the string
80 // in the form of special Unicode characters. However, we don't insert
81 // directionality characters into strings if the locale is LTR because some
82 // platforms (for example, an English Windows XP with no RTL fonts
83 // installed) don't support these characters. Thus, this flag should be
84 // used to render text using RTL directionality when the locale is LTR.
85 FORCE_RTL_DIRECTIONALITY = 1 << 11,
86
87 // Similar to FORCE_RTL_DIRECTIONALITY, but left-to-right.
88 // See FORCE_RTL_DIRECTIONALITY for details.
89 FORCE_LTR_DIRECTIONALITY = 1 << 12,
90
91 // Instructs DrawStringInt() to not use subpixel rendering. This is useful
92 // when rendering text onto a fully- or partially-transparent background
93 // that will later be blended with another image.
94 NO_SUBPIXEL_RENDERING = 1 << 13,
95 };
96
97 // Creates an empty canvas.
[email protected]94a0d2582012-03-09 00:30:5998 Canvas();
[email protected]267c03d2011-02-02 23:03:0799
[email protected]3127f6632012-03-17 00:14:06100 // If this canvas is not opaque, it's explicitly cleared to transparent before
101 // being returned.
102 Canvas(const gfx::Size& size, bool is_opaque);
103
104 // Constructs a canvas the size of the provided |bitmap|, and draws the
105 // bitmap into it.
106 Canvas(const SkBitmap& bitmap, bool is_opaque);
107
[email protected]94a0d2582012-03-09 00:30:59108 explicit Canvas(SkCanvas* canvas);
[email protected]267c03d2011-02-02 23:03:07109
[email protected]3127f6632012-03-17 00:14:06110 virtual ~Canvas();
[email protected]267c03d2011-02-02 23:03:07111
[email protected]3127f6632012-03-17 00:14:06112 // Compute the size required to draw some text with the provided font.
113 // Attempts to fit the text with the provided width and height. Increases
114 // height and then width as needed to make the text fit. This method
115 // supports multiple lines.
116 static void SizeStringInt(const string16& text,
117 const gfx::Font& font,
118 int* width, int* height,
119 int flags);
120
121 // Returns the number of horizontal pixels needed to display the specified
122 // |text| with |font|.
123 static int GetStringWidth(const string16& text, const gfx::Font& font);
124
125 // Returns the default text alignment to be used when drawing text on a
126 // gfx::Canvas based on the directionality of the system locale language.
127 // This function is used by gfx::Canvas::DrawStringInt when the text alignment
128 // is not specified.
129 //
130 // This function returns either gfx::Canvas::TEXT_ALIGN_LEFT or
131 // gfx::Canvas::TEXT_ALIGN_RIGHT.
132 static int DefaultCanvasTextAlignment();
133
134 // Draws text with a 1-pixel halo around it of the given color.
135 // On Windows, it allows ClearType to be drawn to an otherwise transparenct
136 // bitmap for drag images. Drag images have only 1-bit of transparency, so
137 // we don't do any fancy blurring.
138 // On Linux, text with halo is created by stroking it with 2px |halo_color|
139 // then filling it with |text_color|.
140 // On Mac, NOTIMPLEMENTED.
141 // TODO(dhollowa): Skia-native implementation is underway. Cut over to
142 // that when ready. http::/crbug.com/109946
143 void DrawStringWithHalo(const string16& text,
144 const gfx::Font& font,
145 const SkColor& text_color,
146 const SkColor& halo_color,
147 int x, int y, int w, int h,
148 int flags);
149
150 // Extracts a bitmap from the contents of this canvas.
151 SkBitmap ExtractBitmap() const;
152
153 // Draws a dashed rectangle of the specified color.
154 void DrawDashedRect(const gfx::Rect& rect, SkColor color);
155
156 // Saves a copy of the drawing state onto a stack, operating on this copy
157 // until a balanced call to Restore() is made.
158 void Save();
159
160 // As with Save(), except draws to a layer that is blended with the canvas
161 // at the specified alpha once Restore() is called.
162 // |layer_bounds| are the bounds of the layer relative to the current
163 // transform.
164 void SaveLayerAlpha(uint8 alpha);
165 void SaveLayerAlpha(uint8 alpha, const gfx::Rect& layer_bounds);
166
167 // Restores the drawing state after a call to Save*(). It is an error to
168 // call Restore() more times than Save*().
169 void Restore() ;
170
171 // Returns true if the clip is non-empty.
172 bool ClipRect(const gfx::Rect& rect);
173
174 void Translate(const gfx::Point& point);
175
176 void Scale(int x_scale, int y_scale);
177
178 // Fills |rect| with |color| using a transfer mode of
179 // SkXfermode::kSrcOver_Mode.
180 void FillRect(const gfx::Rect& rect, const SkColor& color);
181
182 // Fills |rect| with the specified |color| and |mode|.
183 void FillRect(const gfx::Rect& rect,
184 const SkColor& color,
185 SkXfermode::Mode mode);
186
187 // Fills |rect| with the specified |brush|.
188 void FillRect(const gfx::Rect& rect, const gfx::Brush* brush);
189
190 // Draws a single pixel rect in the specified region with the specified
191 // color, using a transfer mode of SkXfermode::kSrcOver_Mode.
192 //
193 // NOTE: if you need a single pixel line, use DrawLine.
194 void DrawRect(const gfx::Rect& rect, const SkColor& color);
195
196 // Draws a single pixel rect in the specified region with the specified
197 // color and transfer mode.
198 //
199 // NOTE: if you need a single pixel line, use DrawLine.
200 void DrawRect(const gfx::Rect& rect,
201 const SkColor& color,
202 SkXfermode::Mode mode);
203
204 // Draws the given rectangle with the given paint's parameters.
205 void DrawRect(const gfx::Rect& rect, const SkPaint& paint);
206
207 // Draws a single pixel line with the specified color.
208 void DrawLine(const gfx::Point& p1,
209 const gfx::Point& p2,
210 const SkColor& color);
211
212 // Draws a bitmap with the origin at the specified location. The upper left
213 // corner of the bitmap is rendered at the specified location.
214 void DrawBitmapInt(const SkBitmap& bitmap, int x, int y);
215
216 // Draws a bitmap with the origin at the specified location, using the
217 // specified paint. The upper left corner of the bitmap is rendered at the
218 // specified location.
219 void DrawBitmapInt(const SkBitmap& bitmap,
220 int x, int y,
221 const SkPaint& paint);
222
223 // Draws a portion of a bitmap in the specified location. The src parameters
224 // correspond to the region of the bitmap to draw in the region defined
225 // by the dest coordinates.
226 //
227 // If the width or height of the source differs from that of the destination,
228 // the bitmap will be scaled. When scaling down, it is highly recommended
229 // that you call buildMipMap(false) on your bitmap to ensure that it has
230 // a mipmap, which will result in much higher-quality output. Set |filter|
231 // to use filtering for bitmaps, otherwise the nearest-neighbor algorithm
232 // is used for resampling.
233 //
234 // An optional custom SkPaint can be provided.
235 void DrawBitmapInt(const SkBitmap& bitmap,
236 int src_x, int src_y, int src_w, int src_h,
237 int dest_x, int dest_y, int dest_w, int dest_h,
238 bool filter);
239 void DrawBitmapInt(const SkBitmap& bitmap,
240 int src_x, int src_y, int src_w, int src_h,
241 int dest_x, int dest_y, int dest_w, int dest_h,
242 bool filter,
243 const SkPaint& paint);
244
245 // Draws text with the specified color, font and location. The text is
246 // aligned to the left, vertically centered, clipped to the region. If the
247 // text is too big, it is truncated and '...' is added to the end.
248 void DrawStringInt(const string16& text,
249 const gfx::Font& font,
250 const SkColor& color,
251 int x, int y, int w, int h);
252 void DrawStringInt(const string16& text,
253 const gfx::Font& font,
254 const SkColor& color,
255 const gfx::Rect& display_rect);
256
257 // Draws text with the specified color, font and location. The last argument
258 // specifies flags for how the text should be rendered. It can be one of
259 // TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT.
260 void DrawStringInt(const string16& text,
261 const gfx::Font& font,
262 const SkColor& color,
263 int x, int y, int w, int h,
264 int flags);
265
266 // Draws a dotted gray rectangle used for focus purposes.
267 void DrawFocusRect(const gfx::Rect& rect);
268
269 // Tiles the image in the specified region.
270 void TileImageInt(const SkBitmap& bitmap,
271 int x, int y, int w, int h);
272 void TileImageInt(const SkBitmap& bitmap,
273 int src_x, int src_y,
274 int dest_x, int dest_y, int w, int h);
275
276 // Returns a native drawing context for platform specific drawing routines to
277 // use. Must be balanced by a call to EndPlatformPaint().
278 NativeDrawingContext BeginPlatformPaint();
279
280 // Signifies the end of platform drawing using the native drawing context
281 // returned by BeginPlatformPaint().
282 void EndPlatformPaint();
283
284 // Apply transformation on the canvas.
285 void Transform(const ui::Transform& transform);
286
287#if defined(OS_WIN)
288 // Draws the given string with the beginning and/or the end using a fade
289 // gradient. When truncating the head
290 // |desired_characters_to_truncate_from_head| specifies the maximum number of
291 // characters that can be truncated.
292 void DrawFadeTruncatingString(
293 const string16& text,
294 TruncateFadeMode truncate_mode,
295 size_t desired_characters_to_truncate_from_head,
296 const gfx::Font& font,
297 const SkColor& color,
298 const gfx::Rect& display_rect);
299#endif
300
301 skia::PlatformCanvas* platform_canvas() const { return owned_canvas_.get(); }
302 SkCanvas* sk_canvas() const { return canvas_; }
303
304 private:
305 // Test whether the provided rectangle intersects the current clip rect.
306 bool IntersectsClipRectInt(int x, int y, int w, int h);
307
308#if defined(OS_WIN)
309 // Draws text with the specified color, font and location. The text is
310 // aligned to the left, vertically centered, clipped to the region. If the
311 // text is too big, it is truncated and '...' is added to the end.
312 void DrawStringInt(const string16& text,
313 HFONT font,
314 const SkColor& color,
315 int x, int y, int w, int h,
316 int flags);
317#endif
318
319 scoped_ptr<skia::PlatformCanvas> owned_canvas_;
320 SkCanvas* canvas_;
321
322 DISALLOW_COPY_AND_ASSIGN(Canvas);
[email protected]267c03d2011-02-02 23:03:07323};
324
[email protected]7fe28392011-10-27 00:16:05325} // namespace gfx
[email protected]267c03d2011-02-02 23:03:07326
327#endif // UI_GFX_CANVAS_H_