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