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