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