blob: bc39ec2850bf345e06f8626954bc075b0c1cdf95 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
8#ifndef SkCanvas_DEFINED
9#define SkCanvas_DEFINED
10
11#include "SkTypes.h"
12#include "SkBitmap.h"
13#include "SkDeque.h"
14#include "SkPaint.h"
15#include "SkRefCnt.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000016#include "SkRegion.h"
reed4a8126e2014-09-22 07:29:03 -070017#include "SkSurfaceProps.h"
reed@android.com845fdac2009-06-23 03:01:32 +000018#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000019
bungeman7403d872015-08-04 14:56:53 -070020class GrContext;
21class GrRenderTarget;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000022class SkBaseDevice;
reed6a070dc2014-11-11 19:36:09 -080023class SkCanvasClipVisitor;
bungeman7403d872015-08-04 14:56:53 -070024class SkClipStack;
reed@android.com8a1c16f2008-12-17 15:59:43 +000025class SkDraw;
reed3cb38402015-02-06 08:36:15 -080026class SkDrawable;
reed@android.com8a1c16f2008-12-17 15:59:43 +000027class SkDrawFilter;
piotaixrb5fae932014-09-24 13:03:30 -070028class SkImage;
bungeman7403d872015-08-04 14:56:53 -070029class SkImageFilter;
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +000030class SkMetaData;
bungeman7403d872015-08-04 14:56:53 -070031class SkPath;
reed@android.com8a1c16f2008-12-17 15:59:43 +000032class SkPicture;
bungeman7403d872015-08-04 14:56:53 -070033class SkPixmap;
reed@google.com4ed0fb72012-12-12 20:48:18 +000034class SkRRect;
reed71c3c762015-06-24 10:29:17 -070035struct SkRSXform;
reed@google.com76f10a32014-02-05 15:32:21 +000036class SkSurface;
reed@google.com97af1a62012-08-28 12:19:02 +000037class SkSurface_Base;
fmalita00d5c2c2014-08-21 08:53:26 -070038class SkTextBlob;
reedfa35f8e2014-09-04 12:14:36 -070039
reed@android.com8a1c16f2008-12-17 15:59:43 +000040/** \class SkCanvas
41
42 A Canvas encapsulates all of the state about drawing into a device (bitmap).
43 This includes a reference to the device itself, and a stack of matrix/clip
44 values. For any given draw call (e.g. drawRect), the geometry of the object
45 being drawn is transformed by the concatenation of all the matrices in the
46 stack. The transformed geometry is clipped by the intersection of all of
47 the clips in the stack.
48
49 While the Canvas holds the state of the drawing device, the state (style)
50 of the object being drawn is held by the Paint, which is provided as a
51 parameter to each of the draw() methods. The Paint holds attributes such as
52 color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
53 etc.
54*/
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +000055class SK_API SkCanvas : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000056public:
commit-bot@chromium.orge2543102014-01-31 19:42:58 +000057 /**
commit-bot@chromium.org42b08932014-03-17 02:13:07 +000058 * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
59 * specified pixels. To access the pixels after drawing to them, the caller should call
60 * flush() or call peekPixels(...).
61 *
62 * On failure, return NULL. This can fail for several reasons:
63 * 1. invalid ImageInfo (e.g. negative dimensions)
64 * 2. unsupported ImageInfo for a canvas
65 * - kUnknown_SkColorType, kIndex_8_SkColorType
reed44977482015-02-27 10:23:00 -080066 * - kUnknown_SkAlphaType
commit-bot@chromium.org42b08932014-03-17 02:13:07 +000067 * - this list is not complete, so others may also be unsupported
68 *
69 * Note: it is valid to request a supported ImageInfo, but with zero
70 * dimensions.
71 */
72 static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
73
74 static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
75 return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
76 }
77
78 /**
commit-bot@chromium.orge2543102014-01-31 19:42:58 +000079 * Creates an empty canvas with no backing device/pixels, and zero
80 * dimensions.
81 */
reed@google.comcde92112011-07-06 20:00:52 +000082 SkCanvas();
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000083
commit-bot@chromium.orge2543102014-01-31 19:42:58 +000084 /**
85 * Creates a canvas of the specified dimensions, but explicitly not backed
86 * by any device/pixels. Typically this use used by subclasses who handle
87 * the draw calls in some other way.
88 */
reed96a857e2015-01-25 10:33:58 -080089 SkCanvas(int width, int height, const SkSurfaceProps* = NULL);
commit-bot@chromium.orge2543102014-01-31 19:42:58 +000090
reed@google.com6dc74552011-07-21 18:00:46 +000091 /** Construct a canvas with the specified device to draw into.
bsalomon@google.come97f0852011-06-17 13:10:25 +000092
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000093 @param device Specifies a device for the canvas to draw into.
94 */
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000095 explicit SkCanvas(SkBaseDevice* device);
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +000096
reed@google.com44699382013-10-31 17:28:30 +000097 /** Construct a canvas with the specified bitmap to draw into.
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 @param bitmap Specifies a bitmap for the canvas to draw into. Its
99 structure are copied to the canvas.
100 */
101 explicit SkCanvas(const SkBitmap& bitmap);
fmalita3d91aad2015-02-02 05:25:04 -0800102
103 /** Construct a canvas with the specified bitmap to draw into.
104 @param bitmap Specifies a bitmap for the canvas to draw into. Its
105 structure are copied to the canvas.
106 @param props New canvas surface properties.
107 */
108 SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
109
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110 virtual ~SkCanvas();
111
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +0000112 SkMetaData& getMetaData();
113
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000114 /**
115 * Return ImageInfo for this canvas. If the canvas is not backed by pixels
116 * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
117 */
118 SkImageInfo imageInfo() const;
119
reed@android.com8a1c16f2008-12-17 15:59:43 +0000120 ///////////////////////////////////////////////////////////////////////////
121
reed@google.com210ce002011-11-01 14:24:23 +0000122 /**
junov@chromium.orgbf6c1e42012-01-30 14:53:22 +0000123 * Trigger the immediate execution of all pending draw operations.
124 */
125 void flush();
126
127 /**
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000128 * Gets the size of the base or root layer in global canvas coordinates. The
129 * origin of the base layer is always (0,0). The current drawable area may be
130 * smaller (due to clipping or saveLayer).
reed@google.com210ce002011-11-01 14:24:23 +0000131 */
tomhudson68260fa2015-03-23 07:22:40 -0700132 virtual SkISize getBaseLayerSize() const;
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000133
134 /**
135 * DEPRECATED: call getBaseLayerSize
136 */
137 SkISize getDeviceSize() const { return this->getBaseLayerSize(); }
reed@google.com210ce002011-11-01 14:24:23 +0000138
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000139 /**
140 * DEPRECATED.
141 * Return the canvas' device object, which may be null. The device holds
142 * the bitmap of the pixels that the canvas draws into. The reference count
143 * of the returned device is not changed by this call.
144 */
reed52d9ac62014-06-30 09:05:34 -0700145#ifndef SK_SUPPORT_LEGACY_GETDEVICE
146protected: // Can we make this private?
147#endif
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000148 SkBaseDevice* getDevice() const;
reed52d9ac62014-06-30 09:05:34 -0700149public:
reed41e010c2015-06-09 12:16:53 -0700150 SkBaseDevice* getDevice_just_for_deprecated_compatibility_testing() const {
151 return this->getDevice();
152 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000153
reed@google.com9266fed2011-03-30 00:18:03 +0000154 /**
155 * saveLayer() can create another device (which is later drawn onto
156 * the previous device). getTopDevice() returns the top-most device current
157 * installed. Note that this can change on other calls like save/restore,
158 * so do not access this device after subsequent canvas calls.
159 * The reference count of the device is not changed.
reed@google.com0b53d592012-03-19 18:26:34 +0000160 *
161 * @param updateMatrixClip If this is true, then before the device is
162 * returned, we ensure that its has been notified about the current
163 * matrix and clip. Note: this happens automatically when the device
164 * is drawn to, but is optional here, as there is a small perf hit
165 * sometimes.
reed@google.com9266fed2011-03-30 00:18:03 +0000166 */
reed@google.com9c135db2014-03-12 18:28:35 +0000167#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE
168private:
169#endif
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000170 SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
reed@google.com9c135db2014-03-12 18:28:35 +0000171public:
reed@google.com9266fed2011-03-30 00:18:03 +0000172
reed@google.com76f10a32014-02-05 15:32:21 +0000173 /**
174 * Create a new surface matching the specified info, one that attempts to
commit-bot@chromium.orgcae54f12014-04-11 18:34:35 +0000175 * be maximally compatible when used with this canvas. If there is no matching Surface type,
176 * NULL is returned.
reed4a8126e2014-09-22 07:29:03 -0700177 *
178 * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
179 * inherits the properties of the surface that owns this canvas. If this canvas has no parent
180 * surface, then the new surface is created with default properties.
reed@google.com76f10a32014-02-05 15:32:21 +0000181 */
reed4a8126e2014-09-22 07:29:03 -0700182 SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL);
bsalomon@google.come97f0852011-06-17 13:10:25 +0000183
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000184 /**
185 * Return the GPU context of the device that is associated with the canvas.
186 * For a canvas with non-GPU device, NULL is returned.
187 */
188 GrContext* getGrContext();
189
reed@google.com4b226022011-01-11 18:32:13 +0000190 ///////////////////////////////////////////////////////////////////////////
191
bsalomon@google.comdaba14b2011-11-02 20:10:48 +0000192 /**
reed@google.com9c135db2014-03-12 18:28:35 +0000193 * If the canvas has writable pixels in its top layer (and is not recording to a picture
194 * or other non-raster target) and has direct access to its pixels (i.e. they are in
195 * local RAM) return the address of those pixels, and if not null,
commit-bot@chromium.org6b4aaa72014-04-21 21:09:38 +0000196 * return the ImageInfo, rowBytes and origin. The returned address is only valid
reed@google.com9c135db2014-03-12 18:28:35 +0000197 * while the canvas object is in scope and unchanged. Any API calls made on
198 * canvas (or its parent surface if any) will invalidate the
199 * returned address (and associated information).
200 *
commit-bot@chromium.org6b4aaa72014-04-21 21:09:38 +0000201 * On failure, returns NULL and the info, rowBytes, and origin parameters are ignored.
reed@google.com9c135db2014-03-12 18:28:35 +0000202 */
commit-bot@chromium.org6b4aaa72014-04-21 21:09:38 +0000203 void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
reed@google.com9c135db2014-03-12 18:28:35 +0000204
205 /**
206 * If the canvas has readable pixels in its base layer (and is not recording to a picture
207 * or other non-raster target) and has direct access to its pixels (i.e. they are in
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000208 * local RAM) return the const-address of those pixels, and if not null,
209 * return the ImageInfo and rowBytes. The returned address is only valid
210 * while the canvas object is in scope and unchanged. Any API calls made on
211 * canvas (or its parent surface if any) will invalidate the
212 * returned address (and associated information).
213 *
214 * On failure, returns NULL and the info and rowBytes parameters are
215 * ignored.
216 */
217 const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
218
reed@google.com4b226022011-01-11 18:32:13 +0000219 /**
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000220 * Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
221 * converting them into the requested format (SkImageInfo). The base-layer pixels are read
reedb184f7f2014-07-13 04:32:32 -0700222 * starting at the specified (srcX,srcY) location in the coordinate system of the base-layer.
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000223 *
reedb184f7f2014-07-13 04:32:32 -0700224 * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000225 *
reedb184f7f2014-07-13 04:32:32 -0700226 * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000227 *
reedb184f7f2014-07-13 04:32:32 -0700228 * srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
229 * then we have two sets of pixels (of equal size). Replace the dst pixels with the
230 * corresponding src pixels, performing any colortype/alphatype transformations needed
231 * (in the case where the src and dst have different colortypes or alphatypes).
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000232 *
233 * This call can fail, returning false, for several reasons:
reedb184f7f2014-07-13 04:32:32 -0700234 * - If srcR does not intersect the base-layer bounds.
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000235 * - If the requested colortype/alphatype cannot be converted from the base-layer's types.
236 * - If this canvas is not backed by pixels (e.g. picture or PDF)
237 */
reedb184f7f2014-07-13 04:32:32 -0700238 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
239 int srcX, int srcY);
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000240
241 /**
242 * Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated.
243 * If not, it will attempt to call allocPixels(). If this fails, it will return false. If not,
244 * it calls through to readPixels(info, ...) and returns its result.
245 */
reedb184f7f2014-07-13 04:32:32 -0700246 bool readPixels(SkBitmap* bitmap, int srcX, int srcY);
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000247
248 /**
249 * Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized
250 * to the intersection of srcRect and the base-layer bounds. On success, pixels will be
251 * allocated in bitmap and true returned. On failure, false is returned and bitmap will be
252 * set to empty.
reed@google.com51df9e32010-12-23 19:29:18 +0000253 */
254 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
reed@google.com51df9e32010-12-23 19:29:18 +0000255
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000256 /**
257 * This method affects the pixels in the base-layer, and operates in pixel coordinates,
258 * ignoring the matrix and clip.
259 *
260 * The specified ImageInfo and (x,y) offset specifies a rectangle: target.
261 *
262 * target.setXYWH(x, y, info.width(), info.height());
263 *
264 * Target is intersected with the bounds of the base-layer. If this intersection is not empty,
265 * then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
266 * and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
267 * pixels, performing any colortype/alphatype transformations needed (in the case where the
268 * src and dst have different colortypes or alphatypes).
269 *
270 * This call can fail, returning false, for several reasons:
271 * - If the src colortype/alphatype cannot be converted to the canvas' types
272 * - If this canvas is not backed by pixels (e.g. picture or PDF)
273 */
274 bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
275
276 /**
277 * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
278 * is just wrapping a texture, returns false and does nothing.
279 */
280 bool writePixels(const SkBitmap& bitmap, int x, int y);
reed@google.com4b226022011-01-11 18:32:13 +0000281
reed@android.com8a1c16f2008-12-17 15:59:43 +0000282 ///////////////////////////////////////////////////////////////////////////
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000283
reed@android.com8a1c16f2008-12-17 15:59:43 +0000284 enum SaveFlags {
285 /** save the matrix state, restoring it on restore() */
Florin Malita5f6102d2014-06-30 10:13:28 -0400286 // [deprecated] kMatrix_SaveFlag = 0x01,
fmalita696d3612014-07-01 11:55:41 -0700287 kMatrix_SaveFlag = 0x01,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000288 /** save the clip state, restoring it on restore() */
Florin Malita5f6102d2014-06-30 10:13:28 -0400289 // [deprecated] kClip_SaveFlag = 0x02,
fmalita696d3612014-07-01 11:55:41 -0700290 kClip_SaveFlag = 0x02,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000291 /** the layer needs to support per-pixel alpha */
292 kHasAlphaLayer_SaveFlag = 0x04,
293 /** the layer needs to support 8-bits per color component */
294 kFullColorLayer_SaveFlag = 0x08,
reed@google.comb93ba452014-03-10 19:47:58 +0000295 /**
296 * the layer should clip against the bounds argument
297 *
298 * if SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG is undefined, this is treated as always on.
299 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000300 kClipToLayer_SaveFlag = 0x10,
301
302 // helper masks for common choices
Florin Malita5f6102d2014-06-30 10:13:28 -0400303 // [deprecated] kMatrixClip_SaveFlag = 0x03,
fmalita696d3612014-07-01 11:55:41 -0700304 kMatrixClip_SaveFlag = 0x03,
reed@google.comb93ba452014-03-10 19:47:58 +0000305#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
reed@android.com8a1c16f2008-12-17 15:59:43 +0000306 kARGB_NoClipLayer_SaveFlag = 0x0F,
reed@google.comb93ba452014-03-10 19:47:58 +0000307#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000308 kARGB_ClipLayer_SaveFlag = 0x1F
309 };
310
reed@android.comdc3381f2010-02-11 16:05:15 +0000311 /** This call saves the current matrix, clip, and drawFilter, and pushes a
reed@android.com8a1c16f2008-12-17 15:59:43 +0000312 copy onto a private stack. Subsequent calls to translate, scale,
reed@android.comdc3381f2010-02-11 16:05:15 +0000313 rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
314 operate on this copy.
315 When the balancing call to restore() is made, the previous matrix, clip,
316 and drawFilter are restored.
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000317
318 @return The value to pass to restoreToCount() to balance this save()
319 */
320 int save();
321
reed@android.com8a1c16f2008-12-17 15:59:43 +0000322 /** This behaves the same as save(), but in addition it allocates an
323 offscreen bitmap. All drawing calls are directed there, and only when
324 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000325 the canvas (or the previous layer).
reed@android.comad164b22010-07-02 17:20:51 +0000326 @param bounds (may be null) This rect, if non-null, is used as a hint to
327 limit the size of the offscreen, and thus drawing may be
328 clipped to it, though that clipping is not guaranteed to
329 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000330 @param paint (may be null) This is copied, and is applied to the
331 offscreen when restore() is called
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000332 @return The value to pass to restoreToCount() to balance this save()
333 */
334 int saveLayer(const SkRect* bounds, const SkPaint* paint);
335
336 /** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead.
337
338 This behaves the same as saveLayer(const SkRect*, const SkPaint*),
339 but it allows fine-grained control of which state bits to be saved
340 (and subsequently restored).
341
342 @param bounds (may be null) This rect, if non-null, is used as a hint to
343 limit the size of the offscreen, and thus drawing may be
344 clipped to it, though that clipping is not guaranteed to
345 happen. If exact clipping is desired, use clipRect().
346 @param paint (may be null) This is copied, and is applied to the
347 offscreen when restore() is called
reed@android.com8a1c16f2008-12-17 15:59:43 +0000348 @param flags LayerFlags
349 @return The value to pass to restoreToCount() to balance this save()
350 */
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000351 SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
352 int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000353
354 /** This behaves the same as save(), but in addition it allocates an
355 offscreen bitmap. All drawing calls are directed there, and only when
356 the balancing call to restore() is made is that offscreen transfered to
reed@android.comdc3381f2010-02-11 16:05:15 +0000357 the canvas (or the previous layer).
reed@android.com40408612010-07-02 17:24:23 +0000358 @param bounds (may be null) This rect, if non-null, is used as a hint to
359 limit the size of the offscreen, and thus drawing may be
360 clipped to it, though that clipping is not guaranteed to
361 happen. If exact clipping is desired, use clipRect().
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362 @param alpha This is applied to the offscreen when restore() is called.
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000363 @return The value to pass to restoreToCount() to balance this save()
364 */
365 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
366
367 /** DEPRECATED - use saveLayerAlpha(const SkRect*, U8CPU) instead.
368
369 This behaves the same as saveLayerAlpha(const SkRect*, U8CPU),
370 but it allows fine-grained control of which state bits to be saved
371 (and subsequently restored).
372
373 @param bounds (may be null) This rect, if non-null, is used as a hint to
374 limit the size of the offscreen, and thus drawing may be
375 clipped to it, though that clipping is not guaranteed to
376 happen. If exact clipping is desired, use clipRect().
377 @param alpha This is applied to the offscreen when restore() is called.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000378 @param flags LayerFlags
379 @return The value to pass to restoreToCount() to balance this save()
380 */
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000381 SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
382 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, SaveFlags flags);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000383
384 /** This call balances a previous call to save(), and is used to remove all
reed@android.comdc3381f2010-02-11 16:05:15 +0000385 modifications to the matrix/clip/drawFilter state since the last save
386 call.
387 It is an error to call restore() more times than save() was called.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000388 */
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +0000389 void restore();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000390
391 /** Returns the number of matrix/clip states on the SkCanvas' private stack.
commit-bot@chromium.orgea7d08e2014-02-13 16:00:51 +0000392 This will equal # save() calls - # restore() calls + 1. The save count on
393 a new canvas is 1.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000394 */
junov@chromium.orga907ac32012-02-24 21:54:07 +0000395 int getSaveCount() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000396
397 /** Efficient way to pop any calls to save() that happened after the save
commit-bot@chromium.orgea7d08e2014-02-13 16:00:51 +0000398 count reached saveCount. It is an error for saveCount to be greater than
399 getSaveCount(). To pop all the way back to the initial matrix/clip context
400 pass saveCount == 1.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000401 @param saveCount The number of save() levels to restore from
402 */
403 void restoreToCount(int saveCount);
404
405 /** Preconcat the current matrix with the specified translation
406 @param dx The distance to translate in X
407 @param dy The distance to translate in Y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000408 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000409 void translate(SkScalar dx, SkScalar dy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000410
411 /** Preconcat the current matrix with the specified scale.
412 @param sx The amount to scale in X
413 @param sy The amount to scale in Y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000414 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000415 void scale(SkScalar sx, SkScalar sy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000416
417 /** Preconcat the current matrix with the specified rotation.
418 @param degrees The amount to rotate, in degrees
reed@android.com8a1c16f2008-12-17 15:59:43 +0000419 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000420 void rotate(SkScalar degrees);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000421
422 /** Preconcat the current matrix with the specified skew.
423 @param sx The amount to skew in X
424 @param sy The amount to skew in Y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000425 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000426 void skew(SkScalar sx, SkScalar sy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000427
428 /** Preconcat the current matrix with the specified matrix.
429 @param matrix The matrix to preconcatenate with the current matrix
reed@android.com8a1c16f2008-12-17 15:59:43 +0000430 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000431 void concat(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000432
reed@android.com8a1c16f2008-12-17 15:59:43 +0000433 /** Replace the current matrix with a copy of the specified matrix.
434 @param matrix The matrix that will be copied into the current matrix.
435 */
commit-bot@chromium.org44c48d02014-03-13 20:03:58 +0000436 void setMatrix(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000437
reed@android.com8a1c16f2008-12-17 15:59:43 +0000438 /** Helper for setMatrix(identity). Sets the current matrix to identity.
439 */
440 void resetMatrix();
441
reed@google.com4ed0fb72012-12-12 20:48:18 +0000442 /**
443 * Modify the current clip with the specified rectangle.
444 * @param rect The rect to combine with the current clip
445 * @param op The region op to apply to the current clip
446 * @param doAntiAlias true if the clip should be antialiased
reed@google.com4ed0fb72012-12-12 20:48:18 +0000447 */
commit-bot@chromium.org759cf482014-03-06 13:18:07 +0000448 void clipRect(const SkRect& rect,
449 SkRegion::Op op = SkRegion::kIntersect_Op,
450 bool doAntiAlias = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000451
reed@google.com4ed0fb72012-12-12 20:48:18 +0000452 /**
453 * Modify the current clip with the specified SkRRect.
454 * @param rrect The rrect to combine with the current clip
455 * @param op The region op to apply to the current clip
456 * @param doAntiAlias true if the clip should be antialiased
reed@google.com4ed0fb72012-12-12 20:48:18 +0000457 */
commit-bot@chromium.org759cf482014-03-06 13:18:07 +0000458 void clipRRect(const SkRRect& rrect,
459 SkRegion::Op op = SkRegion::kIntersect_Op,
460 bool doAntiAlias = false);
reed@google.com4ed0fb72012-12-12 20:48:18 +0000461
462 /**
463 * Modify the current clip with the specified path.
464 * @param path The path to combine with the current clip
465 * @param op The region op to apply to the current clip
466 * @param doAntiAlias true if the clip should be antialiased
reed@google.com4ed0fb72012-12-12 20:48:18 +0000467 */
commit-bot@chromium.org759cf482014-03-06 13:18:07 +0000468 void clipPath(const SkPath& path,
469 SkRegion::Op op = SkRegion::kIntersect_Op,
470 bool doAntiAlias = false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000471
caryclark@google.com8f0a7b82012-11-07 14:54:49 +0000472 /** EXPERIMENTAL -- only used for testing
473 Set to false to force clips to be hard, even if doAntiAlias=true is
474 passed to clipRect or clipPath.
475 */
476 void setAllowSoftClip(bool allow) {
477 fAllowSoftClip = allow;
478 }
479
caryclark@google.com45a75fb2013-04-25 13:34:40 +0000480 /** EXPERIMENTAL -- only used for testing
481 Set to simplify clip stack using path ops.
482 */
483 void setAllowSimplifyClip(bool allow) {
484 fAllowSimplifyClip = allow;
485 }
486
reed@android.com8a1c16f2008-12-17 15:59:43 +0000487 /** Modify the current clip with the specified region. Note that unlike
488 clipRect() and clipPath() which transform their arguments by the current
489 matrix, clipRegion() assumes its argument is already in device
490 coordinates, and so no transformation is performed.
491 @param deviceRgn The region to apply to the current clip
492 @param op The region op to apply to the current clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000493 */
commit-bot@chromium.org759cf482014-03-06 13:18:07 +0000494 void clipRegion(const SkRegion& deviceRgn,
495 SkRegion::Op op = SkRegion::kIntersect_Op);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000496
497 /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
498 specified region. This does not intersect or in any other way account
499 for the existing clip region.
500 @param deviceRgn The region to copy into the current clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000501 */
robertphillips@google.com8f90a892014-02-28 18:19:39 +0000502 void setClipRegion(const SkRegion& deviceRgn) {
503 this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000504 }
505
reed@android.com8a1c16f2008-12-17 15:59:43 +0000506 /** Return true if the specified rectangle, after being transformed by the
507 current matrix, would lie completely outside of the current clip. Call
508 this to check if an area you intend to draw into is clipped out (and
509 therefore you can skip making the draw calls).
510 @param rect the rect to compare with the current clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000511 @return true if the rect (transformed by the canvas' matrix) does not
512 intersect with the canvas' clip
513 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000514 bool quickReject(const SkRect& rect) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000515
516 /** Return true if the specified path, after being transformed by the
517 current matrix, would lie completely outside of the current clip. Call
518 this to check if an area you intend to draw into is clipped out (and
519 therefore you can skip making the draw calls). Note, for speed it may
520 return false even if the path itself might not intersect the clip
521 (i.e. the bounds of the path intersects, but the path does not).
522 @param path The path to compare with the current clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000523 @return true if the path (transformed by the canvas' matrix) does not
524 intersect with the canvas' clip
525 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000526 bool quickReject(const SkPath& path) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000527
528 /** Return true if the horizontal band specified by top and bottom is
529 completely clipped out. This is a conservative calculation, meaning
530 that it is possible that if the method returns false, the band may still
531 in fact be clipped out, but the converse is not true. If this method
532 returns true, then the band is guaranteed to be clipped out.
533 @param top The top of the horizontal band to compare with the clip
534 @param bottom The bottom of the horizontal and to compare with the clip
535 @return true if the horizontal band is completely clipped out (i.e. does
536 not intersect the current clip)
537 */
reed@google.com3b3e8952012-08-16 20:53:31 +0000538 bool quickRejectY(SkScalar top, SkScalar bottom) const {
reed@google.comc0784db2013-12-13 21:16:12 +0000539 SkASSERT(top <= bottom);
commit-bot@chromium.org9836bc32014-02-14 19:52:18 +0000540
541#ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT
542 // TODO: add a hasPerspective method similar to getLocalClipBounds. This
543 // would cache the SkMatrix::hasPerspective result. Alternatively, have
544 // the MC stack just set a hasPerspective boolean as it is updated.
545 if (this->getTotalMatrix().hasPerspective()) {
skia.committer@gmail.coma3b53272014-02-15 03:02:15 +0000546 // TODO: consider implementing some half-plane test between the
commit-bot@chromium.org9836bc32014-02-14 19:52:18 +0000547 // two Y planes and the device-bounds (i.e., project the top and
548 // bottom Y planes and then determine if the clip bounds is completely
549 // outside either one).
550 return false;
551 }
552#endif
553
reed@google.comc0784db2013-12-13 21:16:12 +0000554 const SkRect& clipR = this->getLocalClipBounds();
djsollen@google.com92d2a292012-02-27 16:17:59 +0000555 // In the case where the clip is empty and we are provided with a
556 // negative top and positive bottom parameter then this test will return
557 // false even though it will be clipped. We have chosen to exclude that
558 // check as it is rare and would result double the comparisons.
reed@google.comc0784db2013-12-13 21:16:12 +0000559 return top >= clipR.fBottom || bottom <= clipR.fTop;
djsollen@google.com92d2a292012-02-27 16:17:59 +0000560 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000561
562 /** Return the bounds of the current clip (in local coordinates) in the
563 bounds parameter, and return true if it is non-empty. This can be useful
564 in a way similar to quickReject, in that it tells you that drawing
565 outside of these bounds will be clipped out.
566 */
robertphillips@google.com8f90a892014-02-28 18:19:39 +0000567 virtual bool getClipBounds(SkRect* bounds) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000568
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000569 /** Return the bounds of the current clip, in device coordinates; returns
570 true if non-empty. Maybe faster than getting the clip explicitly and
571 then taking its bounds.
572 */
robertphillips@google.com8f90a892014-02-28 18:19:39 +0000573 virtual bool getClipDeviceBounds(SkIRect* bounds) const;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000574
tomhudson@google.combcb671c2011-09-13 15:07:58 +0000575
reed@android.com8a1c16f2008-12-17 15:59:43 +0000576 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000577 specified ARGB color, using the specified mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000578 @param a the alpha component (0..255) of the color to fill the canvas
579 @param r the red component (0..255) of the color to fill the canvas
580 @param g the green component (0..255) of the color to fill the canvas
581 @param b the blue component (0..255) of the color to fill the canvas
582 @param mode the mode to apply the color in (defaults to SrcOver)
583 */
584 void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
reed@android.com845fdac2009-06-23 03:01:32 +0000585 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000586
587 /** Fill the entire canvas' bitmap (restricted to the current clip) with the
reed@android.com845fdac2009-06-23 03:01:32 +0000588 specified color and mode.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000589 @param color the color to draw with
590 @param mode the mode to apply the color in (defaults to SrcOver)
591 */
reed8eddfb52014-12-04 07:50:14 -0800592 void drawColor(SkColor color, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000593
reedf4e0d9e2014-12-05 20:49:03 -0800594 /**
595 * Helper method for drawing a color in SRC mode, completely replacing all the pixels
596 * in the current clip with this color.
597 */
598 void clear(SkColor color) {
reed8eddfb52014-12-04 07:50:14 -0800599 this->drawColor(color, SkXfermode::kSrc_Mode);
600 }
reed@google.com2a981812011-04-14 18:59:28 +0000601
602 /**
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000603 * This makes the contents of the canvas undefined. Subsequent calls that
604 * require reading the canvas contents will produce undefined results. Examples
605 * include blending and readPixels. The actual implementation is backend-
606 * dependent and one legal implementation is to do nothing. Like clear(), this
607 * ignores the clip.
608 *
609 * This function should only be called if the caller intends to subsequently
610 * draw to the canvas. The canvas may do real work at discard() time in order
611 * to optimize performance on subsequent draws. Thus, if you call this and then
612 * never draw to the canvas subsequently you may pay a perfomance penalty.
613 */
614 void discard() { this->onDiscard(); }
615
616 /**
reed@google.com2a981812011-04-14 18:59:28 +0000617 * Fill the entire canvas' bitmap (restricted to the current clip) with the
618 * specified paint.
619 * @param paint The paint used to fill the canvas
620 */
reed0846f1b2015-01-09 14:17:40 -0800621 void drawPaint(const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000622
623 enum PointMode {
624 /** drawPoints draws each point separately */
625 kPoints_PointMode,
626 /** drawPoints draws each pair of points as a line segment */
627 kLines_PointMode,
628 /** drawPoints draws the array of points as a polygon */
629 kPolygon_PointMode
630 };
631
632 /** Draw a series of points, interpreted based on the PointMode mode. For
633 all modes, the count parameter is interpreted as the total number of
634 points. For kLine mode, count/2 line segments are drawn.
635 For kPoint mode, each point is drawn centered at its coordinate, and its
636 size is specified by the paint's stroke-width. It draws as a square,
637 unless the paint's cap-type is round, in which the points are drawn as
638 circles.
639 For kLine mode, each pair of points is drawn as a line segment,
640 respecting the paint's settings for cap/join/width.
641 For kPolygon mode, the entire array is drawn as a series of connected
642 line segments.
643 Note that, while similar, kLine and kPolygon modes draw slightly
644 differently than the equivalent path built with a series of moveto,
645 lineto calls, in that the path will draw all of its contours at once,
646 with no interactions if contours intersect each other (think XOR
647 xfermode). drawPoints always draws each element one at a time.
648 @param mode PointMode specifying how to draw the array of points.
649 @param count The number of points in the array
650 @param pts Array of points to draw
651 @param paint The paint used to draw the points
652 */
reed0846f1b2015-01-09 14:17:40 -0800653 void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000654
655 /** Helper method for drawing a single point. See drawPoints() for a more
656 details.
657 */
658 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000659
reed@android.com8a1c16f2008-12-17 15:59:43 +0000660 /** Draws a single pixel in the specified color.
661 @param x The X coordinate of which pixel to draw
662 @param y The Y coordiante of which pixel to draw
663 @param color The color to draw
664 */
665 void drawPoint(SkScalar x, SkScalar y, SkColor color);
666
667 /** Draw a line segment with the specified start and stop x,y coordinates,
668 using the specified paint. NOTE: since a line is always "framed", the
669 paint's Style is ignored.
670 @param x0 The x-coordinate of the start point of the line
671 @param y0 The y-coordinate of the start point of the line
672 @param x1 The x-coordinate of the end point of the line
673 @param y1 The y-coordinate of the end point of the line
674 @param paint The paint used to draw the line
675 */
676 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
677 const SkPaint& paint);
678
679 /** Draw the specified rectangle using the specified paint. The rectangle
680 will be filled or stroked based on the Style in the paint.
681 @param rect The rect to be drawn
682 @param paint The paint used to draw the rect
683 */
reed0846f1b2015-01-09 14:17:40 -0800684 void drawRect(const SkRect& rect, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000685
686 /** Draw the specified rectangle using the specified paint. The rectangle
687 will be filled or framed based on the Style in the paint.
688 @param rect The rect to be drawn
689 @param paint The paint used to draw the rect
690 */
reed@google.com87001ed2014-02-17 16:28:05 +0000691 void drawIRect(const SkIRect& rect, const SkPaint& paint) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000692 SkRect r;
693 r.set(rect); // promotes the ints to scalars
694 this->drawRect(r, paint);
695 }
reed@google.com4b226022011-01-11 18:32:13 +0000696
reed@android.com8a1c16f2008-12-17 15:59:43 +0000697 /** Draw the specified rectangle using the specified paint. The rectangle
698 will be filled or framed based on the Style in the paint.
699 @param left The left side of the rectangle to be drawn
700 @param top The top side of the rectangle to be drawn
701 @param right The right side of the rectangle to be drawn
702 @param bottom The bottom side of the rectangle to be drawn
703 @param paint The paint used to draw the rect
704 */
705 void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
706 SkScalar bottom, const SkPaint& paint);
707
708 /** Draw the specified oval using the specified paint. The oval will be
709 filled or framed based on the Style in the paint.
710 @param oval The rectangle bounds of the oval to be drawn
711 @param paint The paint used to draw the oval
712 */
reed0846f1b2015-01-09 14:17:40 -0800713 void drawOval(const SkRect& oval, const SkPaint&);
reed@google.com4ed0fb72012-12-12 20:48:18 +0000714
715 /**
716 * Draw the specified RRect using the specified paint The rrect will be filled or stroked
717 * based on the Style in the paint.
718 *
719 * @param rrect The round-rect to draw
720 * @param paint The paint used to draw the round-rect
721 */
reed0846f1b2015-01-09 14:17:40 -0800722 void drawRRect(const SkRRect& rrect, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000723
commit-bot@chromium.orged9806f2014-02-21 02:32:36 +0000724 /**
725 * Draw the annulus formed by the outer and inner rrects. The results
726 * are undefined if the outer does not contain the inner.
727 */
728 void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&);
729
reed@android.com8a1c16f2008-12-17 15:59:43 +0000730 /** Draw the specified circle using the specified paint. If radius is <= 0,
731 then nothing will be drawn. The circle will be filled
732 or framed based on the Style in the paint.
733 @param cx The x-coordinate of the center of the cirle to be drawn
734 @param cy The y-coordinate of the center of the cirle to be drawn
735 @param radius The radius of the cirle to be drawn
736 @param paint The paint used to draw the circle
737 */
738 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
739 const SkPaint& paint);
740
741 /** Draw the specified arc, which will be scaled to fit inside the
742 specified oval. If the sweep angle is >= 360, then the oval is drawn
743 completely. Note that this differs slightly from SkPath::arcTo, which
744 treats the sweep angle mod 360.
745 @param oval The bounds of oval used to define the shape of the arc
746 @param startAngle Starting angle (in degrees) where the arc begins
747 @param sweepAngle Sweep angle (in degrees) measured clockwise
748 @param useCenter true means include the center of the oval. For filling
749 this will draw a wedge. False means just use the arc.
750 @param paint The paint used to draw the arc
751 */
752 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
753 bool useCenter, const SkPaint& paint);
754
755 /** Draw the specified round-rect using the specified paint. The round-rect
756 will be filled or framed based on the Style in the paint.
757 @param rect The rectangular bounds of the roundRect to be drawn
758 @param rx The x-radius of the oval used to round the corners
759 @param ry The y-radius of the oval used to round the corners
760 @param paint The paint used to draw the roundRect
761 */
762 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
763 const SkPaint& paint);
764
765 /** Draw the specified path using the specified paint. The path will be
766 filled or framed based on the Style in the paint.
767 @param path The path to be drawn
768 @param paint The paint used to draw the path
769 */
reed0846f1b2015-01-09 14:17:40 -0800770 void drawPath(const SkPath& path, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000771
piotaixrd52893c2014-09-25 14:39:40 -0700772 /** Draw the specified image, with its top/left corner at (x,y), using the
773 specified paint, transformed by the current matrix.
774
775 @param image The image to be drawn
776 @param left The position of the left side of the image being drawn
777 @param top The position of the top side of the image being drawn
778 @param paint The paint used to draw the image, or NULL
779 */
reed0846f1b2015-01-09 14:17:40 -0800780 void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL);
piotaixrb5fae932014-09-24 13:03:30 -0700781
reeda5517e22015-07-14 10:54:12 -0700782 /**
783 * Controls the behavior at the edge of the src-rect, when specified in drawImageRect,
784 * trading off speed for exactness.
785 *
786 * When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around
787 * the pixels in the image. If there is a src-rect specified, it is intended to restrict the
788 * pixels that will be read. However, for performance reasons, some implementations may slow
789 * down if they cannot read 1-pixel past the src-rect boundary at times.
790 *
791 * This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable.
792 * If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect
793 * must be strictly respected, the caller should pass kStrict.
794 */
795 enum SrcRectConstraint {
796 /**
797 * If kStrict is specified, the implementation must respect the src-rect
798 * (if specified) strictly, and will never sample outside of those bounds during sampling
799 * even when filtering. This may be slower than kFast.
800 */
801 kStrict_SrcRectConstraint,
802
803 /**
804 * If kFast is specified, the implementation may sample outside of the src-rect
805 * (if specified) by at most 1 pixel when filtering. This allows greater flexibility
806 * to the implementation and can make the draw much faster.
807 */
808 kFast_SrcRectConstraint,
809 };
810
811 /** Draw the specified image, scaling and translating so that it fills the specified
812 * dst rect. If the src rect is non-null, only that subset of the image is transformed
813 * and drawn.
814 *
815 * @param image The image to be drawn
816 * @param src Optional: specify the subset of the image to be drawn
817 * @param dst The destination rectangle where the scaled/translated
818 * image will be drawn
819 * @param paint The paint used to draw the image, or NULL
820 * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
821 */
reed0846f1b2015-01-09 14:17:40 -0800822 void drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
reed84984ef2015-07-17 07:09:43 -0700823 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
reeda5517e22015-07-14 10:54:12 -0700824
reed84984ef2015-07-17 07:09:43 -0700825 void drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst) {
826 this->drawImageRect(image, src, dst, NULL, kStrict_SrcRectConstraint);
reeda5517e22015-07-14 10:54:12 -0700827 }
828
829 void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint = NULL) {
830 // With no src-rect, the constraint value is ignored, so we just use the default.
831 this->drawImageRect(image, NULL, dst, paint, kStrict_SrcRectConstraint);
832 }
piotaixrb5fae932014-09-24 13:03:30 -0700833
reed84984ef2015-07-17 07:09:43 -0700834 void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
835 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
836
reed4c21dc52015-06-25 12:32:03 -0700837 /**
838 * Draw the image stretched differentially to fit into dst.
839 * center is a rect within the image, and logically divides the image
840 * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
841 * image is the "center", then the center-rect should be [2, 2, 3, 3].
842 *
843 * If the dst is >= the image size, then...
844 * - The 4 corners are not stretched at all.
845 * - The sides are stretched in only one axis.
846 * - The center is stretched in both axes.
847 * Else, for each axis where dst < image,
848 * - The corners shrink proportionally
849 * - The sides (along the shrink axis) and center are not drawn
850 */
851 void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
852 const SkPaint* paint = NULL);
853
reed@android.com8a1c16f2008-12-17 15:59:43 +0000854 /** Draw the specified bitmap, with its top/left corner at (x,y), using the
855 specified paint, transformed by the current matrix. Note: if the paint
856 contains a maskfilter that generates a mask which extends beyond the
857 bitmap's original width/height, then the bitmap will be drawn as if it
858 were in a Shader with CLAMP mode. Thus the color outside of the original
859 width/height will be the edge color replicated.
commit-bot@chromium.org91246b92013-12-05 15:43:19 +0000860
861 If a shader is present on the paint it will be ignored, except in the
reed@google.comf20fc242014-03-26 13:44:58 +0000862 case where the bitmap is kAlpha_8_SkColorType. In that case, the color is
commit-bot@chromium.org91246b92013-12-05 15:43:19 +0000863 generated by the shader.
864
reed@android.com8a1c16f2008-12-17 15:59:43 +0000865 @param bitmap The bitmap to be drawn
866 @param left The position of the left side of the bitmap being drawn
867 @param top The position of the top side of the bitmap being drawn
868 @param paint The paint used to draw the bitmap, or NULL
869 */
reed0846f1b2015-01-09 14:17:40 -0800870 void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
871 const SkPaint* paint = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000872
reeda5517e22015-07-14 10:54:12 -0700873 /** Draw the specified bitmap, scaling and translating so that it fills the specified
874 * dst rect. If the src rect is non-null, only that subset of the bitmap is transformed
875 * and drawn.
876 *
877 * @param bitmap The bitmap to be drawn
878 * @param src Optional: specify the subset of the bitmap to be drawn
879 * @param dst The destination rectangle where the scaled/translated
880 * bitmap will be drawn
881 * @param paint The paint used to draw the bitmap, or NULL
882 * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
883 */
reed84984ef2015-07-17 07:09:43 -0700884 void drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
885 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
reeda5517e22015-07-14 10:54:12 -0700886
887 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint = NULL) {
888 this->drawBitmapRect(bitmap, NULL, dst, paint, kStrict_SrcRectConstraint);
889 }
890
reed84984ef2015-07-17 07:09:43 -0700891 void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
892 const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint);
893
reed@google.comf0b5e112011-09-07 11:57:34 +0000894 /**
895 * Draw the bitmap stretched differentially to fit into dst.
896 * center is a rect within the bitmap, and logically divides the bitmap
897 * into 9 sections (3x3). For example, if the middle pixel of a [5x5]
898 * bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
899 *
900 * If the dst is >= the bitmap size, then...
robertphillips@google.com9bf380c2013-07-25 12:10:42 +0000901 * - The 4 corners are not stretched at all.
902 * - The sides are stretched in only one axis.
903 * - The center is stretched in both axes.
reed@google.comf0b5e112011-09-07 11:57:34 +0000904 * Else, for each axis where dst < bitmap,
905 * - The corners shrink proportionally
906 * - The sides (along the shrink axis) and center are not drawn
907 */
reed0846f1b2015-01-09 14:17:40 -0800908 void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
909 const SkPaint* paint = NULL);
reed@google.comf0b5e112011-09-07 11:57:34 +0000910
reed@android.com8a1c16f2008-12-17 15:59:43 +0000911 /** Draw the specified bitmap, with its top/left corner at (x,y),
912 NOT transformed by the current matrix. Note: if the paint
913 contains a maskfilter that generates a mask which extends beyond the
914 bitmap's original width/height, then the bitmap will be drawn as if it
915 were in a Shader with CLAMP mode. Thus the color outside of the original
916 width/height will be the edge color replicated.
917 @param bitmap The bitmap to be drawn
918 @param left The position of the left side of the bitmap being drawn
919 @param top The position of the top side of the bitmap being drawn
920 @param paint The paint used to draw the bitmap, or NULL
921 */
reed0846f1b2015-01-09 14:17:40 -0800922 void drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint = NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000923
924 /** Draw the text, with origin at (x,y), using the specified paint.
925 The origin is interpreted based on the Align setting in the paint.
926 @param text The text to be drawn
927 @param byteLength The number of bytes to read from the text parameter
928 @param x The x-coordinate of the origin of the text being drawn
929 @param y The y-coordinate of the origin of the text being drawn
930 @param paint The paint used for the text (e.g. color, size, style)
931 */
reedf7430cc2014-12-21 11:38:35 -0800932 void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
933 const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000934
935 /** Draw the text, with each character/glyph origin specified by the pos[]
reed@google.com4b226022011-01-11 18:32:13 +0000936 array. The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000937 @param text The text to be drawn
938 @param byteLength The number of bytes to read from the text parameter
939 @param pos Array of positions, used to position each character
940 @param paint The paint used for the text (e.g. color, size, style)
941 */
reedf7430cc2014-12-21 11:38:35 -0800942 void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
943 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000944
reed@android.com8a1c16f2008-12-17 15:59:43 +0000945 /** Draw the text, with each character/glyph origin specified by the x
946 coordinate taken from the xpos[] array, and the y from the constY param.
reed@google.com4b226022011-01-11 18:32:13 +0000947 The origin is interpreted by the Align setting in the paint.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000948 @param text The text to be drawn
949 @param byteLength The number of bytes to read from the text parameter
950 @param xpos Array of x-positions, used to position each character
951 @param constY The shared Y coordinate for all of the positions
952 @param paint The paint used for the text (e.g. color, size, style)
953 */
reedf7430cc2014-12-21 11:38:35 -0800954 void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
955 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +0000956
reed@android.com8a1c16f2008-12-17 15:59:43 +0000957 /** Draw the text, with origin at (x,y), using the specified paint, along
958 the specified path. The paint's Align setting determins where along the
959 path to start the text.
960 @param text The text to be drawn
961 @param byteLength The number of bytes to read from the text parameter
962 @param path The path the text should follow for its baseline
963 @param hOffset The distance along the path to add to the text's
964 starting position
965 @param vOffset The distance above(-) or below(+) the path to
966 position the text
967 @param paint The paint used for the text
968 */
reedf7430cc2014-12-21 11:38:35 -0800969 void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000970 SkScalar vOffset, const SkPaint& paint);
971
972 /** Draw the text, with origin at (x,y), using the specified paint, along
973 the specified path. The paint's Align setting determins where along the
974 path to start the text.
975 @param text The text to be drawn
976 @param byteLength The number of bytes to read from the text parameter
977 @param path The path the text should follow for its baseline
978 @param matrix (may be null) Applied to the text before it is
979 mapped onto the path
980 @param paint The paint used for the text
981 */
reedf7430cc2014-12-21 11:38:35 -0800982 void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
983 const SkMatrix* matrix, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000984
fmalita00d5c2c2014-08-21 08:53:26 -0700985 /** Draw the text blob, offset by (x,y), using the specified paint.
986 @param blob The text blob to be drawn
987 @param x The x-offset of the text being drawn
988 @param y The y-offset of the text being drawn
989 @param paint The paint used for the text (e.g. color, size, style)
990 */
991 void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
992
reed@android.com8a1c16f2008-12-17 15:59:43 +0000993 /** Draw the picture into this canvas. This method effective brackets the
994 playback of the picture's draw calls with save/restore, so the state
djsollen@google.coma44de962013-01-02 16:59:19 +0000995 of this canvas will be unchanged after this call.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000996 @param picture The recorded drawing commands to playback into this
997 canvas.
998 */
reed1c2c4412015-04-30 13:09:24 -0700999 void drawPicture(const SkPicture* picture) {
1000 this->drawPicture(picture, NULL, NULL);
1001 }
robertphillips9b14f262014-06-04 05:40:44 -07001002
reedd5fa1a42014-08-09 11:08:05 -07001003 /**
1004 * Draw the picture into this canvas.
1005 *
1006 * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
1007 * logically equivalent to
1008 * save/concat/drawPicture/restore
1009 *
1010 * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
1011 * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
1012 * This is logically equivalent to
1013 * saveLayer(paint)/drawPicture/restore
1014 */
1015 void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint);
1016
reed@android.com8a1c16f2008-12-17 15:59:43 +00001017 enum VertexMode {
1018 kTriangles_VertexMode,
1019 kTriangleStrip_VertexMode,
1020 kTriangleFan_VertexMode
1021 };
reed@google.com4b226022011-01-11 18:32:13 +00001022
reed@android.com8a1c16f2008-12-17 15:59:43 +00001023 /** Draw the array of vertices, interpreted as triangles (based on mode).
commit-bot@chromium.org559a8832014-05-30 10:08:22 +00001024
1025 If both textures and vertex-colors are NULL, it strokes hairlines with
1026 the paint's color. This behavior is a useful debugging mode to visualize
1027 the mesh.
1028
reed@android.com8a1c16f2008-12-17 15:59:43 +00001029 @param vmode How to interpret the array of vertices
1030 @param vertexCount The number of points in the vertices array (and
1031 corresponding texs and colors arrays if non-null)
1032 @param vertices Array of vertices for the mesh
1033 @param texs May be null. If not null, specifies the coordinate
robertphillips@google.com631a59b2013-07-31 14:57:53 +00001034 in _texture_ space (not uv space) for each vertex.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001035 @param colors May be null. If not null, specifies a color for each
1036 vertex, to be interpolated across the triangle.
1037 @param xmode Used if both texs and colors are present. In this
1038 case the colors are combined with the texture using mode,
1039 before being drawn using the paint. If mode is null, then
reed@google.com8d3cd7a2013-01-30 21:36:11 +00001040 kModulate_Mode is used.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001041 @param indices If not null, array of indices to reference into the
1042 vertex (texs, colors) array.
1043 @param indexCount number of entries in the indices array (if not null)
reed@google.com4b226022011-01-11 18:32:13 +00001044 @param paint Specifies the shader/texture if present.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001045 */
reed0846f1b2015-01-09 14:17:40 -08001046 void drawVertices(VertexMode vmode, int vertexCount,
1047 const SkPoint vertices[], const SkPoint texs[],
1048 const SkColor colors[], SkXfermode* xmode,
1049 const uint16_t indices[], int indexCount,
1050 const SkPaint& paint);
mtklein6cfa73a2014-08-13 13:33:49 -07001051
dandovb3c9d1c2014-08-12 08:34:29 -07001052 /**
1053 Draw a cubic coons patch
mtklein6cfa73a2014-08-13 13:33:49 -07001054
dandovb3c9d1c2014-08-12 08:34:29 -07001055 @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
1056 starting at the top left corner.
1057 @param colors specifies the colors for the corners which will be bilerp across the patch,
1058 their order is clockwise starting at the top left corner.
mtklein6cfa73a2014-08-13 13:33:49 -07001059 @param texCoords specifies the texture coordinates that will be bilerp across the patch,
dandovb3c9d1c2014-08-12 08:34:29 -07001060 their order is the same as the colors.
mtklein6cfa73a2014-08-13 13:33:49 -07001061 @param xmode specifies how are the colors and the textures combined if both of them are
dandovb3c9d1c2014-08-12 08:34:29 -07001062 present.
dandov963137b2014-08-07 07:49:53 -07001063 @param paint Specifies the shader/texture if present.
1064 */
dandovb3c9d1c2014-08-12 08:34:29 -07001065 void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
1066 const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001067
reed3cb38402015-02-06 08:36:15 -08001068 /**
reed71c3c762015-06-24 10:29:17 -07001069 * Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the
1070 * coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle
1071 * into a quad.
1072 *
1073 * xform maps [0, 0, tex.width, tex.height] -> quad
1074 *
1075 * The color array is optional. When specified, each color modulates the pixels in its
1076 * corresponding quad (via the specified SkXfermode::Mode).
1077 *
1078 * The cullRect is optional. When specified, it must be a conservative bounds of all of the
1079 * resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
1080 * intersect the current clip.
1081 *
1082 * The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
1083 * and xfermode are used to affect each of the quads.
1084 */
1085 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
1086 const SkColor colors[], int count, SkXfermode::Mode, const SkRect* cullRect,
1087 const SkPaint* paint);
1088
1089 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
1090 const SkRect* cullRect, const SkPaint* paint) {
1091 this->drawAtlas(atlas, xform, tex, NULL, count, SkXfermode::kDst_Mode, cullRect, paint);
1092 }
1093
1094 /**
reed3cb38402015-02-06 08:36:15 -08001095 * Draw the contents of this drawable into the canvas. If the canvas is async
1096 * (e.g. it is recording into a picture) then the drawable will be referenced instead,
1097 * to have its draw() method called when the picture is finalized.
1098 *
1099 * If the intent is to force the contents of the drawable into this canvas immediately,
1100 * then drawable->draw(canvas) may be called.
1101 */
reeda8db7282015-07-07 10:22:31 -07001102 void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL);
1103 void drawDrawable(SkDrawable*, SkScalar x, SkScalar y);
reed6a070dc2014-11-11 19:36:09 -08001104
reed@android.com8a1c16f2008-12-17 15:59:43 +00001105 //////////////////////////////////////////////////////////////////////////
reed@google.com4b226022011-01-11 18:32:13 +00001106
reed@android.com8a1c16f2008-12-17 15:59:43 +00001107 /** Get the current filter object. The filter's reference count is not
reed@android.comdc3381f2010-02-11 16:05:15 +00001108 affected. The filter is saved/restored, just like the matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001109 @return the canvas' filter (or NULL).
1110 */
1111 SkDrawFilter* getDrawFilter() const;
reed@google.com4b226022011-01-11 18:32:13 +00001112
reed@android.com8a1c16f2008-12-17 15:59:43 +00001113 /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
1114 As a convenience, the parameter is returned. If an existing filter
1115 exists, its refcnt is decrement. If the new filter is not null, its
reed@android.comdc3381f2010-02-11 16:05:15 +00001116 refcnt is incremented. The filter is saved/restored, just like the
1117 matrix and clip.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001118 @param filter the new filter (or NULL)
1119 @return the new filter
1120 */
1121 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
1122
1123 //////////////////////////////////////////////////////////////////////////
1124
reed@google.com754de5f2014-02-24 19:38:20 +00001125 /**
1126 * Return true if the current clip is empty (i.e. nothing will draw).
1127 * Note: this is not always a free call, so it should not be used
1128 * more often than necessary. However, once the canvas has computed this
1129 * result, subsequent calls will be cheap (until the clip state changes,
1130 * which can happen on any clip..() or restore() call.
1131 */
robertphillips@google.com8f90a892014-02-28 18:19:39 +00001132 virtual bool isClipEmpty() const;
reed@google.com754de5f2014-02-24 19:38:20 +00001133
commit-bot@chromium.org5c70cdc2014-03-08 03:57:19 +00001134 /**
1135 * Returns true if the current clip is just a (non-empty) rectangle.
1136 * Returns false if the clip is empty, or if it is complex.
1137 */
1138 virtual bool isClipRect() const;
1139
reed@android.com8a1c16f2008-12-17 15:59:43 +00001140 /** Return the current matrix on the canvas.
1141 This does not account for the translate in any of the devices.
1142 @return The current matrix on the canvas.
1143 */
junov@chromium.orga907ac32012-02-24 21:54:07 +00001144 const SkMatrix& getTotalMatrix() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001145
robertphillips@google.com40a1ae42012-07-13 15:36:15 +00001146 /** Return the clip stack. The clip stack stores all the individual
1147 * clips organized by the save/restore frame in which they were
1148 * added.
1149 * @return the current clip stack ("list" of individual clip elements)
1150 */
1151 const SkClipStack* getClipStack() const {
reed687fa1c2015-04-07 08:00:56 -07001152 return fClipStack;
robertphillips@google.com40a1ae42012-07-13 15:36:15 +00001153 }
1154
fmalitac3b589a2014-06-05 12:40:07 -07001155 typedef SkCanvasClipVisitor ClipVisitor;
reed@google.com90c07ea2012-04-13 13:50:27 +00001156 /**
1157 * Replays the clip operations, back to front, that have been applied to
1158 * the canvas, calling the appropriate method on the visitor for each
1159 * clip. All clips have already been transformed into device space.
1160 */
1161 void replayClips(ClipVisitor*) const;
1162
reed@android.com8a1c16f2008-12-17 15:59:43 +00001163 ///////////////////////////////////////////////////////////////////////////
1164
1165 /** After calling saveLayer(), there can be any number of devices that make
1166 up the top-most drawing area. LayerIter can be used to iterate through
1167 those devices. Note that the iterator is only valid until the next API
1168 call made on the canvas. Ownership of all pointers in the iterator stays
1169 with the canvas, so none of them should be modified or deleted.
1170 */
ctguil@chromium.org7ffb1b22011-03-15 21:27:08 +00001171 class SK_API LayerIter /*: SkNoncopyable*/ {
reed@android.com8a1c16f2008-12-17 15:59:43 +00001172 public:
1173 /** Initialize iterator with canvas, and set values for 1st device */
1174 LayerIter(SkCanvas*, bool skipEmptyClips);
1175 ~LayerIter();
reed@google.com4b226022011-01-11 18:32:13 +00001176
reed@android.com8a1c16f2008-12-17 15:59:43 +00001177 /** Return true if the iterator is done */
1178 bool done() const { return fDone; }
1179 /** Cycle to the next device */
1180 void next();
reed@google.com4b226022011-01-11 18:32:13 +00001181
reed@android.com8a1c16f2008-12-17 15:59:43 +00001182 // These reflect the current device in the iterator
1183
robertphillips@google.com1f2f3382013-08-29 11:54:56 +00001184 SkBaseDevice* device() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001185 const SkMatrix& matrix() const;
1186 const SkRegion& clip() const;
1187 const SkPaint& paint() const;
1188 int x() const;
1189 int y() const;
reed@google.com4b226022011-01-11 18:32:13 +00001190
reed@android.com8a1c16f2008-12-17 15:59:43 +00001191 private:
1192 // used to embed the SkDrawIter object directly in our instance, w/o
1193 // having to expose that class def to the public. There is an assert
1194 // in our constructor to ensure that fStorage is large enough
1195 // (though needs to be a compile-time-assert!). We use intptr_t to work
1196 // safely with 32 and 64 bit machines (to ensure the storage is enough)
reed@android.comf2b98d62010-12-20 18:26:13 +00001197 intptr_t fStorage[32];
reed@android.com8a1c16f2008-12-17 15:59:43 +00001198 class SkDrawIter* fImpl; // this points at fStorage
1199 SkPaint fDefaultPaint;
1200 bool fDone;
1201 };
1202
commit-bot@chromium.org5c70cdc2014-03-08 03:57:19 +00001203 // don't call
reed@google.com9c135db2014-03-12 18:28:35 +00001204 GrRenderTarget* internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org5c70cdc2014-03-08 03:57:19 +00001205
reedd990e2f2014-12-22 11:58:30 -08001206 // don't call
1207 static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
1208 static bool Internal_Private_GetIgnoreSaveLayerBounds();
reed0acf1b42014-12-22 16:12:38 -08001209 static void Internal_Private_SetTreatSpriteAsBitmap(bool);
1210 static bool Internal_Private_GetTreatSpriteAsBitmap();
reedd990e2f2014-12-22 11:58:30 -08001211
reed@android.com8a1c16f2008-12-17 15:59:43 +00001212protected:
reed@google.com76f10a32014-02-05 15:32:21 +00001213 // default impl defers to getDevice()->newSurface(info)
reed4a8126e2014-09-22 07:29:03 -07001214 virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
reed@google.com76f10a32014-02-05 15:32:21 +00001215
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00001216 // default impl defers to its device
reed884e97c2015-05-26 11:31:54 -07001217 virtual bool onPeekPixels(SkPixmap*);
1218 virtual bool onAccessTopLayerPixels(SkPixmap*);
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00001219
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00001220 // Subclass save/restore notifiers.
1221 // Overriders should call the corresponding INHERITED method up the inheritance chain.
1222 // willSaveLayer()'s return value may suppress full layer allocation.
1223 enum SaveLayerStrategy {
1224 kFullLayer_SaveLayerStrategy,
1225 kNoLayer_SaveLayerStrategy
1226 };
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00001227
fmalita6ca763f2014-06-17 13:52:18 -07001228 virtual void willSave() {}
commit-bot@chromium.orgfc6dfba2014-05-14 13:13:44 +00001229 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
1230 return kFullLayer_SaveLayerStrategy;
1231 }
1232 virtual void willRestore() {}
mtklein6cfa73a2014-08-13 13:33:49 -07001233 virtual void didRestore() {}
commit-bot@chromium.orgfc6dfba2014-05-14 13:13:44 +00001234 virtual void didConcat(const SkMatrix&) {}
1235 virtual void didSetMatrix(const SkMatrix&) {}
commit-bot@chromium.org44c48d02014-03-13 20:03:58 +00001236
commit-bot@chromium.orged9806f2014-02-21 02:32:36 +00001237 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
1238
reed@google.come0d9ce82014-04-23 04:00:17 +00001239 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
1240 SkScalar y, const SkPaint& paint);
skia.committer@gmail.comb0430d02014-04-24 03:05:07 +00001241
reed@google.come0d9ce82014-04-23 04:00:17 +00001242 virtual void onDrawPosText(const void* text, size_t byteLength,
1243 const SkPoint pos[], const SkPaint& paint);
skia.committer@gmail.comb0430d02014-04-24 03:05:07 +00001244
reed@google.come0d9ce82014-04-23 04:00:17 +00001245 virtual void onDrawPosTextH(const void* text, size_t byteLength,
1246 const SkScalar xpos[], SkScalar constY,
1247 const SkPaint& paint);
skia.committer@gmail.comb0430d02014-04-24 03:05:07 +00001248
reed@google.come0d9ce82014-04-23 04:00:17 +00001249 virtual void onDrawTextOnPath(const void* text, size_t byteLength,
1250 const SkPath& path, const SkMatrix* matrix,
1251 const SkPaint& paint);
mtklein6cfa73a2014-08-13 13:33:49 -07001252
fmalita00d5c2c2014-08-21 08:53:26 -07001253 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
1254 const SkPaint& paint);
1255
dandovb3c9d1c2014-08-12 08:34:29 -07001256 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
1257 const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
reed@google.come0d9ce82014-04-23 04:00:17 +00001258
reeda8db7282015-07-07 10:22:31 -07001259 virtual void onDrawDrawable(SkDrawable*, const SkMatrix*);
reed6a070dc2014-11-11 19:36:09 -08001260
reed41af9662015-01-05 07:49:08 -08001261 virtual void onDrawPaint(const SkPaint&);
1262 virtual void onDrawRect(const SkRect&, const SkPaint&);
1263 virtual void onDrawOval(const SkRect&, const SkPaint&);
1264 virtual void onDrawRRect(const SkRRect&, const SkPaint&);
1265 virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&);
1266 virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
1267 const SkPoint texs[], const SkColor colors[], SkXfermode*,
1268 const uint16_t indices[], int indexCount, const SkPaint&);
mtklein2766c002015-06-26 11:45:03 -07001269
reed71c3c762015-06-24 10:29:17 -07001270 virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
1271 int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*);
reed41af9662015-01-05 07:49:08 -08001272 virtual void onDrawPath(const SkPath&, const SkPaint&);
1273 virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
reed562fe472015-07-28 07:35:14 -07001274 virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
1275 SrcRectConstraint);
reed4c21dc52015-06-25 12:32:03 -07001276 virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
1277 const SkPaint*);
1278
reed41af9662015-01-05 07:49:08 -08001279 virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*);
1280 virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
reed562fe472015-07-28 07:35:14 -07001281 SrcRectConstraint);
reed41af9662015-01-05 07:49:08 -08001282 virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
1283 const SkPaint*);
1284 virtual void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*);
1285
robertphillips@google.com8f90a892014-02-28 18:19:39 +00001286 enum ClipEdgeStyle {
1287 kHard_ClipEdgeStyle,
1288 kSoft_ClipEdgeStyle
1289 };
1290
1291 virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
1292 virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
1293 virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle);
1294 virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op);
1295
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +00001296 virtual void onDiscard();
1297
reedd5fa1a42014-08-09 11:08:05 -07001298 virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
robertphillips9b14f262014-06-04 05:40:44 -07001299
vandebo@chromium.org74b46192012-01-28 01:45:11 +00001300 // Returns the canvas to be used by DrawIter. Default implementation
junov@google.com4370aed2012-01-18 16:21:08 +00001301 // returns this. Subclasses that encapsulate an indirect canvas may
1302 // need to overload this method. The impl must keep track of this, as it
1303 // is not released or deleted by the caller.
1304 virtual SkCanvas* canvasForDrawIter();
1305
junov@chromium.orga907ac32012-02-24 21:54:07 +00001306 // Clip rectangle bounds. Called internally by saveLayer.
1307 // returns false if the entire rectangle is entirely clipped out
senorblanco@chromium.orgc4b12f12014-02-05 17:51:22 +00001308 // If non-NULL, The imageFilter parameter will be used to expand the clip
1309 // and offscreen bounds for any margin required by the filter DAG.
junov@chromium.orga907ac32012-02-24 21:54:07 +00001310 bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
senorblanco@chromium.orgc4b12f12014-02-05 17:51:22 +00001311 SkIRect* intersection,
1312 const SkImageFilter* imageFilter = NULL);
junov@chromium.orga907ac32012-02-24 21:54:07 +00001313
reedc83a2972015-07-16 07:40:45 -07001314private:
1315 enum ShaderOverrideOpacity {
1316 kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
1317 kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
1318 kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
1319 };
1320
reed@google.com97af1a62012-08-28 12:19:02 +00001321 // notify our surface (if we have one) that we are about to draw, so it
1322 // can perform copy-on-write or invalidate any cached images
reedc83a2972015-07-16 07:40:45 -07001323 void predrawNotify(bool willOverwritesEntireSurface = false);
1324 void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
1325 void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
1326 this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
1327 : kNotOpaque_ShaderOverrideOpacity);
1328 }
reed@google.com97af1a62012-08-28 12:19:02 +00001329
reed@android.com8a1c16f2008-12-17 15:59:43 +00001330 class MCRec;
1331
reed687fa1c2015-04-07 08:00:56 -07001332 SkAutoTUnref<SkClipStack> fClipStack;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001333 SkDeque fMCStack;
1334 // points to top of stack
1335 MCRec* fMCRec;
1336 // the first N recs that can fit here mean we won't call malloc
reedb679ca82015-04-07 04:40:48 -07001337 enum {
reeda499f902015-05-01 09:34:31 -07001338 kMCRecSize = 128, // most recent measurement
1339 kMCRecCount = 8, // common depth for save/restores
reed86a17e72015-05-14 12:25:22 -07001340 kDeviceCMSize = 136, // most recent measurement
reedb679ca82015-04-07 04:40:48 -07001341 };
1342 intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
reeda499f902015-05-01 09:34:31 -07001343 intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
reed@android.com8a1c16f2008-12-17 15:59:43 +00001344
reed4a8126e2014-09-22 07:29:03 -07001345 const SkSurfaceProps fProps;
1346
reed2ff1fce2014-12-11 07:07:37 -08001347 int fSaveCount; // value returned by getSaveCount()
reed@android.com8a1c16f2008-12-17 15:59:43 +00001348
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +00001349 SkMetaData* fMetaData;
1350
reed@google.com97af1a62012-08-28 12:19:02 +00001351 SkSurface_Base* fSurfaceBase;
1352 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
1353 void setSurfaceBase(SkSurface_Base* sb) {
1354 fSurfaceBase = sb;
1355 }
1356 friend class SkSurface_Base;
junov@chromium.org45c3db82013-04-11 17:52:05 +00001357 friend class SkSurface_Gpu;
skia.committer@gmail.comfc843592012-10-11 02:01:14 +00001358
reed@android.com8a1c16f2008-12-17 15:59:43 +00001359 bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
1360 void updateDeviceCMCache();
1361
reed2ff1fce2014-12-11 07:07:37 -08001362 void doSave();
1363 void checkForDeferredSave();
1364
reed@google.com9c135db2014-03-12 18:28:35 +00001365 friend class SkDrawIter; // needs setupDrawForLayerDevice()
reed@google.com8926b162012-03-23 15:36:36 +00001366 friend class AutoDrawLooper;
reed@google.com9c135db2014-03-12 18:28:35 +00001367 friend class SkLua; // needs top layer size and offset
commit-bot@chromium.org2a67e122014-05-19 13:53:10 +00001368 friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
reed@google.com9c135db2014-03-12 18:28:35 +00001369 friend class SkDeferredDevice; // needs getTopDevice()
reed52d9ac62014-06-30 09:05:34 -07001370 friend class SkSurface_Raster; // needs getDevice()
reedd9544982014-09-09 18:46:22 -07001371 friend class SkRecorder; // InitFlags
1372 friend class SkNoSaveLayerCanvas; // InitFlags
fmalita2d97bc12014-11-20 10:44:58 -08001373 friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
reedc83a2972015-07-16 07:40:45 -07001374 friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
piotaixrb5fae932014-09-24 13:03:30 -07001375
reedd9544982014-09-09 18:46:22 -07001376 enum InitFlags {
1377 kDefault_InitFlags = 0,
1378 kConservativeRasterClip_InitFlag = 1 << 0,
1379 };
reed78e27682014-11-19 08:04:34 -08001380 SkCanvas(const SkIRect& bounds, InitFlags);
robertphillipsfcf78292015-06-19 11:49:52 -07001381 SkCanvas(SkBaseDevice* device, InitFlags);
reedd9544982014-09-09 18:46:22 -07001382
mtkleinfeaadee2015-04-08 11:25:48 -07001383 void resetForNextPicture(const SkIRect& bounds);
1384
reed8f2e7912014-09-04 12:45:18 -07001385 // needs gettotalclip()
tfarinaa5414c42014-10-10 06:19:09 -07001386 friend class SkCanvasStateUtils;
piotaixrb5fae932014-09-24 13:03:30 -07001387
reed4a8126e2014-09-22 07:29:03 -07001388 // call this each time we attach ourselves to a device
1389 // - constructor
1390 // - internalSaveLayer
1391 void setupDevice(SkBaseDevice*);
1392
reedd9544982014-09-09 18:46:22 -07001393 SkBaseDevice* init(SkBaseDevice*, InitFlags);
reed@google.comf0b5e112011-09-07 11:57:34 +00001394
commit-bot@chromium.org403f8d72014-02-17 15:24:26 +00001395 /**
bsalomon@google.com4ebe3822014-02-26 20:22:32 +00001396 * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this
1397 * to be public because it exposes decisions about layer sizes that are internal to the canvas.
1398 */
1399 SkISize getTopLayerSize() const;
1400 SkIPoint getTopLayerOrigin() const;
commit-bot@chromium.org403f8d72014-02-17 15:24:26 +00001401
reed@google.comf0b5e112011-09-07 11:57:34 +00001402 // internal methods are not virtual, so they can safely be called by other
1403 // canvas apis, without confusing subclasses (like SkPictureRecording)
robertphillips@google.com9bf380c2013-07-25 12:10:42 +00001404 void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint);
reed@google.com71121732012-09-18 15:14:33 +00001405 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001406 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07001407 SrcRectConstraint);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00001408 void internalDrawPaint(const SkPaint& paint);
reed76033be2015-03-14 10:54:31 -07001409 void internalSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags, SaveLayerStrategy);
reed61f501f2015-04-29 08:34:00 -07001410 void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00001411
reed@android.com8a1c16f2008-12-17 15:59:43 +00001412 // shared by save() and saveLayer()
reed2ff1fce2014-12-11 07:07:37 -08001413 void internalSave();
reed@android.com8a1c16f2008-12-17 15:59:43 +00001414 void internalRestore();
bungeman@google.com52c748b2011-08-22 21:30:43 +00001415 static void DrawRect(const SkDraw& draw, const SkPaint& paint,
1416 const SkRect& r, SkScalar textSize);
1417 static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
1418 const char text[], size_t byteLength,
1419 SkScalar x, SkScalar y);
reed@google.com4b226022011-01-11 18:32:13 +00001420
reedfa35f8e2014-09-04 12:14:36 -07001421 // only for canvasutils
1422 const SkRegion& internal_private_getTotalClip() const;
1423
reedc83a2972015-07-16 07:40:45 -07001424 /*
1425 * Returns true if drawing the specified rect (or all if it is null) with the specified
1426 * paint (or default if null) would overwrite the entire root device of the canvas
1427 * (i.e. the canvas' surface if it had one).
1428 */
1429 bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
1430
1431
reed@android.com8a1c16f2008-12-17 15:59:43 +00001432 /* These maintain a cache of the clip bounds in local coordinates,
1433 (converted to 2s-compliment if floats are slow).
1434 */
reed@google.comc0784db2013-12-13 21:16:12 +00001435 mutable SkRect fCachedLocalClipBounds;
1436 mutable bool fCachedLocalClipBoundsDirty;
caryclark@google.com8f0a7b82012-11-07 14:54:49 +00001437 bool fAllowSoftClip;
caryclark@google.com45a75fb2013-04-25 13:34:40 +00001438 bool fAllowSimplifyClip;
reedd9544982014-09-09 18:46:22 -07001439 bool fConservativeRasterClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001440
reed@google.comc0784db2013-12-13 21:16:12 +00001441 const SkRect& getLocalClipBounds() const {
1442 if (fCachedLocalClipBoundsDirty) {
1443 if (!this->getClipBounds(&fCachedLocalClipBounds)) {
1444 fCachedLocalClipBounds.setEmpty();
1445 }
1446 fCachedLocalClipBoundsDirty = false;
reed@android.comba09de42010-02-05 20:46:05 +00001447 }
reed@google.comc0784db2013-12-13 21:16:12 +00001448 return fCachedLocalClipBounds;
reed@android.comba09de42010-02-05 20:46:05 +00001449 }
caryclark@google.com45a75fb2013-04-25 13:34:40 +00001450
reed@google.com5c3d1472011-02-22 19:12:23 +00001451 class AutoValidateClip : ::SkNoncopyable {
1452 public:
1453 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1454 fCanvas->validateClip();
1455 }
1456 ~AutoValidateClip() { fCanvas->validateClip(); }
1457
1458 private:
1459 const SkCanvas* fCanvas;
1460 };
1461
1462#ifdef SK_DEBUG
1463 void validateClip() const;
1464#else
1465 void validateClip() const {}
1466#endif
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +00001467
1468 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001469};
1470
1471/** Stack helper class to automatically call restoreToCount() on the canvas
1472 when this object goes out of scope. Use this to guarantee that the canvas
1473 is restored to a known state.
1474*/
1475class SkAutoCanvasRestore : SkNoncopyable {
1476public:
commit-bot@chromium.org28871192013-10-14 15:28:01 +00001477 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
1478 if (fCanvas) {
1479 fSaveCount = canvas->getSaveCount();
1480 if (doSave) {
1481 canvas->save();
1482 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00001483 }
1484 }
1485 ~SkAutoCanvasRestore() {
reed@google.comf6c9a5b2012-11-20 15:12:21 +00001486 if (fCanvas) {
1487 fCanvas->restoreToCount(fSaveCount);
1488 }
1489 }
1490
1491 /**
1492 * Perform the restore now, instead of waiting for the destructor. Will
1493 * only do this once.
1494 */
1495 void restore() {
1496 if (fCanvas) {
1497 fCanvas->restoreToCount(fSaveCount);
1498 fCanvas = NULL;
1499 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00001500 }
1501
1502private:
1503 SkCanvas* fCanvas;
1504 int fSaveCount;
1505};
commit-bot@chromium.orge61a86c2013-11-18 16:03:59 +00001506#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
reed@android.com8a1c16f2008-12-17 15:59:43 +00001507
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00001508/**
1509 * If the caller wants read-only access to the pixels in a canvas, it can just
1510 * call canvas->peekPixels(), since that is the fastest way to "peek" at the
1511 * pixels on a raster-backed canvas.
1512 *
1513 * If the canvas has pixels, but they are not readily available to the CPU
1514 * (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will
1515 * succeed (though be slower, since it will return a copy of the pixels).
1516 *
1517 * SkAutoROCanvasPixels encapsulates these two techniques, trying first to call
1518 * peekPixels() (for performance), but if that fails, calling readPixels() and
1519 * storing the copy locally.
1520 *
1521 * The caller must respect the restrictions associated with peekPixels(), since
1522 * that may have been called: The returned information is invalidated if...
1523 * - any API is called on the canvas (or its parent surface if present)
1524 * - the canvas goes out of scope
1525 */
1526class SkAutoROCanvasPixels : SkNoncopyable {
1527public:
1528 SkAutoROCanvasPixels(SkCanvas* canvas);
1529
1530 // returns NULL on failure
1531 const void* addr() const { return fAddr; }
skia.committer@gmail.com02d6f542014-02-14 03:02:05 +00001532
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00001533 // undefined if addr() == NULL
1534 size_t rowBytes() const { return fRowBytes; }
skia.committer@gmail.com02d6f542014-02-14 03:02:05 +00001535
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00001536 // undefined if addr() == NULL
1537 const SkImageInfo& info() const { return fInfo; }
1538
1539 // helper that, if returns true, installs the pixels into the bitmap. Note
1540 // that the bitmap may reference the address returned by peekPixels(), so
1541 // the caller must respect the restrictions associated with peekPixels().
1542 bool asROBitmap(SkBitmap*) const;
1543
1544private:
1545 SkBitmap fBitmap; // used if peekPixels() fails
1546 const void* fAddr; // NULL on failure
1547 SkImageInfo fInfo;
1548 size_t fRowBytes;
1549};
1550
commit-bot@chromium.org2a5cd602014-05-30 20:41:20 +00001551static inline SkCanvas::SaveFlags operator|(const SkCanvas::SaveFlags lhs,
1552 const SkCanvas::SaveFlags rhs) {
commit-bot@chromium.org92a89162014-05-30 21:07:05 +00001553 return static_cast<SkCanvas::SaveFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
commit-bot@chromium.org2a5cd602014-05-30 20:41:20 +00001554}
1555
1556static inline SkCanvas::SaveFlags& operator|=(SkCanvas::SaveFlags& lhs,
1557 const SkCanvas::SaveFlags rhs) {
1558 lhs = lhs | rhs;
1559 return lhs;
1560}
1561
fmalitac3b589a2014-06-05 12:40:07 -07001562class SkCanvasClipVisitor {
1563public:
1564 virtual ~SkCanvasClipVisitor();
1565 virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
1566 virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
1567 virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
1568};
commit-bot@chromium.org2a5cd602014-05-30 20:41:20 +00001569
reed@android.com8a1c16f2008-12-17 15:59:43 +00001570#endif