• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkCanvas_DEFINED
9 #define SkCanvas_DEFINED
10 
11 #include "include/core/SkBlendMode.h"
12 #include "include/core/SkClipOp.h"
13 #include "include/core/SkColor.h"
14 #include "include/core/SkFontTypes.h"
15 #include "include/core/SkImageInfo.h"
16 #include "include/core/SkM44.h"
17 #include "include/core/SkMatrix.h"
18 #include "include/core/SkPaint.h"
19 #include "include/core/SkPoint.h"
20 #include "include/core/SkRasterHandleAllocator.h"
21 #include "include/core/SkRect.h"
22 #include "include/core/SkRefCnt.h"
23 #include "include/core/SkSamplingOptions.h"
24 #include "include/core/SkScalar.h"
25 #include "include/core/SkSize.h"
26 #include "include/core/SkString.h"
27 #include "include/core/SkSurfaceProps.h"
28 #include "include/core/SkTypes.h"
29 #include "include/private/SkDeque.h"
30 #include "include/private/SkMacros.h"
31 
32 #include <cstring>
33 #include <memory>
34 #include <vector>
35 
36 #ifndef SK_SUPPORT_LEGACY_GETTOTALMATRIX
37 #define SK_SUPPORT_LEGACY_GETTOTALMATRIX
38 #endif
39 
40 class AutoLayerForImageFilter;
41 class GrBackendRenderTarget;
42 class GrRecordingContext;
43 class SkBaseDevice;
44 class SkBitmap;
45 class SkData;
46 class SkDrawable;
47 struct SkDrawShadowRec;
48 class SkFont;
49 class SkGlyphRunBuilder;
50 class SkGlyphRunList;
51 class SkImage;
52 class SkImageFilter;
53 class SkMarkerStack;
54 class SkPaintFilterCanvas;
55 class SkPath;
56 class SkPicture;
57 class SkPixmap;
58 class SkRegion;
59 class SkRRect;
60 struct SkRSXform;
61 class SkSpecialImage;
62 class SkSurface;
63 class SkSurface_Base;
64 class SkTextBlob;
65 class SkVertices;
66 
67 namespace skstd {
68     template<typename T> class optional;
69 }
70 
71 /** \class SkCanvas
72     SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
73     SkCanvas contains a stack of SkMatrix and clip values.
74 
75     SkCanvas and SkPaint together provide the state to draw into SkSurface or SkBaseDevice.
76     Each SkCanvas draw call transforms the geometry of the object by the concatenation of all
77     SkMatrix values in the stack. The transformed geometry is clipped by the intersection
78     of all of clip values in the stack. The SkCanvas draw calls use SkPaint to supply drawing
79     state such as color, SkTypeface, text size, stroke width, SkShader and so on.
80 
81     To draw to a pixel-based destination, create raster surface or GPU surface.
82     Request SkCanvas from SkSurface to obtain the interface to draw.
83     SkCanvas generated by raster surface draws to memory visible to the CPU.
84     SkCanvas generated by GPU surface uses Vulkan or OpenGL to draw to the GPU.
85 
86     To draw to a document, obtain SkCanvas from SVG canvas, document PDF, or SkPictureRecorder.
87     SkDocument based SkCanvas and other SkCanvas subclasses reference SkBaseDevice describing the
88     destination.
89 
90     SkCanvas can be constructed to draw to SkBitmap without first creating raster surface.
91     This approach may be deprecated in the future.
92 */
93 class SK_API SkCanvas {
94 public:
95 
96     /** Allocates raster SkCanvas that will draw directly into pixels.
97 
98         SkCanvas is returned if all parameters are valid.
99         Valid parameters include:
100         info dimensions are zero or positive;
101         info contains SkColorType and SkAlphaType supported by raster surface;
102         pixels is not nullptr;
103         rowBytes is zero or large enough to contain info width pixels of SkColorType.
104 
105         Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
106         If rowBytes is greater than zero, it must be equal to or greater than
107         info width times bytes required for SkColorType.
108 
109         Pixel buffer size should be info height times computed rowBytes.
110         Pixels are not initialized.
111         To access pixels after drawing, call flush() or peekPixels().
112 
113         @param info      width, height, SkColorType, SkAlphaType, SkColorSpace, of raster surface;
114                          width, or height, or both, may be zero
115         @param pixels    pointer to destination pixels buffer
116         @param rowBytes  interval from one SkSurface row to the next, or zero
117         @param props     LCD striping orientation and setting for device independent fonts;
118                          may be nullptr
119         @return          SkCanvas if all parameters are valid; otherwise, nullptr
120     */
121     static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
122                                                       size_t rowBytes,
123                                                       const SkSurfaceProps* props = nullptr);
124 
125     /** Allocates raster SkCanvas specified by inline image specification. Subsequent SkCanvas
126         calls draw into pixels.
127         SkColorType is set to kN32_SkColorType.
128         SkAlphaType is set to kPremul_SkAlphaType.
129         To access pixels after drawing, call flush() or peekPixels().
130 
131         SkCanvas is returned if all parameters are valid.
132         Valid parameters include:
133         width and height are zero or positive;
134         pixels is not nullptr;
135         rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
136 
137         Pass zero for rowBytes to compute rowBytes from width and size of pixel.
138         If rowBytes is greater than zero, it must be equal to or greater than
139         width times bytes required for SkColorType.
140 
141         Pixel buffer size should be height times rowBytes.
142 
143         @param width     pixel column count on raster surface created; must be zero or greater
144         @param height    pixel row count on raster surface created; must be zero or greater
145         @param pixels    pointer to destination pixels buffer; buffer size should be height
146                          times rowBytes
147         @param rowBytes  interval from one SkSurface row to the next, or zero
148         @return          SkCanvas if all parameters are valid; otherwise, nullptr
149     */
MakeRasterDirectN32(int width,int height,SkPMColor * pixels,size_t rowBytes)150     static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
151                                                          size_t rowBytes) {
152         return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
153     }
154 
155     /** Creates an empty SkCanvas with no backing device or pixels, with
156         a width and height of zero.
157 
158         @return  empty SkCanvas
159 
160         example: https://fiddle.skia.org/c/@Canvas_empty_constructor
161     */
162     SkCanvas();
163 
164     /** Creates SkCanvas of the specified dimensions without a SkSurface.
165         Used by subclasses with custom implementations for draw member functions.
166 
167         If props equals nullptr, SkSurfaceProps are created with
168         SkSurfaceProps::InitType settings, which choose the pixel striping
169         direction and order. Since a platform may dynamically change its direction when
170         the device is rotated, and since a platform may have multiple monitors with
171         different characteristics, it is best not to rely on this legacy behavior.
172 
173         @param width   zero or greater
174         @param height  zero or greater
175         @param props   LCD striping orientation and setting for device independent fonts;
176                        may be nullptr
177         @return        SkCanvas placeholder with dimensions
178 
179         example: https://fiddle.skia.org/c/@Canvas_int_int_const_SkSurfaceProps_star
180     */
181     SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr);
182 
183     /** Private. For internal use only.
184     */
185     explicit SkCanvas(sk_sp<SkBaseDevice> device);
186 
187     /** Constructs a canvas that draws into bitmap.
188         Sets kUnknown_SkPixelGeometry in constructed SkSurface.
189 
190         SkBitmap is copied so that subsequently editing bitmap will not affect
191         constructed SkCanvas.
192 
193         May be deprecated in the future.
194 
195         @param bitmap  width, height, SkColorType, SkAlphaType, and pixel
196                        storage of raster surface
197         @return        SkCanvas that can be used to draw into bitmap
198 
199         example: https://fiddle.skia.org/c/@Canvas_copy_const_SkBitmap
200     */
201     explicit SkCanvas(const SkBitmap& bitmap);
202 
203 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
204     /** Private.
205      */
206     enum class ColorBehavior {
207         kLegacy, //!< placeholder
208     };
209 
210     /** Private. For use by Android framework only.
211 
212         @param bitmap    specifies a bitmap for the canvas to draw into
213         @param behavior  specializes this constructor; value is unused
214         @return          SkCanvas that can be used to draw into bitmap
215     */
216     SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
217 #endif
218 
219     /** Constructs a canvas that draws into bitmap.
220         Use props to match the device characteristics, like LCD striping.
221 
222         bitmap is copied so that subsequently editing bitmap will not affect
223         constructed SkCanvas.
224 
225         @param bitmap  width, height, SkColorType, SkAlphaType,
226                        and pixel storage of raster surface
227         @param props   order and orientation of RGB striping; and whether to use
228                        device independent fonts
229         @return        SkCanvas that can be used to draw into bitmap
230 
231         example: https://fiddle.skia.org/c/@Canvas_const_SkBitmap_const_SkSurfaceProps
232     */
233     SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
234 
235     /** Draws saved layers, if any.
236         Frees up resources used by SkCanvas.
237 
238         example: https://fiddle.skia.org/c/@Canvas_destructor
239     */
240     virtual ~SkCanvas();
241 
242     /** Returns SkImageInfo for SkCanvas. If SkCanvas is not associated with raster surface or
243         GPU surface, returned SkColorType is set to kUnknown_SkColorType.
244 
245         @return  dimensions and SkColorType of SkCanvas
246 
247         example: https://fiddle.skia.org/c/@Canvas_imageInfo
248     */
249     SkImageInfo imageInfo() const;
250 
251     /** Copies SkSurfaceProps, if SkCanvas is associated with raster surface or
252         GPU surface, and returns true. Otherwise, returns false and leave props unchanged.
253 
254         @param props  storage for writable SkSurfaceProps
255         @return       true if SkSurfaceProps was copied
256 
257         example: https://fiddle.skia.org/c/@Canvas_getProps
258     */
259     bool getProps(SkSurfaceProps* props) const;
260 
261     /** Triggers the immediate execution of all pending draw operations.
262         If SkCanvas is associated with GPU surface, resolves all pending GPU operations.
263         If SkCanvas is associated with raster surface, has no effect; raster draw
264         operations are never deferred.
265 
266         DEPRECATED: Replace usage with GrDirectContext::flush()
267     */
268     void flush();
269 
270     /** Gets the size of the base or root layer in global canvas coordinates. The
271         origin of the base layer is always (0,0). The area available for drawing may be
272         smaller (due to clipping or saveLayer).
273 
274         @return  integral width and height of base layer
275 
276         example: https://fiddle.skia.org/c/@Canvas_getBaseLayerSize
277     */
278     virtual SkISize getBaseLayerSize() const;
279 
280     /** Creates SkSurface matching info and props, and associates it with SkCanvas.
281         Returns nullptr if no match found.
282 
283         If props is nullptr, matches SkSurfaceProps in SkCanvas. If props is nullptr and SkCanvas
284         does not have SkSurfaceProps, creates SkSurface with default SkSurfaceProps.
285 
286         @param info   width, height, SkColorType, SkAlphaType, and SkColorSpace
287         @param props  SkSurfaceProps to match; may be nullptr to match SkCanvas
288         @return       SkSurface matching info and props, or nullptr if no match is available
289 
290         example: https://fiddle.skia.org/c/@Canvas_makeSurface
291     */
292     sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);
293 
294     /** Returns GPU context of the GPU surface associated with SkCanvas.
295 
296         @return  GPU context, if available; nullptr otherwise
297 
298         example: https://fiddle.skia.org/c/@Canvas_recordingContext
299      */
300     virtual GrRecordingContext* recordingContext();
301 
302     /** Sometimes a canvas is owned by a surface. If it is, getSurface() will return a bare
303      *  pointer to that surface, else this will return nullptr.
304      */
305     SkSurface* getSurface() const;
306 
307     /** Returns the pixel base address, SkImageInfo, rowBytes, and origin if the pixels
308         can be read directly. The returned address is only valid
309         while SkCanvas is in scope and unchanged. Any SkCanvas call or SkSurface call
310         may invalidate the returned address and other returned values.
311 
312         If pixels are inaccessible, info, rowBytes, and origin are unchanged.
313 
314         @param info      storage for writable pixels' SkImageInfo; may be nullptr
315         @param rowBytes  storage for writable pixels' row bytes; may be nullptr
316         @param origin    storage for SkCanvas top layer origin, its top-left corner;
317                          may be nullptr
318         @return          address of pixels, or nullptr if inaccessible
319 
320         example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_a
321         example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_b
322     */
323     void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr);
324 
325     /** Returns custom context that tracks the SkMatrix and clip.
326 
327         Use SkRasterHandleAllocator to blend Skia drawing with custom drawing, typically performed
328         by the host platform user interface. The custom context returned is generated by
329         SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
330         the drawing destination.
331 
332         @return  context of custom allocation
333 
334         example: https://fiddle.skia.org/c/@Canvas_accessTopRasterHandle
335     */
336     SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
337 
338     /** Returns true if SkCanvas has direct access to its pixels.
339 
340         Pixels are readable when SkBaseDevice is raster. Pixels are not readable when SkCanvas
341         is returned from GPU surface, returned by SkDocument::beginPage, returned by
342         SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
343         like DebugCanvas.
344 
345         pixmap is valid only while SkCanvas is in scope and unchanged. Any
346         SkCanvas or SkSurface call may invalidate the pixmap values.
347 
348         @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
349         @return        true if SkCanvas has direct access to pixels
350 
351         example: https://fiddle.skia.org/c/@Canvas_peekPixels
352     */
353     bool peekPixels(SkPixmap* pixmap);
354 
355     /** Copies SkRect of pixels from SkCanvas into dstPixels. SkMatrix and clip are
356         ignored.
357 
358         Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
359         Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
360         Copies each readable pixel intersecting both rectangles, without scaling,
361         converting to dstInfo.colorType() and dstInfo.alphaType() if required.
362 
363         Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
364         Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
365         returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
366         class like DebugCanvas.
367 
368         The destination pixel storage must be allocated by the caller.
369 
370         Pixel values are converted only if SkColorType and SkAlphaType
371         do not match. Only pixels within both source and destination rectangles
372         are copied. dstPixels contents outside SkRect intersection are unchanged.
373 
374         Pass negative values for srcX or srcY to offset pixels across or down destination.
375 
376         Does not copy, and returns false if:
377         - Source and destination rectangles do not intersect.
378         - SkCanvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
379         - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
380         - dstRowBytes is too small to contain one row of pixels.
381 
382         @param dstInfo      width, height, SkColorType, and SkAlphaType of dstPixels
383         @param dstPixels    storage for pixels; dstInfo.height() times dstRowBytes, or larger
384         @param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger
385         @param srcX         offset into readable pixels on x-axis; may be negative
386         @param srcY         offset into readable pixels on y-axis; may be negative
387         @return             true if pixels were copied
388     */
389     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
390                     int srcX, int srcY);
391 
392     /** Copies SkRect of pixels from SkCanvas into pixmap. SkMatrix and clip are
393         ignored.
394 
395         Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
396         Destination SkRect corners are (0, 0) and (pixmap.width(), pixmap.height()).
397         Copies each readable pixel intersecting both rectangles, without scaling,
398         converting to pixmap.colorType() and pixmap.alphaType() if required.
399 
400         Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
401         Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
402         returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
403         class like DebugCanvas.
404 
405         Caller must allocate pixel storage in pixmap if needed.
406 
407         Pixel values are converted only if SkColorType and SkAlphaType
408         do not match. Only pixels within both source and destination SkRect
409         are copied. pixmap pixels contents outside SkRect intersection are unchanged.
410 
411         Pass negative values for srcX or srcY to offset pixels across or down pixmap.
412 
413         Does not copy, and returns false if:
414         - Source and destination rectangles do not intersect.
415         - SkCanvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType().
416         - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
417         - SkPixmap pixels could not be allocated.
418         - pixmap.rowBytes() is too small to contain one row of pixels.
419 
420         @param pixmap  storage for pixels copied from SkCanvas
421         @param srcX    offset into readable pixels on x-axis; may be negative
422         @param srcY    offset into readable pixels on y-axis; may be negative
423         @return        true if pixels were copied
424 
425         example: https://fiddle.skia.org/c/@Canvas_readPixels_2
426     */
427     bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);
428 
429     /** Copies SkRect of pixels from SkCanvas into bitmap. SkMatrix and clip are
430         ignored.
431 
432         Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
433         Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
434         Copies each readable pixel intersecting both rectangles, without scaling,
435         converting to bitmap.colorType() and bitmap.alphaType() if required.
436 
437         Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
438         Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
439         returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
440         class like DebugCanvas.
441 
442         Caller must allocate pixel storage in bitmap if needed.
443 
444         SkBitmap values are converted only if SkColorType and SkAlphaType
445         do not match. Only pixels within both source and destination rectangles
446         are copied. SkBitmap pixels outside SkRect intersection are unchanged.
447 
448         Pass negative values for srcX or srcY to offset pixels across or down bitmap.
449 
450         Does not copy, and returns false if:
451         - Source and destination rectangles do not intersect.
452         - SkCanvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType().
453         - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
454         - bitmap pixels could not be allocated.
455         - bitmap.rowBytes() is too small to contain one row of pixels.
456 
457         @param bitmap  storage for pixels copied from SkCanvas
458         @param srcX    offset into readable pixels on x-axis; may be negative
459         @param srcY    offset into readable pixels on y-axis; may be negative
460         @return        true if pixels were copied
461 
462         example: https://fiddle.skia.org/c/@Canvas_readPixels_3
463     */
464     bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);
465 
466     /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
467         Source SkRect corners are (0, 0) and (info.width(), info.height()).
468         Destination SkRect corners are (x, y) and
469         (imageInfo().width(), imageInfo().height()).
470 
471         Copies each readable pixel intersecting both rectangles, without scaling,
472         converting to imageInfo().colorType() and imageInfo().alphaType() if required.
473 
474         Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
475         Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
476         returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
477         class like DebugCanvas.
478 
479         Pixel values are converted only if SkColorType and SkAlphaType
480         do not match. Only pixels within both source and destination rectangles
481         are copied. SkCanvas pixels outside SkRect intersection are unchanged.
482 
483         Pass negative values for x or y to offset pixels to the left or
484         above SkCanvas pixels.
485 
486         Does not copy, and returns false if:
487         - Source and destination rectangles do not intersect.
488         - pixels could not be converted to SkCanvas imageInfo().colorType() or
489         imageInfo().alphaType().
490         - SkCanvas pixels are not writable; for instance, SkCanvas is document-based.
491         - rowBytes is too small to contain one row of pixels.
492 
493         @param info      width, height, SkColorType, and SkAlphaType of pixels
494         @param pixels    pixels to copy, of size info.height() times rowBytes, or larger
495         @param rowBytes  size of one row of pixels; info.width() times pixel size, or larger
496         @param x         offset into SkCanvas writable pixels on x-axis; may be negative
497         @param y         offset into SkCanvas writable pixels on y-axis; may be negative
498         @return          true if pixels were written to SkCanvas
499 
500         example: https://fiddle.skia.org/c/@Canvas_writePixels
501     */
502     bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);
503 
504     /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
505         Source SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
506 
507         Destination SkRect corners are (x, y) and
508         (imageInfo().width(), imageInfo().height()).
509 
510         Copies each readable pixel intersecting both rectangles, without scaling,
511         converting to imageInfo().colorType() and imageInfo().alphaType() if required.
512 
513         Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
514         Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
515         returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
516         class like DebugCanvas.
517 
518         Pixel values are converted only if SkColorType and SkAlphaType
519         do not match. Only pixels within both source and destination rectangles
520         are copied. SkCanvas pixels outside SkRect intersection are unchanged.
521 
522         Pass negative values for x or y to offset pixels to the left or
523         above SkCanvas pixels.
524 
525         Does not copy, and returns false if:
526         - Source and destination rectangles do not intersect.
527         - bitmap does not have allocated pixels.
528         - bitmap pixels could not be converted to SkCanvas imageInfo().colorType() or
529         imageInfo().alphaType().
530         - SkCanvas pixels are not writable; for instance, SkCanvas is document based.
531         - bitmap pixels are inaccessible; for instance, bitmap wraps a texture.
532 
533         @param bitmap  contains pixels copied to SkCanvas
534         @param x       offset into SkCanvas writable pixels on x-axis; may be negative
535         @param y       offset into SkCanvas writable pixels on y-axis; may be negative
536         @return        true if pixels were written to SkCanvas
537 
538         example: https://fiddle.skia.org/c/@Canvas_writePixels_2
539         example: https://fiddle.skia.org/c/@State_Stack_a
540         example: https://fiddle.skia.org/c/@State_Stack_b
541     */
542     bool writePixels(const SkBitmap& bitmap, int x, int y);
543 
544     /** Saves SkMatrix and clip.
545         Calling restore() discards changes to SkMatrix and clip,
546         restoring the SkMatrix and clip to their state when save() was called.
547 
548         SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix(),
549         and resetMatrix(). Clip may be changed by clipRect(), clipRRect(), clipPath(), clipRegion().
550 
551         Saved SkCanvas state is put on a stack; multiple calls to save() should be balance
552         by an equal number of calls to restore().
553 
554         Call restoreToCount() with result to restore this and subsequent saves.
555 
556         @return  depth of saved stack
557 
558         example: https://fiddle.skia.org/c/@Canvas_save
559     */
560     int save();
561 
562     /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
563         Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.
564 
565         SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
566         setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
567         clipPath(), clipRegion().
568 
569         SkRect bounds suggests but does not define the SkBitmap size. To clip drawing to
570         a specific rectangle, use clipRect().
571 
572         Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
573         SkBlendMode when restore() is called.
574 
575         Call restoreToCount() with returned value to restore this and subsequent saves.
576 
577         @param bounds  hint to limit the size of the layer; may be nullptr
578         @param paint   graphics state for layer; may be nullptr
579         @return        depth of saved stack
580 
581         example: https://fiddle.skia.org/c/@Canvas_saveLayer
582         example: https://fiddle.skia.org/c/@Canvas_saveLayer_4
583     */
584     int saveLayer(const SkRect* bounds, const SkPaint* paint);
585 
586     /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
587         Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.
588 
589         SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
590         setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
591         clipPath(), clipRegion().
592 
593         SkRect bounds suggests but does not define the layer size. To clip drawing to
594         a specific rectangle, use clipRect().
595 
596         Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
597         SkBlendMode when restore() is called.
598 
599         Call restoreToCount() with returned value to restore this and subsequent saves.
600 
601         @param bounds  hint to limit the size of layer; may be nullptr
602         @param paint   graphics state for layer; may be nullptr
603         @return        depth of saved stack
604     */
saveLayer(const SkRect & bounds,const SkPaint * paint)605     int saveLayer(const SkRect& bounds, const SkPaint* paint) {
606         return this->saveLayer(&bounds, paint);
607     }
608 
609     /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.
610 
611         Calling restore() discards changes to SkMatrix and clip,
612         and blends layer with alpha opacity onto prior layer.
613 
614         SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
615         setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
616         clipPath(), clipRegion().
617 
618         SkRect bounds suggests but does not define layer size. To clip drawing to
619         a specific rectangle, use clipRect().
620 
621         alpha of zero is fully transparent, 255 is fully opaque.
622 
623         Call restoreToCount() with returned value to restore this and subsequent saves.
624 
625         @param bounds  hint to limit the size of layer; may be nullptr
626         @param alpha   opacity of layer
627         @return        depth of saved stack
628 
629         example: https://fiddle.skia.org/c/@Canvas_saveLayerAlpha
630     */
631     int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
632 
633     /** \enum SkCanvas::SaveLayerFlagsSet
634         SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
635         defining how layer allocated by saveLayer() operates. It may be set to zero,
636         kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
637     */
638     enum SaveLayerFlagsSet {
639         kPreserveLCDText_SaveLayerFlag  = 1 << 1,
640         kInitWithPrevious_SaveLayerFlag = 1 << 2, //!< initializes with previous contents
641         kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag =
642                                           1 << 3, //!< experimental: do not use
643         // instead of matching previous layer's colortype, use F16
644         kF16ColorType                   = 1 << 4,
645     };
646 
647     typedef uint32_t SaveLayerFlags;
648 
649     /** \struct SkCanvas::SaveLayerRec
650         SaveLayerRec contains the state used to create the layer.
651     */
652     struct SaveLayerRec {
653         /** Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
654 
655             @return  empty SaveLayerRec
656         */
SaveLayerRecSaveLayerRec657         SaveLayerRec() {}
658 
659         /** Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
660 
661             @param bounds          layer dimensions; may be nullptr
662             @param paint           applied to layer when overlaying prior layer; may be nullptr
663             @param saveLayerFlags  SaveLayerRec options to modify layer
664             @return                SaveLayerRec with empty fBackdrop
665         */
666         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
667             : SaveLayerRec(bounds, paint, nullptr, 1.f, saveLayerFlags) {}
668 
669         /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
670 
671             @param bounds          layer dimensions; may be nullptr
672             @param paint           applied to layer when overlaying prior layer;
673                                    may be nullptr
674             @param backdrop        If not null, this causes the current layer to be filtered by
675                                    backdrop, and then drawn into the new layer
676                                    (respecting the current clip).
677                                    If null, the new layer is initialized with transparent-black.
678             @param saveLayerFlags  SaveLayerRec options to modify layer
679             @return                SaveLayerRec fully specified
680         */
SaveLayerRecSaveLayerRec681         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
682                      SaveLayerFlags saveLayerFlags)
683             : SaveLayerRec(bounds, paint, backdrop, 1.f, saveLayerFlags) {}
684 
685         /** hints at layer size limit */
686         const SkRect*        fBounds         = nullptr;
687 
688         /** modifies overlay */
689         const SkPaint*       fPaint          = nullptr;
690 
691         /**
692          *  If not null, this triggers the same initialization behavior as setting
693          *  kInitWithPrevious_SaveLayerFlag on fSaveLayerFlags: the current layer is copied into
694          *  the new layer, rather than initializing the new layer with transparent-black.
695          *  This is then filtered by fBackdrop (respecting the current clip).
696          */
697         const SkImageFilter* fBackdrop       = nullptr;
698 
699         /** preserves LCD text, creates with prior layer contents */
700         SaveLayerFlags       fSaveLayerFlags = 0;
701 
702     private:
703         friend class SkCanvas;
704         friend class SkCanvasPriv;
705 
SaveLayerRecSaveLayerRec706         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
707                      SkScalar backdropScale, SaveLayerFlags saveLayerFlags)
708             : fBounds(bounds)
709             , fPaint(paint)
710             , fBackdrop(backdrop)
711             , fSaveLayerFlags(saveLayerFlags)
712             , fExperimentalBackdropScale(backdropScale) {}
713 
714         // Relative scale factor that the image content used to initialize the layer when the
715         // kInitFromPrevious flag or a backdrop filter is used.
716         SkScalar             fExperimentalBackdropScale = 1.f;
717     };
718 
719     /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.
720 
721         Calling restore() discards changes to SkMatrix and clip,
722         and blends SkBitmap with alpha opacity onto the prior layer.
723 
724         SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
725         setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
726         clipPath(), clipRegion().
727 
728         SaveLayerRec contains the state used to create the layer.
729 
730         Call restoreToCount() with returned value to restore this and subsequent saves.
731 
732         @param layerRec  layer state
733         @return          depth of save state stack before this call was made.
734 
735         example: https://fiddle.skia.org/c/@Canvas_saveLayer_3
736     */
737     int saveLayer(const SaveLayerRec& layerRec);
738 
739     /** Removes changes to SkMatrix and clip since SkCanvas state was
740         last saved. The state is removed from the stack.
741 
742         Does nothing if the stack is empty.
743 
744         example: https://fiddle.skia.org/c/@AutoCanvasRestore_restore
745 
746         example: https://fiddle.skia.org/c/@Canvas_restore
747     */
748     void restore();
749 
750     /** Returns the number of saved states, each containing: SkMatrix and clip.
751         Equals the number of save() calls less the number of restore() calls plus one.
752         The save count of a new canvas is one.
753 
754         @return  depth of save state stack
755 
756         example: https://fiddle.skia.org/c/@Canvas_getSaveCount
757     */
758     int getSaveCount() const;
759 
760     /** Restores state to SkMatrix and clip values when save(), saveLayer(),
761         saveLayerPreserveLCDTextRequests(), or saveLayerAlpha() returned saveCount.
762 
763         Does nothing if saveCount is greater than state stack count.
764         Restores state to initial values if saveCount is less than or equal to one.
765 
766         @param saveCount  depth of state stack to restore
767 
768         example: https://fiddle.skia.org/c/@Canvas_restoreToCount
769     */
770     void restoreToCount(int saveCount);
771 
772     /** Translates SkMatrix by dx along the x-axis and dy along the y-axis.
773 
774         Mathematically, replaces SkMatrix with a translation matrix
775         premultiplied with SkMatrix.
776 
777         This has the effect of moving the drawing by (dx, dy) before transforming
778         the result with SkMatrix.
779 
780         @param dx  distance to translate on x-axis
781         @param dy  distance to translate on y-axis
782 
783         example: https://fiddle.skia.org/c/@Canvas_translate
784     */
785     void translate(SkScalar dx, SkScalar dy);
786 
787     /** Scales SkMatrix by sx on the x-axis and sy on the y-axis.
788 
789         Mathematically, replaces SkMatrix with a scale matrix
790         premultiplied with SkMatrix.
791 
792         This has the effect of scaling the drawing by (sx, sy) before transforming
793         the result with SkMatrix.
794 
795         @param sx  amount to scale on x-axis
796         @param sy  amount to scale on y-axis
797 
798         example: https://fiddle.skia.org/c/@Canvas_scale
799     */
800     void scale(SkScalar sx, SkScalar sy);
801 
802     /** Rotates SkMatrix by degrees. Positive degrees rotates clockwise.
803 
804         Mathematically, replaces SkMatrix with a rotation matrix
805         premultiplied with SkMatrix.
806 
807         This has the effect of rotating the drawing by degrees before transforming
808         the result with SkMatrix.
809 
810         @param degrees  amount to rotate, in degrees
811 
812         example: https://fiddle.skia.org/c/@Canvas_rotate
813     */
814     void rotate(SkScalar degrees);
815 
816     /** Rotates SkMatrix by degrees about a point at (px, py). Positive degrees rotates
817         clockwise.
818 
819         Mathematically, constructs a rotation matrix; premultiplies the rotation matrix by
820         a translation matrix; then replaces SkMatrix with the resulting matrix
821         premultiplied with SkMatrix.
822 
823         This has the effect of rotating the drawing about a given point before
824         transforming the result with SkMatrix.
825 
826         @param degrees  amount to rotate, in degrees
827         @param px       x-axis value of the point to rotate about
828         @param py       y-axis value of the point to rotate about
829 
830         example: https://fiddle.skia.org/c/@Canvas_rotate_2
831     */
832     void rotate(SkScalar degrees, SkScalar px, SkScalar py);
833 
834     /** Skews SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
835         skews the drawing right as y-axis values increase; a positive value of sy skews
836         the drawing down as x-axis values increase.
837 
838         Mathematically, replaces SkMatrix with a skew matrix premultiplied with SkMatrix.
839 
840         This has the effect of skewing the drawing by (sx, sy) before transforming
841         the result with SkMatrix.
842 
843         @param sx  amount to skew on x-axis
844         @param sy  amount to skew on y-axis
845 
846         example: https://fiddle.skia.org/c/@Canvas_skew
847     */
848     void skew(SkScalar sx, SkScalar sy);
849 
850     /** Replaces SkMatrix with matrix premultiplied with existing SkMatrix.
851 
852         This has the effect of transforming the drawn geometry by matrix, before
853         transforming the result with existing SkMatrix.
854 
855         @param matrix  matrix to premultiply with existing SkMatrix
856 
857         example: https://fiddle.skia.org/c/@Canvas_concat
858     */
859     void concat(const SkMatrix& matrix);
860     void concat(const SkM44&);
861 
862     /**
863      *  Record a marker (provided by caller) for the current CTM. This does not change anything
864      *  about the ctm or clip, but does "name" this matrix value, so it can be referenced by
865      *  custom effects (who access it by specifying the same name).
866      *
867      *  Within a save frame, marking with the same name more than once just replaces the previous
868      *  value. However, between save frames, marking with the same name does not lose the marker
869      *  in the previous save frame. It is "visible" when the current save() is balanced with
870      *  a restore().
871      */
872     void markCTM(const char* name);
873 
874     bool findMarkedCTM(const char* name, SkM44*) const;
875 
876     /** Replaces SkMatrix with matrix.
877         Unlike concat(), any prior matrix state is overwritten.
878 
879         @param matrix  matrix to copy, replacing existing SkMatrix
880 
881         example: https://fiddle.skia.org/c/@Canvas_setMatrix
882     */
883     void setMatrix(const SkM44& matrix);
884 
885     // DEPRECATED -- use SkM44 version
886     void setMatrix(const SkMatrix& matrix);
887 
888     /** Sets SkMatrix to the identity matrix.
889         Any prior matrix state is overwritten.
890 
891         example: https://fiddle.skia.org/c/@Canvas_resetMatrix
892     */
893     void resetMatrix();
894 
895     /** Replaces clip with the intersection or difference of clip and rect,
896         with an aliased or anti-aliased clip edge. rect is transformed by SkMatrix
897         before it is combined with clip.
898 
899         @param rect         SkRect to combine with clip
900         @param op           SkClipOp to apply to clip
901         @param doAntiAlias  true if clip is to be anti-aliased
902 
903         example: https://fiddle.skia.org/c/@Canvas_clipRect
904     */
905     void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);
906 
907     /** Replaces clip with the intersection or difference of clip and rect.
908         Resulting clip is aliased; pixels are fully contained by the clip.
909         rect is transformed by SkMatrix before it is combined with clip.
910 
911         @param rect  SkRect to combine with clip
912         @param op    SkClipOp to apply to clip
913     */
clipRect(const SkRect & rect,SkClipOp op)914     void clipRect(const SkRect& rect, SkClipOp op) {
915         this->clipRect(rect, op, false);
916     }
917 
918     /** Replaces clip with the intersection of clip and rect.
919         Resulting clip is aliased; pixels are fully contained by the clip.
920         rect is transformed by SkMatrix
921         before it is combined with clip.
922 
923         @param rect         SkRect to combine with clip
924         @param doAntiAlias  true if clip is to be anti-aliased
925     */
926     void clipRect(const SkRect& rect, bool doAntiAlias = false) {
927         this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
928     }
929 
930     void clipIRect(const SkIRect& irect, SkClipOp op = SkClipOp::kIntersect) {
931         this->clipRect(SkRect::Make(irect), op, false);
932     }
933 
934     /** Sets the maximum clip rectangle, which can be set by clipRect(), clipRRect() and
935         clipPath() and intersect the current clip with the specified rect.
936         The maximum clip affects only future clipping operations; it is not retroactive.
937         The clip restriction is not recorded in pictures.
938 
939         Pass an empty rect to disable maximum clip.
940         This private API is for use by Android framework only.
941 
942         DEPRECATED: Replace usage with SkAndroidFrameworkUtils::replaceClip()
943 
944         @param rect  maximum allowed clip in device coordinates
945     */
946     void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
947 
948     /** Replaces clip with the intersection or difference of clip and rrect,
949         with an aliased or anti-aliased clip edge.
950         rrect is transformed by SkMatrix
951         before it is combined with clip.
952 
953         @param rrect        SkRRect to combine with clip
954         @param op           SkClipOp to apply to clip
955         @param doAntiAlias  true if clip is to be anti-aliased
956 
957         example: https://fiddle.skia.org/c/@Canvas_clipRRect
958     */
959     void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
960 
961     /** Replaces clip with the intersection or difference of clip and rrect.
962         Resulting clip is aliased; pixels are fully contained by the clip.
963         rrect is transformed by SkMatrix before it is combined with clip.
964 
965         @param rrect  SkRRect to combine with clip
966         @param op     SkClipOp to apply to clip
967     */
clipRRect(const SkRRect & rrect,SkClipOp op)968     void clipRRect(const SkRRect& rrect, SkClipOp op) {
969         this->clipRRect(rrect, op, false);
970     }
971 
972     /** Replaces clip with the intersection of clip and rrect,
973         with an aliased or anti-aliased clip edge.
974         rrect is transformed by SkMatrix before it is combined with clip.
975 
976         @param rrect        SkRRect to combine with clip
977         @param doAntiAlias  true if clip is to be anti-aliased
978     */
979     void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
980         this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
981     }
982 
983     /** Replaces clip with the intersection or difference of clip and path,
984         with an aliased or anti-aliased clip edge. SkPath::FillType determines if path
985         describes the area inside or outside its contours; and if path contour overlaps
986         itself or another path contour, whether the overlaps form part of the area.
987         path is transformed by SkMatrix before it is combined with clip.
988 
989         @param path         SkPath to combine with clip
990         @param op           SkClipOp to apply to clip
991         @param doAntiAlias  true if clip is to be anti-aliased
992 
993         example: https://fiddle.skia.org/c/@Canvas_clipPath
994     */
995     void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
996 
997     /** Replaces clip with the intersection or difference of clip and path.
998         Resulting clip is aliased; pixels are fully contained by the clip.
999         SkPath::FillType determines if path
1000         describes the area inside or outside its contours; and if path contour overlaps
1001         itself or another path contour, whether the overlaps form part of the area.
1002         path is transformed by SkMatrix
1003         before it is combined with clip.
1004 
1005         @param path  SkPath to combine with clip
1006         @param op    SkClipOp to apply to clip
1007     */
clipPath(const SkPath & path,SkClipOp op)1008     void clipPath(const SkPath& path, SkClipOp op) {
1009         this->clipPath(path, op, false);
1010     }
1011 
1012     /** Replaces clip with the intersection of clip and path.
1013         Resulting clip is aliased; pixels are fully contained by the clip.
1014         SkPath::FillType determines if path
1015         describes the area inside or outside its contours; and if path contour overlaps
1016         itself or another path contour, whether the overlaps form part of the area.
1017         path is transformed by SkMatrix before it is combined with clip.
1018 
1019         @param path         SkPath to combine with clip
1020         @param doAntiAlias  true if clip is to be anti-aliased
1021     */
1022     void clipPath(const SkPath& path, bool doAntiAlias = false) {
1023         this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
1024     }
1025 
1026     void clipShader(sk_sp<SkShader>, SkClipOp = SkClipOp::kIntersect);
1027 
1028     /** Replaces clip with the intersection or difference of clip and SkRegion deviceRgn.
1029         Resulting clip is aliased; pixels are fully contained by the clip.
1030         deviceRgn is unaffected by SkMatrix.
1031 
1032         @param deviceRgn  SkRegion to combine with clip
1033         @param op         SkClipOp to apply to clip
1034 
1035         example: https://fiddle.skia.org/c/@Canvas_clipRegion
1036     */
1037     void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
1038 
1039     /** Returns true if SkRect rect, transformed by SkMatrix, can be quickly determined to be
1040         outside of clip. May return false even though rect is outside of clip.
1041 
1042         Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
1043 
1044         @param rect  SkRect to compare with clip
1045         @return      true if rect, transformed by SkMatrix, does not intersect clip
1046 
1047         example: https://fiddle.skia.org/c/@Canvas_quickReject
1048     */
1049     bool quickReject(const SkRect& rect) const;
1050 
1051     /** Returns true if path, transformed by SkMatrix, can be quickly determined to be
1052         outside of clip. May return false even though path is outside of clip.
1053 
1054         Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
1055 
1056         @param path  SkPath to compare with clip
1057         @return      true if path, transformed by SkMatrix, does not intersect clip
1058 
1059         example: https://fiddle.skia.org/c/@Canvas_quickReject_2
1060     */
1061     bool quickReject(const SkPath& path) const;
1062 
1063     /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1064         return SkRect::MakeEmpty, where all SkRect sides equal zero.
1065 
1066         SkRect returned is outset by one to account for partial pixel coverage if clip
1067         is anti-aliased.
1068 
1069         @return  bounds of clip in local coordinates
1070 
1071         example: https://fiddle.skia.org/c/@Canvas_getLocalClipBounds
1072     */
1073     SkRect getLocalClipBounds() const;
1074 
1075     /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
1076         return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1077 
1078         bounds is outset by one to account for partial pixel coverage if clip
1079         is anti-aliased.
1080 
1081         @param bounds  SkRect of clip in local coordinates
1082         @return        true if clip bounds is not empty
1083     */
getLocalClipBounds(SkRect * bounds)1084     bool getLocalClipBounds(SkRect* bounds) const {
1085         *bounds = this->getLocalClipBounds();
1086         return !bounds->isEmpty();
1087     }
1088 
1089     /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1090         return SkRect::MakeEmpty, where all SkRect sides equal zero.
1091 
1092         Unlike getLocalClipBounds(), returned SkIRect is not outset.
1093 
1094         @return  bounds of clip in SkBaseDevice coordinates
1095 
1096         example: https://fiddle.skia.org/c/@Canvas_getDeviceClipBounds
1097     */
1098     SkIRect getDeviceClipBounds() const;
1099 
1100     /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
1101         return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
1102 
1103         Unlike getLocalClipBounds(), bounds is not outset.
1104 
1105         @param bounds  SkRect of clip in device coordinates
1106         @return        true if clip bounds is not empty
1107     */
getDeviceClipBounds(SkIRect * bounds)1108     bool getDeviceClipBounds(SkIRect* bounds) const {
1109         *bounds = this->getDeviceClipBounds();
1110         return !bounds->isEmpty();
1111     }
1112 
1113     /** Fills clip with color color.
1114         mode determines how ARGB is combined with destination.
1115 
1116         @param color  unpremultiplied ARGB
1117         @param mode   SkBlendMode used to combine source color and destination
1118 
1119         example: https://fiddle.skia.org/c/@Canvas_drawColor
1120     */
1121     void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver) {
1122         this->drawColor(SkColor4f::FromColor(color), mode);
1123     }
1124 
1125     /** Fills clip with color color.
1126         mode determines how ARGB is combined with destination.
1127 
1128         @param color  SkColor4f representing unpremultiplied color.
1129         @param mode   SkBlendMode used to combine source color and destination
1130     */
1131     void drawColor(const SkColor4f& color, SkBlendMode mode = SkBlendMode::kSrcOver);
1132 
1133     /** Fills clip with color color using SkBlendMode::kSrc.
1134         This has the effect of replacing all pixels contained by clip with color.
1135 
1136         @param color  unpremultiplied ARGB
1137     */
clear(SkColor color)1138     void clear(SkColor color) {
1139         this->clear(SkColor4f::FromColor(color));
1140     }
1141 
1142     /** Fills clip with color color using SkBlendMode::kSrc.
1143         This has the effect of replacing all pixels contained by clip with color.
1144 
1145         @param color  SkColor4f representing unpremultiplied color.
1146     */
clear(const SkColor4f & color)1147     void clear(const SkColor4f& color) {
1148         this->drawColor(color, SkBlendMode::kSrc);
1149     }
1150 
1151     /** Makes SkCanvas contents undefined. Subsequent calls that read SkCanvas pixels,
1152         such as drawing with SkBlendMode, return undefined results. discard() does
1153         not change clip or SkMatrix.
1154 
1155         discard() may do nothing, depending on the implementation of SkSurface or SkBaseDevice
1156         that created SkCanvas.
1157 
1158         discard() allows optimized performance on subsequent draws by removing
1159         cached data associated with SkSurface or SkBaseDevice.
1160         It is not necessary to call discard() once done with SkCanvas;
1161         any cached data is deleted when owning SkSurface or SkBaseDevice is deleted.
1162     */
discard()1163     void discard() { this->onDiscard(); }
1164 
1165     /** Fills clip with SkPaint paint. SkPaint components, SkShader,
1166         SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
1167         SkMaskFilter and SkPathEffect in paint are ignored.
1168 
1169         @param paint  graphics state used to fill SkCanvas
1170 
1171         example: https://fiddle.skia.org/c/@Canvas_drawPaint
1172     */
1173     void drawPaint(const SkPaint& paint);
1174 
1175     /** \enum SkCanvas::PointMode
1176         Selects if an array of points are drawn as discrete points, as lines, or as
1177         an open polygon.
1178     */
1179     enum PointMode {
1180         kPoints_PointMode,  //!< draw each point separately
1181         kLines_PointMode,   //!< draw each pair of points as a line segment
1182         kPolygon_PointMode, //!< draw the array of points as a open polygon
1183     };
1184 
1185     /** Draws pts using clip, SkMatrix and SkPaint paint.
1186         count is the number of points; if count is less than one, has no effect.
1187         mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
1188 
1189         If mode is kPoints_PointMode, the shape of point drawn depends on paint
1190         SkPaint::Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
1191         circle of diameter SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap
1192         or SkPaint::kButt_Cap, each point draws a square of width and height
1193         SkPaint stroke width.
1194 
1195         If mode is kLines_PointMode, each pair of points draws a line segment.
1196         One line is drawn for every two points; each point is used once. If count is odd,
1197         the final point is ignored.
1198 
1199         If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
1200         count minus one lines are drawn; the first and last point are used once.
1201 
1202         Each line segment respects paint SkPaint::Cap and SkPaint stroke width.
1203         SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1204 
1205         Always draws each element one at a time; is not affected by
1206         SkPaint::Join, and unlike drawPath(), does not create a mask from all points
1207         and lines before drawing.
1208 
1209         @param mode   whether pts draws points or lines
1210         @param count  number of points in the array
1211         @param pts    array of points to draw
1212         @param paint  stroke, blend, color, and so on, used to draw
1213 
1214         example: https://fiddle.skia.org/c/@Canvas_drawPoints
1215     */
1216     void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
1217 
1218     /** Draws point at (x, y) using clip, SkMatrix and SkPaint paint.
1219 
1220         The shape of point drawn depends on paint SkPaint::Cap.
1221         If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1222         SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1223         draw a square of width and height SkPaint stroke width.
1224         SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1225 
1226         @param x      left edge of circle or square
1227         @param y      top edge of circle or square
1228         @param paint  stroke, blend, color, and so on, used to draw
1229 
1230         example: https://fiddle.skia.org/c/@Canvas_drawPoint
1231     */
1232     void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
1233 
1234     /** Draws point p using clip, SkMatrix and SkPaint paint.
1235 
1236         The shape of point drawn depends on paint SkPaint::Cap.
1237         If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
1238         SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
1239         draw a square of width and height SkPaint stroke width.
1240         SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1241 
1242         @param p      top-left edge of circle or square
1243         @param paint  stroke, blend, color, and so on, used to draw
1244     */
drawPoint(SkPoint p,const SkPaint & paint)1245     void drawPoint(SkPoint p, const SkPaint& paint) {
1246         this->drawPoint(p.x(), p.y(), paint);
1247     }
1248 
1249     /** Draws line segment from (x0, y0) to (x1, y1) using clip, SkMatrix, and SkPaint paint.
1250         In paint: SkPaint stroke width describes the line thickness;
1251         SkPaint::Cap draws the end rounded or square;
1252         SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1253 
1254         @param x0     start of line segment on x-axis
1255         @param y0     start of line segment on y-axis
1256         @param x1     end of line segment on x-axis
1257         @param y1     end of line segment on y-axis
1258         @param paint  stroke, blend, color, and so on, used to draw
1259 
1260         example: https://fiddle.skia.org/c/@Canvas_drawLine
1261     */
1262     void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
1263 
1264     /** Draws line segment from p0 to p1 using clip, SkMatrix, and SkPaint paint.
1265         In paint: SkPaint stroke width describes the line thickness;
1266         SkPaint::Cap draws the end rounded or square;
1267         SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
1268 
1269         @param p0     start of line segment
1270         @param p1     end of line segment
1271         @param paint  stroke, blend, color, and so on, used to draw
1272     */
drawLine(SkPoint p0,SkPoint p1,const SkPaint & paint)1273     void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
1274         this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
1275     }
1276 
1277     /** Draws SkRect rect using clip, SkMatrix, and SkPaint paint.
1278         In paint: SkPaint::Style determines if rectangle is stroked or filled;
1279         if stroked, SkPaint stroke width describes the line thickness, and
1280         SkPaint::Join draws the corners rounded or square.
1281 
1282         @param rect   rectangle to draw
1283         @param paint  stroke or fill, blend, color, and so on, used to draw
1284 
1285         example: https://fiddle.skia.org/c/@Canvas_drawRect
1286     */
1287     void drawRect(const SkRect& rect, const SkPaint& paint);
1288 
1289     /** Draws SkIRect rect using clip, SkMatrix, and SkPaint paint.
1290         In paint: SkPaint::Style determines if rectangle is stroked or filled;
1291         if stroked, SkPaint stroke width describes the line thickness, and
1292         SkPaint::Join draws the corners rounded or square.
1293 
1294         @param rect   rectangle to draw
1295         @param paint  stroke or fill, blend, color, and so on, used to draw
1296     */
drawIRect(const SkIRect & rect,const SkPaint & paint)1297     void drawIRect(const SkIRect& rect, const SkPaint& paint) {
1298         SkRect r;
1299         r.set(rect);    // promotes the ints to scalars
1300         this->drawRect(r, paint);
1301     }
1302 
1303     /** Draws SkRegion region using clip, SkMatrix, and SkPaint paint.
1304         In paint: SkPaint::Style determines if rectangle is stroked or filled;
1305         if stroked, SkPaint stroke width describes the line thickness, and
1306         SkPaint::Join draws the corners rounded or square.
1307 
1308         @param region  region to draw
1309         @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw
1310 
1311         example: https://fiddle.skia.org/c/@Canvas_drawRegion
1312     */
1313     void drawRegion(const SkRegion& region, const SkPaint& paint);
1314 
1315     /** Draws oval oval using clip, SkMatrix, and SkPaint.
1316         In paint: SkPaint::Style determines if oval is stroked or filled;
1317         if stroked, SkPaint stroke width describes the line thickness.
1318 
1319         @param oval   SkRect bounds of oval
1320         @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw
1321 
1322         example: https://fiddle.skia.org/c/@Canvas_drawOval
1323     */
1324     void drawOval(const SkRect& oval, const SkPaint& paint);
1325 
1326     /** Draws SkRRect rrect using clip, SkMatrix, and SkPaint paint.
1327         In paint: SkPaint::Style determines if rrect is stroked or filled;
1328         if stroked, SkPaint stroke width describes the line thickness.
1329 
1330         rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
1331         may have any combination of positive non-square radii for the four corners.
1332 
1333         @param rrect  SkRRect with up to eight corner radii to draw
1334         @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw
1335 
1336         example: https://fiddle.skia.org/c/@Canvas_drawRRect
1337     */
1338     void drawRRect(const SkRRect& rrect, const SkPaint& paint);
1339 
1340     /** Draws SkRRect outer and inner
1341         using clip, SkMatrix, and SkPaint paint.
1342         outer must contain inner or the drawing is undefined.
1343         In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1344         if stroked, SkPaint stroke width describes the line thickness.
1345         If stroked and SkRRect corner has zero length radii, SkPaint::Join can
1346         draw corners rounded or square.
1347 
1348         GPU-backed platforms optimize drawing when both outer and inner are
1349         concave and outer contains inner. These platforms may not be able to draw
1350         SkPath built with identical data as fast.
1351 
1352         @param outer  SkRRect outer bounds to draw
1353         @param inner  SkRRect inner bounds to draw
1354         @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw
1355 
1356         example: https://fiddle.skia.org/c/@Canvas_drawDRRect_a
1357         example: https://fiddle.skia.org/c/@Canvas_drawDRRect_b
1358     */
1359     void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
1360 
1361     /** Draws circle at (cx, cy) with radius using clip, SkMatrix, and SkPaint paint.
1362         If radius is zero or less, nothing is drawn.
1363         In paint: SkPaint::Style determines if circle is stroked or filled;
1364         if stroked, SkPaint stroke width describes the line thickness.
1365 
1366         @param cx      circle center on the x-axis
1367         @param cy      circle center on the y-axis
1368         @param radius  half the diameter of circle
1369         @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw
1370 
1371         example: https://fiddle.skia.org/c/@Canvas_drawCircle
1372     */
1373     void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
1374 
1375     /** Draws circle at center with radius using clip, SkMatrix, and SkPaint paint.
1376         If radius is zero or less, nothing is drawn.
1377         In paint: SkPaint::Style determines if circle is stroked or filled;
1378         if stroked, SkPaint stroke width describes the line thickness.
1379 
1380         @param center  circle center
1381         @param radius  half the diameter of circle
1382         @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw
1383     */
drawCircle(SkPoint center,SkScalar radius,const SkPaint & paint)1384     void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
1385         this->drawCircle(center.x(), center.y(), radius, paint);
1386     }
1387 
1388     /** Draws arc using clip, SkMatrix, and SkPaint paint.
1389 
1390         Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
1391         sweepAngle. startAngle and sweepAngle are in degrees.
1392 
1393         startAngle of zero places start point at the right middle edge of oval.
1394         A positive sweepAngle places arc end point clockwise from start point;
1395         a negative sweepAngle places arc end point counterclockwise from start point.
1396         sweepAngle may exceed 360 degrees, a full circle.
1397         If useCenter is true, draw a wedge that includes lines from oval
1398         center to arc end points. If useCenter is false, draw arc between end points.
1399 
1400         If SkRect oval is empty or sweepAngle is zero, nothing is drawn.
1401 
1402         @param oval        SkRect bounds of oval containing arc to draw
1403         @param startAngle  angle in degrees where arc begins
1404         @param sweepAngle  sweep angle in degrees; positive is clockwise
1405         @param useCenter   if true, include the center of the oval
1406         @param paint       SkPaint stroke or fill, blend, color, and so on, used to draw
1407     */
1408     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1409                  bool useCenter, const SkPaint& paint);
1410 
1411     /** Draws SkRRect bounded by SkRect rect, with corner radii (rx, ry) using clip,
1412         SkMatrix, and SkPaint paint.
1413 
1414         In paint: SkPaint::Style determines if SkRRect is stroked or filled;
1415         if stroked, SkPaint stroke width describes the line thickness.
1416         If rx or ry are less than zero, they are treated as if they are zero.
1417         If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
1418         If rx and ry are zero, SkRRect is drawn as SkRect and if stroked is affected by
1419         SkPaint::Join.
1420 
1421         @param rect   SkRect bounds of SkRRect to draw
1422         @param rx     axis length on x-axis of oval describing rounded corners
1423         @param ry     axis length on y-axis of oval describing rounded corners
1424         @param paint  stroke, blend, color, and so on, used to draw
1425 
1426         example: https://fiddle.skia.org/c/@Canvas_drawRoundRect
1427     */
1428     void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
1429 
1430     /** Draws SkPath path using clip, SkMatrix, and SkPaint paint.
1431         SkPath contains an array of path contour, each of which may be open or closed.
1432 
1433         In paint: SkPaint::Style determines if SkRRect is stroked or filled:
1434         if filled, SkPath::FillType determines whether path contour describes inside or
1435         outside of fill; if stroked, SkPaint stroke width describes the line thickness,
1436         SkPaint::Cap describes line ends, and SkPaint::Join describes how
1437         corners are drawn.
1438 
1439         @param path   SkPath to draw
1440         @param paint  stroke, blend, color, and so on, used to draw
1441 
1442         example: https://fiddle.skia.org/c/@Canvas_drawPath
1443     */
1444     void drawPath(const SkPath& path, const SkPaint& paint);
1445 
drawImage(const SkImage * image,SkScalar left,SkScalar top)1446     void drawImage(const SkImage* image, SkScalar left, SkScalar top) {
1447         this->drawImage(image, left, top, SkSamplingOptions(), nullptr);
1448     }
drawImage(const sk_sp<SkImage> & image,SkScalar left,SkScalar top)1449     void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top) {
1450         this->drawImage(image.get(), left, top, SkSamplingOptions(), nullptr);
1451     }
1452 
1453     /** \enum SkCanvas::SrcRectConstraint
1454         SrcRectConstraint controls the behavior at the edge of source SkRect,
1455         provided to drawImageRect() when there is any filtering. If kStrict is set,
1456         then extra code is used to ensure it nevers samples outside of the src-rect.
1457     */
1458     enum SrcRectConstraint {
1459         kStrict_SrcRectConstraint, //!< sample only inside bounds; slower
1460         kFast_SrcRectConstraint,   //!< sample outside bounds; faster
1461     };
1462 
1463     void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkSamplingOptions&,
1464                    const SkPaint* = nullptr);
1465     void drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
1466                    const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
1467         this->drawImage(image.get(), x, y, sampling, paint);
1468     }
1469     void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst,
1470                        const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
1471     void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&,
1472                        const SkPaint* = nullptr);
drawImageRect(const sk_sp<SkImage> & image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)1473     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
1474                        const SkSamplingOptions& sampling, const SkPaint* paint,
1475                        SrcRectConstraint constraint) {
1476         this->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
1477     }
1478     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst,
1479                        const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
1480         this->drawImageRect(image.get(), dst, sampling, paint);
1481     }
1482 
1483     /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1484         SkIRect center divides the image into nine sections: four sides, four corners, and
1485         the center. Corners are unmodified or scaled down proportionately if their sides
1486         are larger than dst; center and four sides are scaled to fit remaining space, if any.
1487 
1488         Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1489 
1490         If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
1491         SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
1492         If paint contains SkMaskFilter, generate mask from image bounds.
1493         Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1494 
1495         If generated mask extends beyond image bounds, replicate image edge colors, just
1496         as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1497         replicates the image edge color when it samples outside of its bounds.
1498 
1499         @param image   SkImage containing pixels, dimensions, and format
1500         @param center  SkIRect edge of image corners and sides
1501         @param dst     destination SkRect of image to draw to
1502         @param filter  what technique to use when sampling the image
1503         @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1504                        and so on; or nullptr
1505     */
1506     void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
1507                        SkFilterMode filter, const SkPaint* paint = nullptr);
1508 
1509     /** \struct SkCanvas::Lattice
1510         SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
1511         Grid entries on even columns and even rows are fixed; these entries are
1512         always drawn at their original size if the destination is large enough.
1513         If the destination side is too small to hold the fixed entries, all fixed
1514         entries are proportionately scaled down to fit.
1515         The grid entries not on even columns and rows are scaled to fit the
1516         remaining space, if any.
1517     */
1518     struct Lattice {
1519 
1520         /** \enum SkCanvas::Lattice::RectType
1521             Optional setting per rectangular grid entry to make it transparent,
1522             or to fill the grid entry with a color.
1523         */
1524         enum RectType : uint8_t {
1525             kDefault     = 0, //!< draws SkBitmap into lattice rectangle
1526             kTransparent,     //!< skips lattice rectangle by making it transparent
1527             kFixedColor,      //!< draws one of fColors into lattice rectangle
1528         };
1529 
1530         const int*      fXDivs;     //!< x-axis values dividing bitmap
1531         const int*      fYDivs;     //!< y-axis values dividing bitmap
1532         const RectType* fRectTypes; //!< array of fill types
1533         int             fXCount;    //!< number of x-coordinates
1534         int             fYCount;    //!< number of y-coordinates
1535         const SkIRect*  fBounds;    //!< source bounds to draw from
1536         const SkColor*  fColors;    //!< array of colors
1537     };
1538 
1539     /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1540 
1541         SkCanvas::Lattice lattice divides image into a rectangular grid.
1542         Each intersection of an even-numbered row and column is fixed;
1543         fixed lattice elements never scale larger than their initial
1544         size and shrink proportionately when all fixed elements exceed the bitmap
1545         dimension. All other grid elements scale to fill the available space, if any.
1546 
1547         Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1548 
1549         If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
1550         SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
1551         If paint contains SkMaskFilter, generate mask from image bounds.
1552         Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1553 
1554         If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1555         just as SkShader made from SkShader::MakeBitmapShader with
1556         SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1557         outside of its bounds.
1558 
1559         @param image    SkImage containing pixels, dimensions, and format
1560         @param lattice  division of bitmap into fixed and variable rectangles
1561         @param dst      destination SkRect of image to draw to
1562         @param filter   what technique to use when sampling the image
1563         @param paint    SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1564                         and so on; or nullptr
1565     */
1566     void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
1567                           SkFilterMode filter, const SkPaint* paint = nullptr);
drawImageLattice(const SkImage * image,const Lattice & lattice,const SkRect & dst)1568     void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst) {
1569         this->drawImageLattice(image, lattice, dst, SkFilterMode::kNearest, nullptr);
1570     }
1571 
1572     /**
1573      * Experimental. Controls anti-aliasing of each edge of images in an image-set.
1574      */
1575     enum QuadAAFlags : unsigned {
1576         kLeft_QuadAAFlag    = 0b0001,
1577         kTop_QuadAAFlag     = 0b0010,
1578         kRight_QuadAAFlag   = 0b0100,
1579         kBottom_QuadAAFlag  = 0b1000,
1580 
1581         kNone_QuadAAFlags   = 0b0000,
1582         kAll_QuadAAFlags    = 0b1111,
1583     };
1584 
1585     /** This is used by the experimental API below. */
1586     struct SK_API ImageSetEntry {
1587         ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1588                       int matrixIndex, float alpha, unsigned aaFlags, bool hasClip);
1589 
1590         ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1591                       float alpha, unsigned aaFlags);
1592 
1593         ImageSetEntry();
1594         ~ImageSetEntry();
1595         ImageSetEntry(const ImageSetEntry&);
1596         ImageSetEntry& operator=(const ImageSetEntry&);
1597 
1598         sk_sp<const SkImage> fImage;
1599         SkRect fSrcRect;
1600         SkRect fDstRect;
1601         int fMatrixIndex = -1; // Index into the preViewMatrices arg, or < 0
1602         float fAlpha = 1.f;
1603         unsigned fAAFlags = kNone_QuadAAFlags; // QuadAAFlags
1604         bool fHasClip = false; // True to use next 4 points in dstClip arg as quad
1605     };
1606 
1607     /**
1608      * This is an experimental API for the SkiaRenderer Chromium project, and its API will surely
1609      * evolve if it is not removed outright.
1610      *
1611      * This behaves very similarly to drawRect() combined with a clipPath() formed by clip
1612      * quadrilateral. 'rect' and 'clip' are in the same coordinate space. If 'clip' is null, then it
1613      * is as if the rectangle was not clipped (or, alternatively, clipped to itself). If not null,
1614      * then it must provide 4 points.
1615      *
1616      * In addition to combining the draw and clipping into one operation, this function adds the
1617      * additional capability of controlling each of the rectangle's edges anti-aliasing
1618      * independently.  The edges of the clip will respect the per-edge AA flags. It is required that
1619      * 'clip' be contained inside 'rect'. In terms of mapping to edge labels, the 'clip' points
1620      * should be ordered top-left, top-right, bottom-right, bottom-left so that the edge between [0]
1621      * and [1] is "top", [1] and [2] is "right", [2] and [3] is "bottom", and [3] and [0] is "left".
1622      * This ordering matches SkRect::toQuad().
1623      *
1624      * This API only draws solid color, filled rectangles so it does not accept a full SkPaint.
1625      */
1626     void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1627                                      const SkColor4f& color, SkBlendMode mode);
experimental_DrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aaFlags,SkColor color,SkBlendMode mode)1628     void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1629                                      SkColor color, SkBlendMode mode) {
1630         this->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, SkColor4f::FromColor(color), mode);
1631     }
1632 
1633     /**
1634      * This is an bulk variant of experimental_DrawEdgeAAQuad() that renders 'cnt' textured quads.
1635      * For each entry, 'fDstRect' is rendered with its clip (determined by entry's 'fHasClip' and
1636      * the current index in 'dstClip'). The entry's fImage is applied to the destination rectangle
1637      * by sampling from 'fSrcRect' sub-image.  The corners of 'fSrcRect' map to the corners of
1638      * 'fDstRect', just like in drawImageRect(), and they will be properly interpolated when
1639      * applying a clip.
1640      *
1641      * Like experimental_DrawEdgeAAQuad(), each entry can specify edge AA flags that apply to both
1642      * the destination rect and its clip.
1643      *
1644      * If provided, the 'dstClips' array must have length equal 4 * the number of entries with
1645      * fHasClip true. If 'dstClips' is null, every entry must have 'fHasClip' set to false. The
1646      * destination clip coordinates will be read consecutively with the image set entries, advancing
1647      * by 4 points every time an entry with fHasClip is passed.
1648      *
1649      * This entry point supports per-entry manipulations to the canvas's current matrix. If an
1650      * entry provides 'fMatrixIndex' >= 0, it will be drawn as if the canvas's CTM was
1651      * canvas->getTotalMatrix() * preViewMatrices[fMatrixIndex]. If 'fMatrixIndex' is less than 0,
1652      * the pre-view matrix transform is implicitly the identity, so it will be drawn using just the
1653      * current canvas matrix. The pre-view matrix modifies the canvas's view matrix, it does not
1654      * affect the local coordinates of each entry.
1655      *
1656      * An optional paint may be provided, which supports the same subset of features usable with
1657      * drawImageRect (i.e. assumed to be filled and no path effects). When a paint is provided, the
1658      * image set is drawn as if each image used the applied paint independently, so each is affected
1659      * by the image, color, and/or mask filter.
1660      */
1661     void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
1662                                          const SkPoint dstClips[], const SkMatrix preViewMatrices[],
1663                                          const SkSamplingOptions&, const SkPaint* paint = nullptr,
1664                                          SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1665 
1666     /** Draws text, with origin at (x, y), using clip, SkMatrix, SkFont font,
1667         and SkPaint paint.
1668 
1669         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
1670         SkTextEncoding::kUTF32, this function uses the default
1671         character-to-glyph mapping from the SkTypeface in font.  It does not
1672         perform typeface fallback for characters not found in the SkTypeface.
1673         It does not perform kerning or other complex shaping; glyphs are
1674         positioned based on their default advances.
1675 
1676         Text meaning depends on SkTextEncoding.
1677 
1678         Text size is affected by SkMatrix and SkFont text size. Default text
1679         size is 12 point.
1680 
1681         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1682         SkColorFilter, and SkImageFilter; apply to text. By
1683         default, draws filled black glyphs.
1684 
1685         @param text        character code points or glyphs drawn
1686         @param byteLength  byte length of text array
1687         @param encoding    text encoding used in the text array
1688         @param x           start of text on x-axis
1689         @param y           start of text on y-axis
1690         @param font        typeface, text size and so, used to describe the text
1691         @param paint       blend, color, and so on, used to draw
1692     */
1693     void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
1694                         SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint);
1695 
1696     /** Draws null terminated string, with origin at (x, y), using clip, SkMatrix,
1697         SkFont font, and SkPaint paint.
1698 
1699         This function uses the default character-to-glyph mapping from the
1700         SkTypeface in font.  It does not perform typeface fallback for
1701         characters not found in the SkTypeface.  It does not perform kerning;
1702         glyphs are positioned based on their default advances.
1703 
1704         String str is encoded as UTF-8.
1705 
1706         Text size is affected by SkMatrix and font text size. Default text
1707         size is 12 point.
1708 
1709         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1710         SkColorFilter, and SkImageFilter; apply to text. By
1711         default, draws filled black glyphs.
1712 
1713         @param str     character code points drawn,
1714                        ending with a char value of zero
1715         @param x       start of string on x-axis
1716         @param y       start of string on y-axis
1717         @param font    typeface, text size and so, used to describe the text
1718         @param paint   blend, color, and so on, used to draw
1719     */
drawString(const char str[],SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1720     void drawString(const char str[], SkScalar x, SkScalar y, const SkFont& font,
1721                     const SkPaint& paint) {
1722         this->drawSimpleText(str, strlen(str), SkTextEncoding::kUTF8, x, y, font, paint);
1723     }
1724 
1725     /** Draws SkString, with origin at (x, y), using clip, SkMatrix, SkFont font,
1726         and SkPaint paint.
1727 
1728         This function uses the default character-to-glyph mapping from the
1729         SkTypeface in font.  It does not perform typeface fallback for
1730         characters not found in the SkTypeface.  It does not perform kerning;
1731         glyphs are positioned based on their default advances.
1732 
1733         SkString str is encoded as UTF-8.
1734 
1735         Text size is affected by SkMatrix and SkFont text size. Default text
1736         size is 12 point.
1737 
1738         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1739         SkColorFilter, and SkImageFilter; apply to text. By
1740         default, draws filled black glyphs.
1741 
1742         @param str     character code points drawn,
1743                        ending with a char value of zero
1744         @param x       start of string on x-axis
1745         @param y       start of string on y-axis
1746         @param font    typeface, text size and so, used to describe the text
1747         @param paint   blend, color, and so on, used to draw
1748     */
drawString(const SkString & str,SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1749     void drawString(const SkString& str, SkScalar x, SkScalar y, const SkFont& font,
1750                     const SkPaint& paint) {
1751         this->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8, x, y, font, paint);
1752     }
1753 
1754     /** Draws count glyphs, at positions relative to origin styled with font and paint with
1755         supporting utf8 and cluster information.
1756 
1757        This function draw glyphs at the given positions relative to the given origin.
1758        It does not perform typeface fallback for glyphs not found in the SkTypeface in font.
1759 
1760        The drawing obeys the current transform matrix and clipping.
1761 
1762        All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1763        SkColorFilter, and SkImageFilter; apply to text. By
1764        default, draws filled black glyphs.
1765 
1766        @param count           number of glyphs to draw
1767        @param glyphs          the array of glyphIDs to draw
1768        @param positions       where to draw each glyph relative to origin
1769        @param clusters        array of size count of cluster information
1770        @param textByteCount   size of the utf8text
1771        @param utf8text        utf8text supporting information for the glyphs
1772        @param origin          the origin of all the positions
1773        @param font            typeface, text size and so, used to describe the text
1774        @param paint           blend, color, and so on, used to draw
1775     */
1776     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
1777                     const uint32_t clusters[], int textByteCount, const char utf8text[],
1778                     SkPoint origin, const SkFont& font, const SkPaint& paint);
1779 
1780     /** Draws count glyphs, at positions relative to origin styled with font and paint.
1781 
1782         This function draw glyphs at the given positions relative to the given origin.
1783         It does not perform typeface fallback for glyphs not found in the SkTypeface in font.
1784 
1785         The drawing obeys the current transform matrix and clipping.
1786 
1787         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1788         SkColorFilter, and SkImageFilter; apply to text. By
1789         default, draws filled black glyphs.
1790 
1791         @param count       number of glyphs to draw
1792         @param glyphs      the array of glyphIDs to draw
1793         @param positions   where to draw each glyph relative to origin
1794         @param origin      the origin of all the positions
1795         @param font        typeface, text size and so, used to describe the text
1796         @param paint       blend, color, and so on, used to draw
1797     */
1798     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
1799                     SkPoint origin, const SkFont& font, const SkPaint& paint);
1800 
1801     /** Draws count glyphs, at positions relative to origin styled with font and paint.
1802 
1803         This function draw glyphs using the given scaling and rotations. They are positioned
1804         relative to the given origin. It does not perform typeface fallback for glyphs not found
1805         in the SkTypeface in font.
1806 
1807         The drawing obeys the current transform matrix and clipping.
1808 
1809         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1810         SkColorFilter, and SkImageFilter; apply to text. By
1811         default, draws filled black glyphs.
1812 
1813         @param count    number of glyphs to draw
1814         @param glyphs   the array of glyphIDs to draw
1815         @param xforms   where to draw and orient each glyph
1816         @param origin   the origin of all the positions
1817         @param font     typeface, text size and so, used to describe the text
1818         @param paint    blend, color, and so on, used to draw
1819     */
1820     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkRSXform xforms[],
1821                     SkPoint origin, const SkFont& font, const SkPaint& paint);
1822 
1823     /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
1824 
1825         blob contains glyphs, their positions, and paint attributes specific to text:
1826         SkTypeface, SkPaint text size, SkPaint text scale x,
1827         SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
1828         SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
1829         and SkPaint subpixel text.
1830 
1831         SkTextEncoding must be set to SkTextEncoding::kGlyphID.
1832 
1833         Elements of paint: anti-alias, SkBlendMode, color including alpha,
1834         SkColorFilter, SkPaint dither, SkMaskFilter, SkPathEffect, SkShader, and
1835         SkPaint::Style; apply to blob. If SkPaint contains SkPaint::kStroke_Style:
1836         SkPaint miter limit, SkPaint::Cap, SkPaint::Join, and SkPaint stroke width;
1837         apply to SkPath created from blob.
1838 
1839         @param blob   glyphs, positions, and their paints' text size, typeface, and so on
1840         @param x      horizontal offset applied to blob
1841         @param y      vertical offset applied to blob
1842         @param paint  blend, color, stroking, and so on, used to draw
1843 
1844         example: https://fiddle.skia.org/c/@Canvas_drawTextBlob
1845     */
1846     void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
1847 
1848     /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
1849 
1850         blob contains glyphs, their positions, and paint attributes specific to text:
1851         SkTypeface, SkPaint text size, SkPaint text scale x,
1852         SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
1853         SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
1854         and SkPaint subpixel text.
1855 
1856         SkTextEncoding must be set to SkTextEncoding::kGlyphID.
1857 
1858         Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
1859         and SkImageFilter; apply to blob.
1860 
1861         @param blob   glyphs, positions, and their paints' text size, typeface, and so on
1862         @param x      horizontal offset applied to blob
1863         @param y      vertical offset applied to blob
1864         @param paint  blend, color, stroking, and so on, used to draw
1865     */
drawTextBlob(const sk_sp<SkTextBlob> & blob,SkScalar x,SkScalar y,const SkPaint & paint)1866     void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
1867         this->drawTextBlob(blob.get(), x, y, paint);
1868     }
1869 
1870     /** Draws SkPicture picture, using clip and SkMatrix.
1871         Clip and SkMatrix are unchanged by picture contents, as if
1872         save() was called before and restore() was called after drawPicture().
1873 
1874         SkPicture records a series of draw commands for later playback.
1875 
1876         @param picture  recorded drawing commands to play
1877     */
drawPicture(const SkPicture * picture)1878     void drawPicture(const SkPicture* picture) {
1879         this->drawPicture(picture, nullptr, nullptr);
1880     }
1881 
1882     /** Draws SkPicture picture, using clip and SkMatrix.
1883         Clip and SkMatrix are unchanged by picture contents, as if
1884         save() was called before and restore() was called after drawPicture().
1885 
1886         SkPicture records a series of draw commands for later playback.
1887 
1888         @param picture  recorded drawing commands to play
1889     */
drawPicture(const sk_sp<SkPicture> & picture)1890     void drawPicture(const sk_sp<SkPicture>& picture) {
1891         this->drawPicture(picture.get());
1892     }
1893 
1894     /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
1895         SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
1896         SkImageFilter, and SkBlendMode, if provided.
1897 
1898         If paint is non-null, then the picture is always drawn into a temporary layer before
1899         actually landing on the canvas. Note that drawing into a layer can also change its
1900         appearance if there are any non-associative blendModes inside any of the pictures elements.
1901 
1902         @param picture  recorded drawing commands to play
1903         @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
1904         @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr
1905 
1906         example: https://fiddle.skia.org/c/@Canvas_drawPicture_3
1907     */
1908     void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
1909 
1910     /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
1911         SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
1912         SkImageFilter, and SkBlendMode, if provided.
1913 
1914         If paint is non-null, then the picture is always drawn into a temporary layer before
1915         actually landing on the canvas. Note that drawing into a layer can also change its
1916         appearance if there are any non-associative blendModes inside any of the pictures elements.
1917 
1918         @param picture  recorded drawing commands to play
1919         @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
1920         @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr
1921     */
drawPicture(const sk_sp<SkPicture> & picture,const SkMatrix * matrix,const SkPaint * paint)1922     void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix,
1923                      const SkPaint* paint) {
1924         this->drawPicture(picture.get(), matrix, paint);
1925     }
1926 
1927     /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
1928         If paint contains an SkShader and vertices does not contain texCoords, the shader
1929         is mapped using the vertices' positions.
1930 
1931         If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
1932         SkBlendMode mode combines vertices colors with SkShader.
1933 
1934         SkMaskFilter and SkPathEffect on paint are ignored.
1935 
1936         @param vertices  triangle mesh to draw
1937         @param mode      combines vertices colors with SkShader, if both are present
1938         @param paint     specifies the SkShader, used as SkVertices texture; may be nullptr
1939 
1940         example: https://fiddle.skia.org/c/@Canvas_drawVertices
1941     */
1942     void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
1943 
1944     /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
1945      *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
1946      */
drawVertices(const SkVertices * vertices,const SkPaint & paint)1947     void drawVertices(const SkVertices* vertices, const SkPaint& paint) {
1948         this->drawVertices(vertices, SkBlendMode::kModulate, paint);
1949     }
1950 
1951     /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
1952         If paint contains an SkShader and vertices does not contain texCoords, the shader
1953         is mapped using the vertices' positions.
1954 
1955         If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
1956         SkBlendMode mode combines vertices colors with SkShader.
1957 
1958         SkMaskFilter and SkPathEffect on paint are ignored.
1959 
1960         @param vertices  triangle mesh to draw
1961         @param mode      combines vertices colors with SkShader, if both are present
1962         @param paint     specifies the SkShader, used as SkVertices texture, may be nullptr
1963 
1964         example: https://fiddle.skia.org/c/@Canvas_drawVertices_2
1965     */
1966     void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
1967 
1968     /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
1969      *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
1970      */
drawVertices(const sk_sp<SkVertices> & vertices,const SkPaint & paint)1971     void drawVertices(const sk_sp<SkVertices>& vertices, const SkPaint& paint) {
1972         this->drawVertices(vertices, SkBlendMode::kModulate, paint);
1973     }
1974 
1975     /** Draws a Coons patch: the interpolation of four cubics with shared corners,
1976         associating a color, and optionally a texture SkPoint, with each corner.
1977 
1978         Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
1979         alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
1980         as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
1981         both are provided.
1982 
1983         SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
1984         in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
1985         first point.
1986 
1987         Color array color associates colors with corners in top-left, top-right,
1988         bottom-right, bottom-left order.
1989 
1990         If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
1991         corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
1992         nullptr, SkShader is mapped using positions (derived from cubics).
1993 
1994         SkMaskFilter and SkPathEffect on paint are ignored.
1995 
1996         @param cubics     SkPath cubic array, sharing common points
1997         @param colors     color array, one for each corner
1998         @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
1999                           may be nullptr
2000         @param mode       SkBlendMode for colors, and for SkShader if paint has one
2001         @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
2002     */
2003     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2004                    const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2005 
2006     /** Draws SkPath cubic Coons patch: the interpolation of four cubics with shared corners,
2007         associating a color, and optionally a texture SkPoint, with each corner.
2008 
2009         Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
2010         alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
2011         as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
2012         both are provided.
2013 
2014         SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2015         in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
2016         first point.
2017 
2018         Color array color associates colors with corners in top-left, top-right,
2019         bottom-right, bottom-left order.
2020 
2021         If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
2022         corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
2023         nullptr, SkShader is mapped using positions (derived from cubics).
2024 
2025         SkMaskFilter and SkPathEffect on paint are ignored.
2026 
2027         @param cubics     SkPath cubic array, sharing common points
2028         @param colors     color array, one for each corner
2029         @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
2030                           may be nullptr
2031         @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
2032     */
drawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],const SkPaint & paint)2033     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2034                    const SkPoint texCoords[4], const SkPaint& paint) {
2035         this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
2036     }
2037 
2038     /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2039         paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2040         to draw, if present. For each entry in the array, SkRect tex locates sprite in
2041         atlas, and SkRSXform xform transforms it into destination space.
2042 
2043         SkMaskFilter and SkPathEffect on paint are ignored.
2044 
2045         xform, tex, and colors if present, must contain count entries.
2046         Optional colors are applied for each sprite using SkBlendMode mode, treating
2047         sprite as source and colors as destination.
2048         Optional cullRect is a conservative bounds of all transformed sprites.
2049         If cullRect is outside of clip, canvas can skip drawing.
2050 
2051         If atlas is nullptr, this draws nothing.
2052 
2053         @param atlas     SkImage containing sprites
2054         @param xform     SkRSXform mappings for sprites in atlas
2055         @param tex       SkRect locations of sprites in atlas
2056         @param colors    one per sprite, blended with sprite using SkBlendMode; may be nullptr
2057         @param count     number of sprites to draw
2058         @param mode      SkBlendMode combining colors and sprites
2059         @param sampling  SkSamplingOptions used when sampling from the atlas image
2060         @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
2061         @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2062     */
2063     void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
2064                    const SkColor colors[], int count, SkBlendMode mode,
2065                    const SkSamplingOptions& sampling, const SkRect* cullRect, const SkPaint* paint);
2066 
2067     /** Draws SkDrawable drawable using clip and SkMatrix, concatenated with
2068         optional matrix.
2069 
2070         If SkCanvas has an asynchronous implementation, as is the case
2071         when it is recording into SkPicture, then drawable will be referenced,
2072         so that SkDrawable::draw() can be called when the operation is finalized. To force
2073         immediate drawing, call SkDrawable::draw() instead.
2074 
2075         @param drawable  custom struct encapsulating drawing commands
2076         @param matrix    transformation applied to drawing; may be nullptr
2077 
2078         example: https://fiddle.skia.org/c/@Canvas_drawDrawable
2079     */
2080     void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);
2081 
2082     /** Draws SkDrawable drawable using clip and SkMatrix, offset by (x, y).
2083 
2084         If SkCanvas has an asynchronous implementation, as is the case
2085         when it is recording into SkPicture, then drawable will be referenced,
2086         so that SkDrawable::draw() can be called when the operation is finalized. To force
2087         immediate drawing, call SkDrawable::draw() instead.
2088 
2089         @param drawable  custom struct encapsulating drawing commands
2090         @param x         offset into SkCanvas writable pixels on x-axis
2091         @param y         offset into SkCanvas writable pixels on y-axis
2092 
2093         example: https://fiddle.skia.org/c/@Canvas_drawDrawable_2
2094     */
2095     void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
2096 
2097     /** Associates SkRect on SkCanvas with an annotation; a key-value pair, where the key is
2098         a null-terminated UTF-8 string, and optional value is stored as SkData.
2099 
2100         Only some canvas implementations, such as recording to SkPicture, or drawing to
2101         document PDF, use annotations.
2102 
2103         @param rect   SkRect extent of canvas to annotate
2104         @param key    string used for lookup
2105         @param value  data holding value stored in annotation
2106 
2107         example: https://fiddle.skia.org/c/@Canvas_drawAnnotation_2
2108     */
2109     void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
2110 
2111     /** Associates SkRect on SkCanvas when an annotation; a key-value pair, where the key is
2112         a null-terminated UTF-8 string, and optional value is stored as SkData.
2113 
2114         Only some canvas implementations, such as recording to SkPicture, or drawing to
2115         document PDF, use annotations.
2116 
2117         @param rect   SkRect extent of canvas to annotate
2118         @param key    string used for lookup
2119         @param value  data holding value stored in annotation
2120     */
drawAnnotation(const SkRect & rect,const char key[],const sk_sp<SkData> & value)2121     void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
2122         this->drawAnnotation(rect, key, value.get());
2123     }
2124 
2125     /** Returns true if clip is empty; that is, nothing will draw.
2126 
2127         May do work when called; it should not be called
2128         more often than needed. However, once called, subsequent calls perform no
2129         work until clip changes.
2130 
2131         @return  true if clip is empty
2132 
2133         example: https://fiddle.skia.org/c/@Canvas_isClipEmpty
2134     */
2135     virtual bool isClipEmpty() const;
2136 
2137     /** Returns true if clip is SkRect and not empty.
2138         Returns false if the clip is empty, or if it is not SkRect.
2139 
2140         @return  true if clip is SkRect and not empty
2141 
2142         example: https://fiddle.skia.org/c/@Canvas_isClipRect
2143     */
2144     virtual bool isClipRect() const;
2145 
2146     /** Returns the current transform from local coordinates to the 'device', which for most
2147      *  purposes means pixels.
2148      *
2149      *  @return transformation from local coordinates to device / pixels.
2150      */
2151     SkM44 getLocalToDevice() const;
2152 
2153     /**
2154      *  Throws away the 3rd row and column in the matrix, so be warned.
2155      */
getLocalToDeviceAs3x3()2156     SkMatrix getLocalToDeviceAs3x3() const {
2157         return this->getLocalToDevice().asM33();
2158     }
2159 
2160 #ifdef SK_SUPPORT_LEGACY_GETTOTALMATRIX
2161     /** DEPRECATED
2162      *  Legacy version of getLocalToDevice(), which strips away any Z information, and
2163      *  just returns a 3x3 version.
2164      *
2165      *  @return 3x3 version of getLocalToDevice()
2166      *
2167      *  example: https://fiddle.skia.org/c/@Canvas_getTotalMatrix
2168      *  example: https://fiddle.skia.org/c/@Clip
2169      */
2170     SkMatrix getTotalMatrix() const;
2171 #endif
2172 
2173     ///////////////////////////////////////////////////////////////////////////
2174 
2175 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && SK_SUPPORT_GPU
2176     // These methods exist to support WebView in Android Framework.
2177     SkIRect topLayerBounds() const;
2178     GrBackendRenderTarget topLayerBackendRenderTarget() const;
2179 #endif
2180 
2181     /**
2182      *  Returns the global clip as a region. If the clip contains AA, then only the bounds
2183      *  of the clip may be returned.
2184      */
2185     void temporary_internal_getRgnClip(SkRegion* region);
2186 
2187     void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
2188 
2189 
2190 protected:
2191     // default impl defers to getDevice()->newSurface(info)
2192     virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
2193 
2194     // default impl defers to its device
2195     virtual bool onPeekPixels(SkPixmap* pixmap);
2196     virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
2197     virtual SkImageInfo onImageInfo() const;
2198     virtual bool onGetProps(SkSurfaceProps* props) const;
2199     virtual void onFlush();
2200 
2201     // Subclass save/restore notifiers.
2202     // Overriders should call the corresponding INHERITED method up the inheritance chain.
2203     // getSaveLayerStrategy()'s return value may suppress full layer allocation.
2204     enum SaveLayerStrategy {
2205         kFullLayer_SaveLayerStrategy,
2206         kNoLayer_SaveLayerStrategy,
2207     };
2208 
willSave()2209     virtual void willSave() {}
2210     // Overriders should call the corresponding INHERITED method up the inheritance chain.
getSaveLayerStrategy(const SaveLayerRec &)2211     virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
2212         return kFullLayer_SaveLayerStrategy;
2213     }
2214 
2215     // returns true if we should actually perform the saveBehind, or false if we should just save.
onDoSaveBehind(const SkRect *)2216     virtual bool onDoSaveBehind(const SkRect*) { return true; }
willRestore()2217     virtual void willRestore() {}
didRestore()2218     virtual void didRestore() {}
2219 
onMarkCTM(const char *)2220     virtual void onMarkCTM(const char*) {}
didConcat44(const SkM44 &)2221     virtual void didConcat44(const SkM44&) {}
didSetM44(const SkM44 &)2222     virtual void didSetM44(const SkM44&) {}
didTranslate(SkScalar,SkScalar)2223     virtual void didTranslate(SkScalar, SkScalar) {}
didScale(SkScalar,SkScalar)2224     virtual void didScale(SkScalar, SkScalar) {}
2225 
2226     // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
2227     // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
2228     // that mechanism  will be required to implement the new function.
2229     virtual void onDrawPaint(const SkPaint& paint);
2230     virtual void onDrawBehind(const SkPaint& paint);
2231     virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
2232     virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
2233     virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
2234     virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
2235     virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
2236                            bool useCenter, const SkPaint& paint);
2237     virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
2238     virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
2239 
2240     virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2241                                 const SkPaint& paint);
2242 
2243     virtual void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint);
2244 
2245     virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
2246                            const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2247     virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
2248                               const SkPaint& paint);
2249 
2250     virtual void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
2251                               const SkPaint*);
2252     virtual void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst,
2253                                   const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
2254     virtual void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect& dst,
2255                                      SkFilterMode, const SkPaint*);
2256     virtual void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect src[],
2257                               const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
2258                               const SkRect* cull, const SkPaint*);
2259     virtual void onDrawEdgeAAImageSet2(const ImageSetEntry imageSet[], int count,
2260                                        const SkPoint dstClips[], const SkMatrix preViewMatrices[],
2261                                        const SkSamplingOptions&, const SkPaint*,
2262                                        SrcRectConstraint);
2263 
2264     virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
2265                                       const SkPaint& paint);
2266 
2267     virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
2268     virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
2269 
2270     virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
2271     virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
2272                                const SkPaint* paint);
2273 
2274     virtual void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
2275                                   const SkColor4f& color, SkBlendMode mode);
2276 
2277     enum ClipEdgeStyle {
2278         kHard_ClipEdgeStyle,
2279         kSoft_ClipEdgeStyle
2280     };
2281 
2282     virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
2283     virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
2284     virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
2285     virtual void onClipShader(sk_sp<SkShader>, SkClipOp);
2286     virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
2287     virtual void onResetClip();
2288 
2289     virtual void onDiscard();
2290 
2291 private:
2292 
2293     enum ShaderOverrideOpacity {
2294         kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
2295         kOpaque_ShaderOverrideOpacity,      //!< the overriding shader is opaque
2296         kNotOpaque_ShaderOverrideOpacity,   //!< the overriding shader may not be opaque
2297     };
2298 
2299     // notify our surface (if we have one) that we are about to draw, so it
2300     // can perform copy-on-write or invalidate any cached images
2301     // returns false if the copy failed
2302     bool SK_WARN_UNUSED_RESULT predrawNotify(bool willOverwritesEntireSurface = false);
2303     bool SK_WARN_UNUSED_RESULT predrawNotify(const SkRect*, const SkPaint*, ShaderOverrideOpacity);
2304 
2305     enum class CheckForOverwrite : bool {
2306         kNo = false,
2307         kYes = true
2308     };
2309     // call the appropriate predrawNotify and create a layer if needed.
2310     skstd::optional<AutoLayerForImageFilter> aboutToDraw(
2311         SkCanvas* canvas,
2312         const SkPaint& paint,
2313         const SkRect* rawBounds = nullptr,
2314         CheckForOverwrite = CheckForOverwrite::kNo,
2315         ShaderOverrideOpacity = kNone_ShaderOverrideOpacity);
2316 
2317     // The bottom-most device in the stack, only changed by init(). Image properties and the final
2318     // canvas pixels are determined by this device.
baseDevice()2319     SkBaseDevice* baseDevice() const {
2320         SkASSERT(fBaseDevice);
2321         return fBaseDevice.get();
2322     }
2323 
2324     // The top-most device in the stack, will change within saveLayer()'s. All drawing and clipping
2325     // operations should route to this device.
2326     SkBaseDevice* topDevice() const;
2327 
2328     // Canvases maintain a sparse stack of layers, where the top-most layer receives the drawing,
2329     // clip, and matrix commands. There is a layer per call to saveLayer() using the
2330     // kFullLayer_SaveLayerStrategy.
2331     struct Layer {
2332         sk_sp<SkBaseDevice>  fDevice;
2333         sk_sp<SkImageFilter> fImageFilter; // applied to layer *before* being drawn by paint
2334         SkPaint              fPaint;
2335         bool                 fDiscard;
2336 
2337         Layer(sk_sp<SkBaseDevice> device, sk_sp<SkImageFilter> imageFilter, const SkPaint& paint);
2338     };
2339 
2340     // Encapsulate state needed to restore from saveBehind()
2341     struct BackImage {
2342         sk_sp<SkSpecialImage> fImage;
2343         SkIPoint              fLoc;
2344     };
2345 
2346     class MCRec {
2347     public:
2348         // If not null, this MCRec corresponds with the saveLayer() record that made the layer.
2349         // The base "layer" is not stored here, since it is stored inline in SkCanvas and has no
2350         // restoration behavior.
2351         std::unique_ptr<Layer> fLayer;
2352 
2353         // This points to the device of the top-most layer (which may be lower in the stack), or
2354         // to the canvas's fBaseDevice. The MCRec does not own the device.
2355         SkBaseDevice* fDevice;
2356 
2357         std::unique_ptr<BackImage> fBackImage;
2358         SkM44 fMatrix;
2359         int fDeferredSaveCount = 0;
2360 
2361         MCRec(SkBaseDevice* device);
2362         MCRec(const MCRec* prev);
2363         ~MCRec();
2364 
2365         void newLayer(sk_sp<SkBaseDevice> layerDevice,
2366                       sk_sp<SkImageFilter> filter,
2367                       const SkPaint& restorePaint);
2368 
2369         void reset(SkBaseDevice* device);
2370     };
2371 
2372     SkDeque     fMCStack;
2373     // points to top of stack
2374     MCRec*      fMCRec;
2375 
2376     sk_sp<SkMarkerStack> fMarkerStack;
2377 
2378     // the first N recs that can fit here mean we won't call malloc
2379     static constexpr int kMCRecSize      = 96; // most recent measurement
2380     static constexpr int kMCRecCount     = 32; // common depth for save/restores
2381 
2382     intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
2383 
2384     // Installed via init()
2385     sk_sp<SkBaseDevice> fBaseDevice;
2386     const SkSurfaceProps fProps;
2387 
2388     int         fSaveCount;         // value returned by getSaveCount()
2389 
2390     std::unique_ptr<SkRasterHandleAllocator> fAllocator;
2391 
2392     SkSurface_Base*  fSurfaceBase;
getSurfaceBase()2393     SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
setSurfaceBase(SkSurface_Base * sb)2394     void setSurfaceBase(SkSurface_Base* sb) {
2395         fSurfaceBase = sb;
2396     }
2397     friend class SkSurface_Base;
2398     friend class SkSurface_Gpu;
2399 
2400     SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
2401     int fClipRestrictionSaveCount = -1;
2402 
2403     void doSave();
2404     void checkForDeferredSave();
2405     void internalSetMatrix(const SkM44&);
2406 
2407     friend class SkAndroidFrameworkUtils;
2408     friend class SkCanvasPriv;      // needs to expose android functions for testing outside android
2409     friend class AutoLayerForImageFilter;
2410     friend class SkSurface_Raster;  // needs getDevice()
2411     friend class SkNoDrawCanvas;    // needs resetForNextPicture()
2412     friend class SkNWayCanvas;
2413     friend class SkPictureRecord;   // predrawNotify (why does it need it? <reed>)
2414     friend class SkOverdrawCanvas;
2415     friend class SkRasterHandleAllocator;
2416 protected:
2417     // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
2418     SkCanvas(const SkIRect& bounds);
2419 private:
2420     SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
2421              SkRasterHandleAllocator::Handle);
2422 
2423     SkCanvas(SkCanvas&&) = delete;
2424     SkCanvas(const SkCanvas&) = delete;
2425     SkCanvas& operator=(SkCanvas&&) = delete;
2426     SkCanvas& operator=(const SkCanvas&) = delete;
2427 
2428     /** Experimental
2429      *  Saves the specified subset of the current pixels in the current layer,
2430      *  and then clears those pixels to transparent black.
2431      *  Restores the pixels on restore() by drawing them in SkBlendMode::kDstOver.
2432      *
2433      *  @param subset   conservative bounds of the area to be saved / restored.
2434      *  @return depth of save state stack before this call was made.
2435      */
2436     int only_axis_aligned_saveBehind(const SkRect* subset);
2437 
2438     /**
2439      *  Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
2440      *  If there is no active saveBehind, then this draws nothing.
2441      */
2442     void drawClippedToSaveBehind(const SkPaint&);
2443 
2444     void resetForNextPicture(const SkIRect& bounds);
2445 
2446     // needs gettotalclip()
2447     friend class SkCanvasStateUtils;
2448 
2449     void init(sk_sp<SkBaseDevice>);
2450 
2451     // All base onDrawX() functions should call this and skip drawing if it returns true.
2452     // If 'matrix' is non-null, it maps the paint's fast bounds before checking for quick rejection
2453     bool internalQuickReject(const SkRect& bounds, const SkPaint& paint,
2454                              const SkMatrix* matrix = nullptr);
2455 
2456     void internalDrawPaint(const SkPaint& paint);
2457     void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
2458     void internalSaveBehind(const SkRect*);
2459 
2460     void internalConcat44(const SkM44&);
2461 
2462     // shared by save() and saveLayer()
2463     void internalSave();
2464     void internalRestore();
2465 
2466     enum class DeviceCompatibleWithFilter : bool {
2467         // Check the src device's local-to-device matrix for compatibility with the filter, and if
2468         // it is not compatible, introduce an intermediate image and transformation that allows the
2469         // filter to be evaluated on the modified src content.
2470         kUnknown = false,
2471         // Assume that the src device's local-to-device matrix is compatible with the filter.
2472         kYes     = true
2473     };
2474     /**
2475      * Filters the contents of 'src' and draws the result into 'dst'. The filter is evaluated
2476      * relative to the current canvas matrix, and src is drawn to dst using their relative transform
2477      * 'paint' is applied after the filter and must not have a mask or image filter of its own.
2478      * A null 'filter' behaves as if the identity filter were used.
2479      *
2480      * 'scaleFactor' is an extra uniform scale transform applied to downscale the 'src' image
2481      * before any filtering, or as part of the copy, and is then drawn with 1/scaleFactor to 'dst'.
2482      * Must be 1.0 if 'compat' is kYes (i.e. any scale factor has already been baked into the
2483      * relative transforms between the devices).
2484      */
2485     void internalDrawDeviceWithFilter(SkBaseDevice* src, SkBaseDevice* dst,
2486                                       const SkImageFilter* filter, const SkPaint& paint,
2487                                       DeviceCompatibleWithFilter compat,
2488                                       SkScalar scaleFactor = 1.f);
2489 
2490     /*
2491      *  Returns true if drawing the specified rect (or all if it is null) with the specified
2492      *  paint (or default if null) would overwrite the entire root device of the canvas
2493      *  (i.e. the canvas' surface if it had one).
2494      */
2495     bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
2496 
2497     /**
2498      *  Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
2499      */
2500     bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkSamplingOptions&,
2501                                const SkPaint&);
2502 
2503     /**
2504      *  Returns true if the clip (for any active layer) contains antialiasing.
2505      *  If the clip is empty, this will return false.
2506      */
2507     bool androidFramework_isClipAA() const;
2508 
2509     /**
2510      * Reset the clip to be wide-open (modulo any separately specified device clip restriction).
2511      * This operate within the save/restore clip stack so it can be undone by restoring to an
2512      * earlier save point.
2513      */
2514     void internal_private_resetClip();
2515 
internal_private_asPaintFilterCanvas()2516     virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; }
2517 
2518     // Keep track of the device clip bounds in the canvas' global space to reject draws before
2519     // invoking the top-level device.
2520     SkRect fQuickRejectBounds;
2521 
2522     // Compute the clip's bounds based on all clipped SkDevice's reported device bounds transformed
2523     // into the canvas' global space.
2524     SkRect computeDeviceClipBounds(bool outsetForAA=true) const;
2525 
2526     class AutoUpdateQRBounds;
2527     void validateClip() const;
2528 
2529     std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;
2530 
2531     using INHERITED = SkRefCnt;
2532 };
2533 
2534 /** \class SkAutoCanvasRestore
2535     Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore
2536     goes out of scope. Use this to guarantee that the canvas is restored to a known
2537     state.
2538 */
2539 class SkAutoCanvasRestore {
2540 public:
2541 
2542     /** Preserves SkCanvas::save() count. Optionally saves SkCanvas clip and SkCanvas matrix.
2543 
2544         @param canvas  SkCanvas to guard
2545         @param doSave  call SkCanvas::save()
2546         @return        utility to restore SkCanvas state on destructor
2547     */
SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)2548     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
2549         if (fCanvas) {
2550             fSaveCount = canvas->getSaveCount();
2551             if (doSave) {
2552                 canvas->save();
2553             }
2554         }
2555     }
2556 
2557     /** Restores SkCanvas to saved state. Destructor is called when container goes out of
2558         scope.
2559     */
~SkAutoCanvasRestore()2560     ~SkAutoCanvasRestore() {
2561         if (fCanvas) {
2562             fCanvas->restoreToCount(fSaveCount);
2563         }
2564     }
2565 
2566     /** Restores SkCanvas to saved state immediately. Subsequent calls and
2567         ~SkAutoCanvasRestore() have no effect.
2568     */
restore()2569     void restore() {
2570         if (fCanvas) {
2571             fCanvas->restoreToCount(fSaveCount);
2572             fCanvas = nullptr;
2573         }
2574     }
2575 
2576 private:
2577     SkCanvas*   fCanvas;
2578     int         fSaveCount;
2579 
2580     SkAutoCanvasRestore(SkAutoCanvasRestore&&) = delete;
2581     SkAutoCanvasRestore(const SkAutoCanvasRestore&) = delete;
2582     SkAutoCanvasRestore& operator=(SkAutoCanvasRestore&&) = delete;
2583     SkAutoCanvasRestore& operator=(const SkAutoCanvasRestore&) = delete;
2584 };
2585 
2586 #endif
2587