blob: 8c86cd2f13e814bbb040eaedcd9f2fb45409f952 [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
reed374772b2016-10-05 17:33:02 -070011#include "SkBlendMode.h"
reed73603f32016-09-20 08:42:38 -070012#include "SkClipOp.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013#include "SkDeque.h"
14#include "SkPaint.h"
Mike Reed356f7c22017-01-10 11:58:39 -050015#include "SkRasterHandleAllocator.h"
reed4a8126e2014-09-22 07:29:03 -070016#include "SkSurfaceProps.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000017
bungemand3ebb482015-08-05 13:57:49 -070018class GrContext;
Brian Osman11052242016-10-27 14:47:55 -040019class GrRenderTargetContext;
Stan Iliev73d8fd92017-08-02 15:36:24 -040020class SkAndroidFrameworkUtils;
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000021class SkBaseDevice;
Mike Reed267be7f2017-02-13 09:32:54 -050022class SkBitmap;
bungemand3ebb482015-08-05 13:57:49 -070023class SkClipStack;
reedf70b5312016-03-04 16:36:20 -080024class SkData;
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;
Mike Reed4204da22017-05-17 08:53:36 -040028struct SkDrawShadowRec;
Mike Reed267be7f2017-02-13 09:32:54 -050029class SkImage;
bungemand3ebb482015-08-05 13:57:49 -070030class SkImageFilter;
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +000031class SkMetaData;
bungemand3ebb482015-08-05 13:57:49 -070032class SkPath;
reed@android.com8a1c16f2008-12-17 15:59:43 +000033class SkPicture;
bungemand3ebb482015-08-05 13:57:49 -070034class SkPixmap;
reed1e7f5e72016-04-27 07:49:17 -070035class SkRasterClip;
Mike Reed267be7f2017-02-13 09:32:54 -050036class SkRegion;
reed@google.com4ed0fb72012-12-12 20:48:18 +000037class SkRRect;
reed71c3c762015-06-24 10:29:17 -070038struct SkRSXform;
reed@google.com76f10a32014-02-05 15:32:21 +000039class SkSurface;
reed@google.com97af1a62012-08-28 12:19:02 +000040class SkSurface_Base;
fmalita00d5c2c2014-08-21 08:53:26 -070041class SkTextBlob;
Brian Salomon199fb872017-02-06 09:41:10 -050042class SkVertices;
reedfa35f8e2014-09-04 12:14:36 -070043
reed@android.com8a1c16f2008-12-17 15:59:43 +000044/** \class SkCanvas
Cary Clarkb7da7232017-09-01 13:49:54 -040045 SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
46 SkCanvas contains a stack of SkMatrix and clip values.
reed@android.com8a1c16f2008-12-17 15:59:43 +000047
Cary Clarkb7da7232017-09-01 13:49:54 -040048 SkCanvas and SkPaint together provide the state to draw into SkSurface or SkBaseDevice.
49 Each SkCanvas draw call transforms the geometry of the object by the concatenation of all
50 SkMatrix values in the stack. The transformed geometry is clipped by the intersection
51 of all of clip values in the stack. The SkCanvas draw calls use SkPaint to supply drawing
52 state such as color, SkTypeface, text size, stroke width, SkShader and so on.
reed@android.com8a1c16f2008-12-17 15:59:43 +000053
Cary Clarkb7da7232017-09-01 13:49:54 -040054 To draw to a pixel-based destination, create raster surface or GPU surface.
55 Request SkCanvas from SkSurface to obtain the interface to draw.
56 SkCanvas generated by raster surface draws to memory visible to the CPU.
57 SkCanvas generated by GPU surface uses Vulkan or OpenGL to draw to the GPU.
58
59 To draw to a document, obtain SkCanvas from svg canvas, document pdf, or SkPictureRecorder.
60 SkDocument based SkCanvas and other SkCanvas Subclasses reference SkBaseDevice describing the
61 destination.
62
63 SkCanvas can be constructed to draw to SkBitmap without first creating raster surface.
64 This approach may be deprecated in the future.
reed@android.com8a1c16f2008-12-17 15:59:43 +000065*/
Mike Reed02b73492016-12-07 16:52:58 -050066class SK_API SkCanvas : SkNoncopyable {
reedbada1882015-12-21 13:09:44 -080067 enum PrivateSaveLayerFlags {
caryclark952538e2016-02-26 05:01:42 -080068 kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
reedbada1882015-12-21 13:09:44 -080069 };
reed73603f32016-09-20 08:42:38 -070070
reed@android.com8a1c16f2008-12-17 15:59:43 +000071public:
Cary Clarkb7da7232017-09-01 13:49:54 -040072
73 /** Allocates raster SkCanvas that will draw directly into pixels.
Cary Clarkb7da7232017-09-01 13:49:54 -040074
75 SkCanvas is returned if all parameters are valid.
76 Valid parameters include:
77 info dimensions are zero or positive;
78 info contains SkColorType and SkAlphaType supported by raster surface;
79 pixels is not nullptr;
80 rowBytes is zero or large enough to contain info width pixels of SkColorType.
81
82 Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
83 If rowBytes is greater than zero, it must be equal to or greater than
84 info width times bytes required for SkColorType.
85
86 Pixel buffer size should be info height times computed rowBytes.
Cary Clark2823f9f2018-01-03 10:00:34 -050087 Pixels are not initialized.
88 To access pixels after drawing, call flush() or peekPixels().
Cary Clarkb7da7232017-09-01 13:49:54 -040089
Cary Clark8a02b0b2017-09-21 12:28:43 -040090 @param info width, height, SkColorType, SkAlphaType, SkColorSpace, of raster surface;
Cary Clarkb7da7232017-09-01 13:49:54 -040091 width, or height, or both, may be zero
92 @param pixels pointer to destination pixels buffer
93 @param rowBytes interval from one SkSurface row to the next, or zero
Cary Clark2823f9f2018-01-03 10:00:34 -050094 @param props LCD striping orientation and setting for device independent fonts;
95 may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -040096 @return SkCanvas if all parameters are valid; otherwise, nullptr
97 */
Cary Clark0418a882017-05-10 09:07:42 -040098 static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
Mike Reed12f77342017-11-08 11:19:52 -050099 size_t rowBytes,
100 const SkSurfaceProps* props = nullptr);
Mike Reed5df49342016-11-12 08:06:55 -0600101
Cary Clarkb7da7232017-09-01 13:49:54 -0400102 /** Allocates raster SkCanvas specified by inline image specification. Subsequent SkCanvas
103 calls draw into pixels.
104 SkColorType is set to kN32_SkColorType.
105 SkAlphaType is set to kPremul_SkAlphaType.
106 To access pixels after drawing, call flush() or peekPixels().
107
108 SkCanvas is returned if all parameters are valid.
109 Valid parameters include:
110 width and height are zero or positive;
111 pixels is not nullptr;
112 rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
113
114 Pass zero for rowBytes to compute rowBytes from width and size of pixel.
115 If rowBytes is greater than zero, it must be equal to or greater than
116 width times bytes required for SkColorType.
117
118 Pixel buffer size should be height times rowBytes.
119
120 @param width pixel column count on raster surface created; must be zero or greater
Cary Clarkcc309eb2017-10-30 11:48:35 -0400121 @param height pixel row count on raster surface created; must be zero or greater
Cary Clarkb7da7232017-09-01 13:49:54 -0400122 @param pixels pointer to destination pixels buffer; buffer size should be height
123 times rowBytes
124 @param rowBytes interval from one SkSurface row to the next, or zero
125 @return SkCanvas if all parameters are valid; otherwise, nullptr
126 */
Mike Reed5df49342016-11-12 08:06:55 -0600127 static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
128 size_t rowBytes) {
129 return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
130 }
131
Cary Clark8a02b0b2017-09-21 12:28:43 -0400132 /** Creates an empty SkCanvas with no backing device or pixels, with
Cary Clarkb7da7232017-09-01 13:49:54 -0400133 a width and height of zero.
134
Cary Clark8a02b0b2017-09-21 12:28:43 -0400135 @return empty SkCanvas
Cary Clarkb7da7232017-09-01 13:49:54 -0400136 */
reed@google.comcde92112011-07-06 20:00:52 +0000137 SkCanvas();
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000138
Cary Clarkb7da7232017-09-01 13:49:54 -0400139 /** Creates SkCanvas of the specified dimensions without a SkSurface.
140 Used by Subclasses with custom implementations for draw methods.
141
Cary Clark8a02b0b2017-09-21 12:28:43 -0400142 If props equals nullptr, SkSurfaceProps are created with
143 SkSurfaceProps::InitType settings, which choose the pixel striping
144 direction and order. Since a platform may dynamically change its direction when
145 the device is rotated, and since a platform may have multiple monitors with
146 different characteristics, it is best not to rely on this legacy behavior.
Cary Clarkb7da7232017-09-01 13:49:54 -0400147
148 @param width zero or greater
149 @param height zero or greater
150 @param props LCD striping orientation and setting for device independent fonts;
151 may be nullptr
152 @return SkCanvas placeholder with dimensions
153 */
Ben Wagnera93a14a2017-08-28 10:34:05 -0400154 SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr);
commit-bot@chromium.orge2543102014-01-31 19:42:58 +0000155
Cary Clark75959392018-02-27 10:22:04 -0500156 /** To be deprecated soon.
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000157 */
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000158 explicit SkCanvas(SkBaseDevice* device);
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000159
Cary Clarkb7da7232017-09-01 13:49:54 -0400160 /** Construct a canvas that draws into bitmap.
161 Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed SkSurface.
162
163 SkBitmap is copied so that subsequently editing bitmap will not affect
164 constructed SkCanvas.
165
166 May be deprecated in the future.
167
168 @param bitmap width, height, SkColorType, SkAlphaType, and pixel
169 storage of raster surface
170 @return SkCanvas that can be used to draw into bitmap
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 */
172 explicit SkCanvas(const SkBitmap& bitmap);
fmalita3d91aad2015-02-02 05:25:04 -0800173
Matt Sarett31f99ce2017-04-11 08:46:01 -0400174#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
175 enum class ColorBehavior {
Cary Clarkb7da7232017-09-01 13:49:54 -0400176 kLegacy, //!< Is a placeholder to allow specialized constructor; has no meaning.
Matt Sarett31f99ce2017-04-11 08:46:01 -0400177 };
178
Cary Clarkb7da7232017-09-01 13:49:54 -0400179 /** Android framework only.
180
181 @param bitmap specifies a bitmap for the canvas to draw into
182 @param behavior specializes this constructor; value is unused
183 @return SkCanvas that can be used to draw into bitmap
184 */
Cary Clark304f9d42017-05-13 13:35:35 -0400185 SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
Matt Sarett31f99ce2017-04-11 08:46:01 -0400186#endif
187
Cary Clarkb7da7232017-09-01 13:49:54 -0400188 /** Construct a canvas that draws into bitmap.
189 Use props to match the device characteristics, like LCD striping.
190
191 bitmap is copied so that subsequently editing bitmap will not affect
192 constructed SkCanvas.
193
194 @param bitmap width, height, SkColorType, SkAlphaType,
195 and pixel storage of raster surface
196 @param props order and orientation of RGB striping; and whether to use
197 device independent fonts
198 @return SkCanvas that can be used to draw into bitmap
fmalita3d91aad2015-02-02 05:25:04 -0800199 */
200 SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
201
Cary Clark75959392018-02-27 10:22:04 -0500202 /** Draws saved layer, if any.
203 Frees up resources used by SkCanvas.
Cary Clarkb7da7232017-09-01 13:49:54 -0400204 */
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 virtual ~SkCanvas();
206
Cary Clarkb7da7232017-09-01 13:49:54 -0400207 /** Returns storage to associate additional data with the canvas.
208 The storage is freed when SkCanvas is deleted.
209
210 @return storage that can be read from and written to
211 */
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +0000212 SkMetaData& getMetaData();
213
Cary Clarkb7da7232017-09-01 13:49:54 -0400214 /** Returns SkImageInfo for SkCanvas. If SkCanvas is not associated with raster surface or
215 GPU surface, returned SkColorType is set to kUnknown_SkColorType.
216
217 @return dimensions and SkColorType of SkCanvas
218 */
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +0000219 SkImageInfo imageInfo() const;
220
Cary Clarkb7da7232017-09-01 13:49:54 -0400221 /** If SkCanvas is associated with raster surface or
222 GPU surface, copies SkSurfaceProps and returns true. Otherwise,
223 return false and leave props unchanged.
224
225 @param props storage for writable SkSurfaceProps
226 @return true if SkSurfaceProps was copied
227 */
Cary Clark0418a882017-05-10 09:07:42 -0400228 bool getProps(SkSurfaceProps* props) const;
brianosman898235c2016-04-06 07:38:23 -0700229
Cary Clarkb7da7232017-09-01 13:49:54 -0400230 /** Triggers the immediate execution of all pending draw operations.
231 If SkCanvas is associated with GPU surface, resolves all pending GPU operations.
Cary Clark2823f9f2018-01-03 10:00:34 -0500232 If SkCanvas is associated with raster surface, has no effect; raster draw
233 operations are never deferred.
Cary Clarkb7da7232017-09-01 13:49:54 -0400234 */
junov@chromium.orgbf6c1e42012-01-30 14:53:22 +0000235 void flush();
236
Cary Clark8a02b0b2017-09-21 12:28:43 -0400237 /** Gets the size of the base or root layer in global canvas coordinates. The
238 origin of the base layer is always (0,0). The area available for drawing may be
Cary Clarkb7da7232017-09-01 13:49:54 -0400239 smaller (due to clipping or saveLayer).
240
Cary Clark8a02b0b2017-09-21 12:28:43 -0400241 @return integral width and height of base layer
Cary Clarkb7da7232017-09-01 13:49:54 -0400242 */
tomhudson68260fa2015-03-23 07:22:40 -0700243 virtual SkISize getBaseLayerSize() const;
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000244
Cary Clarkb7da7232017-09-01 13:49:54 -0400245 /** Creates SkSurface matching info and props, and associates it with SkCanvas.
246 Returns nullptr if no match found.
247
248 If props is nullptr, matches SkSurfaceProps in SkCanvas. If props is nullptr and SkCanvas
249 does not have SkSurfaceProps, creates SkSurface with default SkSurfaceProps.
250
Cary Clark8a02b0b2017-09-21 12:28:43 -0400251 @param info width, height, SkColorType, SkAlphaType, and SkColorSpace
Cary Clarkb7da7232017-09-01 13:49:54 -0400252 @param props SkSurfaceProps to match; may be nullptr to match SkCanvas
253 @return SkSurface matching info and props, or nullptr if no match is available
254 */
Cary Clark304f9d42017-05-13 13:35:35 -0400255 sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);
bsalomon@google.come97f0852011-06-17 13:10:25 +0000256
Cary Clarkb7da7232017-09-01 13:49:54 -0400257 /** Returns GPU context of the GPU surface associated with SkCanvas.
258
259 @return GPU context, if available; nullptr otherwise
260 */
Brian Osmand2da87d2017-05-08 16:02:43 -0400261 virtual GrContext* getGrContext();
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000262
Cary Clarkb7da7232017-09-01 13:49:54 -0400263 /** Returns the pixel base address, SkImageInfo, rowBytes, and origin if the pixels
264 can be read directly. The returned address is only valid
265 while SkCanvas is in scope and unchanged. Any SkCanvas call or SkSurface call
266 may invalidate the returned address and other returned values.
reed@google.com4b226022011-01-11 18:32:13 +0000267
Cary Clarkb7da7232017-09-01 13:49:54 -0400268 If pixels are inaccessible, info, rowBytes, and origin are unchanged.
269
270 @param info storage for writable pixels' SkImageInfo; may be nullptr
271 @param rowBytes storage for writable pixels' row bytes; may be nullptr
Cary Clarkcc309eb2017-10-30 11:48:35 -0400272 @param origin storage for SkCanvas top layer origin, its top-left corner;
Cary Clarkb7da7232017-09-01 13:49:54 -0400273 may be nullptr
274 @return address of pixels, or nullptr if inaccessible
275 */
Ben Wagnera93a14a2017-08-28 10:34:05 -0400276 void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr);
reed@google.com9c135db2014-03-12 18:28:35 +0000277
Cary Clarkb7da7232017-09-01 13:49:54 -0400278 /** Returns custom context that tracks the SkMatrix and clip.
279
280 Use SkRasterHandleAllocator to blend Skia drawing with custom drawing, typically performed
Cary Clarkcc309eb2017-10-30 11:48:35 -0400281 by the host platform user interface. The custom context returned is generated by
Cary Clarkb7da7232017-09-01 13:49:54 -0400282 SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
283 the drawing destination.
284
285 @return context of custom allocation
286 */
Mike Reed356f7c22017-01-10 11:58:39 -0500287 SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
288
Cary Clarkb7da7232017-09-01 13:49:54 -0400289 /** Returns true if SkCanvas has direct access to its pixels.
290
291 Pixels are readable when SkBaseDevice is raster. Pixels are not readable when SkCanvas
292 is returned from GPU surface, returned by SkDocument::beginPage, returned by
293 SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
Brian Osman46fe9c72018-03-09 15:44:34 -0500294 like SkDebugCanvas.
Cary Clarkb7da7232017-09-01 13:49:54 -0400295
296 pixmap is valid only while SkCanvas is in scope and unchanged. Any
297 SkCanvas or SkSurface call may invalidate the pixmap values.
298
Cary Clarkcc309eb2017-10-30 11:48:35 -0400299 @param pixmap storage for pixel state if pixels are readable; otherwise, ignored
Cary Clarkb7da7232017-09-01 13:49:54 -0400300 @return true if SkCanvas has direct access to pixels
301 */
Cary Clark0418a882017-05-10 09:07:42 -0400302 bool peekPixels(SkPixmap* pixmap);
reed6ceeebd2016-03-09 14:26:26 -0800303
Cary Clarkcc309eb2017-10-30 11:48:35 -0400304 /** Copies SkRect of pixels from SkCanvas into dstPixels. SkMatrix and clip are
Cary Clark2823f9f2018-01-03 10:00:34 -0500305 ignored.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400306
Cary Clark2823f9f2018-01-03 10:00:34 -0500307 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
308 Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400309 Copies each readable pixel intersecting both rectangles, without scaling,
310 converting to dstInfo.colorType() and dstInfo.alphaType() if required.
311
312 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
313 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
314 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500315 class like SkDebugCanvas.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400316
317 The destination pixel storage must be allocated by the caller.
318
319 Pixel values are converted only if SkColorType and SkAlphaType
320 do not match. Only pixels within both source and destination rectangles
Cary Clarkcc309eb2017-10-30 11:48:35 -0400321 are copied. dstPixels contents outside SkRect intersection are unchanged.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400322
323 Pass negative values for srcX or srcY to offset pixels across or down destination.
324
325 Does not copy, and returns false if:
326 - Source and destination rectangles do not intersect.
327 - SkCanvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
328 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
329 - dstRowBytes is too small to contain one row of pixels.
Cary Clarkb7da7232017-09-01 13:49:54 -0400330
331 @param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels
332 @param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger
333 @param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger
334 @param srcX offset into readable pixels in x; may be negative
335 @param srcY offset into readable pixels in y; may be negative
336 @return true if pixels were copied
337 */
reedb184f7f2014-07-13 04:32:32 -0700338 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
339 int srcX, int srcY);
Cary Clarkb7da7232017-09-01 13:49:54 -0400340
Cary Clarkcc309eb2017-10-30 11:48:35 -0400341 /** Copies SkRect of pixels from SkCanvas into pixmap. SkMatrix and clip are
Cary Clark2823f9f2018-01-03 10:00:34 -0500342 ignored.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400343
Cary Clark2823f9f2018-01-03 10:00:34 -0500344 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
345 Destination SkRect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400346 Copies each readable pixel intersecting both rectangles, without scaling,
347 converting to pixmap.colorType() and pixmap.alphaType() if required.
348
349 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
350 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
351 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500352 class like SkDebugCanvas.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400353
354 Caller must allocate pixel storage in pixmap if needed.
355
356 Pixel values are converted only if SkColorType and SkAlphaType
Cary Clark75959392018-02-27 10:22:04 -0500357 do not match. Only pixels within both source and destination SkRect
Cary Clarkcc309eb2017-10-30 11:48:35 -0400358 are copied. pixmap pixels contents outside SkRect intersection are unchanged.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400359
360 Pass negative values for srcX or srcY to offset pixels across or down pixmap.
361
362 Does not copy, and returns false if:
363 - Source and destination rectangles do not intersect.
364 - SkCanvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType().
365 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
366 - SkPixmap pixels could not be allocated.
367 - pixmap.rowBytes() is too small to contain one row of pixels.
Cary Clarkb7da7232017-09-01 13:49:54 -0400368
369 @param pixmap storage for pixels copied from SkCanvas
370 @param srcX offset into readable pixels in x; may be negative
371 @param srcY offset into readable pixels in y; may be negative
372 @return true if pixels were copied
373 */
Cary Clark0418a882017-05-10 09:07:42 -0400374 bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);
Cary Clarkb7da7232017-09-01 13:49:54 -0400375
Cary Clarkcc309eb2017-10-30 11:48:35 -0400376 /** Copies SkRect of pixels from SkCanvas into bitmap. SkMatrix and clip are
Cary Clark2823f9f2018-01-03 10:00:34 -0500377 ignored.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400378
Cary Clark2823f9f2018-01-03 10:00:34 -0500379 Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Cary Clarkcc309eb2017-10-30 11:48:35 -0400380 Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400381 Copies each readable pixel intersecting both rectangles, without scaling,
382 converting to bitmap.colorType() and bitmap.alphaType() if required.
383
384 Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
385 Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
386 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500387 class like SkDebugCanvas.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400388
389 Caller must allocate pixel storage in bitmap if needed.
390
391 SkBitmap values are converted only if SkColorType and SkAlphaType
392 do not match. Only pixels within both source and destination rectangles
Cary Clarkcc309eb2017-10-30 11:48:35 -0400393 are copied. SkBitmap pixels outside SkRect intersection are unchanged.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400394
395 Pass negative values for srcX or srcY to offset pixels across or down bitmap.
396
397 Does not copy, and returns false if:
398 - Source and destination rectangles do not intersect.
399 - SkCanvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType().
400 - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
401 - bitmap pixels could not be allocated.
402 - bitmap.rowBytes() is too small to contain one row of pixels.
Cary Clarkb7da7232017-09-01 13:49:54 -0400403
404 @param bitmap storage for pixels copied from SkCanvas
405 @param srcX offset into readable pixels in x; may be negative
406 @param srcY offset into readable pixels in y; may be negative
407 @return true if pixels were copied
408 */
Cary Clark304f9d42017-05-13 13:35:35 -0400409 bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);
commit-bot@chromium.orga713f9c2014-03-17 21:31:26 +0000410
Cary Clarkcc309eb2017-10-30 11:48:35 -0400411 /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
412 Source SkRect corners are (0, 0) and (info.width(), info.height()).
413 Destination SkRect corners are (x, y) and
414 (imageInfo().width(), imageInfo().height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400415
416 Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkcc309eb2017-10-30 11:48:35 -0400417 converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400418
419 Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
420 Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
421 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500422 class like SkDebugCanvas.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400423
424 Pixel values are converted only if SkColorType and SkAlphaType
425 do not match. Only pixels within both source and destination rectangles
Cary Clarkcc309eb2017-10-30 11:48:35 -0400426 are copied. SkCanvas pixels outside SkRect intersection are unchanged.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400427
428 Pass negative values for x or y to offset pixels to the left or
429 above SkCanvas pixels.
430
431 Does not copy, and returns false if:
432 - Source and destination rectangles do not intersect.
Cary Clark75959392018-02-27 10:22:04 -0500433 - pixels could not be converted to SkCanvas imageInfo().colorType() or
434 imageInfo().alphaType().
Cary Clark8a02b0b2017-09-21 12:28:43 -0400435 - SkCanvas pixels are not writable; for instance, SkCanvas is document-based.
436 - rowBytes is too small to contain one row of pixels.
Cary Clarkb7da7232017-09-01 13:49:54 -0400437
438 @param info width, height, SkColorType, and SkAlphaType of pixels
439 @param pixels pixels to copy, of size info.height() times rowBytes, or larger
Cary Clark8a02b0b2017-09-21 12:28:43 -0400440 @param rowBytes size of one row of pixels; info.width() times pixel size, or larger
Cary Clarkb7da7232017-09-01 13:49:54 -0400441 @param x offset into SkCanvas writable pixels in x; may be negative
442 @param y offset into SkCanvas writable pixels in y; may be negative
443 @return true if pixels were written to SkCanvas
444 */
Cary Clark0418a882017-05-10 09:07:42 -0400445 bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000446
Cary Clarkcc309eb2017-10-30 11:48:35 -0400447 /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
448 Source SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400449
Cary Clarkcc309eb2017-10-30 11:48:35 -0400450 Destination SkRect corners are (x, y) and
451 (imageInfo().width(), imageInfo().height()).
Cary Clark8a02b0b2017-09-21 12:28:43 -0400452
453 Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clarkcc309eb2017-10-30 11:48:35 -0400454 converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400455
456 Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
457 Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
458 returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
Brian Osman46fe9c72018-03-09 15:44:34 -0500459 class like SkDebugCanvas.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400460
461 Pixel values are converted only if SkColorType and SkAlphaType
462 do not match. Only pixels within both source and destination rectangles
Cary Clarkcc309eb2017-10-30 11:48:35 -0400463 are copied. SkCanvas pixels outside SkRect intersection are unchanged.
Cary Clark8a02b0b2017-09-21 12:28:43 -0400464
465 Pass negative values for x or y to offset pixels to the left or
466 above SkCanvas pixels.
467
468 Does not copy, and returns false if:
469 - Source and destination rectangles do not intersect.
470 - bitmap does not have allocated pixels.
Cary Clark75959392018-02-27 10:22:04 -0500471 - bitmap pixels could not be converted to SkCanvas imageInfo().colorType() or
472 imageInfo().alphaType().
Cary Clark8a02b0b2017-09-21 12:28:43 -0400473 - SkCanvas pixels are not writable; for instance, SkCanvas is document based.
474 - bitmap pixels are inaccessible; for instance, bitmap wraps a texture.
Cary Clarkb7da7232017-09-01 13:49:54 -0400475
476 @param bitmap contains pixels copied to SkCanvas
477 @param x offset into SkCanvas writable pixels in x; may be negative
478 @param y offset into SkCanvas writable pixels in y; may be negative
479 @return true if pixels were written to SkCanvas
480 */
commit-bot@chromium.org4cd9e212014-03-07 03:25:16 +0000481 bool writePixels(const SkBitmap& bitmap, int x, int y);
reed@google.com4b226022011-01-11 18:32:13 +0000482
Cary Clark75959392018-02-27 10:22:04 -0500483 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms).
Cary Clarkb7da7232017-09-01 13:49:54 -0400484 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
485 restoring the SkMatrix, clip, and SkDrawFilter to their state when save() was called.
vandebo@chromium.org8d84fac2010-10-13 22:13:05 +0000486
Cary Clarkb7da7232017-09-01 13:49:54 -0400487 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix(),
488 and resetMatrix(). Clip may be changed by clipRect(), clipRRect(), clipPath(), clipRegion().
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000489
Cary Clarkb7da7232017-09-01 13:49:54 -0400490 Saved SkCanvas state is put on a stack; multiple calls to save() should be balance
491 by an equal number of calls to restore().
492
493 Call restoreToCount() with result to restore this and subsequent saves.
494
495 @return depth of saved stack
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000496 */
497 int save();
498
Cary Clark75959392018-02-27 10:22:04 -0500499 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
Cary Clarkb7da7232017-09-01 13:49:54 -0400500 and allocates a SkBitmap for subsequent drawing.
501 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
502 and draws the SkBitmap.
503
504 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
505 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
506 clipPath(), clipRegion().
507
508 SkRect bounds suggests but does not define the SkBitmap size. To clip drawing to
509 a specific rectangle, use clipRect().
510
511 Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
512 SkBlendMode when restore() is called.
513
514 Call restoreToCount() with returned value to restore this and subsequent saves.
515
Cary Clark8a02b0b2017-09-21 12:28:43 -0400516 @param bounds hint to limit the size of the layer; may be nullptr
517 @param paint graphics state for layer; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -0400518 @return depth of saved stack
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000519 */
520 int saveLayer(const SkRect* bounds, const SkPaint* paint);
Cary Clarkb7da7232017-09-01 13:49:54 -0400521
Cary Clark75959392018-02-27 10:22:04 -0500522 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
Cary Clarkb7da7232017-09-01 13:49:54 -0400523 and allocates a SkBitmap for subsequent drawing.
524 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
525 and draws the SkBitmap.
526
527 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
528 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
529 clipPath(), clipRegion().
530
Cary Clark8a02b0b2017-09-21 12:28:43 -0400531 SkRect bounds suggests but does not define the layer size. To clip drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -0400532 a specific rectangle, use clipRect().
533
534 Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
535 SkBlendMode when restore() is called.
536
537 Call restoreToCount() with returned value to restore this and subsequent saves.
538
Cary Clark8a02b0b2017-09-21 12:28:43 -0400539 @param bounds hint to limit the size of layer; may be nullptr
540 @param paint graphics state for layer; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -0400541 @return depth of saved stack
542 */
reed021f6312015-08-09 19:41:13 -0700543 int saveLayer(const SkRect& bounds, const SkPaint* paint) {
544 return this->saveLayer(&bounds, paint);
545 }
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000546
Cary Clark75959392018-02-27 10:22:04 -0500547 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
Cary Clarkb7da7232017-09-01 13:49:54 -0400548 and allocates a SkBitmap for subsequent drawing.
Cary Clark75959392018-02-27 10:22:04 -0500549 LCD text is preserved when the layer is drawn to the prior layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400550
551 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
Cary Clark8a02b0b2017-09-21 12:28:43 -0400552 and draws layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400553
554 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
555 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
556 clipPath(), clipRegion().
557
Cary Clark8a02b0b2017-09-21 12:28:43 -0400558 SkRect bounds suggests but does not define the layer size. To clip drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -0400559 a specific rectangle, use clipRect().
560
561 Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
562 SkBlendMode when restore() is called.
563
564 Call restoreToCount() with returned value to restore this and subsequent saves.
565
Cary Clark75959392018-02-27 10:22:04 -0500566 Draw text on an opaque background so that LCD text blends correctly with the
567 prior layer. LCD text drawn on a background with transparency may result in
Cary Clark8a02b0b2017-09-21 12:28:43 -0400568 incorrect blending.
Cary Clarkb7da7232017-09-01 13:49:54 -0400569
Cary Clark8a02b0b2017-09-21 12:28:43 -0400570 @param bounds hint to limit the size of layer; may be nullptr
571 @param paint graphics state for layer; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -0400572 @return depth of saved stack
573 */
reed70ee31b2015-12-10 13:44:45 -0800574 int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint);
575
Cary Clark75959392018-02-27 10:22:04 -0500576 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
Cary Clarkb7da7232017-09-01 13:49:54 -0400577 and allocates SkBitmap for subsequent drawing.
578
579 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
Cary Clark8a02b0b2017-09-21 12:28:43 -0400580 and blends layer with alpha opacity onto prior layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400581
582 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
583 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
584 clipPath(), clipRegion().
585
Cary Clark8a02b0b2017-09-21 12:28:43 -0400586 SkRect bounds suggests but does not define layer size. To clip drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -0400587 a specific rectangle, use clipRect().
588
589 alpha of zero is fully transparent, 255 is fully opaque.
590
591 Call restoreToCount() with returned value to restore this and subsequent saves.
592
Cary Clark8a02b0b2017-09-21 12:28:43 -0400593 @param bounds hint to limit the size of layer; may be nullptr
594 @param alpha opacity of layer
Cary Clarkb7da7232017-09-01 13:49:54 -0400595 @return depth of saved stack
commit-bot@chromium.orgd70fa202014-04-24 21:51:58 +0000596 */
597 int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
598
Cary Clarkb7da7232017-09-01 13:49:54 -0400599 /** \enum
600 SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
Cary Clark8a02b0b2017-09-21 12:28:43 -0400601 defining how layer allocated by saveLayer() operates.
Cary Clarkb7da7232017-09-01 13:49:54 -0400602 */
reed4960eee2015-12-18 07:09:18 -0800603 enum {
Cary Clark8a02b0b2017-09-21 12:28:43 -0400604 /** Creates layer for LCD text. Flag is ignored if layer SkPaint contains
Cary Clarkb7da7232017-09-01 13:49:54 -0400605 SkImageFilter or SkColorFilter.
606 */
607 kPreserveLCDText_SaveLayerFlag = 1 << 1,
608
Cary Clark8a02b0b2017-09-21 12:28:43 -0400609 /** Initializes layer with the contents of the previous layer. */
Cary Clarkb7da7232017-09-01 13:49:54 -0400610 kInitWithPrevious_SaveLayerFlag = 1 << 2,
Mike Reedc61abee2017-02-28 17:45:27 -0500611
reedbada1882015-12-21 13:09:44 -0800612#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
Cary Clark75959392018-02-27 10:22:04 -0500613 /** To be deprecated soon. */
reedbada1882015-12-21 13:09:44 -0800614 kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
615#endif
reed4960eee2015-12-18 07:09:18 -0800616 };
Cary Clarkb7da7232017-09-01 13:49:54 -0400617
reed4960eee2015-12-18 07:09:18 -0800618 typedef uint32_t SaveLayerFlags;
619
Cary Clarkb7da7232017-09-01 13:49:54 -0400620 /** \struct SkCanvas::SaveLayerRec
Cary Clarkcc309eb2017-10-30 11:48:35 -0400621 SaveLayerRec contains the state used to create the layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400622 */
reed4960eee2015-12-18 07:09:18 -0800623 struct SaveLayerRec {
Cary Clarkb7da7232017-09-01 13:49:54 -0400624
625 /** Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
626
627 @return empty SaveLayerRec
628 */
Florin Malita53f77bd2017-04-28 13:48:37 -0400629 SaveLayerRec() {}
Cary Clarkb7da7232017-09-01 13:49:54 -0400630
631 /** Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
632
Cary Clark8a02b0b2017-09-21 12:28:43 -0400633 @param bounds layer dimensions; may be nullptr
634 @param paint applied to layer when overlaying prior layer; may be nullptr
635 @param saveLayerFlags SaveLayerRec options to modify layer
Cary Clarkb7da7232017-09-01 13:49:54 -0400636 @return SaveLayerRec with empty backdrop
637 */
reed4960eee2015-12-18 07:09:18 -0800638 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
639 : fBounds(bounds)
640 , fPaint(paint)
reedbfd5f172016-01-07 11:28:08 -0800641 , fSaveLayerFlags(saveLayerFlags)
642 {}
Cary Clarkb7da7232017-09-01 13:49:54 -0400643
644 /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
645
Cary Clark8a02b0b2017-09-21 12:28:43 -0400646 @param bounds layer dimensions; may be nullptr
647 @param paint applied to layer when overlaying prior layer;
Cary Clarkb7da7232017-09-01 13:49:54 -0400648 may be nullptr
Cary Clark8a02b0b2017-09-21 12:28:43 -0400649 @param backdrop prior layer copied with SkImageFilter; may be nullptr
650 @param saveLayerFlags SaveLayerRec options to modify layer
Cary Clarkb7da7232017-09-01 13:49:54 -0400651 @return SaveLayerRec fully specified
652 */
reedbfd5f172016-01-07 11:28:08 -0800653 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
Florin Malita25b37432017-05-01 10:58:40 -0400654 SaveLayerFlags saveLayerFlags)
655 : fBounds(bounds)
656 , fPaint(paint)
657 , fBackdrop(backdrop)
658 , fSaveLayerFlags(saveLayerFlags)
659 {}
Mike Kleinb34ab042017-05-01 21:34:14 +0000660
Cary Clarkb7da7232017-09-01 13:49:54 -0400661 /** EXPERIMENTAL: Not ready for general use.
662 Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
663 clipMatrix uses color alpha channel of image, transformed by clipMatrix, to clip
Cary Clark8a02b0b2017-09-21 12:28:43 -0400664 layer when drawn to SkCanvas.
Cary Clarkb7da7232017-09-01 13:49:54 -0400665
Cary Clark2823f9f2018-01-03 10:00:34 -0500666 Implementation is not complete; has no effect if SkBaseDevice is GPU-backed.
Cary Clarkb7da7232017-09-01 13:49:54 -0400667
Cary Clark8a02b0b2017-09-21 12:28:43 -0400668 @param bounds layer dimensions; may be nullptr
669 @param paint graphics state applied to layer when overlaying prior
670 layer; may be nullptr
671 @param backdrop prior layer copied with SkImageFilter;
Cary Clarkb7da7232017-09-01 13:49:54 -0400672 may be nullptr
Cary Clark8a02b0b2017-09-21 12:28:43 -0400673 @param clipMask clip applied to layer; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -0400674 @param clipMatrix matrix applied to clipMask; may be nullptr to use
675 identity matrix
Cary Clark8a02b0b2017-09-21 12:28:43 -0400676 @param saveLayerFlags SaveLayerRec options to modify layer
Cary Clarkb7da7232017-09-01 13:49:54 -0400677 @return SaveLayerRec fully specified
678 */
Florin Malita25b37432017-05-01 10:58:40 -0400679 SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
Mike Kleinb34ab042017-05-01 21:34:14 +0000680 const SkImage* clipMask, const SkMatrix* clipMatrix,
reedbfd5f172016-01-07 11:28:08 -0800681 SaveLayerFlags saveLayerFlags)
682 : fBounds(bounds)
683 , fPaint(paint)
684 , fBackdrop(backdrop)
Vaclav Brozekd0e0a8f2017-06-04 14:12:50 +0200685 , fClipMask(clipMask)
Florin Malita53f77bd2017-04-28 13:48:37 -0400686 , fClipMatrix(clipMatrix)
reed4960eee2015-12-18 07:09:18 -0800687 , fSaveLayerFlags(saveLayerFlags)
688 {}
689
Cary Clark8a02b0b2017-09-21 12:28:43 -0400690 /** fBounds is used as a hint to limit the size of layer; may be nullptr.
691 fBounds suggests but does not define layer size. To clip drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -0400692 a specific rectangle, use clipRect().
693 */
694 const SkRect* fBounds = nullptr;
695
Cary Clark8a02b0b2017-09-21 12:28:43 -0400696 /** fPaint modifies how layer overlays the prior layer; may be nullptr.
Cary Clarkb7da7232017-09-01 13:49:54 -0400697 color alpha, SkBlendMode, SkColorFilter, SkDrawLooper, SkImageFilter, and
Cary Clark8a02b0b2017-09-21 12:28:43 -0400698 SkMaskFilter affect layer draw.
Cary Clarkb7da7232017-09-01 13:49:54 -0400699 */
700 const SkPaint* fPaint = nullptr;
701
Cary Clark8a02b0b2017-09-21 12:28:43 -0400702 /** fBackdrop applies SkImageFilter to the prior layer when copying to the layer;
Cary Clarkb7da7232017-09-01 13:49:54 -0400703 may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
Cary Clark8a02b0b2017-09-21 12:28:43 -0400704 prior layer without an SkImageFilter.
Cary Clarkb7da7232017-09-01 13:49:54 -0400705 */
706 const SkImageFilter* fBackdrop = nullptr;
707
Cary Clark8a02b0b2017-09-21 12:28:43 -0400708 /** restore() clips layer by the color alpha channel of fClipMask when
709 layer is copied to SkBaseDevice. fClipMask may be nullptr. .
Cary Clarkb7da7232017-09-01 13:49:54 -0400710 */
711 const SkImage* fClipMask = nullptr;
712
Cary Clark8a02b0b2017-09-21 12:28:43 -0400713 /** fClipMatrix transforms fClipMask before it clips layer. If
Cary Clarkb7da7232017-09-01 13:49:54 -0400714 fClipMask describes a translucent gradient, it may be scaled and rotated
715 without introducing artifacts. fClipMatrix may be nullptr.
716 */
717 const SkMatrix* fClipMatrix = nullptr;
718
Cary Clark8a02b0b2017-09-21 12:28:43 -0400719 /** fSaveLayerFlags are used to create layer without transparency,
720 create layer for LCD text, and to create layer with the
721 contents of the previous layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400722 */
723 SaveLayerFlags fSaveLayerFlags = 0;
724
reed4960eee2015-12-18 07:09:18 -0800725 };
726
Cary Clark75959392018-02-27 10:22:04 -0500727 /** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
Cary Clarkb7da7232017-09-01 13:49:54 -0400728 and allocates SkBitmap for subsequent drawing.
729
730 Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
Cary Clark8a02b0b2017-09-21 12:28:43 -0400731 and blends SkBitmap with color alpha opacity onto the prior layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400732
733 SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
734 setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
735 clipPath(), clipRegion().
736
Cary Clark8a02b0b2017-09-21 12:28:43 -0400737 SaveLayerRec contains the state used to create the layer.
Cary Clarkb7da7232017-09-01 13:49:54 -0400738
739 Call restoreToCount() with returned value to restore this and subsequent saves.
740
Cary Clark8a02b0b2017-09-21 12:28:43 -0400741 @param layerRec layer state
Cary Clarkb7da7232017-09-01 13:49:54 -0400742 @return depth of save state stack
743 */
Cary Clark0418a882017-05-10 09:07:42 -0400744 int saveLayer(const SaveLayerRec& layerRec);
reed4960eee2015-12-18 07:09:18 -0800745
Cary Clarkb7da7232017-09-01 13:49:54 -0400746 /** Removes changes to SkMatrix, clip, and SkDrawFilter since SkCanvas state was
747 last saved. The state is removed from the stack.
748
749 Does nothing if the stack is empty.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000750 */
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +0000751 void restore();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000752
Cary Clarkb7da7232017-09-01 13:49:54 -0400753 /** Returns the number of saved states, each containing: SkMatrix, clip, and SkDrawFilter.
754 Equals the number of save() calls less the number of restore() calls plus one.
755 The save count of a new canvas is one.
756
757 @return depth of save state stack
reed@android.com8a1c16f2008-12-17 15:59:43 +0000758 */
junov@chromium.orga907ac32012-02-24 21:54:07 +0000759 int getSaveCount() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000760
Cary Clarkb7da7232017-09-01 13:49:54 -0400761 /** Restores state to SkMatrix, clip, and SkDrawFilter values when save(), saveLayer(),
762 saveLayerPreserveLCDTextRequests(), or saveLayerAlpha() returned saveCount.
763
764 Does nothing if saveCount is greater than state stack count.
765 Restores state to initial values if saveCount is less than or equal to one.
766
767 @param saveCount depth of state stack to restore
reed@android.com8a1c16f2008-12-17 15:59:43 +0000768 */
769 void restoreToCount(int saveCount);
770
Cary Clarkb7da7232017-09-01 13:49:54 -0400771 /** Translate SkMatrix by dx along the x-axis and dy along the y-axis.
772
773 Mathematically, replace SkMatrix with a translation matrix
774 premultiplied with SkMatrix.
775
776 This has the effect of moving the drawing by (dx, dy) before transforming
777 the result with SkMatrix.
778
779 @param dx distance to translate in x
780 @param dy distance to translate in y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000781 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000782 void translate(SkScalar dx, SkScalar dy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000783
Cary Clarkb7da7232017-09-01 13:49:54 -0400784 /** Scale SkMatrix by sx on the x-axis and sy on the y-axis.
785
786 Mathematically, replace SkMatrix with a scale matrix
787 premultiplied with SkMatrix.
788
789 This has the effect of scaling the drawing by (sx, sy) before transforming
790 the result with SkMatrix.
791
792 @param sx amount to scale in x
793 @param sy amount to scale in y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000794 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000795 void scale(SkScalar sx, SkScalar sy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000796
Cary Clarkb7da7232017-09-01 13:49:54 -0400797 /** Rotate SkMatrix by degrees. Positive degrees rotates clockwise.
798
799 Mathematically, replace SkMatrix with a rotation matrix
800 premultiplied with SkMatrix.
801
802 This has the effect of rotating the drawing by degrees before transforming
803 the result with SkMatrix.
804
805 @param degrees amount to rotate, in degrees
reed@android.com8a1c16f2008-12-17 15:59:43 +0000806 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000807 void rotate(SkScalar degrees);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000808
Cary Clark8a02b0b2017-09-21 12:28:43 -0400809 /** Rotate SkMatrix by degrees about a point at (px, py). Positive degrees rotates
810 clockwise.
Cary Clarkb7da7232017-09-01 13:49:54 -0400811
Cary Clark8a02b0b2017-09-21 12:28:43 -0400812 Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
813 a translation matrix, then replace SkMatrix with the resulting matrix
Cary Clarkb7da7232017-09-01 13:49:54 -0400814 premultiplied with SkMatrix.
815
Cary Clark8a02b0b2017-09-21 12:28:43 -0400816 This has the effect of rotating the drawing about a given point before
817 transforming the result with SkMatrix.
Cary Clarkb7da7232017-09-01 13:49:54 -0400818
819 @param degrees amount to rotate, in degrees
Cary Clark8a02b0b2017-09-21 12:28:43 -0400820 @param px x-coordinate of the point to rotate about
821 @param py y-coordinate of the point to rotate about
bungeman7438bfc2016-07-12 15:01:19 -0700822 */
823 void rotate(SkScalar degrees, SkScalar px, SkScalar py);
824
Cary Clarkb7da7232017-09-01 13:49:54 -0400825 /** Skew SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
826 skews the drawing right as y increases; a positive value of sy skews the drawing
827 down as x increases.
828
829 Mathematically, replace SkMatrix with a skew matrix premultiplied with SkMatrix.
830
831 This has the effect of skewing the drawing by (sx, sy) before transforming
832 the result with SkMatrix.
833
834 @param sx amount to skew in x
835 @param sy amount to skew in y
reed@android.com8a1c16f2008-12-17 15:59:43 +0000836 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000837 void skew(SkScalar sx, SkScalar sy);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000838
Cary Clarkb7da7232017-09-01 13:49:54 -0400839 /** Replace SkMatrix with matrix premultiplied with existing SkMatrix.
840
841 This has the effect of transforming the drawn geometry by matrix, before
842 transforming the result with existing SkMatrix.
843
844 @param matrix matrix to premultiply with existing SkMatrix
reed@android.com8a1c16f2008-12-17 15:59:43 +0000845 */
commit-bot@chromium.org92362382014-03-18 12:51:48 +0000846 void concat(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000847
Cary Clarkb7da7232017-09-01 13:49:54 -0400848 /** Replace SkMatrix with matrix.
849 Unlike concat(), any prior matrix state is overwritten.
850
851 @param matrix matrix to copy, replacing existing SkMatrix
reed@android.com8a1c16f2008-12-17 15:59:43 +0000852 */
commit-bot@chromium.org44c48d02014-03-13 20:03:58 +0000853 void setMatrix(const SkMatrix& matrix);
reed@google.com4b226022011-01-11 18:32:13 +0000854
Cary Clarkb7da7232017-09-01 13:49:54 -0400855 /** Sets SkMatrix to the identity matrix.
856 Any prior matrix state is overwritten.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000857 */
858 void resetMatrix();
859
Cary Clarkb7da7232017-09-01 13:49:54 -0400860 /** Replace clip with the intersection or difference of clip and rect,
861 with an aliased or anti-aliased clip edge. rect is transformed by SkMatrix
862 before it is combined with clip.
863
864 @param rect SkRect to combine with clip
865 @param op SkClipOp to apply to clip
866 @param doAntiAlias true if clip is to be anti-aliased
867 */
Cary Clark0418a882017-05-10 09:07:42 -0400868 void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);
Cary Clarkb7da7232017-09-01 13:49:54 -0400869
870 /** Replace clip with the intersection or difference of clip and rect.
871 Resulting clip is aliased; pixels are fully contained by the clip.
872 rect is transformed by SkMatrix before it is combined with clip.
873
874 @param rect SkRect to combine with clip
875 @param op SkClipOp to apply to clip
876 */
Mike Reedc1f77742016-12-09 09:00:50 -0500877 void clipRect(const SkRect& rect, SkClipOp op) {
reed66998382016-09-21 11:15:07 -0700878 this->clipRect(rect, op, false);
879 }
Cary Clarkb7da7232017-09-01 13:49:54 -0400880
881 /** Replace clip with the intersection of clip and rect.
882 Resulting clip is aliased; pixels are fully contained by the clip.
883 rect is transformed by SkMatrix
884 before it is combined with clip.
885
886 @param rect SkRect to combine with clip
887 @param doAntiAlias true if clip is to be anti-aliased
888 */
reed66998382016-09-21 11:15:07 -0700889 void clipRect(const SkRect& rect, bool doAntiAlias = false) {
Mike Reed2dc52372016-12-14 14:00:03 -0500890 this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
reed66998382016-09-21 11:15:07 -0700891 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000892
Cary Clarkb7da7232017-09-01 13:49:54 -0400893 /** Sets the maximum clip rectangle, which can be set by clipRect(), clipRRect() and
894 clipPath() and intersect the current clip with the specified rect.
895 The maximum clip affects only future clipping operations; it is not retroactive.
896 The clip restriction is not recorded in pictures.
897
898 Pass an empty rect to disable maximum clip.
899 This is private API to be used only by Android framework.
900
901 @param rect maximum allowed clip in device coordinates
902 */
Stan Iliev5f1bb0a2016-12-12 17:39:55 -0500903 void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
904
Cary Clarkb7da7232017-09-01 13:49:54 -0400905 /** Replace clip with the intersection or difference of clip and rrect,
906 with an aliased or anti-aliased clip edge.
907 rrect is transformed by SkMatrix
908 before it is combined with clip.
909
910 @param rrect SkRRect to combine with clip
911 @param op SkClipOp to apply to clip
912 @param doAntiAlias true if clip is to be anti-aliased
913 */
Mike Reedc1f77742016-12-09 09:00:50 -0500914 void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
Cary Clarkb7da7232017-09-01 13:49:54 -0400915
916 /** Replace clip with the intersection or difference of clip and rrect.
917 Resulting clip is aliased; pixels are fully contained by the clip.
918 rrect is transformed by SkMatrix before it is combined with clip.
919
920 @param rrect SkRRect to combine with clip
921 @param op SkClipOp to apply to clip
922 */
Mike Reedc1f77742016-12-09 09:00:50 -0500923 void clipRRect(const SkRRect& rrect, SkClipOp op) {
reed66998382016-09-21 11:15:07 -0700924 this->clipRRect(rrect, op, false);
925 }
Cary Clarkb7da7232017-09-01 13:49:54 -0400926
927 /** Replace clip with the intersection of clip and rrect,
928 with an aliased or anti-aliased clip edge.
929 rrect is transformed by SkMatrix before it is combined with clip.
930
931 @param rrect SkRRect to combine with clip
932 @param doAntiAlias true if clip is to be anti-aliased
933 */
reed66998382016-09-21 11:15:07 -0700934 void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
Mike Reed2dc52372016-12-14 14:00:03 -0500935 this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
reed66998382016-09-21 11:15:07 -0700936 }
reed@google.com4ed0fb72012-12-12 20:48:18 +0000937
Cary Clarkb7da7232017-09-01 13:49:54 -0400938 /** Replace clip with the intersection or difference of clip and path,
939 with an aliased or anti-aliased clip edge. SkPath::FillType determines if path
940 describes the area inside or outside its contours; and if path contour overlaps
941 itself or another path contour, whether the overlaps form part of the area.
942 path is transformed by SkMatrix before it is combined with clip.
943
944 @param path SkPath to combine with clip
945 @param op SkClipOp to apply to clip
946 @param doAntiAlias true if clip is to be anti-aliased
947 */
Mike Reedc1f77742016-12-09 09:00:50 -0500948 void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
Cary Clarkb7da7232017-09-01 13:49:54 -0400949
950 /** Replace clip with the intersection or difference of clip and path.
951 Resulting clip is aliased; pixels are fully contained by the clip.
952 SkPath::FillType determines if path
953 describes the area inside or outside its contours; and if path contour overlaps
954 itself or another path contour, whether the overlaps form part of the area.
955 path is transformed by SkMatrix
956 before it is combined with clip.
957
958 @param path SkPath to combine with clip
959 @param op SkClipOp to apply to clip
960 */
Mike Reedc1f77742016-12-09 09:00:50 -0500961 void clipPath(const SkPath& path, SkClipOp op) {
reed66998382016-09-21 11:15:07 -0700962 this->clipPath(path, op, false);
963 }
Cary Clarkb7da7232017-09-01 13:49:54 -0400964
965 /** Replace clip with the intersection of clip and path.
966 Resulting clip is aliased; pixels are fully contained by the clip.
967 SkPath::FillType determines if path
968 describes the area inside or outside its contours; and if path contour overlaps
969 itself or another path contour, whether the overlaps form part of the area.
970 path is transformed by SkMatrix before it is combined with clip.
971
972 @param path SkPath to combine with clip
973 @param doAntiAlias true if clip is to be anti-aliased
974 */
reed66998382016-09-21 11:15:07 -0700975 void clipPath(const SkPath& path, bool doAntiAlias = false) {
Mike Reed2dc52372016-12-14 14:00:03 -0500976 this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
reed66998382016-09-21 11:15:07 -0700977 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000978
Cary Clarkb7da7232017-09-01 13:49:54 -0400979 /** EXPERIMENTAL: Only used for testing.
980 Set to simplify clip stack using PathOps.
981 */
caryclark@google.com45a75fb2013-04-25 13:34:40 +0000982 void setAllowSimplifyClip(bool allow) {
983 fAllowSimplifyClip = allow;
984 }
985
Cary Clarkb7da7232017-09-01 13:49:54 -0400986 /** Replace clip with the intersection or difference of clip and SkRegion deviceRgn.
987 Resulting clip is aliased; pixels are fully contained by the clip.
988 deviceRgn is unaffected by SkMatrix.
989
990 @param deviceRgn SkRegion to combine with clip
991 @param op SkClipOp to apply to clip
reed@android.com8a1c16f2008-12-17 15:59:43 +0000992 */
Mike Reed2dc52372016-12-14 14:00:03 -0500993 void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000994
Cary Clarkb7da7232017-09-01 13:49:54 -0400995 /** Return true if SkRect rect, transformed by SkMatrix, can be quickly determined to be
996 outside of clip. May return false even though rect is outside of clip.
997
998 Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
999
1000 @param rect SkRect to compare with clip
1001 @return true if rect, transformed by SkMatrix, does not intersect clip
reed@android.com8a1c16f2008-12-17 15:59:43 +00001002 */
reed@google.com3b3e8952012-08-16 20:53:31 +00001003 bool quickReject(const SkRect& rect) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001004
Cary Clarkb7da7232017-09-01 13:49:54 -04001005 /** Return true if path, transformed by SkMatrix, can be quickly determined to be
1006 outside of clip. May return false even though path is outside of clip.
1007
1008 Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
1009
1010 @param path SkPath to compare with clip
1011 @return true if path, transformed by SkMatrix, does not intersect clip
reed@android.com8a1c16f2008-12-17 15:59:43 +00001012 */
reed@google.com3b3e8952012-08-16 20:53:31 +00001013 bool quickReject(const SkPath& path) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001014
Cary Clarkb7da7232017-09-01 13:49:54 -04001015 /** Return bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1016 return SkRect::MakeEmpty, where all SkRect sides equal zero.
1017
1018 SkRect returned is outset by one to account for partial pixel coverage if clip
1019 is anti-aliased.
1020
1021 @return bounds of clip in local coordinates
1022 */
Mike Klein83c8dd92017-11-28 17:08:45 -05001023 SkRect getLocalClipBounds() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00001024
Cary Clarkb7da7232017-09-01 13:49:54 -04001025 /** Return bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1026 return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1027
1028 bounds is outset by one to account for partial pixel coverage if clip
1029 is anti-aliased.
1030
1031 @param bounds SkRect of clip in local coordinates
1032 @return true if clip bounds is not empty
1033 */
Mike Reed6f4a9b22017-01-24 09:13:40 -05001034 bool getLocalClipBounds(SkRect* bounds) const {
Mike Klein83c8dd92017-11-28 17:08:45 -05001035 *bounds = this->getLocalClipBounds();
Mike Reed6f4a9b22017-01-24 09:13:40 -05001036 return !bounds->isEmpty();
1037 }
1038
Cary Clarkb7da7232017-09-01 13:49:54 -04001039 /** Return SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1040 return SkRect::MakeEmpty, where all SkRect sides equal zero.
1041
1042 Unlike getLocalClipBounds(), returned SkIRect is not outset.
1043
1044 @return bounds of clip in SkBaseDevice coordinates
1045 */
Mike Klein83c8dd92017-11-28 17:08:45 -05001046 SkIRect getDeviceClipBounds() const;
Mike Reed42e8c532017-01-23 14:09:13 -05001047
Cary Clarkb7da7232017-09-01 13:49:54 -04001048 /** Return SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1049 return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1050
1051 Unlike getLocalClipBounds(), bounds is not outset.
1052
1053 @param bounds SkRect of clip in device coordinates
1054 @return true if clip bounds is not empty
1055 */
Mike Reed6f4a9b22017-01-24 09:13:40 -05001056 bool getDeviceClipBounds(SkIRect* bounds) const {
Mike Klein83c8dd92017-11-28 17:08:45 -05001057 *bounds = this->getDeviceClipBounds();
Mike Reed6f4a9b22017-01-24 09:13:40 -05001058 return !bounds->isEmpty();
1059 }
1060
Cary Clarkb7da7232017-09-01 13:49:54 -04001061 /** Fill clip with color color.
1062 mode determines how ARGB is combined with destination.
1063
Cary Clark8a02b0b2017-09-21 12:28:43 -04001064 @param color unpremultiplied ARGB
Cary Clarkb7da7232017-09-01 13:49:54 -04001065 @param mode SkBlendMode used to combine source color and destination
reed@android.com8a1c16f2008-12-17 15:59:43 +00001066 */
reed374772b2016-10-05 17:33:02 -07001067 void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001068
Cary Clarkb7da7232017-09-01 13:49:54 -04001069 /** Fill clip with color color using SkBlendMode::kSrc.
1070 This has the effect of replacing all pixels contained by clip with color.
1071
Cary Clark8a02b0b2017-09-21 12:28:43 -04001072 @param color unpremultiplied ARGB
Cary Clarkb7da7232017-09-01 13:49:54 -04001073 */
reedf4e0d9e2014-12-05 20:49:03 -08001074 void clear(SkColor color) {
reed374772b2016-10-05 17:33:02 -07001075 this->drawColor(color, SkBlendMode::kSrc);
reed8eddfb52014-12-04 07:50:14 -08001076 }
reed@google.com2a981812011-04-14 18:59:28 +00001077
Cary Clarkb7da7232017-09-01 13:49:54 -04001078 /** Make SkCanvas contents undefined. Subsequent calls that read SkCanvas pixels,
1079 such as drawing with SkBlendMode, return undefined results. discard() does
1080 not change clip or SkMatrix.
1081
1082 discard() may do nothing, depending on the implementation of SkSurface or SkBaseDevice
1083 that created SkCanvas.
1084
1085 discard() allows optimized performance on subsequent draws by removing
1086 cached data associated with SkSurface or SkBaseDevice.
1087 It is not necessary to call discard() once done with SkCanvas;
1088 any cached data is deleted when owning SkSurface or SkBaseDevice is deleted.
1089 */
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +00001090 void discard() { this->onDiscard(); }
1091
Mike Reed8ad91a92018-01-19 19:09:32 -05001092 /** Fill clip with SkPaint paint. SkPaint components SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001093 SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
1094 SkPathEffect in paint is ignored.
1095
1096 @param paint graphics state used to fill SkCanvas
1097 */
reed0846f1b2015-01-09 14:17:40 -08001098 void drawPaint(const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001099
Cary Clarkb7da7232017-09-01 13:49:54 -04001100 /** \enum SkCanvas::PointMode
1101 Selects if an array of points are drawn as discrete points, as lines, or as
1102 an open polygon.
1103 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00001104 enum PointMode {
Cary Clarkb7da7232017-09-01 13:49:54 -04001105 kPoints_PointMode, //!< Draw each point separately.
1106 kLines_PointMode, //!< Draw each pair of points as a line segment.
1107 kPolygon_PointMode, //!< Draw the array of points as a open polygon.
reed@android.com8a1c16f2008-12-17 15:59:43 +00001108 };
1109
Cary Clarkb7da7232017-09-01 13:49:54 -04001110 /** Draw pts using clip, SkMatrix and SkPaint paint.
1111 count is the number of points; if count is less than one, has no effect.
1112 mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
1113
1114 If mode is kPoints_PointMode, the shape of point drawn depends on paint
1115 SkPaint::Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
1116 circle of diameter SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap
1117 or SkPaint::kButt_Cap, each point draws a square of width and height
1118 SkPaint stroke width.
1119
1120 If mode is kLines_PointMode, each pair of points draws a line segment.
1121 One line is drawn for every two points; each point is used once. If count is odd,
1122 the final point is ignored.
1123
1124 If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
1125 count minus one lines are drawn; the first and last point are used once.
1126
1127 Each line segment respects paint SkPaint::Cap and SkPaint stroke width.
1128 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1129
1130 Always draws each element one at a time; is not affected by
1131 SkPaint::Join, and unlike drawPath(), does not create a mask from all points
1132 and lines before drawing.
1133
1134 @param mode whether pts draws points or lines
1135 @param count number of points in the array
1136 @param pts array of points to draw
1137 @param paint stroke, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001138 */
reed0846f1b2015-01-09 14:17:40 -08001139 void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001140
Cary Clarkb7da7232017-09-01 13:49:54 -04001141 /** Draw point at (x, y) using clip, SkMatrix and SkPaint paint.
1142
1143 The shape of point drawn depends on paint SkPaint::Cap.
1144 If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1145 SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1146 draw a square of width and height SkPaint stroke width.
1147 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1148
1149 @param x left edge of circle or square
1150 @param y top edge of circle or square
1151 @param paint stroke, blend, color, and so on, used to draw
1152 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00001153 void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001154
1155 /** Draw point p using clip, SkMatrix and SkPaint paint.
1156
1157 The shape of point drawn depends on paint SkPaint::Cap.
1158 If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1159 SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1160 draw a square of width and height SkPaint stroke width.
1161 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1162
1163 @param p top-left edge of circle or square
1164 @param paint stroke, blend, color, and so on, used to draw
1165 */
Hal Canary23e474c2017-05-15 13:35:35 -04001166 void drawPoint(SkPoint p, const SkPaint& paint) {
1167 this->drawPoint(p.x(), p.y(), paint);
1168 }
reed@google.com4b226022011-01-11 18:32:13 +00001169
Cary Clarkb7da7232017-09-01 13:49:54 -04001170 /** Draws line segment from (x0, y0) to (x1, y1) using clip, SkMatrix, and SkPaint paint.
1171 In paint: SkPaint stroke width describes the line thickness;
1172 SkPaint::Cap draws the end rounded or square;
1173 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1174
1175 @param x0 start of line segment on x-axis
1176 @param y0 start of line segment on y-axis
1177 @param x1 end of line segment on x-axis
1178 @param y1 end of line segment on y-axis
1179 @param paint stroke, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001180 */
Mike Reed3661bc92017-02-22 13:21:42 -05001181 void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001182
1183 /** Draws line segment from p0 to p1 using clip, SkMatrix, and SkPaint paint.
1184 In paint: SkPaint stroke width describes the line thickness;
1185 SkPaint::Cap draws the end rounded or square;
1186 SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1187
1188 @param p0 start of line segment
1189 @param p1 end of line segment
1190 @param paint stroke, blend, color, and so on, used to draw
1191 */
Hal Canary23e474c2017-05-15 13:35:35 -04001192 void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
1193 this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
1194 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00001195
Cary Clarkb7da7232017-09-01 13:49:54 -04001196 /** Draw SkRect rect using clip, SkMatrix, and SkPaint paint.
1197 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1198 if stroked, SkPaint stroke width describes the line thickness, and
1199 SkPaint::Join draws the corners rounded or square.
1200
Cary Clarkcc309eb2017-10-30 11:48:35 -04001201 @param rect rectangle to draw
Cary Clarkb7da7232017-09-01 13:49:54 -04001202 @param paint stroke or fill, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001203 */
reed0846f1b2015-01-09 14:17:40 -08001204 void drawRect(const SkRect& rect, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001205
Cary Clarkb7da7232017-09-01 13:49:54 -04001206 /** Draw SkIRect rect using clip, SkMatrix, and SkPaint paint.
1207 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1208 if stroked, SkPaint stroke width describes the line thickness, and
1209 SkPaint::Join draws the corners rounded or square.
1210
Cary Clarkcc309eb2017-10-30 11:48:35 -04001211 @param rect rectangle to draw
Cary Clarkb7da7232017-09-01 13:49:54 -04001212 @param paint stroke or fill, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001213 */
reed@google.com87001ed2014-02-17 16:28:05 +00001214 void drawIRect(const SkIRect& rect, const SkPaint& paint) {
reed@android.com8a1c16f2008-12-17 15:59:43 +00001215 SkRect r;
1216 r.set(rect); // promotes the ints to scalars
1217 this->drawRect(r, paint);
1218 }
reed@google.com4b226022011-01-11 18:32:13 +00001219
Cary Clarkb7da7232017-09-01 13:49:54 -04001220 /** Draw SkRegion region using clip, SkMatrix, and SkPaint paint.
1221 In paint: SkPaint::Style determines if rectangle is stroked or filled;
1222 if stroked, SkPaint stroke width describes the line thickness, and
1223 SkPaint::Join draws the corners rounded or square.
1224
Cary Clarkcc309eb2017-10-30 11:48:35 -04001225 @param region region to draw
Cary Clarkb7da7232017-09-01 13:49:54 -04001226 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
msarett44df6512016-08-25 13:54:30 -07001227 */
msarettdca352e2016-08-26 06:37:45 -07001228 void drawRegion(const SkRegion& region, const SkPaint& paint);
msarett44df6512016-08-25 13:54:30 -07001229
Cary Clarkb7da7232017-09-01 13:49:54 -04001230 /** Draw oval oval using clip, SkMatrix, and SkPaint.
1231 In paint: SkPaint::Style determines if oval is stroked or filled;
1232 if stroked, SkPaint stroke width describes the line thickness.
1233
1234 @param oval SkRect bounds of oval
1235 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001236 */
Cary Clark304f9d42017-05-13 13:35:35 -04001237 void drawOval(const SkRect& oval, const SkPaint& paint);
reed@google.com4ed0fb72012-12-12 20:48:18 +00001238
Cary Clarkb7da7232017-09-01 13:49:54 -04001239 /** Draw SkRRect rrect using clip, SkMatrix, and SkPaint paint.
1240 In paint: SkPaint::Style determines if rrect is stroked or filled;
1241 if stroked, SkPaint stroke width describes the line thickness.
1242
1243 rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
1244 may have any combination of positive non-square radii for the four corners.
1245
1246 @param rrect SkRRect with up to eight corner radii to draw
1247 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1248 */
reed0846f1b2015-01-09 14:17:40 -08001249 void drawRRect(const SkRRect& rrect, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001250
Cary Clarkb7da7232017-09-01 13:49:54 -04001251 /** Draw SkRRect outer and inner
1252 using clip, SkMatrix, and SkPaint paint.
1253 outer must contain inner or the drawing is undefined.
1254 In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1255 if stroked, SkPaint stroke width describes the line thickness.
1256 If stroked and SkRRect corner has zero length radii, SkPaint::Join can
1257 draw corners rounded or square.
1258
1259 GPU-backed platforms optimize drawing when both outer and inner are
1260 concave and outer contains inner. These platforms may not be able to draw
1261 SkPath built with identical data as fast.
1262
1263 @param outer SkRRect outer bounds to draw
1264 @param inner SkRRect inner bounds to draw
1265 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1266 */
Cary Clark304f9d42017-05-13 13:35:35 -04001267 void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
commit-bot@chromium.orged9806f2014-02-21 02:32:36 +00001268
Cary Clarkb7da7232017-09-01 13:49:54 -04001269 /** Draw circle at (cx, cy) with radius using clip, SkMatrix, and SkPaint paint.
1270 If radius is zero or less, nothing is drawn.
1271 In paint: SkPaint::Style determines if circle is stroked or filled;
1272 if stroked, SkPaint stroke width describes the line thickness.
1273
Cary Clark8a02b0b2017-09-21 12:28:43 -04001274 @param cx circle center on the x-axis
1275 @param cy circle center on the y-axis
Cary Clarkb7da7232017-09-01 13:49:54 -04001276 @param radius half the diameter of circle
1277 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001278 */
Mike Reed3661bc92017-02-22 13:21:42 -05001279 void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001280
1281 /** Draw circle at center with radius using clip, SkMatrix, and SkPaint paint.
1282 If radius is zero or less, nothing is drawn.
1283 In paint: SkPaint::Style determines if circle is stroked or filled;
1284 if stroked, SkPaint stroke width describes the line thickness.
1285
Cary Clark8a02b0b2017-09-21 12:28:43 -04001286 @param center circle center
Cary Clarkb7da7232017-09-01 13:49:54 -04001287 @param radius half the diameter of circle
1288 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
1289 */
Hal Canary23e474c2017-05-15 13:35:35 -04001290 void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
1291 this->drawCircle(center.x(), center.y(), radius, paint);
1292 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00001293
Cary Clarkb7da7232017-09-01 13:49:54 -04001294 /** Draw arc using clip, SkMatrix, and SkPaint paint.
1295
1296 Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
1297 sweepAngle. startAngle and sweepAngle are in degrees.
1298
1299 startAngle of zero places start point at the right middle edge of oval.
1300 A positive sweepAngle places arc end point clockwise from start point;
1301 a negative sweepAngle places arc end point counterclockwise from start point.
1302 sweepAngle may exceed 360 degrees, a full circle.
1303 If useCenter is true, draw a wedge that includes lines from oval
1304 center to arc end points. If useCenter is false, draw arc between end points.
1305
1306 If SkRect oval is empty or sweepAngle is zero, nothing is drawn.
1307
1308 @param oval SkRect bounds of oval containing arc to draw
1309 @param startAngle angle in degrees where arc begins
1310 @param sweepAngle sweep angle in degrees; positive is clockwise
1311 @param useCenter if true, include the center of the oval
1312 @param paint SkPaint stroke or fill, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001313 */
1314 void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1315 bool useCenter, const SkPaint& paint);
1316
Cary Clarkb7da7232017-09-01 13:49:54 -04001317 /** Draw SkRRect bounded by SkRect rect, with corner radii (rx, ry) using clip,
1318 SkMatrix, and SkPaint paint.
1319
1320 In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1321 if stroked, SkPaint stroke width describes the line thickness.
1322 If rx or ry are less than zero, they are treated as if they are zero.
1323 If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
1324 If rx and ry are zero, SkRRect is drawn as SkRect and if stroked is affected by
1325 SkPaint::Join.
1326
1327 @param rect SkRect bounds of SkRRect to draw
1328 @param rx axis length in x of oval describing rounded corners
1329 @param ry axis length in y of oval describing rounded corners
1330 @param paint stroke, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001331 */
Mike Reed3661bc92017-02-22 13:21:42 -05001332 void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001333
Cary Clarkb7da7232017-09-01 13:49:54 -04001334 /** Draw SkPath path using clip, SkMatrix, and SkPaint paint.
1335 SkPath contains an array of path contour, each of which may be open or closed.
1336
1337 In paint: SkPaint::Style determines if SkRRect is stroked or filled:
1338 if filled, SkPath::FillType determines whether path contour describes inside or
1339 outside of fill; if stroked, SkPaint stroke width describes the line thickness,
1340 SkPaint::Cap describes line ends, and SkPaint::Join describes how
1341 corners are drawn.
1342
1343 @param path SkPath to draw
1344 @param paint stroke, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001345 */
reed0846f1b2015-01-09 14:17:40 -08001346 void drawPath(const SkPath& path, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001347
Cary Clarkb7da7232017-09-01 13:49:54 -04001348 /** Draw SkImage image, with its top-left corner at (left, top),
1349 using clip, SkMatrix, and optional SkPaint paint.
piotaixrd52893c2014-09-25 14:39:40 -07001350
Cary Clarkb7da7232017-09-01 13:49:54 -04001351 If paint is supplied, apply SkColorFilter, color alpha, SkImageFilter, SkBlendMode,
1352 and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1353 If paint contains SkMaskFilter, generate mask from image bounds. If generated
1354 mask extends beyond image bounds, replicate image edge colors, just as SkShader
1355 made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkcc309eb2017-10-30 11:48:35 -04001356 image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001357
1358 @param image uncompressed rectangular map of pixels
1359 @param left left side of image
1360 @param top top side of image
1361 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1362 and so on; or nullptr
1363 */
Ben Wagnera93a14a2017-08-28 10:34:05 -04001364 void drawImage(const SkImage* image, SkScalar left, SkScalar top,
1365 const SkPaint* paint = nullptr);
Cary Clarkb7da7232017-09-01 13:49:54 -04001366
1367 /** Draw SkImage image, with its top-left corner at (left, top),
1368 using clip, SkMatrix, and optional SkPaint paint.
1369
1370 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1371 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1372 If paint contains SkMaskFilter, generate mask from image bounds. If generated
1373 mask extends beyond image bounds, replicate image edge colors, just as SkShader
1374 made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
Cary Clarkcc309eb2017-10-30 11:48:35 -04001375 image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001376
1377 @param image uncompressed rectangular map of pixels
1378 @param left left side of image
1379 @param top pop side of image
1380 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1381 and so on; or nullptr
1382 */
reedf8053da2016-03-17 08:14:57 -07001383 void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
Ben Wagnera93a14a2017-08-28 10:34:05 -04001384 const SkPaint* paint = nullptr) {
reedf8053da2016-03-17 08:14:57 -07001385 this->drawImage(image.get(), left, top, paint);
1386 }
piotaixrb5fae932014-09-24 13:03:30 -07001387
Cary Clarkb7da7232017-09-01 13:49:54 -04001388 /** \enum SkCanvas::SrcRectConstraint
1389 SrcRectConstraint controls the behavior at the edge of source SkRect,
1390 provided to drawImageRect(), trading off speed for precision.
1391
1392 SkImageFilter in SkPaint may sample multiple pixels in the image. Source SkRect
1393 restricts the bounds of pixels that may be read. SkImageFilter may slow down if
1394 it cannot read outside the bounds, when sampling near the edge of source SkRect.
1395 SrcRectConstraint specifies whether an SkImageFilter is allowed to read pixels
1396 outside source SkRect.
1397 */
reeda5517e22015-07-14 10:54:12 -07001398 enum SrcRectConstraint {
Cary Clarkb7da7232017-09-01 13:49:54 -04001399 /** sampling only inside of its bounds, possibly with a performance penalty. */
reeda5517e22015-07-14 10:54:12 -07001400 kStrict_SrcRectConstraint,
1401
Cary Clarkb7da7232017-09-01 13:49:54 -04001402 /** by half the width of SkImageFilter, permitting it to run faster but with
1403 error at the image edges.
1404 */
reeda5517e22015-07-14 10:54:12 -07001405 kFast_SrcRectConstraint,
1406 };
1407
Cary Clarkb7da7232017-09-01 13:49:54 -04001408 /** Draw SkRect src of SkImage image, scaled and translated to fill SkRect dst.
1409 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1410
1411 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1412 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1413 If paint contains SkMaskFilter, generate mask from image bounds.
1414
1415 If generated mask extends beyond image bounds, replicate image edge colors, just
1416 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001417 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001418
1419 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1420 sample within src; set to kFast_SrcRectConstraint allows sampling outside to
1421 improve performance.
1422
1423 @param image SkImage containing pixels, dimensions, and format
1424 @param src source SkRect of image to draw from
1425 @param dst destination SkRect of image to draw to
1426 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1427 and so on; or nullptr
1428 @param constraint filter strictly within src or draw faster
1429 */
reede47829b2015-08-06 10:02:53 -07001430 void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
1431 const SkPaint* paint,
1432 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001433
1434 /** Draw SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
1435 Note that isrc is on integer pixel boundaries; dst may include fractional
1436 boundaries. Additionally transform draw using clip, SkMatrix, and optional SkPaint
1437 paint.
1438
1439 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1440 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1441 If paint contains SkMaskFilter, generate mask from image bounds.
1442
1443 If generated mask extends beyond image bounds, replicate image edge colors, just
1444 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001445 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001446
1447 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1448 sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
1449 improve performance.
1450
1451 @param image SkImage containing pixels, dimensions, and format
1452 @param isrc source SkIRect of image to draw from
1453 @param dst destination SkRect of image to draw to
1454 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1455 and so on; or nullptr
1456 @param constraint filter strictly within isrc or draw faster
1457 */
reede47829b2015-08-06 10:02:53 -07001458 void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
Cary Clark0418a882017-05-10 09:07:42 -04001459 const SkPaint* paint,
1460 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001461
1462 /** Draw SkImage image, scaled and translated to fill SkRect dst, using clip, SkMatrix,
1463 and optional SkPaint paint.
1464
1465 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1466 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1467 If paint contains SkMaskFilter, generate mask from image bounds.
1468
1469 If generated mask extends beyond image bounds, replicate image edge colors, just
1470 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001471 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001472
1473 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1474 sample within image; set to kFast_SrcRectConstraint allows sampling outside to
1475 improve performance.
1476
1477 @param image SkImage containing pixels, dimensions, and format
1478 @param dst destination SkRect of image to draw to
1479 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1480 and so on; or nullptr
1481 @param constraint filter strictly within image or draw faster
1482 */
reede47829b2015-08-06 10:02:53 -07001483 void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
Cary Clark0418a882017-05-10 09:07:42 -04001484 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
reed84984ef2015-07-17 07:09:43 -07001485
Cary Clarkb7da7232017-09-01 13:49:54 -04001486 /** Draw SkRect src of SkImage image, scaled and translated to fill SkRect dst.
1487 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1488
1489 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1490 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1491 If paint contains SkMaskFilter, generate mask from image bounds.
1492
1493 If generated mask extends beyond image bounds, replicate image edge colors, just
1494 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001495 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001496
1497 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1498 sample within src; set to kFast_SrcRectConstraint allows sampling outside to
1499 improve performance.
1500
1501 @param image SkImage containing pixels, dimensions, and format
1502 @param src source SkRect of image to draw from
1503 @param dst destination SkRect of image to draw to
1504 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1505 and so on; or nullptr
1506 @param constraint filter strictly within src or draw faster
1507 */
reedf8053da2016-03-17 08:14:57 -07001508 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
1509 const SkPaint* paint,
1510 SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
1511 this->drawImageRect(image.get(), src, dst, paint, constraint);
1512 }
Cary Clarkb7da7232017-09-01 13:49:54 -04001513
1514 /** Draw SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
1515 isrc is on integer pixel boundaries; dst may include fractional boundaries.
1516 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1517
1518 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1519 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1520 If paint contains SkMaskFilter, generate mask from image bounds.
1521
1522 If generated mask extends beyond image bounds, replicate image edge colors, just
1523 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001524 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001525
1526 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1527 sample within image; set to kFast_SrcRectConstraint allows sampling outside to
1528 improve performance.
1529
1530 @param image SkImage containing pixels, dimensions, and format
1531 @param isrc source SkIRect of image to draw from
1532 @param dst destination SkRect of image to draw to
1533 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1534 and so on; or nullptr
1535 @param constraint filter strictly within image or draw faster
1536 */
reedf8053da2016-03-17 08:14:57 -07001537 void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
Ben Wagner63fd7602017-10-09 15:45:33 -04001538 const SkPaint* paint,
Cary Clark0418a882017-05-10 09:07:42 -04001539 SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
1540 this->drawImageRect(image.get(), isrc, dst, paint, constraint);
reedf8053da2016-03-17 08:14:57 -07001541 }
Cary Clarkb7da7232017-09-01 13:49:54 -04001542
1543 /** Draw SkImage image, scaled and translated to fill SkRect dst,
1544 using clip, SkMatrix, and optional SkPaint paint.
1545
1546 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1547 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1548 If paint contains SkMaskFilter, generate mask from image bounds.
1549
1550 If generated mask extends beyond image bounds, replicate image edge colors, just
1551 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001552 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001553
1554 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1555 sample within image; set to kFast_SrcRectConstraint allows sampling outside to
1556 improve performance.
1557
1558 @param image SkImage containing pixels, dimensions, and format
1559 @param dst destination SkRect of image to draw to
1560 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1561 and so on; or nullptr
1562 @param constraint filter strictly within image or draw faster
1563 */
reedf8053da2016-03-17 08:14:57 -07001564 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
Cary Clark0418a882017-05-10 09:07:42 -04001565 SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
1566 this->drawImageRect(image.get(), dst, paint, constraint);
reedf8053da2016-03-17 08:14:57 -07001567 }
1568
Cary Clark8a02b0b2017-09-21 12:28:43 -04001569 /** Draw SkImage image stretched proportionally to fit into SkRect dst.
Cary Clarkb7da7232017-09-01 13:49:54 -04001570 SkIRect center divides the image into nine sections: four sides, four corners, and
1571 the center. Corners are unmodified or scaled down proportionately if their sides
1572 are larger than dst; center and four sides are scaled to fit remaining space, if any.
1573
1574 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1575
1576 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1577 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1578 If paint contains SkMaskFilter, generate mask from image bounds.
1579
1580 If generated mask extends beyond image bounds, replicate image edge colors, just
1581 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001582 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001583
1584 @param image SkImage containing pixels, dimensions, and format
1585 @param center SkIRect edge of image corners and sides
1586 @param dst destination SkRect of image to draw to
1587 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1588 and so on; or nullptr
1589 */
Cary Clark0418a882017-05-10 09:07:42 -04001590 void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
reedf8053da2016-03-17 08:14:57 -07001591 const SkPaint* paint = nullptr);
Cary Clarkb7da7232017-09-01 13:49:54 -04001592
Cary Clark8a02b0b2017-09-21 12:28:43 -04001593 /** Draw SkImage image stretched proportionally to fit into SkRect dst.
Cary Clarkb7da7232017-09-01 13:49:54 -04001594 SkIRect center divides the image into nine sections: four sides, four corners, and
1595 the center. Corners are not scaled, or scaled down proportionately if their sides
1596 are larger than dst; center and four sides are scaled to fit remaining space, if any.
1597
1598 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1599
1600 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1601 SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
1602 If paint contains SkMaskFilter, generate mask from image bounds.
1603
1604 If generated mask extends beyond image bounds, replicate image edge colors, just
1605 as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
Cary Clarkcc309eb2017-10-30 11:48:35 -04001606 replicates the image edge color when it samples outside of its bounds.
Cary Clarkb7da7232017-09-01 13:49:54 -04001607
1608 @param image SkImage containing pixels, dimensions, and format
1609 @param center SkIRect edge of image corners and sides
1610 @param dst destination SkRect of image to draw to
1611 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1612 and so on; or nullptr
1613 */
reedf8053da2016-03-17 08:14:57 -07001614 void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
1615 const SkPaint* paint = nullptr) {
1616 this->drawImageNine(image.get(), center, dst, paint);
1617 }
reed4c21dc52015-06-25 12:32:03 -07001618
Cary Clarkb7da7232017-09-01 13:49:54 -04001619 /** Draw SkBitmap bitmap, with its top-left corner at (left, top),
1620 using clip, SkMatrix, and optional SkPaint paint.
commit-bot@chromium.org91246b92013-12-05 15:43:19 +00001621
Cary Clark2823f9f2018-01-03 10:00:34 -05001622 If SkPaint paint is not nullptr, apply SkColorFilter, color alpha, SkImageFilter,
Cary Clarkb7da7232017-09-01 13:49:54 -04001623 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1624 If paint contains SkMaskFilter, generate mask from bitmap bounds.
commit-bot@chromium.org91246b92013-12-05 15:43:19 +00001625
Cary Clarkb7da7232017-09-01 13:49:54 -04001626 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1627 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001628 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001629 outside of its bounds.
1630
1631 @param bitmap SkBitmap containing pixels, dimensions, and format
1632 @param left left side of bitmap
1633 @param top top side of bitmap
1634 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1635 and so on; or nullptr
reed@android.com8a1c16f2008-12-17 15:59:43 +00001636 */
reed0846f1b2015-01-09 14:17:40 -08001637 void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
Ben Wagnera93a14a2017-08-28 10:34:05 -04001638 const SkPaint* paint = nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001639
Cary Clarkb7da7232017-09-01 13:49:54 -04001640 /** Draw SkRect src of SkBitmap bitmap, scaled and translated to fill SkRect dst.
1641 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1642
1643 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1644 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1645 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1646
1647 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1648 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001649 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001650 outside of its bounds.
1651
1652 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1653 sample within src; set to kFast_SrcRectConstraint allows sampling outside to
1654 improve performance.
1655
1656 @param bitmap SkBitmap containing pixels, dimensions, and format
1657 @param src source SkRect of image to draw from
1658 @param dst destination SkRect of image to draw to
1659 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1660 and so on; or nullptr
1661 @param constraint filter strictly within src or draw faster
1662 */
reede47829b2015-08-06 10:02:53 -07001663 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
Cary Clark0418a882017-05-10 09:07:42 -04001664 const SkPaint* paint,
1665 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001666
1667 /** Draw SkIRect isrc of SkBitmap bitmap, scaled and translated to fill SkRect dst.
1668 isrc is on integer pixel boundaries; dst may include fractional boundaries.
1669 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1670
1671 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1672 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1673 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1674
1675 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1676 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001677 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001678 outside of its bounds.
1679
1680 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1681 sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
1682 improve performance.
1683
1684 @param bitmap SkBitmap containing pixels, dimensions, and format
1685 @param isrc source SkIRect of image to draw from
1686 @param dst destination SkRect of image to draw to
1687 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1688 and so on; or nullptr
1689 @param constraint sample strictly within isrc, or draw faster
1690 */
reed84984ef2015-07-17 07:09:43 -07001691 void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
Ben Wagner63fd7602017-10-09 15:45:33 -04001692 const SkPaint* paint,
Cary Clark0418a882017-05-10 09:07:42 -04001693 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
Cary Clarkb7da7232017-09-01 13:49:54 -04001694
1695 /** Draw SkBitmap bitmap, scaled and translated to fill SkRect dst.
1696 bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
1697 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1698
1699 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1700 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1701 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1702
1703 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1704 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001705 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001706 outside of its bounds.
1707
1708 constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
1709 sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
1710 improve performance.
1711
1712 @param bitmap SkBitmap containing pixels, dimensions, and format
1713 @param dst destination SkRect of image to draw to
1714 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1715 and so on; or nullptr
1716 @param constraint filter strictly within bitmap or draw faster
1717 */
reede47829b2015-08-06 10:02:53 -07001718 void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
Cary Clark0418a882017-05-10 09:07:42 -04001719 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
reed84984ef2015-07-17 07:09:43 -07001720
Cary Clark8a02b0b2017-09-21 12:28:43 -04001721 /** Draw SkBitmap bitmap stretched proportionally to fit into SkRect dst.
Cary Clarkb7da7232017-09-01 13:49:54 -04001722 SkIRect center divides the bitmap into nine sections: four sides, four corners,
1723 and the center. Corners are not scaled, or scaled down proportionately if their
1724 sides are larger than dst; center and four sides are scaled to fit remaining
1725 space, if any.
1726
1727 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1728
1729 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1730 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1731 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1732
1733 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1734 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001735 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001736 outside of its bounds.
1737
1738 @param bitmap SkBitmap containing pixels, dimensions, and format
1739 @param center SkIRect edge of image corners and sides
1740 @param dst destination SkRect of image to draw to
1741 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1742 and so on; or nullptr
1743 */
reed0846f1b2015-01-09 14:17:40 -08001744 void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
Ben Wagnera93a14a2017-08-28 10:34:05 -04001745 const SkPaint* paint = nullptr);
reed@google.comf0b5e112011-09-07 11:57:34 +00001746
Cary Clarkb7da7232017-09-01 13:49:54 -04001747 /** \struct SkCanvas::Lattice
Cary Clark75959392018-02-27 10:22:04 -05001748 SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
Cary Clark8a02b0b2017-09-21 12:28:43 -04001749 Grid entries on even columns and even rows are fixed; these entries are
1750 always drawn at their original size if the destination is large enough.
1751 If the destination side is too small to hold the fixed entries, all fixed
1752 entries are proportionately scaled down to fit.
1753 The grid entries not on even columns and rows are scaled to fit the
1754 remaining space, if any.
Cary Clarkb7da7232017-09-01 13:49:54 -04001755 */
msarettc573a402016-08-02 08:05:56 -07001756 struct Lattice {
Cary Clarkb7da7232017-09-01 13:49:54 -04001757
Stan Ilievca8c0952017-12-11 13:01:58 -05001758 /** \enum SkCanvas::Lattice::RectType
Cary Clark2823f9f2018-01-03 10:00:34 -05001759 Optional setting per rectangular grid entry to make it transparent,
1760 or to fill the grid entry with a color.
Cary Clarkb7da7232017-09-01 13:49:54 -04001761 */
Stan Ilievca8c0952017-12-11 13:01:58 -05001762 enum RectType : uint8_t {
Cary Clark2823f9f2018-01-03 10:00:34 -05001763 kDefault = 0, //!< Draws SkBitmap into lattice rectangle.
1764 kTransparent, //!< Skips lattice rectangle by making it transparent.
1765 kFixedColor, //!< Draws one of fColors into lattice rectangle.
msarett0764efe2016-09-02 11:24:30 -07001766 };
msarettc573a402016-08-02 08:05:56 -07001767
Cary Clarkb7da7232017-09-01 13:49:54 -04001768 /** Array of x-coordinates that divide the bitmap vertically.
1769 Array entries must be unique, increasing, greater than or equal to
1770 fBounds left edge, and less than fBounds right edge.
1771 Set the first element to fBounds left to collapse the left column of
1772 fixed grid entries.
1773 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001774 const int* fXDivs;
msarettc573a402016-08-02 08:05:56 -07001775
Cary Clarkb7da7232017-09-01 13:49:54 -04001776 /** Array of y-coordinates that divide the bitmap horizontally.
1777 Array entries must be unique, increasing, greater than or equal to
1778 fBounds top edge, and less than fBounds bottom edge.
1779 Set the first element to fBounds top to collapse the top row of fixed
1780 grid entries.
1781 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001782 const int* fYDivs;
msarett0764efe2016-09-02 11:24:30 -07001783
Cary Clark2823f9f2018-01-03 10:00:34 -05001784 /** Optional array of fill types, one per rectangular grid entry:
Cary Clarkb7da7232017-09-01 13:49:54 -04001785 array length must be (fXCount + 1) * (fYCount + 1).
Cary Clark8a02b0b2017-09-21 12:28:43 -04001786
Cary Clark2823f9f2018-01-03 10:00:34 -05001787 Each RectType is one of: kDefault, kTransparent, kFixedColor.
1788
Cary Clarkb7da7232017-09-01 13:49:54 -04001789 Array entries correspond to the rectangular grid entries, ascending
1790 left to right and then top to bottom.
1791 */
Stan Ilievca8c0952017-12-11 13:01:58 -05001792 const RectType* fRectTypes;
msarett0764efe2016-09-02 11:24:30 -07001793
Cary Clarkb7da7232017-09-01 13:49:54 -04001794 /** Number of entries in fXDivs array; one less than the number of
1795 horizontal divisions.
1796 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001797 int fXCount;
msarettc573a402016-08-02 08:05:56 -07001798
Cary Clarkb7da7232017-09-01 13:49:54 -04001799 /** Number of entries in fYDivs array; one less than the number of vertical
1800 divisions.
1801 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001802 int fYCount;
msarett71df2d72016-09-30 12:41:42 -07001803
Cary Clarkb7da7232017-09-01 13:49:54 -04001804 /** Optional subset SkIRect source to draw from.
1805 If nullptr, source bounds is dimensions of SkBitmap or SkImage.
1806 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001807 const SkIRect* fBounds;
Cary Clarkb7da7232017-09-01 13:49:54 -04001808
Cary Clark2823f9f2018-01-03 10:00:34 -05001809 /** Optional array of colors, one per rectangular grid entry.
1810 Array length must be (fXCount + 1) * (fYCount + 1).
Stan Ilievca8c0952017-12-11 13:01:58 -05001811
1812 Array entries correspond to the rectangular grid entries, ascending
Cary Clark2823f9f2018-01-03 10:00:34 -05001813 left to right, then top to bottom.
Stan Ilievca8c0952017-12-11 13:01:58 -05001814 */
Cary Clark2823f9f2018-01-03 10:00:34 -05001815 const SkColor* fColors;
Stan Ilievca8c0952017-12-11 13:01:58 -05001816
msarettc573a402016-08-02 08:05:56 -07001817 };
1818
Cary Clark8a02b0b2017-09-21 12:28:43 -04001819 /** Draw SkBitmap bitmap stretched proportionally to fit into SkRect dst.
Cary Clarkb7da7232017-09-01 13:49:54 -04001820
Cary Clark75959392018-02-27 10:22:04 -05001821 SkCanvas::Lattice lattice divides bitmap into a rectangular grid.
Cary Clarkb7da7232017-09-01 13:49:54 -04001822 Each intersection of an even-numbered row and column is fixed; like the corners
1823 of drawBitmapNine(), fixed lattice elements never scale larger than their initial
Cary Clarkcc309eb2017-10-30 11:48:35 -04001824 size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkb7da7232017-09-01 13:49:54 -04001825 dimension. All other grid elements scale to fill the available space, if any.
1826
1827 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1828
1829 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1830 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1831 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1832
1833 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1834 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001835 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001836 outside of its bounds.
1837
1838 @param bitmap SkBitmap containing pixels, dimensions, and format
1839 @param lattice division of bitmap into fixed and variable rectangles
1840 @param dst destination SkRect of image to draw to
1841 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1842 and so on; or nullptr
1843 */
msarettc573a402016-08-02 08:05:56 -07001844 void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
1845 const SkPaint* paint = nullptr);
Cary Clarkb7da7232017-09-01 13:49:54 -04001846
Cary Clark8a02b0b2017-09-21 12:28:43 -04001847 /** Draw SkImage image stretched proportionally to fit into SkRect dst.
Cary Clarkb7da7232017-09-01 13:49:54 -04001848
Cary Clark75959392018-02-27 10:22:04 -05001849 SkCanvas::Lattice lattice divides image into a rectangular grid.
Cary Clarkb7da7232017-09-01 13:49:54 -04001850 Each intersection of an even-numbered row and column is fixed; like the corners
1851 of drawBitmapNine(), fixed lattice elements never scale larger than their initial
Cary Clarkcc309eb2017-10-30 11:48:35 -04001852 size and shrink proportionately when all fixed elements exceed the bitmap
Cary Clarkb7da7232017-09-01 13:49:54 -04001853 dimension. All other grid elements scale to fill the available space, if any.
1854
1855 Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1856
1857 If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
1858 SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
1859 If paint contains SkMaskFilter, generate mask from bitmap bounds.
1860
1861 If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1862 just as SkShader made from SkShader::MakeBitmapShader with
Cary Clarkcc309eb2017-10-30 11:48:35 -04001863 SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
Cary Clarkb7da7232017-09-01 13:49:54 -04001864 outside of its bounds.
1865
1866 @param image SkImage containing pixels, dimensions, and format
1867 @param lattice division of bitmap into fixed and variable rectangles
1868 @param dst destination SkRect of image to draw to
1869 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1870 and so on; or nullptr
1871 */
msarettc573a402016-08-02 08:05:56 -07001872 void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
1873 const SkPaint* paint = nullptr);
1874
Cary Clarkb7da7232017-09-01 13:49:54 -04001875 /** Draw text, with origin at (x, y), using clip, SkMatrix, and SkPaint paint.
1876
Cary Clarkcc309eb2017-10-30 11:48:35 -04001877 text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
Cary Clarkb7da7232017-09-01 13:49:54 -04001878 UTF-8.
1879
1880 x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
Cary Clarkcc309eb2017-10-30 11:48:35 -04001881 text draws left to right, positioning the first glyph left side bearing at x
Cary Clarkb7da7232017-09-01 13:49:54 -04001882 and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
1883
Mike Reed8ad91a92018-01-19 19:09:32 -05001884 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001885 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
1886 filled 12 point black glyphs.
1887
1888 @param text character code points or glyphs drawn
1889 @param byteLength byte length of text array
1890 @param x start of text on x-axis
1891 @param y start of text on y-axis
1892 @param paint text size, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00001893 */
reedf7430cc2014-12-21 11:38:35 -08001894 void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
1895 const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001896
Cary Clarkb7da7232017-09-01 13:49:54 -04001897 /** Draw null terminated string, with origin at (x, y), using clip, SkMatrix, and
1898 SkPaint paint.
1899
Cary Clarkcc309eb2017-10-30 11:48:35 -04001900 string meaning depends on SkPaint::TextEncoding; by default, strings are encoded
1901 as UTF-8. Other values of SkPaint::TextEncoding are unlikely to produce the desired
Cary Clarkb7da7232017-09-01 13:49:54 -04001902 results, since zero bytes may be embedded in the string.
1903
1904 x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
Cary Clarkcc309eb2017-10-30 11:48:35 -04001905 string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkb7da7232017-09-01 13:49:54 -04001906 and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
1907
Mike Reed8ad91a92018-01-19 19:09:32 -05001908 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001909 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
1910 filled 12 point black glyphs.
1911
1912 @param string character code points or glyphs drawn,
1913 ending with a char value of zero
1914 @param x start of string on x-axis
1915 @param y start of string on y-axis
1916 @param paint text size, blend, color, and so on, used to draw
Cary Clark2a475ea2017-04-28 15:35:12 -04001917 */
1918 void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint) {
1919 if (!string) {
1920 return;
1921 }
1922 this->drawText(string, strlen(string), x, y, paint);
1923 }
1924
Cary Clarkb7da7232017-09-01 13:49:54 -04001925 /** Draw null terminated string, with origin at (x, y), using clip, SkMatrix, and
1926 SkPaint paint.
1927
Cary Clarkcc309eb2017-10-30 11:48:35 -04001928 string meaning depends on SkPaint::TextEncoding; by default, strings are encoded
1929 as UTF-8. Other values of SkPaint::TextEncoding are unlikely to produce the desired
Cary Clarkb7da7232017-09-01 13:49:54 -04001930 results, since zero bytes may be embedded in the string.
1931
1932 x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
Cary Clarkcc309eb2017-10-30 11:48:35 -04001933 string draws left to right, positioning the first glyph left side bearing at x
Cary Clarkb7da7232017-09-01 13:49:54 -04001934 and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
1935
Mike Reed8ad91a92018-01-19 19:09:32 -05001936 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001937 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
1938 filled 12 point black glyphs.
1939
1940 @param string character code points or glyphs drawn,
1941 ending with a char value of zero
1942 @param x start of string on x-axis
1943 @param y start of string on y-axis
1944 @param paint text size, blend, color, and so on, used to draw
Cary Clark2a475ea2017-04-28 15:35:12 -04001945 */
1946 void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint);
1947
Cary Clarkb7da7232017-09-01 13:49:54 -04001948 /** Draw each glyph in text with the origin in pos array, using clip, SkMatrix, and
1949 SkPaint paint. The number of entries in pos array must match the number of glyphs
1950 described by byteLength of text.
1951
Cary Clarkcc309eb2017-10-30 11:48:35 -04001952 text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
Cary Clarkb7da7232017-09-01 13:49:54 -04001953 UTF-8. pos elements' meaning depends on SkPaint::Align and SkPaint vertical text;
Cary Clarkcc309eb2017-10-30 11:48:35 -04001954 by default each glyph left side bearing is positioned at x and its
Cary Clarkb7da7232017-09-01 13:49:54 -04001955 baseline is positioned at y. Text size is affected by SkMatrix and
1956 SkPaint text size.
1957
Mike Reed8ad91a92018-01-19 19:09:32 -05001958 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001959 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
1960 filled 12 point black glyphs.
1961
1962 Layout engines such as Harfbuzz typically position each glyph
Cary Clarkcc309eb2017-10-30 11:48:35 -04001963 rather than using the font advance widths.
Cary Clarkb7da7232017-09-01 13:49:54 -04001964
1965 @param text character code points or glyphs drawn
1966 @param byteLength byte length of text array
1967 @param pos array of glyph origins
1968 @param paint text size, blend, color, and so on, used to draw
1969 */
reedf7430cc2014-12-21 11:38:35 -08001970 void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
1971 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +00001972
Cary Clarkb7da7232017-09-01 13:49:54 -04001973 /** Draw each glyph in text with its (x, y) origin composed from xpos array and
1974 constY, using clip, SkMatrix, and SkPaint paint. The number of entries in xpos array
1975 must match the number of glyphs described by byteLength of text.
1976
Cary Clarkcc309eb2017-10-30 11:48:35 -04001977 text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
Cary Clarkb7da7232017-09-01 13:49:54 -04001978 UTF-8. xpos elements' meaning depends on SkPaint::Align and SkPaint vertical text;
Cary Clarkcc309eb2017-10-30 11:48:35 -04001979 by default each glyph left side bearing is positioned at an xpos element and
Cary Clarkb7da7232017-09-01 13:49:54 -04001980 its baseline is positioned at constY. Text size is affected by SkMatrix and
1981 SkPaint text size.
1982
Mike Reed8ad91a92018-01-19 19:09:32 -05001983 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04001984 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
1985 filled 12 point black glyphs.
1986
1987 Layout engines such as Harfbuzz typically position each glyph
Cary Clarkcc309eb2017-10-30 11:48:35 -04001988 rather than using the font advance widths if all glyphs share the same
Cary Clarkb7da7232017-09-01 13:49:54 -04001989 baseline.
1990
1991 @param text character code points or glyphs drawn
1992 @param byteLength byte length of text array
1993 @param xpos array of x positions, used to position each glyph
1994 @param constY shared y coordinate for all of x positions
1995 @param paint text size, blend, color, and so on, used to draw
1996 */
reedf7430cc2014-12-21 11:38:35 -08001997 void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
1998 const SkPaint& paint);
reed@google.com4b226022011-01-11 18:32:13 +00001999
Cary Clarkb7da7232017-09-01 13:49:54 -04002000 /** Draw text on SkPath path, using clip, SkMatrix, and SkPaint paint.
2001
2002 Origin of text is at distance hOffset along the path, offset by a perpendicular
2003 vector of length vOffset. If the path section corresponding the glyph advance is
2004 curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkcc309eb2017-10-30 11:48:35 -04002005 mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkb7da7232017-09-01 13:49:54 -04002006 than the path length, the excess text is clipped.
2007
Cary Clarkcc309eb2017-10-30 11:48:35 -04002008 text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
Cary Clarkb7da7232017-09-01 13:49:54 -04002009 UTF-8. Origin meaning depends on SkPaint::Align and SkPaint vertical text; by
Cary Clarkcc309eb2017-10-30 11:48:35 -04002010 default text positions the first glyph left side bearing at origin x and its
Cary Clarkb7da7232017-09-01 13:49:54 -04002011 baseline at origin y. Text size is affected by SkMatrix and SkPaint text size.
2012
Mike Reed8ad91a92018-01-19 19:09:32 -05002013 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04002014 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
2015 filled 12 point black glyphs.
2016
2017 @param text character code points or glyphs drawn
2018 @param byteLength byte length of text array
2019 @param path SkPath providing text baseline
2020 @param hOffset distance along path to offset origin
2021 @param vOffset offset of text above (if negative) or below (if positive) the path
2022 @param paint text size, blend, color, and so on, used to draw
reed@android.com8a1c16f2008-12-17 15:59:43 +00002023 */
reedf7430cc2014-12-21 11:38:35 -08002024 void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
reed@android.com8a1c16f2008-12-17 15:59:43 +00002025 SkScalar vOffset, const SkPaint& paint);
2026
Cary Clarkb7da7232017-09-01 13:49:54 -04002027 /** Draw text on SkPath path, using clip, SkMatrix, and SkPaint paint.
2028
2029 Origin of text is at beginning of path offset by matrix, if provided, before it
2030 is mapped to path. If the path section corresponding the glyph advance is
2031 curved, the glyph is drawn curved to match; control points in the glyph are
Cary Clarkcc309eb2017-10-30 11:48:35 -04002032 mapped to projected points parallel to the path. If the text advance is larger
Cary Clarkb7da7232017-09-01 13:49:54 -04002033 than the path length, the excess text is clipped.
2034
Cary Clarkcc309eb2017-10-30 11:48:35 -04002035 text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
Cary Clarkb7da7232017-09-01 13:49:54 -04002036 UTF-8. Origin meaning depends on SkPaint::Align and SkPaint vertical text; by
Cary Clarkcc309eb2017-10-30 11:48:35 -04002037 default text positions the first glyph left side bearing at origin x and its
Cary Clarkb7da7232017-09-01 13:49:54 -04002038 baseline at origin y. Text size is affected by SkMatrix and SkPaint text size.
2039
Mike Reed8ad91a92018-01-19 19:09:32 -05002040 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04002041 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
2042 filled 12 point black glyphs.
2043
2044 @param text character code points or glyphs drawn
2045 @param byteLength byte length of text array
2046 @param path SkPath providing text baseline
2047 @param matrix transform of glyphs before mapping to path; may be nullptr
2048 to use identity SkMatrix
2049 @param paint text size, blend, color, and so on, used to draw
2050 */
reedf7430cc2014-12-21 11:38:35 -08002051 void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
2052 const SkMatrix* matrix, const SkPaint& paint);
reed@android.com8a1c16f2008-12-17 15:59:43 +00002053
Cary Clarkb7da7232017-09-01 13:49:54 -04002054 /** Draw text, transforming each glyph by the corresponding SkRSXform,
2055 using clip, SkMatrix, and SkPaint paint.
2056
2057 SkRSXform array specifies a separate square scale, rotation, and translation for
2058 each glyph.
2059
2060 Optional SkRect cullRect is a conservative bounds of text, taking into account
2061 SkRSXform and paint. If cullRect is outside of clip, canvas can skip drawing.
2062
Mike Reed8ad91a92018-01-19 19:09:32 -05002063 All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
Cary Clarkb7da7232017-09-01 13:49:54 -04002064 SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
2065 filled 12 point black glyphs.
2066
2067 @param text character code points or glyphs drawn
2068 @param byteLength byte length of text array
2069 @param xform SkRSXform rotates, scales, and translates each glyph individually
2070 @param cullRect SkRect bounds of text for efficient clipping; or nullptr
2071 @param paint text size, blend, color, and so on, used to draw
2072 */
Cary Clark0418a882017-05-10 09:07:42 -04002073 void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
reed45561a02016-07-07 12:47:17 -07002074 const SkRect* cullRect, const SkPaint& paint);
2075
Cary Clarkb7da7232017-09-01 13:49:54 -04002076 /** Draw SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
2077
2078 blob contains glyphs, their positions, and paint attributes specific to text:
2079 SkTypeface, SkPaint text size, SkPaint text scale x, SkPaint text skew x,
Cary Clark75959392018-02-27 10:22:04 -05002080 SkPaint::Align, SkPaint::Hinting, SkPaint anti-alias, SkPaint fake bold,
2081 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
2082 SkPaint subpixel text, and SkPaint vertical text.
Cary Clarkb7da7232017-09-01 13:49:54 -04002083
Cary Clark2823f9f2018-01-03 10:00:34 -05002084 SkPaint::TextEncoding must be set to SkPaint::kGlyphID_TextEncoding.
2085
Mike Reed8ad91a92018-01-19 19:09:32 -05002086 Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
Cary Clarkb7da7232017-09-01 13:49:54 -04002087 SkImageFilter, and SkDrawLooper; apply to blob.
2088
Cary Clark8a02b0b2017-09-21 12:28:43 -04002089 @param blob glyphs, positions, and their paints' text size, typeface, and so on
Cary Clarkb7da7232017-09-01 13:49:54 -04002090 @param x horizontal offset applied to blob
2091 @param y vertical offset applied to blob
2092 @param paint blend, color, stroking, and so on, used to draw
fmalita00d5c2c2014-08-21 08:53:26 -07002093 */
2094 void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04002095
2096 /** Draw SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
2097
2098 blob contains glyphs, their positions, and paint attributes specific to text:
2099 SkTypeface, SkPaint text size, SkPaint text scale x, SkPaint text skew x,
Cary Clark75959392018-02-27 10:22:04 -05002100 SkPaint::Align, SkPaint::Hinting, SkPaint anti-alias, SkPaint fake bold,
2101 SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
2102 SkPaint subpixel text, and SkPaint vertical text.
Cary Clarkb7da7232017-09-01 13:49:54 -04002103
Cary Clark2823f9f2018-01-03 10:00:34 -05002104 SkPaint::TextEncoding must be set to SkPaint::kGlyphID_TextEncoding.
2105
Mike Reed8ad91a92018-01-19 19:09:32 -05002106 Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
Cary Clarkb7da7232017-09-01 13:49:54 -04002107 SkImageFilter, and SkDrawLooper; apply to blob.
2108
Cary Clark8a02b0b2017-09-21 12:28:43 -04002109 @param blob glyphs, positions, and their paints' text size, typeface, and so on
Cary Clarkb7da7232017-09-01 13:49:54 -04002110 @param x horizontal offset applied to blob
2111 @param y vertical offset applied to blob
2112 @param paint blend, color, stroking, and so on, used to draw
2113 */
reed2ab90572016-08-10 14:16:41 -07002114 void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
2115 this->drawTextBlob(blob.get(), x, y, paint);
2116 }
fmalita00d5c2c2014-08-21 08:53:26 -07002117
Cary Clark2823f9f2018-01-03 10:00:34 -05002118 /** Draw SkPicture picture, using clip and SkMatrix.
Cary Clarkb7da7232017-09-01 13:49:54 -04002119 Clip and SkMatrix are unchanged by picture contents, as if
2120 save() was called before and restore() was called after drawPicture().
2121
Cary Clark2823f9f2018-01-03 10:00:34 -05002122 SkPicture records a series of draw commands for later playback.
Cary Clarkb7da7232017-09-01 13:49:54 -04002123
2124 @param picture recorded drawing commands to play
reed@android.com8a1c16f2008-12-17 15:59:43 +00002125 */
reed1c2c4412015-04-30 13:09:24 -07002126 void drawPicture(const SkPicture* picture) {
Ben Wagnera93a14a2017-08-28 10:34:05 -04002127 this->drawPicture(picture, nullptr, nullptr);
reed1c2c4412015-04-30 13:09:24 -07002128 }
Cary Clarkb7da7232017-09-01 13:49:54 -04002129
Cary Clark2823f9f2018-01-03 10:00:34 -05002130 /** Draw SkPicture picture, using clip and SkMatrix.
Cary Clarkb7da7232017-09-01 13:49:54 -04002131 Clip and SkMatrix are unchanged by picture contents, as if
2132 save() was called before and restore() was called after drawPicture().
2133
Cary Clark2823f9f2018-01-03 10:00:34 -05002134 SkPicture records a series of draw commands for later playback.
Cary Clarkb7da7232017-09-01 13:49:54 -04002135
2136 @param picture recorded drawing commands to play
2137 */
reedca2622b2016-03-18 07:25:55 -07002138 void drawPicture(const sk_sp<SkPicture>& picture) {
reedf8053da2016-03-17 08:14:57 -07002139 this->drawPicture(picture.get());
2140 }
robertphillips9b14f262014-06-04 05:40:44 -07002141
Cary Clark2823f9f2018-01-03 10:00:34 -05002142 /** Draw SkPicture picture, using clip and SkMatrix; transforming picture with
Cary Clarkb7da7232017-09-01 13:49:54 -04002143 SkMatrix matrix, if provided; and use SkPaint paint color alpha, SkColorFilter,
2144 SkImageFilter, and SkBlendMode, if provided.
2145
2146 matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
2147 paint use is equivalent to: saveLayer(), drawPicture(), restore().
2148
2149 @param picture recorded drawing commands to play
2150 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
2151 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
2152 */
Cary Clark0418a882017-05-10 09:07:42 -04002153 void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04002154
Cary Clark2823f9f2018-01-03 10:00:34 -05002155 /** Draw SkPicture picture, using clip and SkMatrix; transforming picture with
Cary Clarkb7da7232017-09-01 13:49:54 -04002156 SkMatrix matrix, if provided; and use SkPaint paint color alpha, SkColorFilter,
2157 SkImageFilter, and SkBlendMode, if provided.
2158
2159 matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
2160 paint use is equivalent to: saveLayer(), drawPicture(), restore().
2161
2162 @param picture recorded drawing commands to play
2163 @param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
2164 @param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
2165 */
reedca2622b2016-03-18 07:25:55 -07002166 void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint) {
reedf8053da2016-03-17 08:14:57 -07002167 this->drawPicture(picture.get(), matrix, paint);
2168 }
reedd5fa1a42014-08-09 11:08:05 -07002169
Cary Clarkb7da7232017-09-01 13:49:54 -04002170 /** Draw vertices vertices, a triangle mesh, using clip and SkMatrix.
2171 If vertices texs and vertices colors are defined in vertices, and SkPaint paint
2172 contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
Brian Salomon199fb872017-02-06 09:41:10 -05002173
Cary Clarkb7da7232017-09-01 13:49:54 -04002174 @param vertices triangle mesh to draw
2175 @param mode combines vertices colors with SkShader, if both are present
2176 @param paint specifies the SkShader, used as vertices texture; may be nullptr
2177 */
Mike Reede88a1cb2017-03-17 09:50:46 -04002178 void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04002179
2180 /** Draw vertices vertices, a triangle mesh, using clip and SkMatrix.
2181 If vertices texs and vertices colors are defined in vertices, and SkPaint paint
2182 contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
2183
2184 @param vertices triangle mesh to draw
2185 @param mode combines vertices colors with SkShader, if both are present
2186 @param paint specifies the SkShader, used as vertices texture, may be nullptr
2187 */
Mike Reede88a1cb2017-03-17 09:50:46 -04002188 void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04002189
Cary Clark2823f9f2018-01-03 10:00:34 -05002190 /** Draws a Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkb7da7232017-09-01 13:49:54 -04002191 associating a color, and optionally a texture coordinate, with each corner.
mtklein6cfa73a2014-08-13 13:33:49 -07002192
Cary Clark2823f9f2018-01-03 10:00:34 -05002193 Coons_Patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
Cary Clarkb7da7232017-09-01 13:49:54 -04002194 color alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
Cary Clark2823f9f2018-01-03 10:00:34 -05002195 as Coons_Patch texture; SkBlendMode mode combines color colors and SkShader if
Cary Clarkb7da7232017-09-01 13:49:54 -04002196 both are provided.
2197
Cary Clark75959392018-02-27 10:22:04 -05002198 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2199 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
Cary Clarkb7da7232017-09-01 13:49:54 -04002200 first point.
2201
Cary Clarkcc309eb2017-10-30 11:48:35 -04002202 Color array color associates colors with corners in top-left, top-right,
2203 bottom-right, bottom-left order.
Cary Clarkb7da7232017-09-01 13:49:54 -04002204
2205 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
Cary Clarkcc309eb2017-10-30 11:48:35 -04002206 corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkb7da7232017-09-01 13:49:54 -04002207
2208 @param cubics SkPath cubic array, sharing common points
Cary Clark8a02b0b2017-09-21 12:28:43 -04002209 @param colors color array, one for each corner
Cary Clarkb7da7232017-09-01 13:49:54 -04002210 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
2211 may be nullptr
2212 @param mode SkBlendMode for colors, and for SkShader if paint has one
2213 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw
2214 */
dandovb3c9d1c2014-08-12 08:34:29 -07002215 void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04002216 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04002217
Cary Clark75959392018-02-27 10:22:04 -05002218 /** Draws SkPath cubic Coons_Patch: the interpolation of four cubics with shared corners,
Cary Clarkb7da7232017-09-01 13:49:54 -04002219 associating a color, and optionally a texture coordinate, with each corner.
2220
Cary Clark2823f9f2018-01-03 10:00:34 -05002221 Coons_Patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
Cary Clarkb7da7232017-09-01 13:49:54 -04002222 color alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
Cary Clark2823f9f2018-01-03 10:00:34 -05002223 as Coons_Patch texture; SkBlendMode mode combines color colors and SkShader if
Cary Clarkb7da7232017-09-01 13:49:54 -04002224 both are provided.
2225
Cary Clark75959392018-02-27 10:22:04 -05002226 SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2227 in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
Cary Clarkb7da7232017-09-01 13:49:54 -04002228 first point.
2229
Cary Clarkcc309eb2017-10-30 11:48:35 -04002230 Color array color associates colors with corners in top-left, top-right,
2231 bottom-right, bottom-left order.
Cary Clarkb7da7232017-09-01 13:49:54 -04002232
2233 If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
Cary Clarkcc309eb2017-10-30 11:48:35 -04002234 corners in top-left, top-right, bottom-right, bottom-left order.
Cary Clarkb7da7232017-09-01 13:49:54 -04002235
2236 @param cubics SkPath cubic array, sharing common points
Cary Clark8a02b0b2017-09-21 12:28:43 -04002237 @param colors color array, one for each corner
Cary Clarkb7da7232017-09-01 13:49:54 -04002238 @param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
2239 may be nullptr
2240 @param paint SkShader, SkColorFilter, SkBlendMode, used to draw
2241 */
Mike Reed7d954ad2016-10-28 15:42:34 -04002242 void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2243 const SkPoint texCoords[4], const SkPaint& paint) {
2244 this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
2245 }
2246
Cary Clarkb7da7232017-09-01 13:49:54 -04002247 /** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
Cary Clark75959392018-02-27 10:22:04 -05002248 paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
Cary Clarkb7da7232017-09-01 13:49:54 -04002249 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2250 atlas, and SkRSXform xform transforms it into destination space.
2251
2252 xform, text, and colors if present, must contain count entries.
2253 Optional colors are applied for each sprite using SkBlendMode.
2254 Optional cullRect is a conservative bounds of all transformed sprites.
2255 If cullRect is outside of clip, canvas can skip drawing.
2256
2257 @param atlas SkImage containing sprites
2258 @param xform SkRSXform mappings for sprites in atlas
2259 @param tex SkRect locations of sprites in atlas
Cary Clark8a02b0b2017-09-21 12:28:43 -04002260 @param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002261 @param count number of sprites to draw
2262 @param mode SkBlendMode combining colors and sprites
Cary Clark8a02b0b2017-09-21 12:28:43 -04002263 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2264 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002265 */
reed71c3c762015-06-24 10:29:17 -07002266 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
Cary Clark0418a882017-05-10 09:07:42 -04002267 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
reed71c3c762015-06-24 10:29:17 -07002268 const SkPaint* paint);
Cary Clarkb7da7232017-09-01 13:49:54 -04002269
2270 /** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
Cary Clark75959392018-02-27 10:22:04 -05002271 paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
Cary Clarkb7da7232017-09-01 13:49:54 -04002272 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2273 atlas, and SkRSXform xform transforms it into destination space.
2274
2275 xform, text, and colors if present, must contain count entries.
2276 Optional colors is applied for each sprite using SkBlendMode.
2277 Optional cullRect is a conservative bounds of all transformed sprites.
2278 If cullRect is outside of clip, canvas can skip drawing.
2279
2280 @param atlas SkImage containing sprites
2281 @param xform SkRSXform mappings for sprites in atlas
2282 @param tex SkRect locations of sprites in atlas
Cary Clark8a02b0b2017-09-21 12:28:43 -04002283 @param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002284 @param count number of sprites to draw
2285 @param mode SkBlendMode combining colors and sprites
Cary Clark8a02b0b2017-09-21 12:28:43 -04002286 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2287 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002288 */
Mike Reed7d954ad2016-10-28 15:42:34 -04002289 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
2290 const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
2291 const SkPaint* paint) {
2292 this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
2293 }
Cary Clarkb7da7232017-09-01 13:49:54 -04002294
2295 /** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
Cary Clark75959392018-02-27 10:22:04 -05002296 paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
Cary Clarkb7da7232017-09-01 13:49:54 -04002297 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2298 atlas, and SkRSXform xform transforms it into destination space.
2299
2300 xform and text must contain count entries.
2301 Optional cullRect is a conservative bounds of all transformed sprites.
2302 If cullRect is outside of clip, canvas can skip drawing.
2303
2304 @param atlas SkImage containing sprites
2305 @param xform SkRSXform mappings for sprites in atlas
2306 @param tex SkRect locations of sprites in atlas
2307 @param count number of sprites to draw
Cary Clark8a02b0b2017-09-21 12:28:43 -04002308 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2309 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002310 */
reed71c3c762015-06-24 10:29:17 -07002311 void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
2312 const SkRect* cullRect, const SkPaint* paint) {
Mike Reed7d954ad2016-10-28 15:42:34 -04002313 this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
2314 }
Cary Clarkb7da7232017-09-01 13:49:54 -04002315
2316 /** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
Cary Clark75959392018-02-27 10:22:04 -05002317 paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
Cary Clarkb7da7232017-09-01 13:49:54 -04002318 to draw, if present. For each entry in the array, SkRect tex locates sprite in
2319 atlas, and SkRSXform xform transforms it into destination space.
2320
2321 xform and text must contain count entries.
2322 Optional cullRect is a conservative bounds of all transformed sprites.
2323 If cullRect is outside of clip, canvas can skip drawing.
2324
2325 @param atlas SkImage containing sprites
2326 @param xform SkRSXform mappings for sprites in atlas
2327 @param tex SkRect locations of sprites in atlas
2328 @param count number of sprites to draw
Cary Clark8a02b0b2017-09-21 12:28:43 -04002329 @param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
2330 @param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
Cary Clarkb7da7232017-09-01 13:49:54 -04002331 */
Mike Reed7d954ad2016-10-28 15:42:34 -04002332 void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
2333 int count, const SkRect* cullRect, const SkPaint* paint) {
2334 this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
2335 cullRect, paint);
2336 }
2337
Cary Clarkb7da7232017-09-01 13:49:54 -04002338 /** Draw SkDrawable drawable using clip and SkMatrix, concatenated with
2339 optional matrix.
2340
2341 If SkCanvas has an asynchronous implementation, as is the case
Cary Clark2823f9f2018-01-03 10:00:34 -05002342 when it is recording into SkPicture, then drawable will be referenced,
Cary Clarkb7da7232017-09-01 13:49:54 -04002343 so that SkDrawable::draw() can be called when the operation is finalized. To force
2344 immediate drawing, call SkDrawable::draw() instead.
2345
2346 @param drawable custom struct encapsulating drawing commands
2347 @param matrix transformation applied to drawing; may be nullptr
2348 */
Ben Wagnera93a14a2017-08-28 10:34:05 -04002349 void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);
Cary Clarkb7da7232017-09-01 13:49:54 -04002350
2351 /** Draw SkDrawable drawable using clip and SkMatrix, offset by (x, y).
2352
2353 If SkCanvas has an asynchronous implementation, as is the case
Cary Clark2823f9f2018-01-03 10:00:34 -05002354 when it is recording into SkPicture, then drawable will be referenced,
Cary Clarkb7da7232017-09-01 13:49:54 -04002355 so that SkDrawable::draw() can be called when the operation is finalized. To force
2356 immediate drawing, call SkDrawable::draw() instead.
2357
2358 @param drawable custom struct encapsulating drawing commands
2359 @param x offset into SkCanvas writable pixels in x
2360 @param y offset into SkCanvas writable pixels in y
2361 */
Cary Clark0418a882017-05-10 09:07:42 -04002362 void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
reed6a070dc2014-11-11 19:36:09 -08002363
Cary Clark75959392018-02-27 10:22:04 -05002364 /** Associate SkRect on SkCanvas with an annotation; a key-value pair, where the key is
Cary Clark2823f9f2018-01-03 10:00:34 -05002365 a null-terminated utf8 string, and optional value is stored as SkData.
Cary Clarkb7da7232017-09-01 13:49:54 -04002366
Cary Clark2823f9f2018-01-03 10:00:34 -05002367 Only some canvas implementations, such as recording to SkPicture, or drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -04002368 document pdf, use annotations.
2369
2370 @param rect SkRect extent of canvas to annotate
2371 @param key string used for lookup
2372 @param value data holding value stored in annotation
2373 */
Cary Clark0418a882017-05-10 09:07:42 -04002374 void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
Cary Clarkb7da7232017-09-01 13:49:54 -04002375
2376 /** Associate SkRect on SkCanvas when an annotation; a key-value pair, where the key is
Cary Clark2823f9f2018-01-03 10:00:34 -05002377 a null-terminated utf8 string, and optional value is stored as SkData.
Cary Clarkb7da7232017-09-01 13:49:54 -04002378
Cary Clark2823f9f2018-01-03 10:00:34 -05002379 Only some canvas implementations, such as recording to SkPicture, or drawing to
Cary Clarkb7da7232017-09-01 13:49:54 -04002380 document pdf, use annotations.
2381
2382 @param rect SkRect extent of canvas to annotate
2383 @param key string used for lookup
2384 @param value data holding value stored in annotation
2385 */
mtklein0fba3b92016-04-01 04:55:51 -07002386 void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
2387 this->drawAnnotation(rect, key, value.get());
2388 }
reedf70b5312016-03-04 16:36:20 -08002389
reed@android.com8a1c16f2008-12-17 15:59:43 +00002390 //////////////////////////////////////////////////////////////////////////
reed@google.com4b226022011-01-11 18:32:13 +00002391
fmalita53d9f1c2016-01-25 06:23:54 -08002392#ifdef SK_SUPPORT_LEGACY_DRAWFILTER
Cary Clark75959392018-02-27 10:22:04 -05002393 /** To be deprecated soon.
reed@android.com8a1c16f2008-12-17 15:59:43 +00002394 */
2395 SkDrawFilter* getDrawFilter() const;
reed@google.com4b226022011-01-11 18:32:13 +00002396
Cary Clark75959392018-02-27 10:22:04 -05002397 /** To be deprecated soon.
reed@android.com8a1c16f2008-12-17 15:59:43 +00002398 */
2399 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
fmalita77650002016-01-21 18:47:11 -08002400#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +00002401
Cary Clarkb7da7232017-09-01 13:49:54 -04002402 /** Returns true if clip is empty; that is, nothing will draw.
2403
2404 May do work when called; it should not be called
2405 more often than needed. However, once called, subsequent calls perform no
2406 work until clip changes.
2407
2408 @return true if clip is empty
2409 */
robertphillips@google.com8f90a892014-02-28 18:19:39 +00002410 virtual bool isClipEmpty() const;
reed@google.com754de5f2014-02-24 19:38:20 +00002411
Cary Clarkb7da7232017-09-01 13:49:54 -04002412 /** Returns true if clip is SkRect and not empty.
2413 Returns false if the clip is empty, or if it is not SkRect.
2414
2415 @return true if clip is SkRect and not empty
2416 */
commit-bot@chromium.org5c70cdc2014-03-08 03:57:19 +00002417 virtual bool isClipRect() const;
2418
Cary Clarkb7da7232017-09-01 13:49:54 -04002419 /** Returns SkMatrix.
2420 This does not account for translation by SkBaseDevice or SkSurface.
2421
2422 @return SkMatrix in SkCanvas
reed@android.com8a1c16f2008-12-17 15:59:43 +00002423 */
junov@chromium.orga907ac32012-02-24 21:54:07 +00002424 const SkMatrix& getTotalMatrix() const;
reed@android.com8a1c16f2008-12-17 15:59:43 +00002425
reed@android.com8a1c16f2008-12-17 15:59:43 +00002426 ///////////////////////////////////////////////////////////////////////////
2427
robertphillips36736a22016-04-23 08:26:43 -07002428 // don't call
Brian Osman61b43da2017-11-01 09:26:38 -04002429 virtual GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
robertphillips36736a22016-04-23 08:26:43 -07002430
robertphillips36736a22016-04-23 08:26:43 -07002431 // TEMP helpers until we switch virtual over to const& for src-rect
2432 void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
2433 const SkPaint* paint,
2434 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
2435 void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
2436 const SkPaint* paint,
2437 SrcRectConstraint constraint = kStrict_SrcRectConstraint);
2438
Mike Reeda1361362017-03-07 09:37:29 -05002439 /**
2440 * Returns the global clip as a region. If the clip contains AA, then only the bounds
2441 * of the clip may be returned.
2442 */
Cary Clark0418a882017-05-10 09:07:42 -04002443 void temporary_internal_getRgnClip(SkRegion* region);
Mike Reed3726a4a2017-01-19 11:36:41 -05002444
Mike Reed4204da22017-05-17 08:53:36 -04002445 void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
2446
robertphillipsda2cd8b2016-04-21 11:05:32 -07002447protected:
reed@google.com76f10a32014-02-05 15:32:21 +00002448 // default impl defers to getDevice()->newSurface(info)
Cary Clark0418a882017-05-10 09:07:42 -04002449 virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
reed@google.com76f10a32014-02-05 15:32:21 +00002450
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00002451 // default impl defers to its device
Cary Clark0418a882017-05-10 09:07:42 -04002452 virtual bool onPeekPixels(SkPixmap* pixmap);
2453 virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
reedea5a6512016-07-07 16:44:27 -07002454 virtual SkImageInfo onImageInfo() const;
Cary Clark0418a882017-05-10 09:07:42 -04002455 virtual bool onGetProps(SkSurfaceProps* props) const;
reedea5a6512016-07-07 16:44:27 -07002456 virtual void onFlush();
commit-bot@chromium.orgc3bd8af2014-02-13 17:14:46 +00002457
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00002458 // Subclass save/restore notifiers.
2459 // Overriders should call the corresponding INHERITED method up the inheritance chain.
reed4960eee2015-12-18 07:09:18 -08002460 // getSaveLayerStrategy()'s return value may suppress full layer allocation.
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00002461 enum SaveLayerStrategy {
2462 kFullLayer_SaveLayerStrategy,
reed4960eee2015-12-18 07:09:18 -08002463 kNoLayer_SaveLayerStrategy,
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00002464 };
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +00002465
fmalita6ca763f2014-06-17 13:52:18 -07002466 virtual void willSave() {}
reed4960eee2015-12-18 07:09:18 -08002467 // Overriders should call the corresponding INHERITED method up the inheritance chain.
Cary Clark0418a882017-05-10 09:07:42 -04002468 virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
reed4960eee2015-12-18 07:09:18 -08002469 return kFullLayer_SaveLayerStrategy;
2470 }
commit-bot@chromium.orgfc6dfba2014-05-14 13:13:44 +00002471 virtual void willRestore() {}
mtklein6cfa73a2014-08-13 13:33:49 -07002472 virtual void didRestore() {}
Cary Clark0418a882017-05-10 09:07:42 -04002473 virtual void didConcat(const SkMatrix& ) {}
2474 virtual void didSetMatrix(const SkMatrix& ) {}
mtkleincbdf0072016-08-19 09:05:27 -07002475 virtual void didTranslate(SkScalar dx, SkScalar dy) {
2476 this->didConcat(SkMatrix::MakeTrans(dx, dy));
2477 }
vjiaoblack95302da2016-07-21 10:25:54 -07002478
Brian Osman37886ce2018-03-09 13:40:31 -05002479 // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
2480 // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
2481 // that mechanism will be required to implement the new function.
2482 virtual void onDrawPaint(const SkPaint& paint);
2483 virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
2484 virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
Cary Clark0418a882017-05-10 09:07:42 -04002485 virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
Brian Osman37886ce2018-03-09 13:40:31 -05002486 virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
2487 virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
2488 bool useCenter, const SkPaint& paint);
2489 virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
2490 virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
commit-bot@chromium.orged9806f2014-02-21 02:32:36 +00002491
reed@google.come0d9ce82014-04-23 04:00:17 +00002492 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
2493 SkScalar y, const SkPaint& paint);
reed@google.come0d9ce82014-04-23 04:00:17 +00002494 virtual void onDrawPosText(const void* text, size_t byteLength,
2495 const SkPoint pos[], const SkPaint& paint);
reed@google.come0d9ce82014-04-23 04:00:17 +00002496 virtual void onDrawPosTextH(const void* text, size_t byteLength,
2497 const SkScalar xpos[], SkScalar constY,
2498 const SkPaint& paint);
reed@google.come0d9ce82014-04-23 04:00:17 +00002499 virtual void onDrawTextOnPath(const void* text, size_t byteLength,
2500 const SkPath& path, const SkMatrix* matrix,
2501 const SkPaint& paint);
Cary Clark0418a882017-05-10 09:07:42 -04002502 virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
reed45561a02016-07-07 12:47:17 -07002503 const SkRect* cullRect, const SkPaint& paint);
fmalita00d5c2c2014-08-21 08:53:26 -07002504 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2505 const SkPaint& paint);
2506
dandovb3c9d1c2014-08-12 08:34:29 -07002507 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
Cary Clark0418a882017-05-10 09:07:42 -04002508 const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
Cary Clark0418a882017-05-10 09:07:42 -04002509 virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
2510 const SkPaint& paint);
2511 virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
2512 const SkPaint& paint);
Brian Osman37886ce2018-03-09 13:40:31 -05002513
Cary Clark0418a882017-05-10 09:07:42 -04002514 virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
2515 virtual void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
2516 const SkPaint* paint, SrcRectConstraint constraint);
2517 virtual void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
2518 const SkPaint* paint);
2519 virtual void onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
2520 const SkPaint* paint);
reed4c21dc52015-06-25 12:32:03 -07002521
Cary Clark0418a882017-05-10 09:07:42 -04002522 virtual void onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
2523 const SkPaint* paint);
2524 virtual void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
2525 const SkPaint* paint, SrcRectConstraint constraint);
2526 virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
2527 const SkPaint* paint);
2528 virtual void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
2529 const SkRect& dst, const SkPaint* paint);
Brian Osman37886ce2018-03-09 13:40:31 -05002530
2531 virtual void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
2532 const SkColor colors[], int count, SkBlendMode mode,
2533 const SkRect* cull, const SkPaint* paint);
2534
2535 virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
Mike Reed4204da22017-05-17 08:53:36 -04002536 virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
reed41af9662015-01-05 07:49:08 -08002537
Brian Osman37886ce2018-03-09 13:40:31 -05002538 virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
2539 virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
2540 const SkPaint* paint);
2541
robertphillips@google.com8f90a892014-02-28 18:19:39 +00002542 enum ClipEdgeStyle {
2543 kHard_ClipEdgeStyle,
2544 kSoft_ClipEdgeStyle
2545 };
2546
Cary Clark0418a882017-05-10 09:07:42 -04002547 virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
2548 virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
2549 virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
2550 virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
robertphillips@google.com8f90a892014-02-28 18:19:39 +00002551
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +00002552 virtual void onDiscard();
2553
junov@chromium.orga907ac32012-02-24 21:54:07 +00002554 // Clip rectangle bounds. Called internally by saveLayer.
2555 // returns false if the entire rectangle is entirely clipped out
senorblanco@chromium.orgc4b12f12014-02-05 17:51:22 +00002556 // If non-NULL, The imageFilter parameter will be used to expand the clip
2557 // and offscreen bounds for any margin required by the filter DAG.
Cary Clark0418a882017-05-10 09:07:42 -04002558 bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
Ben Wagnera93a14a2017-08-28 10:34:05 -04002559 const SkImageFilter* imageFilter = nullptr);
junov@chromium.orga907ac32012-02-24 21:54:07 +00002560
reedc83a2972015-07-16 07:40:45 -07002561private:
reed3aafe112016-08-18 12:45:34 -07002562 /** After calling saveLayer(), there can be any number of devices that make
2563 up the top-most drawing area. LayerIter can be used to iterate through
2564 those devices. Note that the iterator is only valid until the next API
2565 call made on the canvas. Ownership of all pointers in the iterator stays
2566 with the canvas, so none of them should be modified or deleted.
2567 */
2568 class LayerIter /*: SkNoncopyable*/ {
2569 public:
2570 /** Initialize iterator with canvas, and set values for 1st device */
2571 LayerIter(SkCanvas*);
2572 ~LayerIter();
2573
2574 /** Return true if the iterator is done */
2575 bool done() const { return fDone; }
2576 /** Cycle to the next device */
2577 void next();
2578
2579 // These reflect the current device in the iterator
2580
2581 SkBaseDevice* device() const;
2582 const SkMatrix& matrix() const;
Mike Reeda1361362017-03-07 09:37:29 -05002583 void clip(SkRegion*) const;
reed3aafe112016-08-18 12:45:34 -07002584 const SkPaint& paint() const;
2585 int x() const;
2586 int y() const;
2587
2588 private:
2589 // used to embed the SkDrawIter object directly in our instance, w/o
2590 // having to expose that class def to the public. There is an assert
2591 // in our constructor to ensure that fStorage is large enough
2592 // (though needs to be a compile-time-assert!). We use intptr_t to work
2593 // safely with 32 and 64 bit machines (to ensure the storage is enough)
2594 intptr_t fStorage[32];
2595 class SkDrawIter* fImpl; // this points at fStorage
2596 SkPaint fDefaultPaint;
2597 bool fDone;
2598 };
Herb Derby13569782016-10-06 14:33:43 -04002599
reed4960eee2015-12-18 07:09:18 -08002600 static bool BoundsAffectsClip(SaveLayerFlags);
reed4960eee2015-12-18 07:09:18 -08002601
reeda2217ef2016-07-20 06:04:34 -07002602 static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
Mike Reedc42a1cd2017-02-14 14:25:14 -05002603 SkBaseDevice* dst, const SkIPoint& dstOrigin,
Mike Reeda1361362017-03-07 09:37:29 -05002604 const SkMatrix& ctm);
reeda2217ef2016-07-20 06:04:34 -07002605
reedc83a2972015-07-16 07:40:45 -07002606 enum ShaderOverrideOpacity {
2607 kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
2608 kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
2609 kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
2610 };
2611
reed@google.com97af1a62012-08-28 12:19:02 +00002612 // notify our surface (if we have one) that we are about to draw, so it
2613 // can perform copy-on-write or invalidate any cached images
reedc83a2972015-07-16 07:40:45 -07002614 void predrawNotify(bool willOverwritesEntireSurface = false);
2615 void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
2616 void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
2617 this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
2618 : kNotOpaque_ShaderOverrideOpacity);
2619 }
reed@google.com97af1a62012-08-28 12:19:02 +00002620
Florin Malita0ed3b642017-01-13 16:56:38 +00002621 SkBaseDevice* getDevice() const;
2622 SkBaseDevice* getTopDevice() const;
2623
reed@android.com8a1c16f2008-12-17 15:59:43 +00002624 class MCRec;
2625
2626 SkDeque fMCStack;
2627 // points to top of stack
2628 MCRec* fMCRec;
2629 // the first N recs that can fit here mean we won't call malloc
reedb679ca82015-04-07 04:40:48 -07002630 enum {
reeda499f902015-05-01 09:34:31 -07002631 kMCRecSize = 128, // most recent measurement
reed31b80a92015-11-16 13:22:24 -08002632 kMCRecCount = 32, // common depth for save/restores
Florin Malita53f77bd2017-04-28 13:48:37 -04002633 kDeviceCMSize = 224, // most recent measurement
reedb679ca82015-04-07 04:40:48 -07002634 };
2635 intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
reeda499f902015-05-01 09:34:31 -07002636 intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
reed@android.com8a1c16f2008-12-17 15:59:43 +00002637
reed4a8126e2014-09-22 07:29:03 -07002638 const SkSurfaceProps fProps;
2639
reed2ff1fce2014-12-11 07:07:37 -08002640 int fSaveCount; // value returned by getSaveCount()
reed@android.com8a1c16f2008-12-17 15:59:43 +00002641
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +00002642 SkMetaData* fMetaData;
Mike Reed356f7c22017-01-10 11:58:39 -05002643 std::unique_ptr<SkRasterHandleAllocator> fAllocator;
mike@reedtribe.org74bb77e2012-09-26 02:24:45 +00002644
reed@google.com97af1a62012-08-28 12:19:02 +00002645 SkSurface_Base* fSurfaceBase;
2646 SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
2647 void setSurfaceBase(SkSurface_Base* sb) {
2648 fSurfaceBase = sb;
2649 }
2650 friend class SkSurface_Base;
junov@chromium.org45c3db82013-04-11 17:52:05 +00002651 friend class SkSurface_Gpu;
skia.committer@gmail.comfc843592012-10-11 02:01:14 +00002652
Stan Iliev5f1bb0a2016-12-12 17:39:55 -05002653 SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
reed@android.com8a1c16f2008-12-17 15:59:43 +00002654
reed2ff1fce2014-12-11 07:07:37 -08002655 void doSave();
2656 void checkForDeferredSave();
reed8c30a812016-04-20 16:36:51 -07002657 void internalSetMatrix(const SkMatrix&);
reed2ff1fce2014-12-11 07:07:37 -08002658
Stan Iliev73d8fd92017-08-02 15:36:24 -04002659 friend class SkAndroidFrameworkUtils;
Cary Clark7eddfb82018-03-13 14:41:10 -04002660 friend class SkCanvasPriv; // needs kDontClipToLayer_PrivateSaveLayerFlag
reed@google.com9c135db2014-03-12 18:28:35 +00002661 friend class SkDrawIter; // needs setupDrawForLayerDevice()
reed@google.com8926b162012-03-23 15:36:36 +00002662 friend class AutoDrawLooper;
commit-bot@chromium.org2a67e122014-05-19 13:53:10 +00002663 friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
reed52d9ac62014-06-30 09:05:34 -07002664 friend class SkSurface_Raster; // needs getDevice()
Florin Malita439ace92016-12-02 12:05:41 -05002665 friend class SkNoDrawCanvas; // InitFlags
fmalita2d97bc12014-11-20 10:44:58 -08002666 friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
reedc83a2972015-07-16 07:40:45 -07002667 friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
Matt Sarett22886c42016-11-22 11:31:41 -05002668 friend class SkOverdrawCanvas;
Mike Reed356f7c22017-01-10 11:58:39 -05002669 friend class SkRasterHandleAllocator;
piotaixrb5fae932014-09-24 13:03:30 -07002670
reedd9544982014-09-09 18:46:22 -07002671 enum InitFlags {
2672 kDefault_InitFlags = 0,
2673 kConservativeRasterClip_InitFlag = 1 << 0,
2674 };
Brian Osman37886ce2018-03-09 13:40:31 -05002675protected:
2676 // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
reed78e27682014-11-19 08:04:34 -08002677 SkCanvas(const SkIRect& bounds, InitFlags);
Brian Osman37886ce2018-03-09 13:40:31 -05002678private:
robertphillipsfcf78292015-06-19 11:49:52 -07002679 SkCanvas(SkBaseDevice* device, InitFlags);
Mike Reed356f7c22017-01-10 11:58:39 -05002680 SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
2681 SkRasterHandleAllocator::Handle);
reedd9544982014-09-09 18:46:22 -07002682
mtkleinfeaadee2015-04-08 11:25:48 -07002683 void resetForNextPicture(const SkIRect& bounds);
2684
reed8f2e7912014-09-04 12:45:18 -07002685 // needs gettotalclip()
tfarinaa5414c42014-10-10 06:19:09 -07002686 friend class SkCanvasStateUtils;
piotaixrb5fae932014-09-24 13:03:30 -07002687
reed4a8126e2014-09-22 07:29:03 -07002688 // call this each time we attach ourselves to a device
2689 // - constructor
2690 // - internalSaveLayer
2691 void setupDevice(SkBaseDevice*);
2692
reedd9544982014-09-09 18:46:22 -07002693 SkBaseDevice* init(SkBaseDevice*, InitFlags);
reed@google.comf0b5e112011-09-07 11:57:34 +00002694
commit-bot@chromium.org403f8d72014-02-17 15:24:26 +00002695 /**
senorblancoafc7cce2016-02-02 18:44:15 -08002696 * Gets the bounds of the top level layer in global canvas coordinates. We don't want this
bsalomon@google.com4ebe3822014-02-26 20:22:32 +00002697 * to be public because it exposes decisions about layer sizes that are internal to the canvas.
2698 */
senorblancoafc7cce2016-02-02 18:44:15 -08002699 SkIRect getTopLayerBounds() const;
commit-bot@chromium.org403f8d72014-02-17 15:24:26 +00002700
reed@google.com71121732012-09-18 15:14:33 +00002701 void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002702 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002703 SrcRectConstraint);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00002704 void internalDrawPaint(const SkPaint& paint);
reed4960eee2015-12-18 07:09:18 -08002705 void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
Florin Malita53f77bd2017-04-28 13:48:37 -04002706 void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, SkImage* clipImage,
2707 const SkMatrix& clipMatrix);
bsalomon@google.comfa6ac932011-10-05 19:57:55 +00002708
reed@android.com8a1c16f2008-12-17 15:59:43 +00002709 // shared by save() and saveLayer()
reed2ff1fce2014-12-11 07:07:37 -08002710 void internalSave();
reed@android.com8a1c16f2008-12-17 15:59:43 +00002711 void internalRestore();
reed@google.com4b226022011-01-11 18:32:13 +00002712
reedc83a2972015-07-16 07:40:45 -07002713 /*
2714 * Returns true if drawing the specified rect (or all if it is null) with the specified
2715 * paint (or default if null) would overwrite the entire root device of the canvas
2716 * (i.e. the canvas' surface if it had one).
2717 */
2718 bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
2719
reed262a71b2015-12-05 13:07:27 -08002720 /**
2721 * Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
2722 */
2723 bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
reedc83a2972015-07-16 07:40:45 -07002724
Mike Reeda1361362017-03-07 09:37:29 -05002725 /**
2726 * Returns true if the clip (for any active layer) contains antialiasing.
2727 * If the clip is empty, this will return false.
Mike Reed46784be2017-01-15 20:02:32 -05002728 */
Mike Reeda1361362017-03-07 09:37:29 -05002729 bool androidFramework_isClipAA() const;
msarettfbfa2582016-08-12 08:29:08 -07002730
2731 /**
2732 * Keep track of the device clip bounds and if the matrix is scale-translate. This allows
2733 * us to do a fast quick reject in the common case.
reed@android.com8a1c16f2008-12-17 15:59:43 +00002734 */
msarett9637ea92016-08-18 14:03:30 -07002735 bool fIsScaleTranslate;
msarettfbfa2582016-08-12 08:29:08 -07002736 SkRect fDeviceClipBounds;
2737
caryclark@google.com8f0a7b82012-11-07 14:54:49 +00002738 bool fAllowSoftClip;
caryclark@google.com45a75fb2013-04-25 13:34:40 +00002739 bool fAllowSimplifyClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +00002740
reed@google.com5c3d1472011-02-22 19:12:23 +00002741 class AutoValidateClip : ::SkNoncopyable {
2742 public:
2743 explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
2744 fCanvas->validateClip();
2745 }
2746 ~AutoValidateClip() { fCanvas->validateClip(); }
2747
2748 private:
2749 const SkCanvas* fCanvas;
2750 };
2751
2752#ifdef SK_DEBUG
2753 void validateClip() const;
2754#else
2755 void validateClip() const {}
2756#endif
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +00002757
2758 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +00002759};
2760
Cary Clarkcc309eb2017-10-30 11:48:35 -04002761/** \class SkAutoCanvasRestore
2762 Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
2763 goes out of scope. Use this to guarantee that the canvas is restored to a known
2764 state.
reed@android.com8a1c16f2008-12-17 15:59:43 +00002765*/
2766class SkAutoCanvasRestore : SkNoncopyable {
2767public:
Cary Clarkcc309eb2017-10-30 11:48:35 -04002768
Cary Clark75959392018-02-27 10:22:04 -05002769 /** Preserves SkCanvas save count. Optionally saves SkCanvas clip and SkCanvas matrix.
Cary Clarkcc309eb2017-10-30 11:48:35 -04002770
2771 @param canvas SkCanvas to guard
2772 @param doSave call SkCanvas::save()
2773 @return utility to restore SkCanvas state on destructor
2774 */
commit-bot@chromium.org28871192013-10-14 15:28:01 +00002775 SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
2776 if (fCanvas) {
2777 fSaveCount = canvas->getSaveCount();
2778 if (doSave) {
2779 canvas->save();
2780 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00002781 }
2782 }
Cary Clarkcc309eb2017-10-30 11:48:35 -04002783
Cary Clark2823f9f2018-01-03 10:00:34 -05002784 /** Restores SkCanvas to saved state. Destructor is called when container goes out of
2785 scope.
Cary Clarkcc309eb2017-10-30 11:48:35 -04002786 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00002787 ~SkAutoCanvasRestore() {
reed@google.comf6c9a5b2012-11-20 15:12:21 +00002788 if (fCanvas) {
2789 fCanvas->restoreToCount(fSaveCount);
2790 }
2791 }
2792
Cary Clarkcc309eb2017-10-30 11:48:35 -04002793 /** Restores SkCanvas to saved state immediately. Subsequent calls and
2794 ~SkAutoCanvasRestore have no effect.
2795 */
reed@google.comf6c9a5b2012-11-20 15:12:21 +00002796 void restore() {
2797 if (fCanvas) {
2798 fCanvas->restoreToCount(fSaveCount);
Ben Wagnera93a14a2017-08-28 10:34:05 -04002799 fCanvas = nullptr;
reed@google.comf6c9a5b2012-11-20 15:12:21 +00002800 }
reed@android.com8a1c16f2008-12-17 15:59:43 +00002801 }
2802
2803private:
2804 SkCanvas* fCanvas;
2805 int fSaveCount;
2806};
commit-bot@chromium.orge61a86c2013-11-18 16:03:59 +00002807#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
reed@android.com8a1c16f2008-12-17 15:59:43 +00002808
2809#endif