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