blob: 1f29e1c00ab68d4a65ec86be5063deb71a5c6024 [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;
reed@google.com97af1a62012-08-28 12:19:02 +000029class SkSurface_Base;
reed@android.com8a1c16f2008-12-17 15:59:43 +000030
31/** \class SkCanvas
32
33 A Canvas encapsulates all of the state about drawing into a device (bitmap).
34 This includes a reference to the device itself, and a stack of matrix/clip
35 values. For any given draw call (e.g. drawRect), the geometry of the object
36 being drawn is transformed by the concatenation of all the matrices in the
37 stack. The transformed geometry is clipped by the intersection of all of
38 the clips in the stack.
39
40 While the Canvas holds the state of the drawing device, the state (style)
41 of the object being drawn is held by the Paint, which is provided as a
42 parameter to each of the draw() methods. The Paint holds attributes such as
43 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
44 etc.
45*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000046class SK_API SkCanvas : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000047public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000048 SK_DECLARE_INST_COUNT(SkCanvas)
49
reed@google.comcde92112011-07-06 20:00:52 +000050 SkCanvas();
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000051
reed@google.com6dc74552011-07-21 18:00:46 +000052 /** Construct a canvas with the specified device to draw into.
bsalomon@google.come97f0852011-06-17 13:10:25 +000053
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000054 @param device Specifies a device for the canvas to draw into.
55 */
56 explicit SkCanvas(SkDevice* device);
57
58 /** Deprecated - Construct a canvas with the specified bitmap to draw into.
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 @param bitmap Specifies a bitmap for the canvas to draw into. Its
60 structure are copied to the canvas.
61 */
62 explicit SkCanvas(const SkBitmap& bitmap);
reed@android.com8a1c16f2008-12-17 15:59:43 +000063 virtual ~SkCanvas();
64
65 ///////////////////////////////////////////////////////////////////////////
66
reed@google.com210ce002011-11-01 14:24:23 +000067 /**
junov@chromium.orgbf6c1e42012-01-30 14:53:22 +000068 * Trigger the immediate execution of all pending draw operations.
69 */
70 void flush();
71
72 /**
reed@google.com210ce002011-11-01 14:24:23 +000073 * Return the width/height of the underlying device. The current drawable
74 * area may be small (due to clipping or saveLayer). For a canvas with
75 * no device, 0,0 will be returned.
76 */
77 SkISize getDeviceSize() const;
78
reed@android.com8a1c16f2008-12-17 15:59:43 +000079 /** Return the canvas' device object, which may be null. The device holds
80 the bitmap of the pixels that the canvas draws into. The reference count
81 of the returned device is not changed by this call.
82 */
83 SkDevice* getDevice() const;
84
85 /** Specify a device for this canvas to draw into. If it is not null, its
86 reference count is incremented. If the canvas was already holding a
87 device, its reference count is decremented. The new device is returned.
88 */
junov@google.com4370aed2012-01-18 16:21:08 +000089 virtual SkDevice* setDevice(SkDevice* device);
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000090
reed@google.com9266fed2011-03-30 00:18:03 +000091 /**
92 * saveLayer() can create another device (which is later drawn onto
93 * the previous device). getTopDevice() returns the top-most device current
94 * installed. Note that this can change on other calls like save/restore,
95 * so do not access this device after subsequent canvas calls.
96 * The reference count of the device is not changed.
reed@google.com0b53d592012-03-19 18:26:34 +000097 *
98 * @param updateMatrixClip If this is true, then before the device is
99 * returned, we ensure that its has been notified about the current
100 * matrix and clip. Note: this happens automatically when the device
101 * is drawn to, but is optional here, as there is a small perf hit
102 * sometimes.
reed@google.com9266fed2011-03-30 00:18:03 +0000103 */
reed@google.com0b53d592012-03-19 18:26:34 +0000104 SkDevice* getTopDevice(bool updateMatrixClip = false) const;
reed@google.com9266fed2011-03-30 00:18:03 +0000105
reed@android.comf2b98d62010-12-20 18:26:13 +0000106 /**
107 * Create a new raster device and make it current. This also returns
108 * the new device.
109 */
reed@google.comaf951c92011-06-16 19:10:39 +0000110 SkDevice* setBitmapDevice(const SkBitmap& bitmap);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111
reed@google.com51df9e32010-12-23 19:29:18 +0000112 /**
reed@google.comcde92112011-07-06 20:00:52 +0000113 * Shortcut for getDevice()->createCompatibleDevice(...).
114 * If getDevice() == NULL, this method does nothing, and returns NULL.
bsalomon@google.come97f0852011-06-17 13:10:25 +0000115 */
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000116 SkDevice* createCompatibleDevice(SkBitmap::Config config,
bsalomon@google.come97f0852011-06-17 13:10:25 +0000117 int width, int height,
118 bool isOpaque);
119
reed@google.com4b226022011-01-11 18:32:13 +0000120 ///////////////////////////////////////////////////////////////////////////
121
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000122 /**
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000123 * This enum can be used with read/writePixels to perform a pixel ops to or
124 * from an 8888 config other than Skia's native config (SkPMColor). There
125 * are three byte orders supported: native, BGRA, and RGBA. Each has a
126 * premultiplied and unpremultiplied variant.
127 *
128 * Components of a 8888 pixel can be packed/unpacked from a 32bit word using
129 * either byte offsets or shift values. Byte offsets are endian-invariant
130 * while shifts are not. BGRA and RGBA configs are defined by byte
131 * orderings. The native config is defined by shift values (SK_A32_SHIFT,
132 * ..., SK_B32_SHIFT).
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000133 */
134 enum Config8888 {
135 /**
136 * Skia's native order specified by:
137 * SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
138 *
139 * kNative_Premul_Config8888 is equivalent to SkPMColor
140 * kNative_Unpremul_Config8888 has the same component order as SkPMColor
141 * but is not premultiplied.
142 */
143 kNative_Premul_Config8888,
144 kNative_Unpremul_Config8888,
145 /**
146 * low byte to high byte: B, G, R, A.
147 */
148 kBGRA_Premul_Config8888,
149 kBGRA_Unpremul_Config8888,
150 /**
151 * low byte to high byte: R, G, B, A.
152 */
153 kRGBA_Premul_Config8888,
tomhudson@google.com1f902872012-06-01 13:15:47 +0000154 kRGBA_Unpremul_Config8888
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000155 };
156
157 /**
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000158 * On success (returns true), copy the canvas pixels into the bitmap.
159 * On failure, the bitmap parameter is left unchanged and false is
160 * returned.
161 *
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000162 * The canvas' pixels are converted to the bitmap's config. The only
163 * supported config is kARGB_8888_Config, though this is likely to be
164 * relaxed in the future. The meaning of config kARGB_8888_Config is
165 * modified by the enum param config8888. The default value interprets
166 * kARGB_8888_Config as SkPMColor
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000167 *
168 * If the bitmap has pixels already allocated, the canvas pixels will be
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000169 * written there. If not, bitmap->allocPixels() will be called
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000170 * automatically. If the bitmap is backed by a texture readPixels will
171 * fail.
172 *
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000173 * The actual pixels written is the intersection of the canvas' bounds, and
174 * the rectangle formed by the bitmap's width,height and the specified x,y.
175 * If bitmap pixels extend outside of that intersection, they will not be
176 * modified.
177 *
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000178 * Other failure conditions:
179 * * If the canvas is backed by a non-raster device (e.g. PDF) then
180 * readPixels will fail.
181 * * If bitmap is texture-backed then readPixels will fail. (This may be
182 * relaxed in the future.)
183 *
184 * Example that reads the entire canvas into a bitmap using the native
185 * SkPMColor:
186 * SkISize size = canvas->getDeviceSize();
187 * bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
188 * size.fHeight);
189 * if (canvas->readPixels(bitmap, 0, 0)) {
190 * // use the pixels
191 * }
bsalomon@google.comc6980972011-11-02 19:57:21 +0000192 */
bsalomon@google.com6850eab2011-11-03 20:29:47 +0000193 bool readPixels(SkBitmap* bitmap,
194 int x, int y,
195 Config8888 config8888 = kNative_Premul_Config8888);
bsalomon@google.comc6980972011-11-02 19:57:21 +0000196
reed@google.com4b226022011-01-11 18:32:13 +0000197 /**
bsalomon@google.comc6980972011-11-02 19:57:21 +0000198 * DEPRECATED: This will be removed as soon as webkit is no longer relying
199 * on it. The bitmap is resized to the intersection of srcRect and the
200 * canvas bounds. New pixels are always allocated on success. Bitmap is
201 * unmodified on failure.
reed@google.com51df9e32010-12-23 19:29:18 +0000202 */
203 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
reed@google.com51df9e32010-12-23 19:29:18 +0000204
205 /**
206 * Similar to draw sprite, this method will copy the pixels in bitmap onto
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000207 * the canvas, with the top/left corner specified by (x, y). The canvas'
208 * pixel values are completely replaced: there is no blending.
209 *
210 * Currently if bitmap is backed by a texture this is a no-op. This may be
211 * relaxed in the future.
212 *
213 * If the bitmap has config kARGB_8888_Config then the config8888 param
214 * will determines how the pixel valuess are intepreted. If the bitmap is
215 * not kARGB_8888_Config then this parameter is ignored.
epoger@google.com4f1151a2011-07-25 15:47:33 +0000216 *
217 * Note: If you are recording drawing commands on this canvas to
218 * SkPicture, writePixels() is ignored!
reed@google.com51df9e32010-12-23 19:29:18 +0000219 */
bsalomon@google.comd58a1cd2011-11-10 20:57:43 +0000220 void writePixels(const SkBitmap& bitmap,
221 int x, int y,
222 Config8888 config8888 = kNative_Premul_Config8888);
reed@google.com4b226022011-01-11 18:32:13 +0000223
reed@android.com8a1c16f2008-12-17 15:59:43 +0000224 ///////////////////////////////////////////////////////////////////////////
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000225
reed@android.com8a1c16f2008-12-17 15:59:43 +0000226 enum SaveFlags {
227 /** save the matrix state, restoring it on restore() */
228 kMatrix_SaveFlag = 0x01,
229 /** save the clip state, restoring it on restore() */
230 kClip_SaveFlag = 0x02,
231 /** the layer needs to support per-pixel alpha */
232 kHasAlphaLayer_SaveFlag = 0x04,
233 /** the layer needs to support 8-bits per color component */
234 kFullColorLayer_SaveFlag = 0x08,
235 /** the layer should clip against the bounds argument */
236 kClipToLayer_SaveFlag = 0x10,
237
238 // helper masks for common choices
239 kMatrixClip_SaveFlag = 0x03,
240 kARGB_NoClipLayer_SaveFlag = 0x0F,
241 kARGB_ClipLayer_SaveFlag = 0x1F
242 };
243
reed@android.comdc3381f2010-02-11 16:05:15 +0000244 /** This call saves the current matrix, clip, and drawFilter, and pushes a
reed@android.com8a1c16f2008-12-17 15:59:43 +0000245 copy onto a private stack. Subsequent calls to translate, scale,
reed@android.comdc3381f2010-02-11 16:05:15 +0000246 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
247 operate on this copy.
248 When the balancing call to restore() is made, the previous matrix, clip,
249 and drawFilter are restored.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250 @return The value to pass to restoreToCount() to balance this save()
251 */
252 virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
253
254 /** This behaves the same as save(), but in addition it allocates an
255 offscreen bitmap. All drawing calls are directed there, and only when
256 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000257 the canvas (or the previous layer).
reed@android.comad164b22010-07-02 17:20:51 +0000258 @param bounds (may be null) This rect, if non-null, is used as a hint to
259 limit the size of the offscreen, and thus drawing may be
260 clipped to it, though that clipping is not guaranteed to
261 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000262 @param paint (may be null) This is copied, and is applied to the
263 offscreen when restore() is called
264 @param flags LayerFlags
265 @return The value to pass to restoreToCount() to balance this save()
266 */
267 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
268 SaveFlags flags = kARGB_ClipLayer_SaveFlag);
269
270 /** This behaves the same as save(), but in addition it allocates an
271 offscreen bitmap. All drawing calls are directed there, and only when
272 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000273 the canvas (or the previous layer).
reed@android.com40408612010-07-02 17:24:23 +0000274 @param bounds (may be null) This rect, if non-null, is used as a hint to
275 limit the size of the offscreen, and thus drawing may be
276 clipped to it, though that clipping is not guaranteed to
277 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000278 @param alpha This is applied to the offscreen when restore() is called.
279 @param flags LayerFlags
280 @return The value to pass to restoreToCount() to balance this save()
281 */
282 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
283 SaveFlags flags = kARGB_ClipLayer_SaveFlag);
284
285 /** This call balances a previous call to save(), and is used to remove all
reed@android.comdc3381f2010-02-11 16:05:15 +0000286 modifications to the matrix/clip/drawFilter state since the last save
287 call.
288 It is an error to call restore() more times than save() was called.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000289 */
290 virtual void restore();
291
292 /** Returns the number of matrix/clip states on the SkCanvas' private stack.
293 This will equal # save() calls - # restore() calls.
294 */
junov@chromium.orga907ac32012-02-24 21:54:07 +0000295 int getSaveCount() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000296
297 /** Efficient way to pop any calls to save() that happened after the save
298 count reached saveCount. It is an error for saveCount to be less than
299 getSaveCount()
300 @param saveCount The number of save() levels to restore from
301 */
302 void restoreToCount(int saveCount);
303
reed@google.com7c202932011-12-14 18:48:05 +0000304 /** Returns true if drawing is currently going to a layer (from saveLayer)
305 * rather than to the root device.
306 */
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000307 virtual bool isDrawingToLayer() const;
reed@google.com7c202932011-12-14 18:48:05 +0000308
reed@android.com8a1c16f2008-12-17 15:59:43 +0000309 /** Preconcat the current matrix with the specified translation
310 @param dx The distance to translate in X
311 @param dy The distance to translate in Y
312 returns true if the operation succeeded (e.g. did not overflow)
313 */
314 virtual bool translate(SkScalar dx, SkScalar dy);
315
316 /** Preconcat the current matrix with the specified scale.
317 @param sx The amount to scale in X
318 @param sy The amount to scale in Y
319 returns true if the operation succeeded (e.g. did not overflow)
320 */
321 virtual bool scale(SkScalar sx, SkScalar sy);
322
323 /** Preconcat the current matrix with the specified rotation.
324 @param degrees The amount to rotate, in degrees
325 returns true if the operation succeeded (e.g. did not overflow)
326 */
327 virtual bool rotate(SkScalar degrees);
328
329 /** Preconcat the current matrix with the specified skew.
330 @param sx The amount to skew in X
331 @param sy The amount to skew in Y
332 returns true if the operation succeeded (e.g. did not overflow)
333 */
334 virtual bool skew(SkScalar sx, SkScalar sy);
335
336 /** Preconcat the current matrix with the specified matrix.
337 @param matrix The matrix to preconcatenate with the current matrix
338 @return true if the operation succeeded (e.g. did not overflow)
339 */
340 virtual bool concat(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000341
reed@android.com8a1c16f2008-12-17 15:59:43 +0000342 /** Replace the current matrix with a copy of the specified matrix.
343 @param matrix The matrix that will be copied into the current matrix.
344 */
345 virtual void setMatrix(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000346
reed@android.com8a1c16f2008-12-17 15:59:43 +0000347 /** Helper for setMatrix(identity). Sets the current matrix to identity.
348 */
349 void resetMatrix();
350
351 /** Modify the current clip with the specified rectangle.
352 @param rect The rect to intersect with the current clip
353 @param op The region op to apply to the current clip
354 @return true if the canvas' clip is non-empty
355 */
356 virtual bool clipRect(const SkRect& rect,
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 path.
361 @param path The path to apply to the current clip
362 @param op The region op to apply to the current clip
363 @return true if the canvas' new clip is non-empty
364 */
365 virtual bool clipPath(const SkPath& path,
reed@google.com071eef92011-10-12 11:52:53 +0000366 SkRegion::Op op = SkRegion::kIntersect_Op,
367 bool doAntiAlias = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000368
369 /** Modify the current clip with the specified region. Note that unlike
370 clipRect() and clipPath() which transform their arguments by the current
371 matrix, clipRegion() assumes its argument is already in device
372 coordinates, and so no transformation is performed.
373 @param deviceRgn The region to apply to the current clip
374 @param op The region op to apply to the current clip
375 @return true if the canvas' new clip is non-empty
376 */
377 virtual bool clipRegion(const SkRegion& deviceRgn,
378 SkRegion::Op op = SkRegion::kIntersect_Op);
379
380 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
381 specified region. This does not intersect or in any other way account
382 for the existing clip region.
383 @param deviceRgn The region to copy into the current clip.
384 @return true if the new clip region is non-empty
385 */
386 bool setClipRegion(const SkRegion& deviceRgn) {
387 return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
388 }
389
reed@android.com8a1c16f2008-12-17 15:59:43 +0000390 /** Return true if the specified rectangle, after being transformed by the
391 current matrix, would lie completely outside of the current clip. Call
392 this to check if an area you intend to draw into is clipped out (and
393 therefore you can skip making the draw calls).
394 @param rect the rect to compare with the current clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000395 @return true if the rect (transformed by the canvas' matrix) does not
396 intersect with the canvas' clip
397 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000398 bool quickReject(const SkRect& rect) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000399
400 /** Return true if the specified path, after being transformed by the
401 current matrix, would lie completely outside of the current clip. Call
402 this to check if an area you intend to draw into is clipped out (and
403 therefore you can skip making the draw calls). Note, for speed it may
404 return false even if the path itself might not intersect the clip
405 (i.e. the bounds of the path intersects, but the path does not).
406 @param path The path to compare with the current clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000407 @return true if the path (transformed by the canvas' matrix) does not
408 intersect with the canvas' clip
409 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000410 bool quickReject(const SkPath& path) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000411
412 /** Return true if the horizontal band specified by top and bottom is
413 completely clipped out. This is a conservative calculation, meaning
414 that it is possible that if the method returns false, the band may still
415 in fact be clipped out, but the converse is not true. If this method
416 returns true, then the band is guaranteed to be clipped out.
417 @param top The top of the horizontal band to compare with the clip
418 @param bottom The bottom of the horizontal and to compare with the clip
419 @return true if the horizontal band is completely clipped out (i.e. does
420 not intersect the current clip)
421 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000422 bool quickRejectY(SkScalar top, SkScalar bottom) const {
djsollen@google.com92d2a292012-02-27 16:17:59 +0000423 SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
reed@google.com3b3e8952012-08-16 20:53:31 +0000424 const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType();
djsollen@google.com92d2a292012-02-27 16:17:59 +0000425 // In the case where the clip is empty and we are provided with a
426 // negative top and positive bottom parameter then this test will return
427 // false even though it will be clipped. We have chosen to exclude that
428 // check as it is rare and would result double the comparisons.
429 return SkScalarToCompareType(top) >= clipR.fBottom
430 || SkScalarToCompareType(bottom) <= clipR.fTop;
431 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000432
433 /** Return the bounds of the current clip (in local coordinates) in the
434 bounds parameter, and return true if it is non-empty. This can be useful
435 in a way similar to quickReject, in that it tells you that drawing
436 outside of these bounds will be clipped out.
437 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000438 bool getClipBounds(SkRect* bounds) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000439
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000440 /** Return the bounds of the current clip, in device coordinates; returns
441 true if non-empty. Maybe faster than getting the clip explicitly and
442 then taking its bounds.
443 */
444 bool getClipDeviceBounds(SkIRect* bounds) const;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000445
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000446
reed@android.com8a1c16f2008-12-17 15:59:43 +0000447 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000448 specified ARGB color, using the specified mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000449 @param a the alpha component (0..255) of the color to fill the canvas
450 @param r the red component (0..255) of the color to fill the canvas
451 @param g the green component (0..255) of the color to fill the canvas
452 @param b the blue component (0..255) of the color to fill the canvas
453 @param mode the mode to apply the color in (defaults to SrcOver)
454 */
455 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
reed@android.com845fdac2009-06-23 03:01:32 +0000456 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000457
458 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000459 specified color and mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000460 @param color the color to draw with
461 @param mode the mode to apply the color in (defaults to SrcOver)
462 */
463 void drawColor(SkColor color,
reed@android.com845fdac2009-06-23 03:01:32 +0000464 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000465
reed@google.com2a981812011-04-14 18:59:28 +0000466 /**
467 * This erases the entire drawing surface to the specified color,
468 * irrespective of the clip. It does not blend with the previous pixels,
469 * but always overwrites them.
470 *
471 * It is roughly equivalent to the following:
472 * canvas.save();
473 * canvas.clipRect(hugeRect, kReplace_Op);
474 * paint.setColor(color);
475 * paint.setXfermodeMode(kSrc_Mode);
476 * canvas.drawPaint(paint);
477 * canvas.restore();
478 * though it is almost always much more efficient.
479 */
480 virtual void clear(SkColor);
481
482 /**
483 * Fill the entire canvas' bitmap (restricted to the current clip) with the
484 * specified paint.
485 * @param paint The paint used to fill the canvas
486 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000487 virtual void drawPaint(const SkPaint& paint);
488
489 enum PointMode {
490 /** drawPoints draws each point separately */
491 kPoints_PointMode,
492 /** drawPoints draws each pair of points as a line segment */
493 kLines_PointMode,
494 /** drawPoints draws the array of points as a polygon */
495 kPolygon_PointMode
496 };
497
498 /** Draw a series of points, interpreted based on the PointMode mode. For
499 all modes, the count parameter is interpreted as the total number of
500 points. For kLine mode, count/2 line segments are drawn.
501 For kPoint mode, each point is drawn centered at its coordinate, and its
502 size is specified by the paint's stroke-width. It draws as a square,
503 unless the paint's cap-type is round, in which the points are drawn as
504 circles.
505 For kLine mode, each pair of points is drawn as a line segment,
506 respecting the paint's settings for cap/join/width.
507 For kPolygon mode, the entire array is drawn as a series of connected
508 line segments.
509 Note that, while similar, kLine and kPolygon modes draw slightly
510 differently than the equivalent path built with a series of moveto,
511 lineto calls, in that the path will draw all of its contours at once,
512 with no interactions if contours intersect each other (think XOR
513 xfermode). drawPoints always draws each element one at a time.
514 @param mode PointMode specifying how to draw the array of points.
515 @param count The number of points in the array
516 @param pts Array of points to draw
517 @param paint The paint used to draw the points
518 */
519 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
520 const SkPaint& paint);
521
522 /** Helper method for drawing a single point. See drawPoints() for a more
523 details.
524 */
525 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000526
reed@android.com8a1c16f2008-12-17 15:59:43 +0000527 /** Draws a single pixel in the specified color.
528 @param x The X coordinate of which pixel to draw
529 @param y The Y coordiante of which pixel to draw
530 @param color The color to draw
531 */
532 void drawPoint(SkScalar x, SkScalar y, SkColor color);
533
534 /** Draw a line segment with the specified start and stop x,y coordinates,
535 using the specified paint. NOTE: since a line is always "framed", the
536 paint's Style is ignored.
537 @param x0 The x-coordinate of the start point of the line
538 @param y0 The y-coordinate of the start point of the line
539 @param x1 The x-coordinate of the end point of the line
540 @param y1 The y-coordinate of the end point of the line
541 @param paint The paint used to draw the line
542 */
543 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
544 const SkPaint& paint);
545
546 /** Draw the specified rectangle using the specified paint. The rectangle
547 will be filled or stroked based on the Style in the paint.
548 @param rect The rect to be drawn
549 @param paint The paint used to draw the rect
550 */
551 virtual void drawRect(const SkRect& rect, const SkPaint& paint);
552
553 /** Draw the specified rectangle using the specified paint. The rectangle
554 will be filled or framed based on the Style in the paint.
555 @param rect The rect to be drawn
556 @param paint The paint used to draw the rect
557 */
558 void drawIRect(const SkIRect& rect, const SkPaint& paint)
559 {
560 SkRect r;
561 r.set(rect); // promotes the ints to scalars
562 this->drawRect(r, paint);
563 }
reed@google.com4b226022011-01-11 18:32:13 +0000564
reed@android.com8a1c16f2008-12-17 15:59:43 +0000565 /** Draw the specified rectangle using the specified paint. The rectangle
566 will be filled or framed based on the Style in the paint.
567 @param left The left side of the rectangle to be drawn
568 @param top The top side of the rectangle to be drawn
569 @param right The right side of the rectangle to be drawn
570 @param bottom The bottom side of the rectangle to be drawn
571 @param paint The paint used to draw the rect
572 */
573 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
574 SkScalar bottom, const SkPaint& paint);
575
576 /** Draw the specified oval using the specified paint. The oval will be
577 filled or framed based on the Style in the paint.
578 @param oval The rectangle bounds of the oval to be drawn
579 @param paint The paint used to draw the oval
580 */
581 void drawOval(const SkRect& oval, const SkPaint&);
582
583 /** Draw the specified circle using the specified paint. If radius is <= 0,
584 then nothing will be drawn. The circle will be filled
585 or framed based on the Style in the paint.
586 @param cx The x-coordinate of the center of the cirle to be drawn
587 @param cy The y-coordinate of the center of the cirle to be drawn
588 @param radius The radius of the cirle to be drawn
589 @param paint The paint used to draw the circle
590 */
591 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
592 const SkPaint& paint);
593
594 /** Draw the specified arc, which will be scaled to fit inside the
595 specified oval. If the sweep angle is >= 360, then the oval is drawn
596 completely. Note that this differs slightly from SkPath::arcTo, which
597 treats the sweep angle mod 360.
598 @param oval The bounds of oval used to define the shape of the arc
599 @param startAngle Starting angle (in degrees) where the arc begins
600 @param sweepAngle Sweep angle (in degrees) measured clockwise
601 @param useCenter true means include the center of the oval. For filling
602 this will draw a wedge. False means just use the arc.
603 @param paint The paint used to draw the arc
604 */
605 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
606 bool useCenter, const SkPaint& paint);
607
608 /** Draw the specified round-rect using the specified paint. The round-rect
609 will be filled or framed based on the Style in the paint.
610 @param rect The rectangular bounds of the roundRect to be drawn
611 @param rx The x-radius of the oval used to round the corners
612 @param ry The y-radius of the oval used to round the corners
613 @param paint The paint used to draw the roundRect
614 */
615 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
616 const SkPaint& paint);
617
618 /** Draw the specified path using the specified paint. The path will be
619 filled or framed based on the Style in the paint.
620 @param path The path to be drawn
621 @param paint The paint used to draw the path
622 */
623 virtual void drawPath(const SkPath& path, const SkPaint& paint);
624
625 /** Draw the specified bitmap, with its top/left corner at (x,y), using the
626 specified paint, transformed by the current matrix. Note: if the paint
627 contains a maskfilter that generates a mask which extends beyond the
628 bitmap's original width/height, then the bitmap will be drawn as if it
629 were in a Shader with CLAMP mode. Thus the color outside of the original
630 width/height will be the edge color replicated.
631 @param bitmap The bitmap to be drawn
632 @param left The position of the left side of the bitmap being drawn
633 @param top The position of the top side of the bitmap being drawn
634 @param paint The paint used to draw the bitmap, or NULL
635 */
636 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
637 const SkPaint* paint = NULL);
638
639 /** Draw the specified bitmap, with the specified matrix applied (before the
640 canvas' matrix is applied).
641 @param bitmap The bitmap to be drawn
642 @param src Optional: specify the subset of the bitmap to be drawn
643 @param dst The destination rectangle where the scaled/translated
644 image will be drawn
645 @param paint The paint used to draw the bitmap, or NULL
646 */
647 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
648 const SkRect& dst, const SkPaint* paint = NULL);
649
650 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
651 const SkPaint* paint = NULL);
reed@google.com4b226022011-01-11 18:32:13 +0000652
reed@google.comf0b5e112011-09-07 11:57:34 +0000653 /**
654 * Draw the bitmap stretched differentially to fit into dst.
655 * center is a rect within the bitmap, and logically divides the bitmap
656 * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
657 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
658 *
659 * If the dst is >= the bitmap size, then...
660 * - The 4 corners are not stretch at all.
661 * - The sides are stretch in only one axis.
662 * - The center is stretch in both axes.
663 * Else, for each axis where dst < bitmap,
664 * - The corners shrink proportionally
665 * - The sides (along the shrink axis) and center are not drawn
666 */
667 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
668 const SkRect& dst, const SkPaint* paint = NULL);
669
reed@android.com8a1c16f2008-12-17 15:59:43 +0000670 /** Draw the specified bitmap, with its top/left corner at (x,y),
671 NOT transformed by the current matrix. Note: if the paint
672 contains a maskfilter that generates a mask which extends beyond the
673 bitmap's original width/height, then the bitmap will be drawn as if it
674 were in a Shader with CLAMP mode. Thus the color outside of the original
675 width/height will be the edge color replicated.
676 @param bitmap The bitmap to be drawn
677 @param left The position of the left side of the bitmap being drawn
678 @param top The position of the top side of the bitmap being drawn
679 @param paint The paint used to draw the bitmap, or NULL
680 */
681 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
682 const SkPaint* paint = NULL);
683
684 /** Draw the text, with origin at (x,y), using the specified paint.
685 The origin is interpreted based on the Align setting in the paint.
686 @param text The text to be drawn
687 @param byteLength The number of bytes to read from the text parameter
688 @param x The x-coordinate of the origin of the text being drawn
689 @param y The y-coordinate of the origin of the text being drawn
690 @param paint The paint used for the text (e.g. color, size, style)
691 */
692 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
693 SkScalar y, const SkPaint& paint);
694
695 /** Draw the text, with each character/glyph origin specified by the pos[]
reed@google.com4b226022011-01-11 18:32:13 +0000696 array. The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000697 @param text The text to be drawn
698 @param byteLength The number of bytes to read from the text parameter
699 @param pos Array of positions, used to position each character
700 @param paint The paint used for the text (e.g. color, size, style)
701 */
702 virtual void drawPosText(const void* text, size_t byteLength,
703 const SkPoint pos[], const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000704
reed@android.com8a1c16f2008-12-17 15:59:43 +0000705 /** Draw the text, with each character/glyph origin specified by the x
706 coordinate taken from the xpos[] array, and the y from the constY param.
reed@google.com4b226022011-01-11 18:32:13 +0000707 The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000708 @param text The text to be drawn
709 @param byteLength The number of bytes to read from the text parameter
710 @param xpos Array of x-positions, used to position each character
711 @param constY The shared Y coordinate for all of the positions
712 @param paint The paint used for the text (e.g. color, size, style)
713 */
714 virtual void drawPosTextH(const void* text, size_t byteLength,
715 const SkScalar xpos[], SkScalar constY,
716 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000717
reed@android.com8a1c16f2008-12-17 15:59:43 +0000718 /** Draw the text, with origin at (x,y), using the specified paint, along
719 the specified path. The paint's Align setting determins where along the
720 path to start the text.
721 @param text The text to be drawn
722 @param byteLength The number of bytes to read from the text parameter
723 @param path The path the text should follow for its baseline
724 @param hOffset The distance along the path to add to the text's
725 starting position
726 @param vOffset The distance above(-) or below(+) the path to
727 position the text
728 @param paint The paint used for the text
729 */
730 void drawTextOnPathHV(const void* text, size_t byteLength,
731 const SkPath& path, SkScalar hOffset,
732 SkScalar vOffset, const SkPaint& paint);
733
734 /** Draw the text, with origin at (x,y), using the specified paint, along
735 the specified path. The paint's Align setting determins where along the
736 path to start the text.
737 @param text The text to be drawn
738 @param byteLength The number of bytes to read from the text parameter
739 @param path The path the text should follow for its baseline
740 @param matrix (may be null) Applied to the text before it is
741 mapped onto the path
742 @param paint The paint used for the text
743 */
744 virtual void drawTextOnPath(const void* text, size_t byteLength,
745 const SkPath& path, const SkMatrix* matrix,
746 const SkPaint& paint);
747
djsollen@google.com56c69772011-11-08 19:00:26 +0000748#ifdef SK_BUILD_FOR_ANDROID
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000749 /** Draw the text on path, with each character/glyph origin specified by the pos[]
750 array. The origin is interpreted by the Align setting in the paint.
751 @param text The text to be drawn
752 @param byteLength The number of bytes to read from the text parameter
753 @param pos Array of positions, used to position each character
754 @param paint The paint used for the text (e.g. color, size, style)
755 @param path The path to draw on
756 @param matrix The canvas matrix
757 */
758 void drawPosTextOnPath(const void* text, size_t byteLength,
759 const SkPoint pos[], const SkPaint& paint,
760 const SkPath& path, const SkMatrix* matrix);
761#endif
762
reed@android.com8a1c16f2008-12-17 15:59:43 +0000763 /** Draw the picture into this canvas. This method effective brackets the
764 playback of the picture's draw calls with save/restore, so the state
765 of this canvas will be unchanged after this call. This contrasts with
766 the more immediate method SkPicture::draw(), which does not bracket
767 the canvas with save/restore, thus the canvas may be left in a changed
768 state after the call.
769 @param picture The recorded drawing commands to playback into this
770 canvas.
771 */
772 virtual void drawPicture(SkPicture& picture);
reed@google.com4b226022011-01-11 18:32:13 +0000773
reed@android.com8a1c16f2008-12-17 15:59:43 +0000774 enum VertexMode {
775 kTriangles_VertexMode,
776 kTriangleStrip_VertexMode,
777 kTriangleFan_VertexMode
778 };
reed@google.com4b226022011-01-11 18:32:13 +0000779
reed@android.com8a1c16f2008-12-17 15:59:43 +0000780 /** Draw the array of vertices, interpreted as triangles (based on mode).
781 @param vmode How to interpret the array of vertices
782 @param vertexCount The number of points in the vertices array (and
783 corresponding texs and colors arrays if non-null)
784 @param vertices Array of vertices for the mesh
785 @param texs May be null. If not null, specifies the coordinate
786 in texture space for each vertex.
787 @param colors May be null. If not null, specifies a color for each
788 vertex, to be interpolated across the triangle.
789 @param xmode Used if both texs and colors are present. In this
790 case the colors are combined with the texture using mode,
791 before being drawn using the paint. If mode is null, then
reed@android.com845fdac2009-06-23 03:01:32 +0000792 kMultiply_Mode is used.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000793 @param indices If not null, array of indices to reference into the
794 vertex (texs, colors) array.
795 @param indexCount number of entries in the indices array (if not null)
reed@google.com4b226022011-01-11 18:32:13 +0000796 @param paint Specifies the shader/texture if present.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000797 */
798 virtual void drawVertices(VertexMode vmode, int vertexCount,
799 const SkPoint vertices[], const SkPoint texs[],
800 const SkColor colors[], SkXfermode* xmode,
801 const uint16_t indices[], int indexCount,
802 const SkPaint& paint);
803
reed@android.comcb608442009-12-04 21:32:27 +0000804 /** Send a blob of data to the canvas.
805 For canvases that draw, this call is effectively a no-op, as the data
806 is not parsed, but just ignored. However, this call exists for
807 subclasses like SkPicture's recording canvas, that can store the data
808 and then play it back later (via another call to drawData).
809 */
810 virtual void drawData(const void* data, size_t length);
811
reed@android.com8a1c16f2008-12-17 15:59:43 +0000812 //////////////////////////////////////////////////////////////////////////
reed@google.com4b226022011-01-11 18:32:13 +0000813
reed@android.com8a1c16f2008-12-17 15:59:43 +0000814 /** Get the current bounder object.
815 The bounder's reference count is unchaged.
816 @return the canva's bounder (or NULL).
817 */
818 SkBounder* getBounder() const { return fBounder; }
819
820 /** Set a new bounder (or NULL).
821 Pass NULL to clear any previous bounder.
822 As a convenience, the parameter passed is also returned.
823 If a previous bounder exists, its reference count is decremented.
824 If bounder is not NULL, its reference count is incremented.
825 @param bounder the new bounder (or NULL) to be installed in the canvas
826 @return the set bounder object
827 */
828 virtual SkBounder* setBounder(SkBounder* bounder);
reed@google.com4b226022011-01-11 18:32:13 +0000829
reed@android.com8a1c16f2008-12-17 15:59:43 +0000830 /** Get the current filter object. The filter's reference count is not
reed@android.comdc3381f2010-02-11 16:05:15 +0000831 affected. The filter is saved/restored, just like the matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000832 @return the canvas' filter (or NULL).
833 */
834 SkDrawFilter* getDrawFilter() const;
reed@google.com4b226022011-01-11 18:32:13 +0000835
reed@android.com8a1c16f2008-12-17 15:59:43 +0000836 /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
837 As a convenience, the parameter is returned. If an existing filter
838 exists, its refcnt is decrement. If the new filter is not null, its
reed@android.comdc3381f2010-02-11 16:05:15 +0000839 refcnt is incremented. The filter is saved/restored, just like the
840 matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000841 @param filter the new filter (or NULL)
842 @return the new filter
843 */
844 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
845
846 //////////////////////////////////////////////////////////////////////////
847
848 /** Return the current matrix on the canvas.
849 This does not account for the translate in any of the devices.
850 @return The current matrix on the canvas.
851 */
junov@chromium.orga907ac32012-02-24 21:54:07 +0000852 const SkMatrix& getTotalMatrix() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000853
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000854 enum ClipType {
855 kEmpty_ClipType = 0,
856 kRect_ClipType,
857 kComplex_ClipType
858 };
859
860 /** Returns a description of the total clip; may be cheaper than
861 getting the clip and querying it directly.
862 */
863 ClipType getClipType() const;
864
reed@android.com8a1c16f2008-12-17 15:59:43 +0000865 /** Return the current device clip (concatenation of all clip calls).
reed@google.coma707f602012-04-12 16:12:16 +0000866 * This does not account for the translate in any of the devices.
867 * @return the current device clip (concatenation of all clip calls).
reed@google.com5e2457e2011-10-10 21:24:37 +0000868 *
reed@google.coma707f602012-04-12 16:12:16 +0000869 * DEPRECATED -- call getClipDeviceBounds() instead.
reed@google.com5e2457e2011-10-10 21:24:37 +0000870 */
reed@google.coma707f602012-04-12 16:12:16 +0000871 const SkRegion& getTotalClip() const;
reed@google.com5e2457e2011-10-10 21:24:37 +0000872
robertphillips@google.com40a1ae42012-07-13 15:36:15 +0000873 /** Return the clip stack. The clip stack stores all the individual
874 * clips organized by the save/restore frame in which they were
875 * added.
876 * @return the current clip stack ("list" of individual clip elements)
877 */
878 const SkClipStack* getClipStack() const {
879 return &fClipStack;
880 }
881
reed@android.comf2b98d62010-12-20 18:26:13 +0000882 void setExternalMatrix(const SkMatrix* = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000883
reed@google.com90c07ea2012-04-13 13:50:27 +0000884 class ClipVisitor {
885 public:
justinlin@google.com20a550c2012-07-27 17:37:12 +0000886 virtual ~ClipVisitor();
reed@google.com90c07ea2012-04-13 13:50:27 +0000887 virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
888 virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
889 };
890
891 /**
892 * Replays the clip operations, back to front, that have been applied to
893 * the canvas, calling the appropriate method on the visitor for each
894 * clip. All clips have already been transformed into device space.
895 */
896 void replayClips(ClipVisitor*) const;
897
reed@android.com8a1c16f2008-12-17 15:59:43 +0000898 ///////////////////////////////////////////////////////////////////////////
899
900 /** After calling saveLayer(), there can be any number of devices that make
901 up the top-most drawing area. LayerIter can be used to iterate through
902 those devices. Note that the iterator is only valid until the next API
903 call made on the canvas. Ownership of all pointers in the iterator stays
904 with the canvas, so none of them should be modified or deleted.
905 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +0000906 class SK_API LayerIter /*: SkNoncopyable*/ {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000907 public:
908 /** Initialize iterator with canvas, and set values for 1st device */
909 LayerIter(SkCanvas*, bool skipEmptyClips);
910 ~LayerIter();
reed@google.com4b226022011-01-11 18:32:13 +0000911
reed@android.com8a1c16f2008-12-17 15:59:43 +0000912 /** Return true if the iterator is done */
913 bool done() const { return fDone; }
914 /** Cycle to the next device */
915 void next();
reed@google.com4b226022011-01-11 18:32:13 +0000916
reed@android.com8a1c16f2008-12-17 15:59:43 +0000917 // These reflect the current device in the iterator
918
919 SkDevice* device() const;
920 const SkMatrix& matrix() const;
921 const SkRegion& clip() const;
922 const SkPaint& paint() const;
923 int x() const;
924 int y() const;
reed@google.com4b226022011-01-11 18:32:13 +0000925
reed@android.com8a1c16f2008-12-17 15:59:43 +0000926 private:
927 // used to embed the SkDrawIter object directly in our instance, w/o
928 // having to expose that class def to the public. There is an assert
929 // in our constructor to ensure that fStorage is large enough
930 // (though needs to be a compile-time-assert!). We use intptr_t to work
931 // safely with 32 and 64 bit machines (to ensure the storage is enough)
reed@android.comf2b98d62010-12-20 18:26:13 +0000932 intptr_t fStorage[32];
reed@android.com8a1c16f2008-12-17 15:59:43 +0000933 class SkDrawIter* fImpl; // this points at fStorage
934 SkPaint fDefaultPaint;
935 bool fDone;
936 };
937
938protected:
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000939 // Returns the canvas to be used by DrawIter. Default implementation
junov@google.com4370aed2012-01-18 16:21:08 +0000940 // returns this. Subclasses that encapsulate an indirect canvas may
941 // need to overload this method. The impl must keep track of this, as it
942 // is not released or deleted by the caller.
943 virtual SkCanvas* canvasForDrawIter();
944
reed@android.com8a1c16f2008-12-17 15:59:43 +0000945 // all of the drawBitmap variants call this guy
reed@google.com49794c02012-03-15 12:10:47 +0000946 void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&,
947 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000948
junov@chromium.orga907ac32012-02-24 21:54:07 +0000949 // Clip rectangle bounds. Called internally by saveLayer.
950 // returns false if the entire rectangle is entirely clipped out
951 bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
reed@google.com49794c02012-03-15 12:10:47 +0000952 SkIRect* intersection);
junov@chromium.orga907ac32012-02-24 21:54:07 +0000953
reed@google.com97af1a62012-08-28 12:19:02 +0000954 // notify our surface (if we have one) that we are about to draw, so it
955 // can perform copy-on-write or invalidate any cached images
956 void predrawNotify();
957
reed@android.com8a1c16f2008-12-17 15:59:43 +0000958private:
959 class MCRec;
960
reed@google.com5c3d1472011-02-22 19:12:23 +0000961 SkClipStack fClipStack;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000962 SkDeque fMCStack;
963 // points to top of stack
964 MCRec* fMCRec;
965 // the first N recs that can fit here mean we won't call malloc
966 uint32_t fMCRecStorage[32];
967
968 SkBounder* fBounder;
reed@android.com199f1082009-06-10 02:12:47 +0000969 SkDevice* fLastDeviceToGainFocus;
junov@chromium.orgb0a7ace2012-04-05 18:33:23 +0000970 int fSaveLayerCount; // number of successful saveLayer calls
reed@android.com8a1c16f2008-12-17 15:59:43 +0000971
reed@google.com97af1a62012-08-28 12:19:02 +0000972 SkSurface_Base* fSurfaceBase;
973 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
974 void setSurfaceBase(SkSurface_Base* sb) {
975 fSurfaceBase = sb;
976 }
977 friend class SkSurface_Base;
978
robertphillips@google.com40a1ae42012-07-13 15:36:15 +0000979 void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&);
reed@google.com4b226022011-01-11 18:32:13 +0000980
reed@android.com8a1c16f2008-12-17 15:59:43 +0000981 bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
982 void updateDeviceCMCache();
983
984 friend class SkDrawIter; // needs setupDrawForLayerDevice()
reed@google.com8926b162012-03-23 15:36:36 +0000985 friend class AutoDrawLooper;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000986
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000987 SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
bsalomon@google.come97f0852011-06-17 13:10:25 +0000988 bool isOpaque);
989
reed@android.com8a1c16f2008-12-17 15:59:43 +0000990 SkDevice* init(SkDevice*);
reed@google.comf0b5e112011-09-07 11:57:34 +0000991
992 // internal methods are not virtual, so they can safely be called by other
993 // canvas apis, without confusing subclasses (like SkPictureRecording)
reed@android.comf2b98d62010-12-20 18:26:13 +0000994 void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000995 const SkPaint* paint);
reed@google.comf0b5e112011-09-07 11:57:34 +0000996 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
997 const SkRect& dst, const SkPaint* paint);
998 void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
999 const SkRect& dst, const SkPaint* paint);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00001000 void internalDrawPaint(const SkPaint& paint);
reed@google.com8926b162012-03-23 15:36:36 +00001001 int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
1002 SaveFlags, bool justForImageFilter);
1003 void internalDrawDevice(SkDevice*, int x, int y, const SkPaint*);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00001004
reed@android.com8a1c16f2008-12-17 15:59:43 +00001005 // shared by save() and saveLayer()
1006 int internalSave(SaveFlags flags);
1007 void internalRestore();
bungeman@google.com52c748b2011-08-22 21:30:43 +00001008 static void DrawRect(const SkDraw& draw, const SkPaint& paint,
1009 const SkRect& r, SkScalar textSize);
1010 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
1011 const char text[], size_t byteLength,
1012 SkScalar x, SkScalar y);
reed@google.com4b226022011-01-11 18:32:13 +00001013
reed@android.com8a1c16f2008-12-17 15:59:43 +00001014 /* These maintain a cache of the clip bounds in local coordinates,
1015 (converted to 2s-compliment if floats are slow).
1016 */
1017 mutable SkRectCompareType fLocalBoundsCompareType;
1018 mutable bool fLocalBoundsCompareTypeDirty;
1019
1020 const SkRectCompareType& getLocalClipBoundsCompareType() const {
reed@google.com3b3e8952012-08-16 20:53:31 +00001021 if (fLocalBoundsCompareTypeDirty) {
1022 this->computeLocalClipBoundsCompareType();
1023 fLocalBoundsCompareTypeDirty = false;
reed@android.comba09de42010-02-05 20:46:05 +00001024 }
reed@google.com3b3e8952012-08-16 20:53:31 +00001025 return fLocalBoundsCompareType;
reed@android.comba09de42010-02-05 20:46:05 +00001026 }
reed@google.com3b3e8952012-08-16 20:53:31 +00001027 void computeLocalClipBoundsCompareType() const;
reed@android.comf2b98d62010-12-20 18:26:13 +00001028
1029 SkMatrix fExternalMatrix, fExternalInverse;
1030 bool fUseExternalMatrix;
reed@google.com5c3d1472011-02-22 19:12:23 +00001031
1032 class AutoValidateClip : ::SkNoncopyable {
1033 public:
1034 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1035 fCanvas->validateClip();
1036 }
1037 ~AutoValidateClip() { fCanvas->validateClip(); }
1038
1039 private:
1040 const SkCanvas* fCanvas;
1041 };
1042
1043#ifdef SK_DEBUG
1044 void validateClip() const;
1045#else
1046 void validateClip() const {}
1047#endif
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +00001048
1049 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001050};
1051
1052/** Stack helper class to automatically call restoreToCount() on the canvas
1053 when this object goes out of scope. Use this to guarantee that the canvas
1054 is restored to a known state.
1055*/
1056class SkAutoCanvasRestore : SkNoncopyable {
1057public:
1058 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
1059 SkASSERT(canvas);
1060 fSaveCount = canvas->getSaveCount();
1061 if (doSave) {
1062 canvas->save();
1063 }
1064 }
1065 ~SkAutoCanvasRestore() {
1066 fCanvas->restoreToCount(fSaveCount);
1067 }
1068
1069private:
1070 SkCanvas* fCanvas;
1071 int fSaveCount;
1072};
1073
1074#endif