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