blob: 058979d0f779afe1d7541223a5db65c71933ff2c [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkCanvas_DEFINED
11#define SkCanvas_DEFINED
12
13#include "SkTypes.h"
14#include "SkBitmap.h"
15#include "SkDeque.h"
reed@google.com5c3d1472011-02-22 19:12:23 +000016#include "SkClipStack.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000017#include "SkPaint.h"
18#include "SkRefCnt.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000019#include "SkPath.h"
20#include "SkRegion.h"
21#include "SkScalarCompare.h"
reed@android.com845fdac2009-06-23 03:01:32 +000022#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000023
24class SkBounder;
25class SkDevice;
26class SkDraw;
27class SkDrawFilter;
28class SkPicture;
29
30/** \class SkCanvas
31
32 A Canvas encapsulates all of the state about drawing into a device (bitmap).
33 This includes a reference to the device itself, and a stack of matrix/clip
34 values. For any given draw call (e.g. drawRect), the geometry of the object
35 being drawn is transformed by the concatenation of all the matrices in the
36 stack. The transformed geometry is clipped by the intersection of all of
37 the clips in the stack.
38
39 While the Canvas holds the state of the drawing device, the state (style)
40 of the object being drawn is held by the Paint, which is provided as a
41 parameter to each of the draw() methods. The Paint holds attributes such as
42 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
43 etc.
44*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000045class SK_API SkCanvas : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000046public:
reed@google.comcde92112011-07-06 20:00:52 +000047 SkCanvas();
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000048
reed@google.com6dc74552011-07-21 18:00:46 +000049 /** Construct a canvas with the specified device to draw into.
bsalomon@google.come97f0852011-06-17 13:10:25 +000050
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000051 @param device Specifies a device for the canvas to draw into.
52 */
53 explicit SkCanvas(SkDevice* device);
54
55 /** Deprecated - Construct a canvas with the specified bitmap to draw into.
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 @param bitmap Specifies a bitmap for the canvas to draw into. Its
57 structure are copied to the canvas.
58 */
59 explicit SkCanvas(const SkBitmap& bitmap);
reed@android.com8a1c16f2008-12-17 15:59:43 +000060 virtual ~SkCanvas();
61
62 ///////////////////////////////////////////////////////////////////////////
63
reed@google.com210ce002011-11-01 14:24:23 +000064 /**
junov@chromium.orgbf6c1e42012-01-30 14:53:22 +000065 * Trigger the immediate execution of all pending draw operations.
66 */
67 void flush();
68
69 /**
reed@google.com210ce002011-11-01 14:24:23 +000070 * Return the width/height of the underlying device. The current drawable
71 * area may be small (due to clipping or saveLayer). For a canvas with
72 * no device, 0,0 will be returned.
73 */
74 SkISize getDeviceSize() const;
75
reed@android.com8a1c16f2008-12-17 15:59:43 +000076 /** Return the canvas' device object, which may be null. The device holds
77 the bitmap of the pixels that the canvas draws into. The reference count
78 of the returned device is not changed by this call.
79 */
80 SkDevice* getDevice() const;
81
82 /** Specify a device for this canvas to draw into. If it is not null, its
83 reference count is incremented. If the canvas was already holding a
84 device, its reference count is decremented. The new device is returned.
85 */
junov@google.com4370aed2012-01-18 16:21:08 +000086 virtual SkDevice* setDevice(SkDevice* device);
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000087
reed@google.com9266fed2011-03-30 00:18:03 +000088 /**
89 * saveLayer() can create another device (which is later drawn onto
90 * the previous device). getTopDevice() returns the top-most device current
91 * installed. Note that this can change on other calls like save/restore,
92 * so do not access this device after subsequent canvas calls.
93 * The reference count of the device is not changed.
94 */
95 SkDevice* getTopDevice() const;
96
reed@android.comf2b98d62010-12-20 18:26:13 +000097 /**
98 * Create a new raster device and make it current. This also returns
99 * the new device.
100 */
reed@google.comaf951c92011-06-16 19:10:39 +0000101 SkDevice* setBitmapDevice(const SkBitmap& bitmap);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102
reed@google.com51df9e32010-12-23 19:29:18 +0000103 /**
reed@google.comcde92112011-07-06 20:00:52 +0000104 * Shortcut for getDevice()->createCompatibleDevice(...).
105 * If getDevice() == NULL, this method does nothing, and returns NULL.
bsalomon@google.come97f0852011-06-17 13:10:25 +0000106 */
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000107 SkDevice* createCompatibleDevice(SkBitmap::Config config,
bsalomon@google.come97f0852011-06-17 13:10:25 +0000108 int width, int height,
109 bool isOpaque);
110
reed@google.com4b226022011-01-11 18:32:13 +0000111 ///////////////////////////////////////////////////////////////////////////
112
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000113 /**
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000114 * This enum can be used with read/writePixels to perform a pixel ops to or
115 * from an 8888 config other than Skia's native config (SkPMColor). There
116 * are three byte orders supported: native, BGRA, and RGBA. Each has a
117 * premultiplied and unpremultiplied variant.
118 *
119 * Components of a 8888 pixel can be packed/unpacked from a 32bit word using
120 * either byte offsets or shift values. Byte offsets are endian-invariant
121 * while shifts are not. BGRA and RGBA configs are defined by byte
122 * orderings. The native config is defined by shift values (SK_A32_SHIFT,
123 * ..., SK_B32_SHIFT).
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000124 */
125 enum Config8888 {
126 /**
127 * Skia's native order specified by:
128 * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
129 *
130 * kNative_Premul_Config8888 is equivalent to SkPMColor
131 * kNative_Unpremul_Config8888 has the same component order as SkPMColor
132 * but is not premultiplied.
133 */
134 kNative_Premul_Config8888,
135 kNative_Unpremul_Config8888,
136 /**
137 * low byte to high byte: B, G, R, A.
138 */
139 kBGRA_Premul_Config8888,
140 kBGRA_Unpremul_Config8888,
141 /**
142 * low byte to high byte: R, G, B, A.
143 */
144 kRGBA_Premul_Config8888,
145 kRGBA_Unpremul_Config8888,
146 };
147
148 /**
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000149 * On success (returns true), copy the canvas pixels into the bitmap.
150 * On failure, the bitmap parameter is left unchanged and false is
151 * returned.
152 *
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000153 * The canvas' pixels are converted to the bitmap's config. The only
154 * supported config is kARGB_8888_Config, though this is likely to be
155 * relaxed in the future. The meaning of config kARGB_8888_Config is
156 * modified by the enum param config8888. The default value interprets
157 * kARGB_8888_Config as SkPMColor
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000158 *
159 * If the bitmap has pixels already allocated, the canvas pixels will be
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000160 * written there. If not, bitmap->allocPixels() will be called
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000161 * automatically. If the bitmap is backed by a texture readPixels will
162 * fail.
163 *
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000164 * The actual pixels written is the intersection of the canvas' bounds, and
165 * the rectangle formed by the bitmap's width,height and the specified x,y.
166 * If bitmap pixels extend outside of that intersection, they will not be
167 * modified.
168 *
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000169 * Other failure conditions:
170 * * If the canvas is backed by a non-raster device (e.g. PDF) then
171 * readPixels will fail.
172 * * If bitmap is texture-backed then readPixels will fail. (This may be
173 * relaxed in the future.)
174 *
175 * Example that reads the entire canvas into a bitmap using the native
176 * SkPMColor:
177 * SkISize size = canvas->getDeviceSize();
178 * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
179 * size.fHeight);
180 * if (canvas->readPixels(bitmap, 0, 0)) {
181 * // use the pixels
182 * }
bsalomon@google.comc6980972011-11-02 19:57:21 +0000183 */
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000184 bool readPixels(SkBitmap* bitmap,
185 int x, int y,
186 Config8888 config8888 = kNative_Premul_Config8888);
bsalomon@google.comc6980972011-11-02 19:57:21 +0000187
reed@google.com4b226022011-01-11 18:32:13 +0000188 /**
bsalomon@google.comc6980972011-11-02 19:57:21 +0000189 * DEPRECATED: This will be removed as soon as webkit is no longer relying
190 * on it. The bitmap is resized to the intersection of srcRect and the
191 * canvas bounds. New pixels are always allocated on success. Bitmap is
192 * unmodified on failure.
reed@google.com51df9e32010-12-23 19:29:18 +0000193 */
194 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
reed@google.com51df9e32010-12-23 19:29:18 +0000195
196 /**
197 * Similar to draw sprite, this method will copy the pixels in bitmap onto
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000198 * the canvas, with the top/left corner specified by (x, y). The canvas'
199 * pixel values are completely replaced: there is no blending.
200 *
201 * Currently if bitmap is backed by a texture this is a no-op. This may be
202 * relaxed in the future.
203 *
204 * If the bitmap has config kARGB_8888_Config then the config8888 param
205 * will determines how the pixel valuess are intepreted. If the bitmap is
206 * not kARGB_8888_Config then this parameter is ignored.
epoger@google.com4f1151a2011-07-25 15:47:33 +0000207 *
208 * Note: If you are recording drawing commands on this canvas to
209 * SkPicture, writePixels() is ignored!
reed@google.com51df9e32010-12-23 19:29:18 +0000210 */
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000211 void writePixels(const SkBitmap& bitmap,
212 int x, int y,
213 Config8888 config8888 = kNative_Premul_Config8888);
reed@google.com4b226022011-01-11 18:32:13 +0000214
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 ///////////////////////////////////////////////////////////////////////////
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000216
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217 enum SaveFlags {
218 /** save the matrix state, restoring it on restore() */
219 kMatrix_SaveFlag = 0x01,
220 /** save the clip state, restoring it on restore() */
221 kClip_SaveFlag = 0x02,
222 /** the layer needs to support per-pixel alpha */
223 kHasAlphaLayer_SaveFlag = 0x04,
224 /** the layer needs to support 8-bits per color component */
225 kFullColorLayer_SaveFlag = 0x08,
226 /** the layer should clip against the bounds argument */
227 kClipToLayer_SaveFlag = 0x10,
228
229 // helper masks for common choices
230 kMatrixClip_SaveFlag = 0x03,
231 kARGB_NoClipLayer_SaveFlag = 0x0F,
232 kARGB_ClipLayer_SaveFlag = 0x1F
233 };
234
reed@android.comdc3381f2010-02-11 16:05:15 +0000235 /** This call saves the current matrix, clip, and drawFilter, and pushes a
reed@android.com8a1c16f2008-12-17 15:59:43 +0000236 copy onto a private stack. Subsequent calls to translate, scale,
reed@android.comdc3381f2010-02-11 16:05:15 +0000237 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
238 operate on this copy.
239 When the balancing call to restore() is made, the previous matrix, clip,
240 and drawFilter are restored.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000241 @return The value to pass to restoreToCount() to balance this save()
242 */
243 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
244
245 /** This behaves the same as save(), but in addition it allocates an
246 offscreen bitmap. All drawing calls are directed there, and only when
247 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000248 the canvas (or the previous layer).
reed@android.comad164b22010-07-02 17:20:51 +0000249 @param bounds (may be null) This rect, if non-null, is used as a hint to
250 limit the size of the offscreen, and thus drawing may be
251 clipped to it, though that clipping is not guaranteed to
252 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000253 @param paint (may be null) This is copied, and is applied to the
254 offscreen when restore() is called
255 @param flags LayerFlags
256 @return The value to pass to restoreToCount() to balance this save()
257 */
258 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
259 SaveFlags flags = kARGB_ClipLayer_SaveFlag);
260
261 /** This behaves the same as save(), but in addition it allocates an
262 offscreen bitmap. All drawing calls are directed there, and only when
263 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000264 the canvas (or the previous layer).
reed@android.com40408612010-07-02 17:24:23 +0000265 @param bounds (may be null) This rect, if non-null, is used as a hint to
266 limit the size of the offscreen, and thus drawing may be
267 clipped to it, though that clipping is not guaranteed to
268 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000269 @param alpha This is applied to the offscreen when restore() is called.
270 @param flags LayerFlags
271 @return The value to pass to restoreToCount() to balance this save()
272 */
273 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
274 SaveFlags flags = kARGB_ClipLayer_SaveFlag);
275
276 /** This call balances a previous call to save(), and is used to remove all
reed@android.comdc3381f2010-02-11 16:05:15 +0000277 modifications to the matrix/clip/drawFilter state since the last save
278 call.
279 It is an error to call restore() more times than save() was called.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000280 */
281 virtual void restore();
282
283 /** Returns the number of matrix/clip states on the SkCanvas' private stack.
284 This will equal # save() calls - # restore() calls.
285 */
junov@google.com4370aed2012-01-18 16:21:08 +0000286 virtual int getSaveCount() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000287
288 /** Efficient way to pop any calls to save() that happened after the save
289 count reached saveCount. It is an error for saveCount to be less than
290 getSaveCount()
291 @param saveCount The number of save() levels to restore from
292 */
293 void restoreToCount(int saveCount);
294
reed@google.com7c202932011-12-14 18:48:05 +0000295 /** Returns true if drawing is currently going to a layer (from saveLayer)
296 * rather than to the root device.
297 */
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000298 virtual bool isDrawingToLayer() const;
reed@google.com7c202932011-12-14 18:48:05 +0000299
reed@android.com8a1c16f2008-12-17 15:59:43 +0000300 /** Preconcat the current matrix with the specified translation
301 @param dx The distance to translate in X
302 @param dy The distance to translate in Y
303 returns true if the operation succeeded (e.g. did not overflow)
304 */
305 virtual bool translate(SkScalar dx, SkScalar dy);
306
307 /** Preconcat the current matrix with the specified scale.
308 @param sx The amount to scale in X
309 @param sy The amount to scale in Y
310 returns true if the operation succeeded (e.g. did not overflow)
311 */
312 virtual bool scale(SkScalar sx, SkScalar sy);
313
314 /** Preconcat the current matrix with the specified rotation.
315 @param degrees The amount to rotate, in degrees
316 returns true if the operation succeeded (e.g. did not overflow)
317 */
318 virtual bool rotate(SkScalar degrees);
319
320 /** Preconcat the current matrix with the specified skew.
321 @param sx The amount to skew in X
322 @param sy The amount to skew in Y
323 returns true if the operation succeeded (e.g. did not overflow)
324 */
325 virtual bool skew(SkScalar sx, SkScalar sy);
326
327 /** Preconcat the current matrix with the specified matrix.
328 @param matrix The matrix to preconcatenate with the current matrix
329 @return true if the operation succeeded (e.g. did not overflow)
330 */
331 virtual bool concat(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000332
reed@android.com8a1c16f2008-12-17 15:59:43 +0000333 /** Replace the current matrix with a copy of the specified matrix.
334 @param matrix The matrix that will be copied into the current matrix.
335 */
336 virtual void setMatrix(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000337
reed@android.com8a1c16f2008-12-17 15:59:43 +0000338 /** Helper for setMatrix(identity). Sets the current matrix to identity.
339 */
340 void resetMatrix();
341
342 /** Modify the current clip with the specified rectangle.
343 @param rect The rect to intersect with the current clip
344 @param op The region op to apply to the current clip
345 @return true if the canvas' clip is non-empty
346 */
347 virtual bool clipRect(const SkRect& rect,
reed@google.com071eef92011-10-12 11:52:53 +0000348 SkRegion::Op op = SkRegion::kIntersect_Op,
349 bool doAntiAlias = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000350
351 /** Modify the current clip with the specified path.
352 @param path The path to apply to the current clip
353 @param op The region op to apply to the current clip
354 @return true if the canvas' new clip is non-empty
355 */
356 virtual bool clipPath(const SkPath& path,
reed@google.com071eef92011-10-12 11:52:53 +0000357 SkRegion::Op op = SkRegion::kIntersect_Op,
358 bool doAntiAlias = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000359
360 /** Modify the current clip with the specified region. Note that unlike
361 clipRect() and clipPath() which transform their arguments by the current
362 matrix, clipRegion() assumes its argument is already in device
363 coordinates, and so no transformation is performed.
364 @param deviceRgn The region to apply to the current clip
365 @param op The region op to apply to the current clip
366 @return true if the canvas' new clip is non-empty
367 */
368 virtual bool clipRegion(const SkRegion& deviceRgn,
369 SkRegion::Op op = SkRegion::kIntersect_Op);
370
371 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
372 specified region. This does not intersect or in any other way account
373 for the existing clip region.
374 @param deviceRgn The region to copy into the current clip.
375 @return true if the new clip region is non-empty
376 */
377 bool setClipRegion(const SkRegion& deviceRgn) {
378 return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
379 }
380
381 /** Enum describing how to treat edges when performing quick-reject tests
382 of a geometry against the current clip. Treating them as antialiased
383 (kAA_EdgeType) will take into account the extra pixels that may be drawn
384 if the edge does not lie exactly on a device pixel boundary (after being
385 transformed by the current matrix).
386 */
387 enum EdgeType {
388 /** Treat the edges as B&W (not antialiased) for the purposes of testing
389 against the current clip
390 */
391 kBW_EdgeType,
392 /** Treat the edges as antialiased for the purposes of testing
393 against the current clip
394 */
395 kAA_EdgeType
396 };
397
398 /** Return true if the specified rectangle, after being transformed by the
399 current matrix, would lie completely outside of the current clip. Call
400 this to check if an area you intend to draw into is clipped out (and
401 therefore you can skip making the draw calls).
402 @param rect the rect to compare with the current clip
403 @param et specifies how to treat the edges (see EdgeType)
404 @return true if the rect (transformed by the canvas' matrix) does not
405 intersect with the canvas' clip
406 */
407 bool quickReject(const SkRect& rect, EdgeType et) const;
408
409 /** Return true if the specified path, after being transformed by the
410 current matrix, would lie completely outside of the current clip. Call
411 this to check if an area you intend to draw into is clipped out (and
412 therefore you can skip making the draw calls). Note, for speed it may
413 return false even if the path itself might not intersect the clip
414 (i.e. the bounds of the path intersects, but the path does not).
415 @param path The path to compare with the current clip
416 @param et specifies how to treat the edges (see EdgeType)
417 @return true if the path (transformed by the canvas' matrix) does not
418 intersect with the canvas' clip
419 */
420 bool quickReject(const SkPath& path, EdgeType et) const;
421
422 /** Return true if the horizontal band specified by top and bottom is
423 completely clipped out. This is a conservative calculation, meaning
424 that it is possible that if the method returns false, the band may still
425 in fact be clipped out, but the converse is not true. If this method
426 returns true, then the band is guaranteed to be clipped out.
427 @param top The top of the horizontal band to compare with the clip
428 @param bottom The bottom of the horizontal and to compare with the clip
429 @return true if the horizontal band is completely clipped out (i.e. does
430 not intersect the current clip)
431 */
432 bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
433
434 /** Return the bounds of the current clip (in local coordinates) in the
435 bounds parameter, and return true if it is non-empty. This can be useful
436 in a way similar to quickReject, in that it tells you that drawing
437 outside of these bounds will be clipped out.
438 */
439 bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
440
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000441 /** Return the bounds of the current clip, in device coordinates; returns
442 true if non-empty. Maybe faster than getting the clip explicitly and
443 then taking its bounds.
444 */
445 bool getClipDeviceBounds(SkIRect* bounds) const;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000446
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000447
reed@android.com8a1c16f2008-12-17 15:59:43 +0000448 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000449 specified ARGB color, using the specified mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000450 @param a the alpha component (0..255) of the color to fill the canvas
451 @param r the red component (0..255) of the color to fill the canvas
452 @param g the green component (0..255) of the color to fill the canvas
453 @param b the blue component (0..255) of the color to fill the canvas
454 @param mode the mode to apply the color in (defaults to SrcOver)
455 */
456 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
reed@android.com845fdac2009-06-23 03:01:32 +0000457 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000458
459 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000460 specified color and mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000461 @param color the color to draw with
462 @param mode the mode to apply the color in (defaults to SrcOver)
463 */
464 void drawColor(SkColor color,
reed@android.com845fdac2009-06-23 03:01:32 +0000465 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000466
reed@google.com2a981812011-04-14 18:59:28 +0000467 /**
468 * This erases the entire drawing surface to the specified color,
469 * irrespective of the clip. It does not blend with the previous pixels,
470 * but always overwrites them.
471 *
472 * It is roughly equivalent to the following:
473 * canvas.save();
474 * canvas.clipRect(hugeRect, kReplace_Op);
475 * paint.setColor(color);
476 * paint.setXfermodeMode(kSrc_Mode);
477 * canvas.drawPaint(paint);
478 * canvas.restore();
479 * though it is almost always much more efficient.
480 */
481 virtual void clear(SkColor);
482
483 /**
484 * Fill the entire canvas' bitmap (restricted to the current clip) with the
485 * specified paint.
486 * @param paint The paint used to fill the canvas
487 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000488 virtual void drawPaint(const SkPaint& paint);
489
490 enum PointMode {
491 /** drawPoints draws each point separately */
492 kPoints_PointMode,
493 /** drawPoints draws each pair of points as a line segment */
494 kLines_PointMode,
495 /** drawPoints draws the array of points as a polygon */
496 kPolygon_PointMode
497 };
498
499 /** Draw a series of points, interpreted based on the PointMode mode. For
500 all modes, the count parameter is interpreted as the total number of
501 points. For kLine mode, count/2 line segments are drawn.
502 For kPoint mode, each point is drawn centered at its coordinate, and its
503 size is specified by the paint's stroke-width. It draws as a square,
504 unless the paint's cap-type is round, in which the points are drawn as
505 circles.
506 For kLine mode, each pair of points is drawn as a line segment,
507 respecting the paint's settings for cap/join/width.
508 For kPolygon mode, the entire array is drawn as a series of connected
509 line segments.
510 Note that, while similar, kLine and kPolygon modes draw slightly
511 differently than the equivalent path built with a series of moveto,
512 lineto calls, in that the path will draw all of its contours at once,
513 with no interactions if contours intersect each other (think XOR
514 xfermode). drawPoints always draws each element one at a time.
515 @param mode PointMode specifying how to draw the array of points.
516 @param count The number of points in the array
517 @param pts Array of points to draw
518 @param paint The paint used to draw the points
519 */
520 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
521 const SkPaint& paint);
522
523 /** Helper method for drawing a single point. See drawPoints() for a more
524 details.
525 */
526 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000527
reed@android.com8a1c16f2008-12-17 15:59:43 +0000528 /** Draws a single pixel in the specified color.
529 @param x The X coordinate of which pixel to draw
530 @param y The Y coordiante of which pixel to draw
531 @param color The color to draw
532 */
533 void drawPoint(SkScalar x, SkScalar y, SkColor color);
534
535 /** Draw a line segment with the specified start and stop x,y coordinates,
536 using the specified paint. NOTE: since a line is always "framed", the
537 paint's Style is ignored.
538 @param x0 The x-coordinate of the start point of the line
539 @param y0 The y-coordinate of the start point of the line
540 @param x1 The x-coordinate of the end point of the line
541 @param y1 The y-coordinate of the end point of the line
542 @param paint The paint used to draw the line
543 */
544 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
545 const SkPaint& paint);
546
547 /** Draw the specified rectangle using the specified paint. The rectangle
548 will be filled or stroked based on the Style in the paint.
549 @param rect The rect to be drawn
550 @param paint The paint used to draw the rect
551 */
552 virtual void drawRect(const SkRect& rect, const SkPaint& paint);
553
554 /** Draw the specified rectangle using the specified paint. The rectangle
555 will be filled or framed based on the Style in the paint.
556 @param rect The rect to be drawn
557 @param paint The paint used to draw the rect
558 */
559 void drawIRect(const SkIRect& rect, const SkPaint& paint)
560 {
561 SkRect r;
562 r.set(rect); // promotes the ints to scalars
563 this->drawRect(r, paint);
564 }
reed@google.com4b226022011-01-11 18:32:13 +0000565
reed@android.com8a1c16f2008-12-17 15:59:43 +0000566 /** Draw the specified rectangle using the specified paint. The rectangle
567 will be filled or framed based on the Style in the paint.
568 @param left The left side of the rectangle to be drawn
569 @param top The top side of the rectangle to be drawn
570 @param right The right side of the rectangle to be drawn
571 @param bottom The bottom side of the rectangle to be drawn
572 @param paint The paint used to draw the rect
573 */
574 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
575 SkScalar bottom, const SkPaint& paint);
576
577 /** Draw the specified oval using the specified paint. The oval will be
578 filled or framed based on the Style in the paint.
579 @param oval The rectangle bounds of the oval to be drawn
580 @param paint The paint used to draw the oval
581 */
582 void drawOval(const SkRect& oval, const SkPaint&);
583
584 /** Draw the specified circle using the specified paint. If radius is <= 0,
585 then nothing will be drawn. The circle will be filled
586 or framed based on the Style in the paint.
587 @param cx The x-coordinate of the center of the cirle to be drawn
588 @param cy The y-coordinate of the center of the cirle to be drawn
589 @param radius The radius of the cirle to be drawn
590 @param paint The paint used to draw the circle
591 */
592 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
593 const SkPaint& paint);
594
595 /** Draw the specified arc, which will be scaled to fit inside the
596 specified oval. If the sweep angle is >= 360, then the oval is drawn
597 completely. Note that this differs slightly from SkPath::arcTo, which
598 treats the sweep angle mod 360.
599 @param oval The bounds of oval used to define the shape of the arc
600 @param startAngle Starting angle (in degrees) where the arc begins
601 @param sweepAngle Sweep angle (in degrees) measured clockwise
602 @param useCenter true means include the center of the oval. For filling
603 this will draw a wedge. False means just use the arc.
604 @param paint The paint used to draw the arc
605 */
606 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
607 bool useCenter, const SkPaint& paint);
608
609 /** Draw the specified round-rect using the specified paint. The round-rect
610 will be filled or framed based on the Style in the paint.
611 @param rect The rectangular bounds of the roundRect to be drawn
612 @param rx The x-radius of the oval used to round the corners
613 @param ry The y-radius of the oval used to round the corners
614 @param paint The paint used to draw the roundRect
615 */
616 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
617 const SkPaint& paint);
618
619 /** Draw the specified path using the specified paint. The path will be
620 filled or framed based on the Style in the paint.
621 @param path The path to be drawn
622 @param paint The paint used to draw the path
623 */
624 virtual void drawPath(const SkPath& path, const SkPaint& paint);
625
626 /** Draw the specified bitmap, with its top/left corner at (x,y), using the
627 specified paint, transformed by the current matrix. Note: if the paint
628 contains a maskfilter that generates a mask which extends beyond the
629 bitmap's original width/height, then the bitmap will be drawn as if it
630 were in a Shader with CLAMP mode. Thus the color outside of the original
631 width/height will be the edge color replicated.
632 @param bitmap The bitmap to be drawn
633 @param left The position of the left side of the bitmap being drawn
634 @param top The position of the top side of the bitmap being drawn
635 @param paint The paint used to draw the bitmap, or NULL
636 */
637 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
638 const SkPaint* paint = NULL);
639
640 /** Draw the specified bitmap, with the specified matrix applied (before the
641 canvas' matrix is applied).
642 @param bitmap The bitmap to be drawn
643 @param src Optional: specify the subset of the bitmap to be drawn
644 @param dst The destination rectangle where the scaled/translated
645 image will be drawn
646 @param paint The paint used to draw the bitmap, or NULL
647 */
648 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
649 const SkRect& dst, const SkPaint* paint = NULL);
650
651 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
652 const SkPaint* paint = NULL);
reed@google.com4b226022011-01-11 18:32:13 +0000653
reed@google.comf0b5e112011-09-07 11:57:34 +0000654 /**
655 * Draw the bitmap stretched differentially to fit into dst.
656 * center is a rect within the bitmap, and logically divides the bitmap
657 * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
658 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
659 *
660 * If the dst is >= the bitmap size, then...
661 * - The 4 corners are not stretch at all.
662 * - The sides are stretch in only one axis.
663 * - The center is stretch in both axes.
664 * Else, for each axis where dst < bitmap,
665 * - The corners shrink proportionally
666 * - The sides (along the shrink axis) and center are not drawn
667 */
668 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
669 const SkRect& dst, const SkPaint* paint = NULL);
670
reed@android.com8a1c16f2008-12-17 15:59:43 +0000671 /** Draw the specified bitmap, with its top/left corner at (x,y),
672 NOT transformed by the current matrix. Note: if the paint
673 contains a maskfilter that generates a mask which extends beyond the
674 bitmap's original width/height, then the bitmap will be drawn as if it
675 were in a Shader with CLAMP mode. Thus the color outside of the original
676 width/height will be the edge color replicated.
677 @param bitmap The bitmap to be drawn
678 @param left The position of the left side of the bitmap being drawn
679 @param top The position of the top side of the bitmap being drawn
680 @param paint The paint used to draw the bitmap, or NULL
681 */
682 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
683 const SkPaint* paint = NULL);
684
685 /** Draw the text, with origin at (x,y), using the specified paint.
686 The origin is interpreted based on the Align setting in the paint.
687 @param text The text to be drawn
688 @param byteLength The number of bytes to read from the text parameter
689 @param x The x-coordinate of the origin of the text being drawn
690 @param y The y-coordinate of the origin of the text being drawn
691 @param paint The paint used for the text (e.g. color, size, style)
692 */
693 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
694 SkScalar y, const SkPaint& paint);
695
696 /** Draw the text, with each character/glyph origin specified by the pos[]
reed@google.com4b226022011-01-11 18:32:13 +0000697 array. The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000698 @param text The text to be drawn
699 @param byteLength The number of bytes to read from the text parameter
700 @param pos Array of positions, used to position each character
701 @param paint The paint used for the text (e.g. color, size, style)
702 */
703 virtual void drawPosText(const void* text, size_t byteLength,
704 const SkPoint pos[], const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000705
reed@android.com8a1c16f2008-12-17 15:59:43 +0000706 /** Draw the text, with each character/glyph origin specified by the x
707 coordinate taken from the xpos[] array, and the y from the constY param.
reed@google.com4b226022011-01-11 18:32:13 +0000708 The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000709 @param text The text to be drawn
710 @param byteLength The number of bytes to read from the text parameter
711 @param xpos Array of x-positions, used to position each character
712 @param constY The shared Y coordinate for all of the positions
713 @param paint The paint used for the text (e.g. color, size, style)
714 */
715 virtual void drawPosTextH(const void* text, size_t byteLength,
716 const SkScalar xpos[], SkScalar constY,
717 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000718
reed@android.com8a1c16f2008-12-17 15:59:43 +0000719 /** Draw the text, with origin at (x,y), using the specified paint, along
720 the specified path. The paint's Align setting determins where along the
721 path to start the text.
722 @param text The text to be drawn
723 @param byteLength The number of bytes to read from the text parameter
724 @param path The path the text should follow for its baseline
725 @param hOffset The distance along the path to add to the text's
726 starting position
727 @param vOffset The distance above(-) or below(+) the path to
728 position the text
729 @param paint The paint used for the text
730 */
731 void drawTextOnPathHV(const void* text, size_t byteLength,
732 const SkPath& path, SkScalar hOffset,
733 SkScalar vOffset, const SkPaint& paint);
734
735 /** Draw the text, with origin at (x,y), using the specified paint, along
736 the specified path. The paint's Align setting determins where along the
737 path to start the text.
738 @param text The text to be drawn
739 @param byteLength The number of bytes to read from the text parameter
740 @param path The path the text should follow for its baseline
741 @param matrix (may be null) Applied to the text before it is
742 mapped onto the path
743 @param paint The paint used for the text
744 */
745 virtual void drawTextOnPath(const void* text, size_t byteLength,
746 const SkPath& path, const SkMatrix* matrix,
747 const SkPaint& paint);
748
djsollen@google.com56c69772011-11-08 19:00:26 +0000749#ifdef SK_BUILD_FOR_ANDROID
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000750 /** Draw the text on path, with each character/glyph origin specified by the pos[]
751 array. The origin is interpreted by the Align setting in the paint.
752 @param text The text to be drawn
753 @param byteLength The number of bytes to read from the text parameter
754 @param pos Array of positions, used to position each character
755 @param paint The paint used for the text (e.g. color, size, style)
756 @param path The path to draw on
757 @param matrix The canvas matrix
758 */
759 void drawPosTextOnPath(const void* text, size_t byteLength,
760 const SkPoint pos[], const SkPaint& paint,
761 const SkPath& path, const SkMatrix* matrix);
762#endif
763
reed@android.com8a1c16f2008-12-17 15:59:43 +0000764 /** Draw the picture into this canvas. This method effective brackets the
765 playback of the picture's draw calls with save/restore, so the state
766 of this canvas will be unchanged after this call. This contrasts with
767 the more immediate method SkPicture::draw(), which does not bracket
768 the canvas with save/restore, thus the canvas may be left in a changed
769 state after the call.
770 @param picture The recorded drawing commands to playback into this
771 canvas.
772 */
773 virtual void drawPicture(SkPicture& picture);
reed@google.com4b226022011-01-11 18:32:13 +0000774
reed@android.com8a1c16f2008-12-17 15:59:43 +0000775 enum VertexMode {
776 kTriangles_VertexMode,
777 kTriangleStrip_VertexMode,
778 kTriangleFan_VertexMode
779 };
reed@google.com4b226022011-01-11 18:32:13 +0000780
reed@android.com8a1c16f2008-12-17 15:59:43 +0000781 /** Draw the array of vertices, interpreted as triangles (based on mode).
782 @param vmode How to interpret the array of vertices
783 @param vertexCount The number of points in the vertices array (and
784 corresponding texs and colors arrays if non-null)
785 @param vertices Array of vertices for the mesh
786 @param texs May be null. If not null, specifies the coordinate
787 in texture space for each vertex.
788 @param colors May be null. If not null, specifies a color for each
789 vertex, to be interpolated across the triangle.
790 @param xmode Used if both texs and colors are present. In this
791 case the colors are combined with the texture using mode,
792 before being drawn using the paint. If mode is null, then
reed@android.com845fdac2009-06-23 03:01:32 +0000793 kMultiply_Mode is used.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000794 @param indices If not null, array of indices to reference into the
795 vertex (texs, colors) array.
796 @param indexCount number of entries in the indices array (if not null)
reed@google.com4b226022011-01-11 18:32:13 +0000797 @param paint Specifies the shader/texture if present.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000798 */
799 virtual void drawVertices(VertexMode vmode, int vertexCount,
800 const SkPoint vertices[], const SkPoint texs[],
801 const SkColor colors[], SkXfermode* xmode,
802 const uint16_t indices[], int indexCount,
803 const SkPaint& paint);
804
reed@android.comcb608442009-12-04 21:32:27 +0000805 /** Send a blob of data to the canvas.
806 For canvases that draw, this call is effectively a no-op, as the data
807 is not parsed, but just ignored. However, this call exists for
808 subclasses like SkPicture's recording canvas, that can store the data
809 and then play it back later (via another call to drawData).
810 */
811 virtual void drawData(const void* data, size_t length);
812
reed@android.com8a1c16f2008-12-17 15:59:43 +0000813 //////////////////////////////////////////////////////////////////////////
reed@google.com4b226022011-01-11 18:32:13 +0000814
reed@android.com8a1c16f2008-12-17 15:59:43 +0000815 /** Get the current bounder object.
816 The bounder's reference count is unchaged.
817 @return the canva's bounder (or NULL).
818 */
819 SkBounder* getBounder() const { return fBounder; }
820
821 /** Set a new bounder (or NULL).
822 Pass NULL to clear any previous bounder.
823 As a convenience, the parameter passed is also returned.
824 If a previous bounder exists, its reference count is decremented.
825 If bounder is not NULL, its reference count is incremented.
826 @param bounder the new bounder (or NULL) to be installed in the canvas
827 @return the set bounder object
828 */
829 virtual SkBounder* setBounder(SkBounder* bounder);
reed@google.com4b226022011-01-11 18:32:13 +0000830
reed@android.com8a1c16f2008-12-17 15:59:43 +0000831 /** Get the current filter object. The filter's reference count is not
reed@android.comdc3381f2010-02-11 16:05:15 +0000832 affected. The filter is saved/restored, just like the matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000833 @return the canvas' filter (or NULL).
834 */
835 SkDrawFilter* getDrawFilter() const;
reed@google.com4b226022011-01-11 18:32:13 +0000836
reed@android.com8a1c16f2008-12-17 15:59:43 +0000837 /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
838 As a convenience, the parameter is returned. If an existing filter
839 exists, its refcnt is decrement. If the new filter is not null, its
reed@android.comdc3381f2010-02-11 16:05:15 +0000840 refcnt is incremented. The filter is saved/restored, just like the
841 matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000842 @param filter the new filter (or NULL)
843 @return the new filter
844 */
845 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
846
847 //////////////////////////////////////////////////////////////////////////
848
849 /** Return the current matrix on the canvas.
850 This does not account for the translate in any of the devices.
851 @return The current matrix on the canvas.
852 */
junov@google.com4370aed2012-01-18 16:21:08 +0000853 virtual const SkMatrix& getTotalMatrix() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000854
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000855 enum ClipType {
856 kEmpty_ClipType = 0,
857 kRect_ClipType,
858 kComplex_ClipType
859 };
860
861 /** Returns a description of the total clip; may be cheaper than
862 getting the clip and querying it directly.
863 */
864 ClipType getClipType() const;
865
reed@android.com8a1c16f2008-12-17 15:59:43 +0000866 /** Return the current device clip (concatenation of all clip calls).
867 This does not account for the translate in any of the devices.
868 @return the current device clip (concatenation of all clip calls).
869 */
870 const SkRegion& getTotalClip() const;
871
reed@google.com7d7ca792011-02-23 22:39:18 +0000872 /**
reed@google.com5e2457e2011-10-10 21:24:37 +0000873 * Return true if the current clip is non-empty.
874 *
875 * If bounds is not NULL, set it to the bounds of the current clip
876 * in global coordinates.
877 */
878 bool getTotalClipBounds(SkIRect* bounds) const;
879
880 /**
reed@google.com7d7ca792011-02-23 22:39:18 +0000881 * Return the current clipstack. This mirrors the result in getTotalClip()
882 * but is represented as a stack of geometric clips + region-ops.
883 */
884 const SkClipStack& getTotalClipStack() const;
885
reed@android.comf2b98d62010-12-20 18:26:13 +0000886 void setExternalMatrix(const SkMatrix* = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000887
888 ///////////////////////////////////////////////////////////////////////////
889
890 /** After calling saveLayer(), there can be any number of devices that make
891 up the top-most drawing area. LayerIter can be used to iterate through
892 those devices. Note that the iterator is only valid until the next API
893 call made on the canvas. Ownership of all pointers in the iterator stays
894 with the canvas, so none of them should be modified or deleted.
895 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000896 class SK_API LayerIter /*: SkNoncopyable*/ {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000897 public:
898 /** Initialize iterator with canvas, and set values for 1st device */
899 LayerIter(SkCanvas*, bool skipEmptyClips);
900 ~LayerIter();
reed@google.com4b226022011-01-11 18:32:13 +0000901
reed@android.com8a1c16f2008-12-17 15:59:43 +0000902 /** Return true if the iterator is done */
903 bool done() const { return fDone; }
904 /** Cycle to the next device */
905 void next();
reed@google.com4b226022011-01-11 18:32:13 +0000906
reed@android.com8a1c16f2008-12-17 15:59:43 +0000907 // These reflect the current device in the iterator
908
909 SkDevice* device() const;
910 const SkMatrix& matrix() const;
911 const SkRegion& clip() const;
912 const SkPaint& paint() const;
913 int x() const;
914 int y() const;
reed@google.com4b226022011-01-11 18:32:13 +0000915
reed@android.com8a1c16f2008-12-17 15:59:43 +0000916 private:
917 // used to embed the SkDrawIter object directly in our instance, w/o
918 // having to expose that class def to the public. There is an assert
919 // in our constructor to ensure that fStorage is large enough
920 // (though needs to be a compile-time-assert!). We use intptr_t to work
921 // safely with 32 and 64 bit machines (to ensure the storage is enough)
reed@android.comf2b98d62010-12-20 18:26:13 +0000922 intptr_t fStorage[32];
reed@android.com8a1c16f2008-12-17 15:59:43 +0000923 class SkDrawIter* fImpl; // this points at fStorage
924 SkPaint fDefaultPaint;
925 bool fDone;
926 };
927
928protected:
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000929 // Returns the canvas to be used by DrawIter. Default implementation
junov@google.com4370aed2012-01-18 16:21:08 +0000930 // returns this. Subclasses that encapsulate an indirect canvas may
931 // need to overload this method. The impl must keep track of this, as it
932 // is not released or deleted by the caller.
933 virtual SkCanvas* canvasForDrawIter();
934
reed@android.com8a1c16f2008-12-17 15:59:43 +0000935 // all of the drawBitmap variants call this guy
reed@android.comf2b98d62010-12-20 18:26:13 +0000936 virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*,
937 const SkMatrix&, const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000938
reed@android.com8a1c16f2008-12-17 15:59:43 +0000939private:
940 class MCRec;
941
reed@google.com5c3d1472011-02-22 19:12:23 +0000942 SkClipStack fClipStack;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000943 SkDeque fMCStack;
944 // points to top of stack
945 MCRec* fMCRec;
946 // the first N recs that can fit here mean we won't call malloc
947 uint32_t fMCRecStorage[32];
948
949 SkBounder* fBounder;
reed@android.com199f1082009-06-10 02:12:47 +0000950 SkDevice* fLastDeviceToGainFocus;
reed@google.com7c202932011-12-14 18:48:05 +0000951 int fLayerCount; // number of successful saveLayer calls
reed@android.com8a1c16f2008-12-17 15:59:43 +0000952
bsalomon@google.comd302f142011-03-03 13:54:13 +0000953 void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
954 const SkClipStack& clipStack);
reed@google.com4b226022011-01-11 18:32:13 +0000955
reed@android.com8a1c16f2008-12-17 15:59:43 +0000956 bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
957 void updateDeviceCMCache();
958
959 friend class SkDrawIter; // needs setupDrawForLayerDevice()
960
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000961 SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
bsalomon@google.come97f0852011-06-17 13:10:25 +0000962 bool isOpaque);
963
reed@android.com8a1c16f2008-12-17 15:59:43 +0000964 SkDevice* init(SkDevice*);
reed@google.comf0b5e112011-09-07 11:57:34 +0000965
966 // internal methods are not virtual, so they can safely be called by other
967 // canvas apis, without confusing subclasses (like SkPictureRecording)
reed@android.comf2b98d62010-12-20 18:26:13 +0000968 void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000969 const SkPaint* paint);
reed@google.comf0b5e112011-09-07 11:57:34 +0000970 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
971 const SkRect& dst, const SkPaint* paint);
972 void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
973 const SkRect& dst, const SkPaint* paint);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +0000974 void internalDrawPaint(const SkPaint& paint);
975
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000976
reed@android.com8a1c16f2008-12-17 15:59:43 +0000977 void drawDevice(SkDevice*, int x, int y, const SkPaint*);
978 // shared by save() and saveLayer()
979 int internalSave(SaveFlags flags);
980 void internalRestore();
bungeman@google.com52c748b2011-08-22 21:30:43 +0000981 static void DrawRect(const SkDraw& draw, const SkPaint& paint,
982 const SkRect& r, SkScalar textSize);
983 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
984 const char text[], size_t byteLength,
985 SkScalar x, SkScalar y);
reed@google.com4b226022011-01-11 18:32:13 +0000986
reed@android.com8a1c16f2008-12-17 15:59:43 +0000987 /* These maintain a cache of the clip bounds in local coordinates,
988 (converted to 2s-compliment if floats are slow).
989 */
990 mutable SkRectCompareType fLocalBoundsCompareType;
991 mutable bool fLocalBoundsCompareTypeDirty;
992
reed@android.comba09de42010-02-05 20:46:05 +0000993 mutable SkRectCompareType fLocalBoundsCompareTypeBW;
994 mutable bool fLocalBoundsCompareTypeDirtyBW;
995
996 /* Get the local clip bounds with an anti-aliased edge.
997 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000998 const SkRectCompareType& getLocalClipBoundsCompareType() const {
reed@android.comba09de42010-02-05 20:46:05 +0000999 return getLocalClipBoundsCompareType(kAA_EdgeType);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001000 }
reed@android.comba09de42010-02-05 20:46:05 +00001001
1002 const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const {
1003 if (et == kAA_EdgeType) {
1004 if (fLocalBoundsCompareTypeDirty) {
1005 this->computeLocalClipBoundsCompareType(et);
1006 fLocalBoundsCompareTypeDirty = false;
1007 }
1008 return fLocalBoundsCompareType;
1009 } else {
1010 if (fLocalBoundsCompareTypeDirtyBW) {
1011 this->computeLocalClipBoundsCompareType(et);
1012 fLocalBoundsCompareTypeDirtyBW = false;
1013 }
1014 return fLocalBoundsCompareTypeBW;
1015 }
1016 }
1017 void computeLocalClipBoundsCompareType(EdgeType et) const;
reed@android.comf2b98d62010-12-20 18:26:13 +00001018
1019 SkMatrix fExternalMatrix, fExternalInverse;
1020 bool fUseExternalMatrix;
reed@google.com5c3d1472011-02-22 19:12:23 +00001021
1022 class AutoValidateClip : ::SkNoncopyable {
1023 public:
1024 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1025 fCanvas->validateClip();
1026 }
1027 ~AutoValidateClip() { fCanvas->validateClip(); }
1028
1029 private:
1030 const SkCanvas* fCanvas;
1031 };
1032
1033#ifdef SK_DEBUG
1034 void validateClip() const;
1035#else
1036 void validateClip() const {}
1037#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +00001038};
1039
1040/** Stack helper class to automatically call restoreToCount() on the canvas
1041 when this object goes out of scope. Use this to guarantee that the canvas
1042 is restored to a known state.
1043*/
1044class SkAutoCanvasRestore : SkNoncopyable {
1045public:
1046 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
1047 SkASSERT(canvas);
1048 fSaveCount = canvas->getSaveCount();
1049 if (doSave) {
1050 canvas->save();
1051 }
1052 }
1053 ~SkAutoCanvasRestore() {
1054 fCanvas->restoreToCount(fSaveCount);
1055 }
1056
1057private:
1058 SkCanvas* fCanvas;
1059 int fSaveCount;
1060};
1061
1062#endif