• 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 
1459 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
1460     /** Only for Stencil Culling use, Please do not use in other cases.
1461         Similar to DrawPath but with Stencil test, which will attempt
1462         to enable Stencil Test using CompareOp GREATER_OR_EQUAL.
1463         it will degenerate into DrawPath if Non-StencilCullingOp use stencil.
1464     */
1465     void drawPathWithStencil(const SkPath& path, const SkPaint& paint, uint32_t stencilRef);
1466 
1467     /** Only for Stencil Culling use, Please do not use in other cases.
1468         Similar to DrawImage but with Stencil test, which will attempt
1469         to enable Stencil Test using CompareOp GREATER_OR_EQUAL.
1470         it will degenerate into DrawImage if Non-StencilCullingOp use stencil.
1471     */
drawImageWithStencil(const sk_sp<SkImage> & image,SkScalar left,SkScalar top,const SkSamplingOptions & sampling,const SkPaint * paint,uint32_t stencilRef)1472     void drawImageWithStencil(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
1473                               const SkSamplingOptions& sampling, const SkPaint* paint, uint32_t stencilRef) {
1474         this->onDrawImage2WithStencil(image.get(), left, top, sampling, paint, stencilRef);
1475     }
1476 
1477     /** Only for Stencil Culling use, Please do not use in other cases.
1478         Use stecnilVal to clear the specified area in stencil Buffer.
1479         it will do nothing if Non-StencilCullingOp use stencil.
1480     */
1481     void clearStencil(const SkIRect& rect, uint32_t stencilVal);
1482 #endif
1483 
drawImage(const SkImage * image,SkScalar left,SkScalar top)1484     void drawImage(const SkImage* image, SkScalar left, SkScalar top) {
1485         this->drawImage(image, left, top, SkSamplingOptions(), nullptr);
1486     }
drawImage(const sk_sp<SkImage> & image,SkScalar left,SkScalar top)1487     void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top) {
1488         this->drawImage(image.get(), left, top, SkSamplingOptions(), nullptr);
1489     }
1490 
1491     /** \enum SkCanvas::SrcRectConstraint
1492         SrcRectConstraint controls the behavior at the edge of source SkRect,
1493         provided to drawImageRect() when there is any filtering. If kStrict is set,
1494         then extra code is used to ensure it nevers samples outside of the src-rect.
1495     */
1496     enum SrcRectConstraint {
1497         kStrict_SrcRectConstraint, //!< sample only inside bounds; slower
1498         kFast_SrcRectConstraint,   //!< sample outside bounds; faster
1499     };
1500 
1501     void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkSamplingOptions&,
1502                    const SkPaint* = nullptr);
1503     void drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
1504                    const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
1505         this->drawImage(image.get(), x, y, sampling, paint);
1506     }
1507     void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst,
1508                        const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
1509     void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&,
1510                        const SkPaint* = nullptr);
drawImageRect(const sk_sp<SkImage> & image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SrcRectConstraint constraint)1511     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
1512                        const SkSamplingOptions& sampling, const SkPaint* paint,
1513                        SrcRectConstraint constraint) {
1514         this->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
1515     }
1516     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst,
1517                        const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
1518         this->drawImageRect(image.get(), dst, sampling, paint);
1519     }
1520 
1521     /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1522         SkIRect center divides the image into nine sections: four sides, four corners, and
1523         the center. Corners are unmodified or scaled down proportionately if their sides
1524         are larger than dst; center and four sides are scaled to fit remaining space, if any.
1525 
1526         Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1527 
1528         If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
1529         SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
1530         If paint contains SkMaskFilter, generate mask from image bounds.
1531         Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1532 
1533         If generated mask extends beyond image bounds, replicate image edge colors, just
1534         as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
1535         replicates the image edge color when it samples outside of its bounds.
1536 
1537         @param image   SkImage containing pixels, dimensions, and format
1538         @param center  SkIRect edge of image corners and sides
1539         @param dst     destination SkRect of image to draw to
1540         @param filter  what technique to use when sampling the image
1541         @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1542                        and so on; or nullptr
1543     */
1544     void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
1545                        SkFilterMode filter, const SkPaint* paint = nullptr);
1546 
1547     /** \struct SkCanvas::Lattice
1548         SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
1549         Grid entries on even columns and even rows are fixed; these entries are
1550         always drawn at their original size if the destination is large enough.
1551         If the destination side is too small to hold the fixed entries, all fixed
1552         entries are proportionately scaled down to fit.
1553         The grid entries not on even columns and rows are scaled to fit the
1554         remaining space, if any.
1555     */
1556     struct Lattice {
1557 
1558         /** \enum SkCanvas::Lattice::RectType
1559             Optional setting per rectangular grid entry to make it transparent,
1560             or to fill the grid entry with a color.
1561         */
1562         enum RectType : uint8_t {
1563             kDefault     = 0, //!< draws SkBitmap into lattice rectangle
1564             kTransparent,     //!< skips lattice rectangle by making it transparent
1565             kFixedColor,      //!< draws one of fColors into lattice rectangle
1566         };
1567 
1568         const int*      fXDivs;     //!< x-axis values dividing bitmap
1569         const int*      fYDivs;     //!< y-axis values dividing bitmap
1570         const RectType* fRectTypes; //!< array of fill types
1571         int             fXCount;    //!< number of x-coordinates
1572         int             fYCount;    //!< number of y-coordinates
1573         const SkIRect*  fBounds;    //!< source bounds to draw from
1574         const SkColor*  fColors;    //!< array of colors
1575     };
1576 
1577     /** Draws SkImage image stretched proportionally to fit into SkRect dst.
1578 
1579         SkCanvas::Lattice lattice divides image into a rectangular grid.
1580         Each intersection of an even-numbered row and column is fixed;
1581         fixed lattice elements never scale larger than their initial
1582         size and shrink proportionately when all fixed elements exceed the bitmap
1583         dimension. All other grid elements scale to fill the available space, if any.
1584 
1585         Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
1586 
1587         If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
1588         SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
1589         If paint contains SkMaskFilter, generate mask from image bounds.
1590         Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.
1591 
1592         If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
1593         just as SkShader made from SkShader::MakeBitmapShader with
1594         SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
1595         outside of its bounds.
1596 
1597         @param image    SkImage containing pixels, dimensions, and format
1598         @param lattice  division of bitmap into fixed and variable rectangles
1599         @param dst      destination SkRect of image to draw to
1600         @param filter   what technique to use when sampling the image
1601         @param paint    SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
1602                         and so on; or nullptr
1603     */
1604     void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
1605                           SkFilterMode filter, const SkPaint* paint = nullptr);
drawImageLattice(const SkImage * image,const Lattice & lattice,const SkRect & dst)1606     void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst) {
1607         this->drawImageLattice(image, lattice, dst, SkFilterMode::kNearest, nullptr);
1608     }
1609 
1610     /**
1611      * Experimental. Controls anti-aliasing of each edge of images in an image-set.
1612      */
1613     enum QuadAAFlags : unsigned {
1614         kLeft_QuadAAFlag    = 0b0001,
1615         kTop_QuadAAFlag     = 0b0010,
1616         kRight_QuadAAFlag   = 0b0100,
1617         kBottom_QuadAAFlag  = 0b1000,
1618 
1619         kNone_QuadAAFlags   = 0b0000,
1620         kAll_QuadAAFlags    = 0b1111,
1621     };
1622 
1623     /** This is used by the experimental API below. */
1624     struct SK_API ImageSetEntry {
1625         ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1626                       int matrixIndex, float alpha, unsigned aaFlags, bool hasClip);
1627 
1628         ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
1629                       float alpha, unsigned aaFlags);
1630 
1631         ImageSetEntry();
1632         ~ImageSetEntry();
1633         ImageSetEntry(const ImageSetEntry&);
1634         ImageSetEntry& operator=(const ImageSetEntry&);
1635 
1636         sk_sp<const SkImage> fImage;
1637         SkRect fSrcRect;
1638         SkRect fDstRect;
1639         int fMatrixIndex = -1; // Index into the preViewMatrices arg, or < 0
1640         float fAlpha = 1.f;
1641         unsigned fAAFlags = kNone_QuadAAFlags; // QuadAAFlags
1642         bool fHasClip = false; // True to use next 4 points in dstClip arg as quad
1643     };
1644 
1645     /**
1646      * This is an experimental API for the SkiaRenderer Chromium project, and its API will surely
1647      * evolve if it is not removed outright.
1648      *
1649      * This behaves very similarly to drawRect() combined with a clipPath() formed by clip
1650      * quadrilateral. 'rect' and 'clip' are in the same coordinate space. If 'clip' is null, then it
1651      * is as if the rectangle was not clipped (or, alternatively, clipped to itself). If not null,
1652      * then it must provide 4 points.
1653      *
1654      * In addition to combining the draw and clipping into one operation, this function adds the
1655      * additional capability of controlling each of the rectangle's edges anti-aliasing
1656      * independently.  The edges of the clip will respect the per-edge AA flags. It is required that
1657      * 'clip' be contained inside 'rect'. In terms of mapping to edge labels, the 'clip' points
1658      * should be ordered top-left, top-right, bottom-right, bottom-left so that the edge between [0]
1659      * and [1] is "top", [1] and [2] is "right", [2] and [3] is "bottom", and [3] and [0] is "left".
1660      * This ordering matches SkRect::toQuad().
1661      *
1662      * This API only draws solid color, filled rectangles so it does not accept a full SkPaint.
1663      */
1664     void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1665                                      const SkColor4f& color, SkBlendMode mode);
experimental_DrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],QuadAAFlags aaFlags,SkColor color,SkBlendMode mode)1666     void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
1667                                      SkColor color, SkBlendMode mode) {
1668         this->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, SkColor4f::FromColor(color), mode);
1669     }
1670 
1671     /**
1672      * This is an bulk variant of experimental_DrawEdgeAAQuad() that renders 'cnt' textured quads.
1673      * For each entry, 'fDstRect' is rendered with its clip (determined by entry's 'fHasClip' and
1674      * the current index in 'dstClip'). The entry's fImage is applied to the destination rectangle
1675      * by sampling from 'fSrcRect' sub-image.  The corners of 'fSrcRect' map to the corners of
1676      * 'fDstRect', just like in drawImageRect(), and they will be properly interpolated when
1677      * applying a clip.
1678      *
1679      * Like experimental_DrawEdgeAAQuad(), each entry can specify edge AA flags that apply to both
1680      * the destination rect and its clip.
1681      *
1682      * If provided, the 'dstClips' array must have length equal 4 * the number of entries with
1683      * fHasClip true. If 'dstClips' is null, every entry must have 'fHasClip' set to false. The
1684      * destination clip coordinates will be read consecutively with the image set entries, advancing
1685      * by 4 points every time an entry with fHasClip is passed.
1686      *
1687      * This entry point supports per-entry manipulations to the canvas's current matrix. If an
1688      * entry provides 'fMatrixIndex' >= 0, it will be drawn as if the canvas's CTM was
1689      * canvas->getTotalMatrix() * preViewMatrices[fMatrixIndex]. If 'fMatrixIndex' is less than 0,
1690      * the pre-view matrix transform is implicitly the identity, so it will be drawn using just the
1691      * current canvas matrix. The pre-view matrix modifies the canvas's view matrix, it does not
1692      * affect the local coordinates of each entry.
1693      *
1694      * An optional paint may be provided, which supports the same subset of features usable with
1695      * drawImageRect (i.e. assumed to be filled and no path effects). When a paint is provided, the
1696      * image set is drawn as if each image used the applied paint independently, so each is affected
1697      * by the image, color, and/or mask filter.
1698      */
1699     void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
1700                                          const SkPoint dstClips[], const SkMatrix preViewMatrices[],
1701                                          const SkSamplingOptions&, const SkPaint* paint = nullptr,
1702                                          SrcRectConstraint constraint = kStrict_SrcRectConstraint);
1703 
1704     /** Draws text, with origin at (x, y), using clip, SkMatrix, SkFont font,
1705         and SkPaint paint.
1706 
1707         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
1708         SkTextEncoding::kUTF32, this function uses the default
1709         character-to-glyph mapping from the SkTypeface in font.  It does not
1710         perform typeface fallback for characters not found in the SkTypeface.
1711         It does not perform kerning or other complex shaping; glyphs are
1712         positioned based on their default advances.
1713 
1714         Text meaning depends on SkTextEncoding.
1715 
1716         Text size is affected by SkMatrix and SkFont text size. Default text
1717         size is 12 point.
1718 
1719         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1720         SkColorFilter, and SkImageFilter; apply to text. By
1721         default, draws filled black glyphs.
1722 
1723         @param text        character code points or glyphs drawn
1724         @param byteLength  byte length of text array
1725         @param encoding    text encoding used in the text array
1726         @param x           start of text on x-axis
1727         @param y           start of text on y-axis
1728         @param font        typeface, text size and so, used to describe the text
1729         @param paint       blend, color, and so on, used to draw
1730     */
1731     void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
1732                         SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint);
1733 
1734     /** Draws null terminated string, with origin at (x, y), using clip, SkMatrix,
1735         SkFont font, and SkPaint paint.
1736 
1737         This function uses the default character-to-glyph mapping from the
1738         SkTypeface in font.  It does not perform typeface fallback for
1739         characters not found in the SkTypeface.  It does not perform kerning;
1740         glyphs are positioned based on their default advances.
1741 
1742         String str is encoded as UTF-8.
1743 
1744         Text size is affected by SkMatrix and font text size. Default text
1745         size is 12 point.
1746 
1747         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1748         SkColorFilter, and SkImageFilter; apply to text. By
1749         default, draws filled black glyphs.
1750 
1751         @param str     character code points drawn,
1752                        ending with a char value of zero
1753         @param x       start of string on x-axis
1754         @param y       start of string on y-axis
1755         @param font    typeface, text size and so, used to describe the text
1756         @param paint   blend, color, and so on, used to draw
1757     */
drawString(const char str[],SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1758     void drawString(const char str[], SkScalar x, SkScalar y, const SkFont& font,
1759                     const SkPaint& paint) {
1760         this->drawSimpleText(str, strlen(str), SkTextEncoding::kUTF8, x, y, font, paint);
1761     }
1762 
1763     /** Draws SkString, with origin at (x, y), using clip, SkMatrix, SkFont font,
1764         and SkPaint paint.
1765 
1766         This function uses the default character-to-glyph mapping from the
1767         SkTypeface in font.  It does not perform typeface fallback for
1768         characters not found in the SkTypeface.  It does not perform kerning;
1769         glyphs are positioned based on their default advances.
1770 
1771         SkString str is encoded as UTF-8.
1772 
1773         Text size is affected by SkMatrix and SkFont text size. Default text
1774         size is 12 point.
1775 
1776         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1777         SkColorFilter, and SkImageFilter; apply to text. By
1778         default, draws filled black glyphs.
1779 
1780         @param str     character code points drawn,
1781                        ending with a char value of zero
1782         @param x       start of string on x-axis
1783         @param y       start of string on y-axis
1784         @param font    typeface, text size and so, used to describe the text
1785         @param paint   blend, color, and so on, used to draw
1786     */
drawString(const SkString & str,SkScalar x,SkScalar y,const SkFont & font,const SkPaint & paint)1787     void drawString(const SkString& str, SkScalar x, SkScalar y, const SkFont& font,
1788                     const SkPaint& paint) {
1789         this->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8, x, y, font, paint);
1790     }
1791 
1792     /** Draws count glyphs, at positions relative to origin styled with font and paint with
1793         supporting utf8 and cluster information.
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 clusters        array of size count of cluster information
1808        @param textByteCount   size of the utf8text
1809        @param utf8text        utf8text supporting information for the glyphs
1810        @param origin          the origin of all the positions
1811        @param font            typeface, text size and so, used to describe the text
1812        @param paint           blend, color, and so on, used to draw
1813     */
1814     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
1815                     const uint32_t clusters[], int textByteCount, const char utf8text[],
1816                     SkPoint origin, const SkFont& font, const SkPaint& paint);
1817 
1818     /** Draws count glyphs, at positions relative to origin styled with font and paint.
1819 
1820         This function draw glyphs at the given positions relative to the given origin.
1821         It does not perform typeface fallback for glyphs not found in the SkTypeface in font.
1822 
1823         The drawing obeys the current transform matrix and clipping.
1824 
1825         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1826         SkColorFilter, and SkImageFilter; apply to text. By
1827         default, draws filled black glyphs.
1828 
1829         @param count       number of glyphs to draw
1830         @param glyphs      the array of glyphIDs to draw
1831         @param positions   where to draw each glyph relative to origin
1832         @param origin      the origin of all the positions
1833         @param font        typeface, text size and so, used to describe the text
1834         @param paint       blend, color, and so on, used to draw
1835     */
1836     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
1837                     SkPoint origin, const SkFont& font, const SkPaint& paint);
1838 
1839     /** Draws count glyphs, at positions relative to origin styled with font and paint.
1840 
1841         This function draw glyphs using the given scaling and rotations. They are positioned
1842         relative to the given origin. It does not perform typeface fallback for glyphs not found
1843         in the SkTypeface in font.
1844 
1845         The drawing obeys the current transform matrix and clipping.
1846 
1847         All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
1848         SkColorFilter, and SkImageFilter; apply to text. By
1849         default, draws filled black glyphs.
1850 
1851         @param count    number of glyphs to draw
1852         @param glyphs   the array of glyphIDs to draw
1853         @param xforms   where to draw and orient each glyph
1854         @param origin   the origin of all the positions
1855         @param font     typeface, text size and so, used to describe the text
1856         @param paint    blend, color, and so on, used to draw
1857     */
1858     void drawGlyphs(int count, const SkGlyphID glyphs[], const SkRSXform xforms[],
1859                     SkPoint origin, const SkFont& font, 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: anti-alias, SkBlendMode, color including alpha,
1872         SkColorFilter, SkPaint dither, SkMaskFilter, SkPathEffect, SkShader, and
1873         SkPaint::Style; apply to blob. If SkPaint contains SkPaint::kStroke_Style:
1874         SkPaint miter limit, SkPaint::Cap, SkPaint::Join, and SkPaint stroke width;
1875         apply to SkPath created from blob.
1876 
1877         @param blob   glyphs, positions, and their paints' text size, typeface, and so on
1878         @param x      horizontal offset applied to blob
1879         @param y      vertical offset applied to blob
1880         @param paint  blend, color, stroking, and so on, used to draw
1881 
1882         example: https://fiddle.skia.org/c/@Canvas_drawTextBlob
1883     */
1884     void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
1885 
1886     /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
1887 
1888         blob contains glyphs, their positions, and paint attributes specific to text:
1889         SkTypeface, SkPaint text size, SkPaint text scale x,
1890         SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
1891         SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
1892         and SkPaint subpixel text.
1893 
1894         SkTextEncoding must be set to SkTextEncoding::kGlyphID.
1895 
1896         Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
1897         and SkImageFilter; apply to blob.
1898 
1899         @param blob   glyphs, positions, and their paints' text size, typeface, and so on
1900         @param x      horizontal offset applied to blob
1901         @param y      vertical offset applied to blob
1902         @param paint  blend, color, stroking, and so on, used to draw
1903     */
drawTextBlob(const sk_sp<SkTextBlob> & blob,SkScalar x,SkScalar y,const SkPaint & paint)1904     void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
1905         this->drawTextBlob(blob.get(), x, y, paint);
1906     }
1907 
1908     /** Draws HMSymbol at locate wih paint.
1909         @param symbol  HMSymbol information
1910         @param locate  draw locate
1911         @param paint  blend, color, stroking, and so on, used to draw
1912     */
drawSymbol(const HMSymbolData & symbol,SkPoint locate,const SkPaint & paint)1913     void drawSymbol(const HMSymbolData& symbol, SkPoint locate, const SkPaint& paint) {
1914         this->onDrawSymbol(symbol, locate, paint);
1915     }
1916 
1917     /** Draws SkPicture picture, using clip and SkMatrix.
1918         Clip and SkMatrix are unchanged by picture contents, as if
1919         save() was called before and restore() was called after drawPicture().
1920 
1921         SkPicture records a series of draw commands for later playback.
1922 
1923         @param picture  recorded drawing commands to play
1924     */
drawPicture(const SkPicture * picture)1925     void drawPicture(const SkPicture* picture) {
1926         this->drawPicture(picture, nullptr, nullptr);
1927     }
1928 
1929     /** Draws SkPicture picture, using clip and SkMatrix.
1930         Clip and SkMatrix are unchanged by picture contents, as if
1931         save() was called before and restore() was called after drawPicture().
1932 
1933         SkPicture records a series of draw commands for later playback.
1934 
1935         @param picture  recorded drawing commands to play
1936     */
drawPicture(const sk_sp<SkPicture> & picture)1937     void drawPicture(const sk_sp<SkPicture>& picture) {
1938         this->drawPicture(picture.get());
1939     }
1940 
1941     /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
1942         SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
1943         SkImageFilter, and SkBlendMode, if provided.
1944 
1945         If paint is non-null, then the picture is always drawn into a temporary layer before
1946         actually landing on the canvas. Note that drawing into a layer can also change its
1947         appearance if there are any non-associative blendModes inside any of the pictures elements.
1948 
1949         @param picture  recorded drawing commands to play
1950         @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
1951         @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr
1952 
1953         example: https://fiddle.skia.org/c/@Canvas_drawPicture_3
1954     */
1955     void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
1956 
1957     /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
1958         SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
1959         SkImageFilter, and SkBlendMode, if provided.
1960 
1961         If paint is non-null, then the picture is always drawn into a temporary layer before
1962         actually landing on the canvas. Note that drawing into a layer can also change its
1963         appearance if there are any non-associative blendModes inside any of the pictures elements.
1964 
1965         @param picture  recorded drawing commands to play
1966         @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
1967         @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr
1968     */
drawPicture(const sk_sp<SkPicture> & picture,const SkMatrix * matrix,const SkPaint * paint)1969     void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix,
1970                      const SkPaint* paint) {
1971         this->drawPicture(picture.get(), matrix, paint);
1972     }
1973 
1974     /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
1975         If paint contains an SkShader and vertices does not contain texCoords, the shader
1976         is mapped using the vertices' positions.
1977 
1978         If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
1979         SkBlendMode mode combines vertices colors with SkShader.
1980 
1981         SkMaskFilter and SkPathEffect on paint are ignored.
1982 
1983         @param vertices  triangle mesh to draw
1984         @param mode      combines vertices colors with SkShader, if both are present
1985         @param paint     specifies the SkShader, used as SkVertices texture; may be nullptr
1986 
1987         example: https://fiddle.skia.org/c/@Canvas_drawVertices
1988     */
1989     void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
1990 
1991     /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
1992      *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
1993      */
drawVertices(const SkVertices * vertices,const SkPaint & paint)1994     void drawVertices(const SkVertices* vertices, const SkPaint& paint) {
1995         this->drawVertices(vertices, SkBlendMode::kModulate, paint);
1996     }
1997 
1998     /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
1999         If paint contains an SkShader and vertices does not contain texCoords, the shader
2000         is mapped using the vertices' positions.
2001 
2002         If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
2003         SkBlendMode mode combines vertices colors with SkShader.
2004 
2005         SkMaskFilter and SkPathEffect on paint are ignored.
2006 
2007         @param vertices  triangle mesh to draw
2008         @param mode      combines vertices colors with SkShader, if both are present
2009         @param paint     specifies the SkShader, used as SkVertices texture, may be nullptr
2010 
2011         example: https://fiddle.skia.org/c/@Canvas_drawVertices_2
2012     */
2013     void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
2014 
2015     /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
2016      *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
2017      */
drawVertices(const sk_sp<SkVertices> & vertices,const SkPaint & paint)2018     void drawVertices(const sk_sp<SkVertices>& vertices, const SkPaint& paint) {
2019         this->drawVertices(vertices, SkBlendMode::kModulate, paint);
2020     }
2021 
2022     /** Draws a Coons patch: the interpolation of four cubics with shared corners,
2023         associating a color, and optionally a texture SkPoint, with each corner.
2024 
2025         Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
2026         alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
2027         as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
2028         both are provided.
2029 
2030         SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2031         in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
2032         first point.
2033 
2034         Color array color associates colors with corners in top-left, top-right,
2035         bottom-right, bottom-left order.
2036 
2037         If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
2038         corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
2039         nullptr, SkShader is mapped using positions (derived from cubics).
2040 
2041         SkMaskFilter and SkPathEffect on paint are ignored.
2042 
2043         @param cubics     SkPath cubic array, sharing common points
2044         @param colors     color array, one for each corner
2045         @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
2046                           may be nullptr
2047         @param mode       SkBlendMode for colors, and for SkShader if paint has one
2048         @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
2049     */
2050     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2051                    const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2052 
2053     /** Draws SkPath cubic Coons patch: the interpolation of four cubics with shared corners,
2054         associating a color, and optionally a texture SkPoint, with each corner.
2055 
2056         Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
2057         alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
2058         as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
2059         both are provided.
2060 
2061         SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
2062         in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
2063         first point.
2064 
2065         Color array color associates colors with corners in top-left, top-right,
2066         bottom-right, bottom-left order.
2067 
2068         If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
2069         corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
2070         nullptr, SkShader is mapped using positions (derived from cubics).
2071 
2072         SkMaskFilter and SkPathEffect on paint are ignored.
2073 
2074         @param cubics     SkPath cubic array, sharing common points
2075         @param colors     color array, one for each corner
2076         @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
2077                           may be nullptr
2078         @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
2079     */
drawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],const SkPaint & paint)2080     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
2081                    const SkPoint texCoords[4], const SkPaint& paint) {
2082         this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
2083     }
2084 
2085     /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
2086         paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
2087         to draw, if present. For each entry in the array, SkRect tex locates sprite in
2088         atlas, and SkRSXform xform transforms it into destination space.
2089 
2090         SkMaskFilter and SkPathEffect on paint are ignored.
2091 
2092         xform, tex, and colors if present, must contain count entries.
2093         Optional colors are applied for each sprite using SkBlendMode mode, treating
2094         sprite as source and colors as destination.
2095         Optional cullRect is a conservative bounds of all transformed sprites.
2096         If cullRect is outside of clip, canvas can skip drawing.
2097 
2098         If atlas is nullptr, this draws nothing.
2099 
2100         @param atlas     SkImage containing sprites
2101         @param xform     SkRSXform mappings for sprites in atlas
2102         @param tex       SkRect locations of sprites in atlas
2103         @param colors    one per sprite, blended with sprite using SkBlendMode; may be nullptr
2104         @param count     number of sprites to draw
2105         @param mode      SkBlendMode combining colors and sprites
2106         @param sampling  SkSamplingOptions used when sampling from the atlas image
2107         @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
2108         @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
2109     */
2110     void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
2111                    const SkColor colors[], int count, SkBlendMode mode,
2112                    const SkSamplingOptions& sampling, const SkRect* cullRect, const SkPaint* paint);
2113 
2114     /** Draws SkDrawable drawable using clip and SkMatrix, concatenated with
2115         optional matrix.
2116 
2117         If SkCanvas has an asynchronous implementation, as is the case
2118         when it is recording into SkPicture, then drawable will be referenced,
2119         so that SkDrawable::draw() can be called when the operation is finalized. To force
2120         immediate drawing, call SkDrawable::draw() instead.
2121 
2122         @param drawable  custom struct encapsulating drawing commands
2123         @param matrix    transformation applied to drawing; may be nullptr
2124 
2125         example: https://fiddle.skia.org/c/@Canvas_drawDrawable
2126     */
2127     void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);
2128 
2129     /** Draws SkDrawable drawable using clip and SkMatrix, offset by (x, y).
2130 
2131         If SkCanvas has an asynchronous implementation, as is the case
2132         when it is recording into SkPicture, then drawable will be referenced,
2133         so that SkDrawable::draw() can be called when the operation is finalized. To force
2134         immediate drawing, call SkDrawable::draw() instead.
2135 
2136         @param drawable  custom struct encapsulating drawing commands
2137         @param x         offset into SkCanvas writable pixels on x-axis
2138         @param y         offset into SkCanvas writable pixels on y-axis
2139 
2140         example: https://fiddle.skia.org/c/@Canvas_drawDrawable_2
2141     */
2142     void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
2143 
2144     /** Associates SkRect on SkCanvas with an annotation; a key-value pair, where the key is
2145         a null-terminated UTF-8 string, and optional value is stored as SkData.
2146 
2147         Only some canvas implementations, such as recording to SkPicture, or drawing to
2148         document PDF, use annotations.
2149 
2150         @param rect   SkRect extent of canvas to annotate
2151         @param key    string used for lookup
2152         @param value  data holding value stored in annotation
2153 
2154         example: https://fiddle.skia.org/c/@Canvas_drawAnnotation_2
2155     */
2156     void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
2157 
2158     /** Associates SkRect on SkCanvas when an annotation; a key-value pair, where the key is
2159         a null-terminated UTF-8 string, and optional value is stored as SkData.
2160 
2161         Only some canvas implementations, such as recording to SkPicture, or drawing to
2162         document PDF, use annotations.
2163 
2164         @param rect   SkRect extent of canvas to annotate
2165         @param key    string used for lookup
2166         @param value  data holding value stored in annotation
2167     */
drawAnnotation(const SkRect & rect,const char key[],const sk_sp<SkData> & value)2168     void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
2169         this->drawAnnotation(rect, key, value.get());
2170     }
2171 
2172     /** Returns true if clip is empty; that is, nothing will draw.
2173 
2174         May do work when called; it should not be called
2175         more often than needed. However, once called, subsequent calls perform no
2176         work until clip changes.
2177 
2178         @return  true if clip is empty
2179 
2180         example: https://fiddle.skia.org/c/@Canvas_isClipEmpty
2181     */
2182     virtual bool isClipEmpty() const;
2183 
2184     /** Returns true if clip is SkRect and not empty.
2185         Returns false if the clip is empty, or if it is not SkRect.
2186 
2187         @return  true if clip is SkRect and not empty
2188 
2189         example: https://fiddle.skia.org/c/@Canvas_isClipRect
2190     */
2191     virtual bool isClipRect() const;
2192 
2193     /** Returns the current transform from local coordinates to the 'device', which for most
2194      *  purposes means pixels.
2195      *
2196      *  @return transformation from local coordinates to device / pixels.
2197      */
2198     SkM44 getLocalToDevice() const;
2199 
2200     /**
2201      *  Throws away the 3rd row and column in the matrix, so be warned.
2202      */
getLocalToDeviceAs3x3()2203     SkMatrix getLocalToDeviceAs3x3() const {
2204         return this->getLocalToDevice().asM33();
2205     }
2206 
2207 #ifdef SK_SUPPORT_LEGACY_GETTOTALMATRIX
2208     /** DEPRECATED
2209      *  Legacy version of getLocalToDevice(), which strips away any Z information, and
2210      *  just returns a 3x3 version.
2211      *
2212      *  @return 3x3 version of getLocalToDevice()
2213      *
2214      *  example: https://fiddle.skia.org/c/@Canvas_getTotalMatrix
2215      *  example: https://fiddle.skia.org/c/@Clip
2216      */
2217     SkMatrix getTotalMatrix() const;
2218 #endif
2219 
2220     ///////////////////////////////////////////////////////////////////////////
2221 
2222 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && SK_SUPPORT_GPU
2223     // These methods exist to support WebView in Android Framework.
2224     SkIRect topLayerBounds() const;
2225     GrBackendRenderTarget topLayerBackendRenderTarget() const;
2226 #endif
2227 
2228     /**
2229      *  Returns the global clip as a region. If the clip contains AA, then only the bounds
2230      *  of the clip may be returned.
2231      */
2232     void temporary_internal_getRgnClip(SkRegion* region);
2233 
2234     void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
2235 
2236     /**
2237      *   Get the downSample Dimension when do drawBlurImage.
2238      *
2239      *   @param blurArg  parameter of blur.
2240      *   @return {width, height}, if return {0, 0}, witch means something error.
2241     */
2242     std::array<int, 2> CalcHpsBluredImageDimension(const SkBlurArg& blurArg);
2243 
2244     /**
2245      *   Draw SkImage image with Gaussian Blur algorithm by the separate X and Y sigma
2246      *   onto destination canvas.  The provided tile mode is used when blur kernel goes
2247      *   outside the input image, by default SkTileMode::kDecal is used.
2248      *
2249      *   @param image    SkImage containing pixels, dimensions, and format.
2250      *   @param blurArg  parameter of blur.
2251     */
drawBlurImage(const SkImage * image,const SkBlurArg & blurArg)2252     bool drawBlurImage(const SkImage* image, const SkBlurArg& blurArg)
2253     {
2254         if (image == nullptr) {
2255             return false;
2256         }
2257         return this->onDrawBlurImage(image, blurArg);
2258     }
2259 
2260 
2261 protected:
2262     // default impl defers to getDevice()->newSurface(info)
2263     virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
2264 
2265     // default impl defers to its device
2266     virtual bool onPeekPixels(SkPixmap* pixmap);
2267     virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
2268     virtual SkImageInfo onImageInfo() const;
2269     virtual bool onGetProps(SkSurfaceProps* props) const;
2270     virtual void onFlush();
2271 
2272     // Subclass save/restore notifiers.
2273     // Overriders should call the corresponding INHERITED method up the inheritance chain.
2274     // getSaveLayerStrategy()'s return value may suppress full layer allocation.
2275     enum SaveLayerStrategy {
2276         kFullLayer_SaveLayerStrategy,
2277         kNoLayer_SaveLayerStrategy,
2278     };
2279 
willSave()2280     virtual void willSave() {}
2281     // Overriders should call the corresponding INHERITED method up the inheritance chain.
getSaveLayerStrategy(const SaveLayerRec &)2282     virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
2283         return kFullLayer_SaveLayerStrategy;
2284     }
2285 
2286     // returns true if we should actually perform the saveBehind, or false if we should just save.
onDoSaveBehind(const SkRect *)2287     virtual bool onDoSaveBehind(const SkRect*) { return true; }
willRestore()2288     virtual void willRestore() {}
didRestore()2289     virtual void didRestore() {}
2290 
onMarkCTM(const char *)2291     virtual void onMarkCTM(const char*) {}
didConcat44(const SkM44 &)2292     virtual void didConcat44(const SkM44&) {}
didSetM44(const SkM44 &)2293     virtual void didSetM44(const SkM44&) {}
didTranslate(SkScalar,SkScalar)2294     virtual void didTranslate(SkScalar, SkScalar) {}
didScale(SkScalar,SkScalar)2295     virtual void didScale(SkScalar, SkScalar) {}
2296 
2297     // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
2298     // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
2299     // that mechanism  will be required to implement the new function.
2300     virtual void onDrawPaint(const SkPaint& paint);
2301     virtual void onDrawBehind(const SkPaint& paint);
2302     virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
2303     virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
2304     virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
2305     virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
2306     virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
2307                            bool useCenter, const SkPaint& paint);
2308     virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
2309 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
2310     virtual void onDrawPathWithStencil(const SkPath& path, const SkPaint& paint, uint32_t stencilRef);
2311     virtual void onDrawImage2WithStencil(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
2312         const SkPaint*, uint32_t stencilRef);
2313 #endif
2314     virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
2315 
2316     virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
2317                                 const SkPaint& paint);
2318 
onDrawSymbol(const HMSymbolData & symbol,SkPoint locate,const SkPaint & paint)2319     virtual void onDrawSymbol(const HMSymbolData& symbol, SkPoint locate, const SkPaint& paint) {}
2320 
2321     virtual void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint);
2322 
2323     virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
2324                            const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
2325     virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
2326                               const SkPaint& paint);
2327 
2328     virtual void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
2329                               const SkPaint*);
2330     virtual void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst,
2331                                   const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
2332     virtual void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect& dst,
2333                                      SkFilterMode, const SkPaint*);
2334     virtual void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect src[],
2335                               const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
2336                               const SkRect* cull, const SkPaint*);
2337     virtual void onDrawEdgeAAImageSet2(const ImageSetEntry imageSet[], int count,
2338                                        const SkPoint dstClips[], const SkMatrix preViewMatrices[],
2339                                        const SkSamplingOptions&, const SkPaint*,
2340                                        SrcRectConstraint);
2341 
2342     virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
2343                                       const SkPaint& paint);
2344 
2345     virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
2346     virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
2347 
2348     virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
2349     virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
2350                                const SkPaint* paint);
2351 
2352     virtual void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
2353                                   const SkColor4f& color, SkBlendMode mode);
2354 
2355     enum ClipEdgeStyle {
2356         kHard_ClipEdgeStyle,
2357         kSoft_ClipEdgeStyle
2358     };
2359 
2360     virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
2361     virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
2362     virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
2363     virtual void onClipShader(sk_sp<SkShader>, SkClipOp);
2364     virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
2365     virtual void onResetClip();
2366 
2367     virtual void onDiscard();
2368 
2369     virtual bool onDrawBlurImage(const SkImage* image, const SkBlurArg& blurArg);
2370 
2371 private:
2372 
2373     enum ShaderOverrideOpacity {
2374         kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
2375         kOpaque_ShaderOverrideOpacity,      //!< the overriding shader is opaque
2376         kNotOpaque_ShaderOverrideOpacity,   //!< the overriding shader may not be opaque
2377     };
2378 
2379     // notify our surface (if we have one) that we are about to draw, so it
2380     // can perform copy-on-write or invalidate any cached images
2381     // returns false if the copy failed
2382     bool SK_WARN_UNUSED_RESULT predrawNotify(bool willOverwritesEntireSurface = false);
2383     bool SK_WARN_UNUSED_RESULT predrawNotify(const SkRect*, const SkPaint*, ShaderOverrideOpacity);
2384 
2385     enum class CheckForOverwrite : bool {
2386         kNo = false,
2387         kYes = true
2388     };
2389     // call the appropriate predrawNotify and create a layer if needed.
2390     skstd::optional<AutoLayerForImageFilter> aboutToDraw(
2391         SkCanvas* canvas,
2392         const SkPaint& paint,
2393         const SkRect* rawBounds = nullptr,
2394         CheckForOverwrite = CheckForOverwrite::kNo,
2395         ShaderOverrideOpacity = kNone_ShaderOverrideOpacity);
2396 
2397     // The bottom-most device in the stack, only changed by init(). Image properties and the final
2398     // canvas pixels are determined by this device.
baseDevice()2399     SkBaseDevice* baseDevice() const {
2400         SkASSERT(fBaseDevice);
2401         return fBaseDevice.get();
2402     }
2403 
2404     // The top-most device in the stack, will change within saveLayer()'s. All drawing and clipping
2405     // operations should route to this device.
2406     SkBaseDevice* topDevice() const;
2407 
2408     // Canvases maintain a sparse stack of layers, where the top-most layer receives the drawing,
2409     // clip, and matrix commands. There is a layer per call to saveLayer() using the
2410     // kFullLayer_SaveLayerStrategy.
2411     struct Layer {
2412         sk_sp<SkBaseDevice>  fDevice;
2413         sk_sp<SkImageFilter> fImageFilter; // applied to layer *before* being drawn by paint
2414         SkPaint              fPaint;
2415         bool                 fDiscard;
2416 
2417         Layer(sk_sp<SkBaseDevice> device, sk_sp<SkImageFilter> imageFilter, const SkPaint& paint);
2418     };
2419 
2420     // Encapsulate state needed to restore from saveBehind()
2421     struct BackImage {
2422         sk_sp<SkSpecialImage> fImage;
2423         SkIPoint              fLoc;
2424     };
2425 
2426     class MCRec {
2427     public:
2428         // If not null, this MCRec corresponds with the saveLayer() record that made the layer.
2429         // The base "layer" is not stored here, since it is stored inline in SkCanvas and has no
2430         // restoration behavior.
2431         std::unique_ptr<Layer> fLayer;
2432 
2433         // This points to the device of the top-most layer (which may be lower in the stack), or
2434         // to the canvas's fBaseDevice. The MCRec does not own the device.
2435         SkBaseDevice* fDevice;
2436 
2437         std::unique_ptr<BackImage> fBackImage;
2438         SkM44 fMatrix;
2439         int fDeferredSaveCount = 0;
2440 
2441         MCRec(SkBaseDevice* device);
2442         MCRec(const MCRec* prev);
2443         ~MCRec();
2444 
2445         void newLayer(sk_sp<SkBaseDevice> layerDevice,
2446                       sk_sp<SkImageFilter> filter,
2447                       const SkPaint& restorePaint);
2448 
2449         void reset(SkBaseDevice* device);
2450     };
2451 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
2452     void drawImageCommon(const SkImage* image, SkScalar x, SkScalar y,
2453                          const SkSamplingOptions& sampling, const SkPaint* paint,
2454                          bool useStencil, uint32_t stencilRef = 0);
2455 
2456     void onDrawPathCommon(const SkPath& path, const SkPaint& paint, bool useStencil, uint32_t stencilRef = 0);
2457 #endif
2458     SkDeque     fMCStack;
2459     // points to top of stack
2460     MCRec*      fMCRec;
2461 
2462     sk_sp<SkMarkerStack> fMarkerStack;
2463 
2464     // the first N recs that can fit here mean we won't call malloc
2465     static constexpr int kMCRecSize      = 96; // most recent measurement
2466     static constexpr int kMCRecCount     = 32; // common depth for save/restores
2467 
2468     intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
2469 
2470     // Installed via init()
2471     sk_sp<SkBaseDevice> fBaseDevice;
2472     const SkSurfaceProps fProps;
2473 
2474     int         fSaveCount;         // value returned by getSaveCount()
2475 
2476     std::unique_ptr<SkRasterHandleAllocator> fAllocator;
2477 
2478     SkSurface_Base*  fSurfaceBase;
getSurfaceBase()2479     SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
setSurfaceBase(SkSurface_Base * sb)2480     void setSurfaceBase(SkSurface_Base* sb) {
2481         fSurfaceBase = sb;
2482     }
2483     friend class SkSurface_Base;
2484     friend class SkSurface_Gpu;
2485 
2486     SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
2487     int fClipRestrictionSaveCount = -1;
2488 
2489     void doSave();
2490     void checkForDeferredSave();
2491     void internalSetMatrix(const SkM44&);
2492 
2493     friend class SkAndroidFrameworkUtils;
2494     friend class SkCanvasPriv;      // needs to expose android functions for testing outside android
2495     friend class AutoLayerForImageFilter;
2496     friend class SkSurface_Raster;  // needs getDevice()
2497     friend class SkNoDrawCanvas;    // needs resetForNextPicture()
2498     friend class SkNWayCanvas;
2499     friend class SkPictureRecord;   // predrawNotify (why does it need it? <reed>)
2500     friend class SkOverdrawCanvas;
2501     friend class SkRasterHandleAllocator;
2502 protected:
2503     // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
2504     SkCanvas(const SkIRect& bounds);
2505 private:
2506     SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
2507              SkRasterHandleAllocator::Handle);
2508 
2509     SkCanvas(SkCanvas&&) = delete;
2510     SkCanvas(const SkCanvas&) = delete;
2511     SkCanvas& operator=(SkCanvas&&) = delete;
2512     SkCanvas& operator=(const SkCanvas&) = delete;
2513 
2514     /** Experimental
2515      *  Saves the specified subset of the current pixels in the current layer,
2516      *  and then clears those pixels to transparent black.
2517      *  Restores the pixels on restore() by drawing them in SkBlendMode::kDstOver.
2518      *
2519      *  @param subset   conservative bounds of the area to be saved / restored.
2520      *  @return depth of save state stack before this call was made.
2521      */
2522     int only_axis_aligned_saveBehind(const SkRect* subset);
2523 
2524     /**
2525      *  Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
2526      *  If there is no active saveBehind, then this draws nothing.
2527      */
2528     void drawClippedToSaveBehind(const SkPaint&);
2529 
2530     void resetForNextPicture(const SkIRect& bounds);
2531 
2532     // needs gettotalclip()
2533     friend class SkCanvasStateUtils;
2534 
2535     void init(sk_sp<SkBaseDevice>);
2536 
2537     // All base onDrawX() functions should call this and skip drawing if it returns true.
2538     // If 'matrix' is non-null, it maps the paint's fast bounds before checking for quick rejection
2539     bool internalQuickReject(const SkRect& bounds, const SkPaint& paint,
2540                              const SkMatrix* matrix = nullptr);
2541 
2542     void internalDrawPaint(const SkPaint& paint);
2543     void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
2544     void internalSaveBehind(const SkRect*);
2545 
2546     void internalConcat44(const SkM44&);
2547 
2548     // shared by save() and saveLayer()
2549     void internalSave();
2550     void internalRestore();
2551 
2552     enum class DeviceCompatibleWithFilter : bool {
2553         // Check the src device's local-to-device matrix for compatibility with the filter, and if
2554         // it is not compatible, introduce an intermediate image and transformation that allows the
2555         // filter to be evaluated on the modified src content.
2556         kUnknown = false,
2557         // Assume that the src device's local-to-device matrix is compatible with the filter.
2558         kYes     = true
2559     };
2560     /**
2561      * Filters the contents of 'src' and draws the result into 'dst'. The filter is evaluated
2562      * relative to the current canvas matrix, and src is drawn to dst using their relative transform
2563      * 'paint' is applied after the filter and must not have a mask or image filter of its own.
2564      * A null 'filter' behaves as if the identity filter were used.
2565      *
2566      * 'scaleFactor' is an extra uniform scale transform applied to downscale the 'src' image
2567      * before any filtering, or as part of the copy, and is then drawn with 1/scaleFactor to 'dst'.
2568      * Must be 1.0 if 'compat' is kYes (i.e. any scale factor has already been baked into the
2569      * relative transforms between the devices).
2570      */
2571     void internalDrawDeviceWithFilter(SkBaseDevice* src, SkBaseDevice* dst,
2572                                       const SkImageFilter* filter, const SkPaint& paint,
2573                                       DeviceCompatibleWithFilter compat,
2574                                       SkScalar scaleFactor = 1.f);
2575 
2576     /*
2577      *  Returns true if drawing the specified rect (or all if it is null) with the specified
2578      *  paint (or default if null) would overwrite the entire root device of the canvas
2579      *  (i.e. the canvas' surface if it had one).
2580      */
2581     bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
2582 
2583     /**
2584      *  Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
2585      */
2586     bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkSamplingOptions&,
2587                                const SkPaint&);
2588 
2589     /**
2590      *  Returns true if the clip (for any active layer) contains antialiasing.
2591      *  If the clip is empty, this will return false.
2592      */
2593     bool androidFramework_isClipAA() const;
2594 
2595     /**
2596      * Reset the clip to be wide-open (modulo any separately specified device clip restriction).
2597      * This operate within the save/restore clip stack so it can be undone by restoring to an
2598      * earlier save point.
2599      */
2600     void internal_private_resetClip();
2601 
internal_private_asPaintFilterCanvas()2602     virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; }
2603 
2604     // Keep track of the device clip bounds in the canvas' global space to reject draws before
2605     // invoking the top-level device.
2606     SkRect fQuickRejectBounds;
2607 
2608     // Compute the clip's bounds based on all clipped SkDevice's reported device bounds transformed
2609     // into the canvas' global space.
2610     SkRect computeDeviceClipBounds(bool outsetForAA=true) const;
2611 
2612     class AutoUpdateQRBounds;
2613     void validateClip() const;
2614 
2615     std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;
2616 
2617     using INHERITED = SkRefCnt;
2618 };
2619 
2620 /** \class SkAutoCanvasRestore
2621     Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore
2622     goes out of scope. Use this to guarantee that the canvas is restored to a known
2623     state.
2624 */
2625 class SkAutoCanvasRestore {
2626 public:
2627 
2628     /** Preserves SkCanvas::save() count. Optionally saves SkCanvas clip and SkCanvas matrix.
2629 
2630         @param canvas  SkCanvas to guard
2631         @param doSave  call SkCanvas::save()
2632         @return        utility to restore SkCanvas state on destructor
2633     */
SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)2634     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
2635         if (fCanvas) {
2636             fSaveCount = canvas->getSaveCount();
2637             if (doSave) {
2638                 canvas->save();
2639             }
2640         }
2641     }
2642 
2643     /** Restores SkCanvas to saved state. Destructor is called when container goes out of
2644         scope.
2645     */
~SkAutoCanvasRestore()2646     ~SkAutoCanvasRestore() {
2647         if (fCanvas) {
2648             fCanvas->restoreToCount(fSaveCount);
2649         }
2650     }
2651 
2652     /** Restores SkCanvas to saved state immediately. Subsequent calls and
2653         ~SkAutoCanvasRestore() have no effect.
2654     */
restore()2655     void restore() {
2656         if (fCanvas) {
2657             fCanvas->restoreToCount(fSaveCount);
2658             fCanvas = nullptr;
2659         }
2660     }
2661 
2662 private:
2663     SkCanvas*   fCanvas;
2664     int         fSaveCount;
2665 
2666     SkAutoCanvasRestore(SkAutoCanvasRestore&&) = delete;
2667     SkAutoCanvasRestore(const SkAutoCanvasRestore&) = delete;
2668     SkAutoCanvasRestore& operator=(SkAutoCanvasRestore&&) = delete;
2669     SkAutoCanvasRestore& operator=(const SkAutoCanvasRestore&) = delete;
2670 };
2671 
2672 #endif
2673