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