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