/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkCanvas_DEFINED
#define SkCanvas_DEFINED

#include "include/core/SkBlendMode.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRasterHandleAllocator.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/private/SkDeque.h"
#include "include/private/SkMacros.h"

#include <cstring>
#include <memory>
#include <vector>

// Working on allow this to be undefined
#define SK_SUPPORT_LEGACY_GETTOTALMATRIX
//#define SK_SUPPORT_LEGACY_ONDRAWIMAGERECT
#define SK_SUPPORT_LEGACY_DRAWBITMAP

class GrBackendRenderTarget;
class GrRecordingContext;
class GrSurfaceDrawContext;
class SkBaseDevice;
class SkBitmap;
class SkData;
class SkDrawable;
struct SkDrawShadowRec;
class SkFont;
class SkGlyphRunBuilder;
class SkImage;
class SkImageFilter;
class SkMarkerStack;
class SkPaintFilterCanvas;
class SkPath;
class SkPicture;
class SkPixmap;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkSurface;
class SkSurface_Base;
class SkTextBlob;
class SkVertices;

/** \class SkCanvas
    SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
    SkCanvas contains a stack of SkMatrix and clip values.

    SkCanvas and SkPaint together provide the state to draw into SkSurface or SkBaseDevice.
    Each SkCanvas draw call transforms the geometry of the object by the concatenation of all
    SkMatrix values in the stack. The transformed geometry is clipped by the intersection
    of all of clip values in the stack. The SkCanvas draw calls use SkPaint to supply drawing
    state such as color, SkTypeface, text size, stroke width, SkShader and so on.

    To draw to a pixel-based destination, create raster surface or GPU surface.
    Request SkCanvas from SkSurface to obtain the interface to draw.
    SkCanvas generated by raster surface draws to memory visible to the CPU.
    SkCanvas generated by GPU surface uses Vulkan or OpenGL to draw to the GPU.

    To draw to a document, obtain SkCanvas from SVG canvas, document PDF, or SkPictureRecorder.
    SkDocument based SkCanvas and other SkCanvas subclasses reference SkBaseDevice describing the
    destination.

    SkCanvas can be constructed to draw to SkBitmap without first creating raster surface.
    This approach may be deprecated in the future.
*/
class SK_API SkCanvas {
public:

    /** Allocates raster SkCanvas that will draw directly into pixels.

        SkCanvas is returned if all parameters are valid.
        Valid parameters include:
        info dimensions are zero or positive;
        info contains SkColorType and SkAlphaType supported by raster surface;
        pixels is not nullptr;
        rowBytes is zero or large enough to contain info width pixels of SkColorType.

        Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
        If rowBytes is greater than zero, it must be equal to or greater than
        info width times bytes required for SkColorType.

        Pixel buffer size should be info height times computed rowBytes.
        Pixels are not initialized.
        To access pixels after drawing, call flush() or peekPixels().

        @param info      width, height, SkColorType, SkAlphaType, SkColorSpace, of raster surface;
                         width, or height, or both, may be zero
        @param pixels    pointer to destination pixels buffer
        @param rowBytes  interval from one SkSurface row to the next, or zero
        @param props     LCD striping orientation and setting for device independent fonts;
                         may be nullptr
        @return          SkCanvas if all parameters are valid; otherwise, nullptr
    */
    static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
                                                      size_t rowBytes,
                                                      const SkSurfaceProps* props = nullptr);

    /** Allocates raster SkCanvas specified by inline image specification. Subsequent SkCanvas
        calls draw into pixels.
        SkColorType is set to kN32_SkColorType.
        SkAlphaType is set to kPremul_SkAlphaType.
        To access pixels after drawing, call flush() or peekPixels().

        SkCanvas is returned if all parameters are valid.
        Valid parameters include:
        width and height are zero or positive;
        pixels is not nullptr;
        rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.

        Pass zero for rowBytes to compute rowBytes from width and size of pixel.
        If rowBytes is greater than zero, it must be equal to or greater than
        width times bytes required for SkColorType.

        Pixel buffer size should be height times rowBytes.

        @param width     pixel column count on raster surface created; must be zero or greater
        @param height    pixel row count on raster surface created; must be zero or greater
        @param pixels    pointer to destination pixels buffer; buffer size should be height
                         times rowBytes
        @param rowBytes  interval from one SkSurface row to the next, or zero
        @return          SkCanvas if all parameters are valid; otherwise, nullptr
    */
    static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
                                                         size_t rowBytes) {
        return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
    }

    /** Creates an empty SkCanvas with no backing device or pixels, with
        a width and height of zero.

        @return  empty SkCanvas

        example: https://fiddle.skia.org/c/@Canvas_empty_constructor
    */
    SkCanvas();

    /** Creates SkCanvas of the specified dimensions without a SkSurface.
        Used by subclasses with custom implementations for draw member functions.

        If props equals nullptr, SkSurfaceProps are created with
        SkSurfaceProps::InitType settings, which choose the pixel striping
        direction and order. Since a platform may dynamically change its direction when
        the device is rotated, and since a platform may have multiple monitors with
        different characteristics, it is best not to rely on this legacy behavior.

        @param width   zero or greater
        @param height  zero or greater
        @param props   LCD striping orientation and setting for device independent fonts;
                       may be nullptr
        @return        SkCanvas placeholder with dimensions

        example: https://fiddle.skia.org/c/@Canvas_int_int_const_SkSurfaceProps_star
    */
    SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr);

    /** Private. For internal use only.
    */
    explicit SkCanvas(sk_sp<SkBaseDevice> device);

    /** Constructs a canvas that draws into bitmap.
        Sets kUnknown_SkPixelGeometry in constructed SkSurface.

        SkBitmap is copied so that subsequently editing bitmap will not affect
        constructed SkCanvas.

        May be deprecated in the future.

        @param bitmap  width, height, SkColorType, SkAlphaType, and pixel
                       storage of raster surface
        @return        SkCanvas that can be used to draw into bitmap

        example: https://fiddle.skia.org/c/@Canvas_copy_const_SkBitmap
    */
    explicit SkCanvas(const SkBitmap& bitmap);

#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    /** Private.
     */
    enum class ColorBehavior {
        kLegacy, //!< placeholder
    };

    /** Private. For use by Android framework only.

        @param bitmap    specifies a bitmap for the canvas to draw into
        @param behavior  specializes this constructor; value is unused
        @return          SkCanvas that can be used to draw into bitmap
    */
    SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
#endif

    /** Constructs a canvas that draws into bitmap.
        Use props to match the device characteristics, like LCD striping.

        bitmap is copied so that subsequently editing bitmap will not affect
        constructed SkCanvas.

        @param bitmap  width, height, SkColorType, SkAlphaType,
                       and pixel storage of raster surface
        @param props   order and orientation of RGB striping; and whether to use
                       device independent fonts
        @return        SkCanvas that can be used to draw into bitmap

        example: https://fiddle.skia.org/c/@Canvas_const_SkBitmap_const_SkSurfaceProps
    */
    SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);

    /** Draws saved layers, if any.
        Frees up resources used by SkCanvas.

        example: https://fiddle.skia.org/c/@Canvas_destructor
    */
    virtual ~SkCanvas();

    /** Returns SkImageInfo for SkCanvas. If SkCanvas is not associated with raster surface or
        GPU surface, returned SkColorType is set to kUnknown_SkColorType.

        @return  dimensions and SkColorType of SkCanvas

        example: https://fiddle.skia.org/c/@Canvas_imageInfo
    */
    SkImageInfo imageInfo() const;

    /** Copies SkSurfaceProps, if SkCanvas is associated with raster surface or
        GPU surface, and returns true. Otherwise, returns false and leave props unchanged.

        @param props  storage for writable SkSurfaceProps
        @return       true if SkSurfaceProps was copied

        example: https://fiddle.skia.org/c/@Canvas_getProps
    */
    bool getProps(SkSurfaceProps* props) const;

    /** Triggers the immediate execution of all pending draw operations.
        If SkCanvas is associated with GPU surface, resolves all pending GPU operations.
        If SkCanvas is associated with raster surface, has no effect; raster draw
        operations are never deferred.

        DEPRECATED: Replace usage with GrDirectContext::flush()
    */
    void flush();

    /** Gets the size of the base or root layer in global canvas coordinates. The
        origin of the base layer is always (0,0). The area available for drawing may be
        smaller (due to clipping or saveLayer).

        @return  integral width and height of base layer

        example: https://fiddle.skia.org/c/@Canvas_getBaseLayerSize
    */
    virtual SkISize getBaseLayerSize() const;

    /** Creates SkSurface matching info and props, and associates it with SkCanvas.
        Returns nullptr if no match found.

        If props is nullptr, matches SkSurfaceProps in SkCanvas. If props is nullptr and SkCanvas
        does not have SkSurfaceProps, creates SkSurface with default SkSurfaceProps.

        @param info   width, height, SkColorType, SkAlphaType, and SkColorSpace
        @param props  SkSurfaceProps to match; may be nullptr to match SkCanvas
        @return       SkSurface matching info and props, or nullptr if no match is available

        example: https://fiddle.skia.org/c/@Canvas_makeSurface
    */
    sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);

    /** Returns GPU context of the GPU surface associated with SkCanvas.

        @return  GPU context, if available; nullptr otherwise

        example: https://fiddle.skia.org/c/@Canvas_recordingContext
     */
    virtual GrRecordingContext* recordingContext();

    /** Sometimes a canvas is owned by a surface. If it is, getSurface() will return a bare
     *  pointer to that surface, else this will return nullptr.
     */
    SkSurface* getSurface() const;

    /** Returns the pixel base address, SkImageInfo, rowBytes, and origin if the pixels
        can be read directly. The returned address is only valid
        while SkCanvas is in scope and unchanged. Any SkCanvas call or SkSurface call
        may invalidate the returned address and other returned values.

        If pixels are inaccessible, info, rowBytes, and origin are unchanged.

        @param info      storage for writable pixels' SkImageInfo; may be nullptr
        @param rowBytes  storage for writable pixels' row bytes; may be nullptr
        @param origin    storage for SkCanvas top layer origin, its top-left corner;
                         may be nullptr
        @return          address of pixels, or nullptr if inaccessible

        example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_a
        example: https://fiddle.skia.org/c/@Canvas_accessTopLayerPixels_b
    */
    void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr);

    /** Returns custom context that tracks the SkMatrix and clip.

        Use SkRasterHandleAllocator to blend Skia drawing with custom drawing, typically performed
        by the host platform user interface. The custom context returned is generated by
        SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
        the drawing destination.

        @return  context of custom allocation

        example: https://fiddle.skia.org/c/@Canvas_accessTopRasterHandle
    */
    SkRasterHandleAllocator::Handle accessTopRasterHandle() const;

    /** Returns true if SkCanvas has direct access to its pixels.

        Pixels are readable when SkBaseDevice is raster. Pixels are not readable when SkCanvas
        is returned from GPU surface, returned by SkDocument::beginPage, returned by
        SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
        like DebugCanvas.

        pixmap is valid only while SkCanvas is in scope and unchanged. Any
        SkCanvas or SkSurface call may invalidate the pixmap values.

        @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
        @return        true if SkCanvas has direct access to pixels

        example: https://fiddle.skia.org/c/@Canvas_peekPixels
    */
    bool peekPixels(SkPixmap* pixmap);

    /** Copies SkRect of pixels from SkCanvas into dstPixels. SkMatrix and clip are
        ignored.

        Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
        Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
        Copies each readable pixel intersecting both rectangles, without scaling,
        converting to dstInfo.colorType() and dstInfo.alphaType() if required.

        Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
        Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
        returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
        class like DebugCanvas.

        The destination pixel storage must be allocated by the caller.

        Pixel values are converted only if SkColorType and SkAlphaType
        do not match. Only pixels within both source and destination rectangles
        are copied. dstPixels contents outside SkRect intersection are unchanged.

        Pass negative values for srcX or srcY to offset pixels across or down destination.

        Does not copy, and returns false if:
        - Source and destination rectangles do not intersect.
        - SkCanvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
        - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
        - dstRowBytes is too small to contain one row of pixels.

        @param dstInfo      width, height, SkColorType, and SkAlphaType of dstPixels
        @param dstPixels    storage for pixels; dstInfo.height() times dstRowBytes, or larger
        @param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger
        @param srcX         offset into readable pixels on x-axis; may be negative
        @param srcY         offset into readable pixels on y-axis; may be negative
        @return             true if pixels were copied
    */
    bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
                    int srcX, int srcY);

    /** Copies SkRect of pixels from SkCanvas into pixmap. SkMatrix and clip are
        ignored.

        Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
        Destination SkRect corners are (0, 0) and (pixmap.width(), pixmap.height()).
        Copies each readable pixel intersecting both rectangles, without scaling,
        converting to pixmap.colorType() and pixmap.alphaType() if required.

        Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
        Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
        returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
        class like DebugCanvas.

        Caller must allocate pixel storage in pixmap if needed.

        Pixel values are converted only if SkColorType and SkAlphaType
        do not match. Only pixels within both source and destination SkRect
        are copied. pixmap pixels contents outside SkRect intersection are unchanged.

        Pass negative values for srcX or srcY to offset pixels across or down pixmap.

        Does not copy, and returns false if:
        - Source and destination rectangles do not intersect.
        - SkCanvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType().
        - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
        - SkPixmap pixels could not be allocated.
        - pixmap.rowBytes() is too small to contain one row of pixels.

        @param pixmap  storage for pixels copied from SkCanvas
        @param srcX    offset into readable pixels on x-axis; may be negative
        @param srcY    offset into readable pixels on y-axis; may be negative
        @return        true if pixels were copied

        example: https://fiddle.skia.org/c/@Canvas_readPixels_2
    */
    bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);

    /** Copies SkRect of pixels from SkCanvas into bitmap. SkMatrix and clip are
        ignored.

        Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
        Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
        Copies each readable pixel intersecting both rectangles, without scaling,
        converting to bitmap.colorType() and bitmap.alphaType() if required.

        Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
        Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
        returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
        class like DebugCanvas.

        Caller must allocate pixel storage in bitmap if needed.

        SkBitmap values are converted only if SkColorType and SkAlphaType
        do not match. Only pixels within both source and destination rectangles
        are copied. SkBitmap pixels outside SkRect intersection are unchanged.

        Pass negative values for srcX or srcY to offset pixels across or down bitmap.

        Does not copy, and returns false if:
        - Source and destination rectangles do not intersect.
        - SkCanvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType().
        - SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
        - bitmap pixels could not be allocated.
        - bitmap.rowBytes() is too small to contain one row of pixels.

        @param bitmap  storage for pixels copied from SkCanvas
        @param srcX    offset into readable pixels on x-axis; may be negative
        @param srcY    offset into readable pixels on y-axis; may be negative
        @return        true if pixels were copied

        example: https://fiddle.skia.org/c/@Canvas_readPixels_3
    */
    bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);

    /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
        Source SkRect corners are (0, 0) and (info.width(), info.height()).
        Destination SkRect corners are (x, y) and
        (imageInfo().width(), imageInfo().height()).

        Copies each readable pixel intersecting both rectangles, without scaling,
        converting to imageInfo().colorType() and imageInfo().alphaType() if required.

        Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
        Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
        returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
        class like DebugCanvas.

        Pixel values are converted only if SkColorType and SkAlphaType
        do not match. Only pixels within both source and destination rectangles
        are copied. SkCanvas pixels outside SkRect intersection are unchanged.

        Pass negative values for x or y to offset pixels to the left or
        above SkCanvas pixels.

        Does not copy, and returns false if:
        - Source and destination rectangles do not intersect.
        - pixels could not be converted to SkCanvas imageInfo().colorType() or
        imageInfo().alphaType().
        - SkCanvas pixels are not writable; for instance, SkCanvas is document-based.
        - rowBytes is too small to contain one row of pixels.

        @param info      width, height, SkColorType, and SkAlphaType of pixels
        @param pixels    pixels to copy, of size info.height() times rowBytes, or larger
        @param rowBytes  size of one row of pixels; info.width() times pixel size, or larger
        @param x         offset into SkCanvas writable pixels on x-axis; may be negative
        @param y         offset into SkCanvas writable pixels on y-axis; may be negative
        @return          true if pixels were written to SkCanvas

        example: https://fiddle.skia.org/c/@Canvas_writePixels
    */
    bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);

    /** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
        Source SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).

        Destination SkRect corners are (x, y) and
        (imageInfo().width(), imageInfo().height()).

        Copies each readable pixel intersecting both rectangles, without scaling,
        converting to imageInfo().colorType() and imageInfo().alphaType() if required.

        Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
        Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
        returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
        class like DebugCanvas.

        Pixel values are converted only if SkColorType and SkAlphaType
        do not match. Only pixels within both source and destination rectangles
        are copied. SkCanvas pixels outside SkRect intersection are unchanged.

        Pass negative values for x or y to offset pixels to the left or
        above SkCanvas pixels.

        Does not copy, and returns false if:
        - Source and destination rectangles do not intersect.
        - bitmap does not have allocated pixels.
        - bitmap pixels could not be converted to SkCanvas imageInfo().colorType() or
        imageInfo().alphaType().
        - SkCanvas pixels are not writable; for instance, SkCanvas is document based.
        - bitmap pixels are inaccessible; for instance, bitmap wraps a texture.

        @param bitmap  contains pixels copied to SkCanvas
        @param x       offset into SkCanvas writable pixels on x-axis; may be negative
        @param y       offset into SkCanvas writable pixels on y-axis; may be negative
        @return        true if pixels were written to SkCanvas

        example: https://fiddle.skia.org/c/@Canvas_writePixels_2
        example: https://fiddle.skia.org/c/@State_Stack_a
        example: https://fiddle.skia.org/c/@State_Stack_b
    */
    bool writePixels(const SkBitmap& bitmap, int x, int y);

    /** Saves SkMatrix and clip.
        Calling restore() discards changes to SkMatrix and clip,
        restoring the SkMatrix and clip to their state when save() was called.

        SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix(),
        and resetMatrix(). Clip may be changed by clipRect(), clipRRect(), clipPath(), clipRegion().

        Saved SkCanvas state is put on a stack; multiple calls to save() should be balance
        by an equal number of calls to restore().

        Call restoreToCount() with result to restore this and subsequent saves.

        @return  depth of saved stack

        example: https://fiddle.skia.org/c/@Canvas_save
    */
    int save();

    /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
        Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.

        SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
        setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
        clipPath(), clipRegion().

        SkRect bounds suggests but does not define the SkBitmap size. To clip drawing to
        a specific rectangle, use clipRect().

        Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
        SkBlendMode when restore() is called.

        Call restoreToCount() with returned value to restore this and subsequent saves.

        @param bounds  hint to limit the size of the layer; may be nullptr
        @param paint   graphics state for layer; may be nullptr
        @return        depth of saved stack

        example: https://fiddle.skia.org/c/@Canvas_saveLayer
        example: https://fiddle.skia.org/c/@Canvas_saveLayer_4
    */
    int saveLayer(const SkRect* bounds, const SkPaint* paint);

    /** Saves SkMatrix and clip, and allocates a SkBitmap for subsequent drawing.
        Calling restore() discards changes to SkMatrix and clip, and draws the SkBitmap.

        SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
        setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
        clipPath(), clipRegion().

        SkRect bounds suggests but does not define the layer size. To clip drawing to
        a specific rectangle, use clipRect().

        Optional SkPaint paint applies alpha, SkColorFilter, SkImageFilter, and
        SkBlendMode when restore() is called.

        Call restoreToCount() with returned value to restore this and subsequent saves.

        @param bounds  hint to limit the size of layer; may be nullptr
        @param paint   graphics state for layer; may be nullptr
        @return        depth of saved stack
    */
    int saveLayer(const SkRect& bounds, const SkPaint* paint) {
        return this->saveLayer(&bounds, paint);
    }

    /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.

        Calling restore() discards changes to SkMatrix and clip,
        and blends layer with alpha opacity onto prior layer.

        SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
        setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
        clipPath(), clipRegion().

        SkRect bounds suggests but does not define layer size. To clip drawing to
        a specific rectangle, use clipRect().

        alpha of zero is fully transparent, 255 is fully opaque.

        Call restoreToCount() with returned value to restore this and subsequent saves.

        @param bounds  hint to limit the size of layer; may be nullptr
        @param alpha   opacity of layer
        @return        depth of saved stack

        example: https://fiddle.skia.org/c/@Canvas_saveLayerAlpha
    */
    int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);

    /** \enum SkCanvas::SaveLayerFlagsSet
        SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
        defining how layer allocated by saveLayer() operates. It may be set to zero,
        kPreserveLCDText_SaveLayerFlag, kInitWithPrevious_SaveLayerFlag, or both flags.
    */
    enum SaveLayerFlagsSet {
        kPreserveLCDText_SaveLayerFlag  = 1 << 1,
        kInitWithPrevious_SaveLayerFlag = 1 << 2, //!< initializes with previous contents
        kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag =
                                          1 << 3, //!< experimental: do not use
        // instead of matching previous layer's colortype, use F16
        kF16ColorType                   = 1 << 4,
    };

    typedef uint32_t SaveLayerFlags;

    /** \struct SkCanvas::SaveLayerRec
        SaveLayerRec contains the state used to create the layer.
    */
    struct SaveLayerRec {

        /** Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.

            @return  empty SaveLayerRec
        */
        SaveLayerRec() {}

        /** Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.

            @param bounds          layer dimensions; may be nullptr
            @param paint           applied to layer when overlaying prior layer; may be nullptr
            @param saveLayerFlags  SaveLayerRec options to modify layer
            @return                SaveLayerRec with empty fBackdrop
        */
        SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
            : fBounds(bounds)
            , fPaint(paint)
            , fSaveLayerFlags(saveLayerFlags)
        {}

        /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.

            @param bounds          layer dimensions; may be nullptr
            @param paint           applied to layer when overlaying prior layer;
                                   may be nullptr
            @param backdrop        If not null, this causes the current layer to be filtered by
                                   backdrop, and then drawn into the new layer
                                   (respecting the current clip).
                                   If null, the new layer is initialized with transparent-black.
            @param saveLayerFlags  SaveLayerRec options to modify layer
            @return                SaveLayerRec fully specified
        */
        SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
                     SaveLayerFlags saveLayerFlags)
            : fBounds(bounds)
            , fPaint(paint)
            , fBackdrop(backdrop)
            , fSaveLayerFlags(saveLayerFlags)
        {}

        /** hints at layer size limit */
        const SkRect*        fBounds         = nullptr;

        /** modifies overlay */
        const SkPaint*       fPaint          = nullptr;

        /**
         *  If not null, this triggers the same initialization behavior as setting
         *  kInitWithPrevious_SaveLayerFlag on fSaveLayerFlags: the current layer is copied into
         *  the new layer, rather than initializing the new layer with transparent-black.
         *  This is then filtered by fBackdrop (respecting the current clip).
         */
        const SkImageFilter* fBackdrop       = nullptr;

        /** preserves LCD text, creates with prior layer contents */
        SaveLayerFlags       fSaveLayerFlags = 0;
    };

    /** Saves SkMatrix and clip, and allocates SkBitmap for subsequent drawing.

        Calling restore() discards changes to SkMatrix and clip,
        and blends SkBitmap with alpha opacity onto the prior layer.

        SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
        setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
        clipPath(), clipRegion().

        SaveLayerRec contains the state used to create the layer.

        Call restoreToCount() with returned value to restore this and subsequent saves.

        @param layerRec  layer state
        @return          depth of save state stack before this call was made.

        example: https://fiddle.skia.org/c/@Canvas_saveLayer_3
    */
    int saveLayer(const SaveLayerRec& layerRec);

    /** Removes changes to SkMatrix and clip since SkCanvas state was
        last saved. The state is removed from the stack.

        Does nothing if the stack is empty.

        example: https://fiddle.skia.org/c/@AutoCanvasRestore_restore

        example: https://fiddle.skia.org/c/@Canvas_restore
    */
    void restore();

    /** Returns the number of saved states, each containing: SkMatrix and clip.
        Equals the number of save() calls less the number of restore() calls plus one.
        The save count of a new canvas is one.

        @return  depth of save state stack

        example: https://fiddle.skia.org/c/@Canvas_getSaveCount
    */
    int getSaveCount() const;

    /** Restores state to SkMatrix and clip values when save(), saveLayer(),
        saveLayerPreserveLCDTextRequests(), or saveLayerAlpha() returned saveCount.

        Does nothing if saveCount is greater than state stack count.
        Restores state to initial values if saveCount is less than or equal to one.

        @param saveCount  depth of state stack to restore

        example: https://fiddle.skia.org/c/@Canvas_restoreToCount
    */
    void restoreToCount(int saveCount);

    /** Translates SkMatrix by dx along the x-axis and dy along the y-axis.

        Mathematically, replaces SkMatrix with a translation matrix
        premultiplied with SkMatrix.

        This has the effect of moving the drawing by (dx, dy) before transforming
        the result with SkMatrix.

        @param dx  distance to translate on x-axis
        @param dy  distance to translate on y-axis

        example: https://fiddle.skia.org/c/@Canvas_translate
    */
    void translate(SkScalar dx, SkScalar dy);

    /** Scales SkMatrix by sx on the x-axis and sy on the y-axis.

        Mathematically, replaces SkMatrix with a scale matrix
        premultiplied with SkMatrix.

        This has the effect of scaling the drawing by (sx, sy) before transforming
        the result with SkMatrix.

        @param sx  amount to scale on x-axis
        @param sy  amount to scale on y-axis

        example: https://fiddle.skia.org/c/@Canvas_scale
    */
    void scale(SkScalar sx, SkScalar sy);

    /** Rotates SkMatrix by degrees. Positive degrees rotates clockwise.

        Mathematically, replaces SkMatrix with a rotation matrix
        premultiplied with SkMatrix.

        This has the effect of rotating the drawing by degrees before transforming
        the result with SkMatrix.

        @param degrees  amount to rotate, in degrees

        example: https://fiddle.skia.org/c/@Canvas_rotate
    */
    void rotate(SkScalar degrees);

    /** Rotates SkMatrix by degrees about a point at (px, py). Positive degrees rotates
        clockwise.

        Mathematically, constructs a rotation matrix; premultiplies the rotation matrix by
        a translation matrix; then replaces SkMatrix with the resulting matrix
        premultiplied with SkMatrix.

        This has the effect of rotating the drawing about a given point before
        transforming the result with SkMatrix.

        @param degrees  amount to rotate, in degrees
        @param px       x-axis value of the point to rotate about
        @param py       y-axis value of the point to rotate about

        example: https://fiddle.skia.org/c/@Canvas_rotate_2
    */
    void rotate(SkScalar degrees, SkScalar px, SkScalar py);

    /** Skews SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
        skews the drawing right as y-axis values increase; a positive value of sy skews
        the drawing down as x-axis values increase.

        Mathematically, replaces SkMatrix with a skew matrix premultiplied with SkMatrix.

        This has the effect of skewing the drawing by (sx, sy) before transforming
        the result with SkMatrix.

        @param sx  amount to skew on x-axis
        @param sy  amount to skew on y-axis

        example: https://fiddle.skia.org/c/@Canvas_skew
    */
    void skew(SkScalar sx, SkScalar sy);

    /** Replaces SkMatrix with matrix premultiplied with existing SkMatrix.

        This has the effect of transforming the drawn geometry by matrix, before
        transforming the result with existing SkMatrix.

        @param matrix  matrix to premultiply with existing SkMatrix

        example: https://fiddle.skia.org/c/@Canvas_concat
    */
    void concat(const SkMatrix& matrix);
    void concat(const SkM44&);

    /**
     *  Record a marker (provided by caller) for the current CTM. This does not change anything
     *  about the ctm or clip, but does "name" this matrix value, so it can be referenced by
     *  custom effects (who access it by specifying the same name).
     *
     *  Within a save frame, marking with the same name more than once just replaces the previous
     *  value. However, between save frames, marking with the same name does not lose the marker
     *  in the previous save frame. It is "visible" when the current save() is balanced with
     *  a restore().
     */
    void markCTM(const char* name);

    bool findMarkedCTM(const char* name, SkM44*) const;

    /** Replaces SkMatrix with matrix.
        Unlike concat(), any prior matrix state is overwritten.

        @param matrix  matrix to copy, replacing existing SkMatrix

        example: https://fiddle.skia.org/c/@Canvas_setMatrix
    */
    void setMatrix(const SkM44& matrix);

    // DEPRECATED -- use SkM44 version
    void setMatrix(const SkMatrix& matrix);

    /** Sets SkMatrix to the identity matrix.
        Any prior matrix state is overwritten.

        example: https://fiddle.skia.org/c/@Canvas_resetMatrix
    */
    void resetMatrix();

    /** Replaces clip with the intersection or difference of clip and rect,
        with an aliased or anti-aliased clip edge. rect is transformed by SkMatrix
        before it is combined with clip.

        @param rect         SkRect to combine with clip
        @param op           SkClipOp to apply to clip
        @param doAntiAlias  true if clip is to be anti-aliased

        example: https://fiddle.skia.org/c/@Canvas_clipRect
    */
    void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);

    /** Replaces clip with the intersection or difference of clip and rect.
        Resulting clip is aliased; pixels are fully contained by the clip.
        rect is transformed by SkMatrix before it is combined with clip.

        @param rect  SkRect to combine with clip
        @param op    SkClipOp to apply to clip
    */
    void clipRect(const SkRect& rect, SkClipOp op) {
        this->clipRect(rect, op, false);
    }

    /** Replaces clip with the intersection of clip and rect.
        Resulting clip is aliased; pixels are fully contained by the clip.
        rect is transformed by SkMatrix
        before it is combined with clip.

        @param rect         SkRect to combine with clip
        @param doAntiAlias  true if clip is to be anti-aliased
    */
    void clipRect(const SkRect& rect, bool doAntiAlias = false) {
        this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
    }

    /** Sets the maximum clip rectangle, which can be set by clipRect(), clipRRect() and
        clipPath() and intersect the current clip with the specified rect.
        The maximum clip affects only future clipping operations; it is not retroactive.
        The clip restriction is not recorded in pictures.

        Pass an empty rect to disable maximum clip.
        This private API is for use by Android framework only.

        DEPRECATED: Replace usage with SkAndroidFrameworkUtils::replaceClip()

        @param rect  maximum allowed clip in device coordinates
    */
    void androidFramework_setDeviceClipRestriction(const SkIRect& rect);

    /** Replaces clip with the intersection or difference of clip and rrect,
        with an aliased or anti-aliased clip edge.
        rrect is transformed by SkMatrix
        before it is combined with clip.

        @param rrect        SkRRect to combine with clip
        @param op           SkClipOp to apply to clip
        @param doAntiAlias  true if clip is to be anti-aliased

        example: https://fiddle.skia.org/c/@Canvas_clipRRect
    */
    void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);

    /** Replaces clip with the intersection or difference of clip and rrect.
        Resulting clip is aliased; pixels are fully contained by the clip.
        rrect is transformed by SkMatrix before it is combined with clip.

        @param rrect  SkRRect to combine with clip
        @param op     SkClipOp to apply to clip
    */
    void clipRRect(const SkRRect& rrect, SkClipOp op) {
        this->clipRRect(rrect, op, false);
    }

    /** Replaces clip with the intersection of clip and rrect,
        with an aliased or anti-aliased clip edge.
        rrect is transformed by SkMatrix before it is combined with clip.

        @param rrect        SkRRect to combine with clip
        @param doAntiAlias  true if clip is to be anti-aliased
    */
    void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
        this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
    }

    /** Replaces clip with the intersection or difference of clip and path,
        with an aliased or anti-aliased clip edge. SkPath::FillType determines if path
        describes the area inside or outside its contours; and if path contour overlaps
        itself or another path contour, whether the overlaps form part of the area.
        path is transformed by SkMatrix before it is combined with clip.

        @param path         SkPath to combine with clip
        @param op           SkClipOp to apply to clip
        @param doAntiAlias  true if clip is to be anti-aliased

        example: https://fiddle.skia.org/c/@Canvas_clipPath
    */
    void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);

    /** Replaces clip with the intersection or difference of clip and path.
        Resulting clip is aliased; pixels are fully contained by the clip.
        SkPath::FillType determines if path
        describes the area inside or outside its contours; and if path contour overlaps
        itself or another path contour, whether the overlaps form part of the area.
        path is transformed by SkMatrix
        before it is combined with clip.

        @param path  SkPath to combine with clip
        @param op    SkClipOp to apply to clip
    */
    void clipPath(const SkPath& path, SkClipOp op) {
        this->clipPath(path, op, false);
    }

    /** Replaces clip with the intersection of clip and path.
        Resulting clip is aliased; pixels are fully contained by the clip.
        SkPath::FillType determines if path
        describes the area inside or outside its contours; and if path contour overlaps
        itself or another path contour, whether the overlaps form part of the area.
        path is transformed by SkMatrix before it is combined with clip.

        @param path         SkPath to combine with clip
        @param doAntiAlias  true if clip is to be anti-aliased
    */
    void clipPath(const SkPath& path, bool doAntiAlias = false) {
        this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
    }

    void clipShader(sk_sp<SkShader>, SkClipOp = SkClipOp::kIntersect);

    /** Replaces clip with the intersection or difference of clip and SkRegion deviceRgn.
        Resulting clip is aliased; pixels are fully contained by the clip.
        deviceRgn is unaffected by SkMatrix.

        @param deviceRgn  SkRegion to combine with clip
        @param op         SkClipOp to apply to clip

        example: https://fiddle.skia.org/c/@Canvas_clipRegion
    */
    void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);

    /** Returns true if SkRect rect, transformed by SkMatrix, can be quickly determined to be
        outside of clip. May return false even though rect is outside of clip.

        Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.

        @param rect  SkRect to compare with clip
        @return      true if rect, transformed by SkMatrix, does not intersect clip

        example: https://fiddle.skia.org/c/@Canvas_quickReject
    */
    bool quickReject(const SkRect& rect) const;

    /** Returns true if path, transformed by SkMatrix, can be quickly determined to be
        outside of clip. May return false even though path is outside of clip.

        Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.

        @param path  SkPath to compare with clip
        @return      true if path, transformed by SkMatrix, does not intersect clip

        example: https://fiddle.skia.org/c/@Canvas_quickReject_2
    */
    bool quickReject(const SkPath& path) const;

    /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
        return SkRect::MakeEmpty, where all SkRect sides equal zero.

        SkRect returned is outset by one to account for partial pixel coverage if clip
        is anti-aliased.

        @return  bounds of clip in local coordinates

        example: https://fiddle.skia.org/c/@Canvas_getLocalClipBounds
    */
    SkRect getLocalClipBounds() const;

    /** Returns bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
        return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.

        bounds is outset by one to account for partial pixel coverage if clip
        is anti-aliased.

        @param bounds  SkRect of clip in local coordinates
        @return        true if clip bounds is not empty
    */
    bool getLocalClipBounds(SkRect* bounds) const {
        *bounds = this->getLocalClipBounds();
        return !bounds->isEmpty();
    }

    /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
        return SkRect::MakeEmpty, where all SkRect sides equal zero.

        Unlike getLocalClipBounds(), returned SkIRect is not outset.

        @return  bounds of clip in SkBaseDevice coordinates

        example: https://fiddle.skia.org/c/@Canvas_getDeviceClipBounds
    */
    SkIRect getDeviceClipBounds() const;

    /** Returns SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
        return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.

        Unlike getLocalClipBounds(), bounds is not outset.

        @param bounds  SkRect of clip in device coordinates
        @return        true if clip bounds is not empty
    */
    bool getDeviceClipBounds(SkIRect* bounds) const {
        *bounds = this->getDeviceClipBounds();
        return !bounds->isEmpty();
    }

    /** Fills clip with color color.
        mode determines how ARGB is combined with destination.

        @param color  unpremultiplied ARGB
        @param mode   SkBlendMode used to combine source color and destination

        example: https://fiddle.skia.org/c/@Canvas_drawColor
    */
    void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver) {
        this->drawColor(SkColor4f::FromColor(color), mode);
    }

    /** Fills clip with color color.
        mode determines how ARGB is combined with destination.

        @param color  SkColor4f representing unpremultiplied color.
        @param mode   SkBlendMode used to combine source color and destination
    */
    void drawColor(const SkColor4f& color, SkBlendMode mode = SkBlendMode::kSrcOver);

    /** Fills clip with color color using SkBlendMode::kSrc.
        This has the effect of replacing all pixels contained by clip with color.

        @param color  unpremultiplied ARGB
    */
    void clear(SkColor color) {
        this->clear(SkColor4f::FromColor(color));
    }

    /** Fills clip with color color using SkBlendMode::kSrc.
        This has the effect of replacing all pixels contained by clip with color.

        @param color  SkColor4f representing unpremultiplied color.
    */
    void clear(const SkColor4f& color) {
        this->drawColor(color, SkBlendMode::kSrc);
    }

    /** Makes SkCanvas contents undefined. Subsequent calls that read SkCanvas pixels,
        such as drawing with SkBlendMode, return undefined results. discard() does
        not change clip or SkMatrix.

        discard() may do nothing, depending on the implementation of SkSurface or SkBaseDevice
        that created SkCanvas.

        discard() allows optimized performance on subsequent draws by removing
        cached data associated with SkSurface or SkBaseDevice.
        It is not necessary to call discard() once done with SkCanvas;
        any cached data is deleted when owning SkSurface or SkBaseDevice is deleted.
    */
    void discard() { this->onDiscard(); }

    /** Fills clip with SkPaint paint. SkPaint components, SkShader,
        SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
        SkMaskFilter and SkPathEffect in paint are ignored.

        @param paint  graphics state used to fill SkCanvas

        example: https://fiddle.skia.org/c/@Canvas_drawPaint
    */
    void drawPaint(const SkPaint& paint);

    /** \enum SkCanvas::PointMode
        Selects if an array of points are drawn as discrete points, as lines, or as
        an open polygon.
    */
    enum PointMode {
        kPoints_PointMode,  //!< draw each point separately
        kLines_PointMode,   //!< draw each pair of points as a line segment
        kPolygon_PointMode, //!< draw the array of points as a open polygon
    };

    /** Draws pts using clip, SkMatrix and SkPaint paint.
        count is the number of points; if count is less than one, has no effect.
        mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.

        If mode is kPoints_PointMode, the shape of point drawn depends on paint
        SkPaint::Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
        circle of diameter SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap
        or SkPaint::kButt_Cap, each point draws a square of width and height
        SkPaint stroke width.

        If mode is kLines_PointMode, each pair of points draws a line segment.
        One line is drawn for every two points; each point is used once. If count is odd,
        the final point is ignored.

        If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
        count minus one lines are drawn; the first and last point are used once.

        Each line segment respects paint SkPaint::Cap and SkPaint stroke width.
        SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.

        Always draws each element one at a time; is not affected by
        SkPaint::Join, and unlike drawPath(), does not create a mask from all points
        and lines before drawing.

        @param mode   whether pts draws points or lines
        @param count  number of points in the array
        @param pts    array of points to draw
        @param paint  stroke, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawPoints
    */
    void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);

    /** Draws point at (x, y) using clip, SkMatrix and SkPaint paint.

        The shape of point drawn depends on paint SkPaint::Cap.
        If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
        SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
        draw a square of width and height SkPaint stroke width.
        SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.

        @param x      left edge of circle or square
        @param y      top edge of circle or square
        @param paint  stroke, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawPoint
    */
    void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);

    /** Draws point p using clip, SkMatrix and SkPaint paint.

        The shape of point drawn depends on paint SkPaint::Cap.
        If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
        SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
        draw a square of width and height SkPaint stroke width.
        SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.

        @param p      top-left edge of circle or square
        @param paint  stroke, blend, color, and so on, used to draw
    */
    void drawPoint(SkPoint p, const SkPaint& paint) {
        this->drawPoint(p.x(), p.y(), paint);
    }

    /** Draws line segment from (x0, y0) to (x1, y1) using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint stroke width describes the line thickness;
        SkPaint::Cap draws the end rounded or square;
        SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.

        @param x0     start of line segment on x-axis
        @param y0     start of line segment on y-axis
        @param x1     end of line segment on x-axis
        @param y1     end of line segment on y-axis
        @param paint  stroke, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawLine
    */
    void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);

    /** Draws line segment from p0 to p1 using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint stroke width describes the line thickness;
        SkPaint::Cap draws the end rounded or square;
        SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.

        @param p0     start of line segment
        @param p1     end of line segment
        @param paint  stroke, blend, color, and so on, used to draw
    */
    void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
        this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
    }

    /** Draws SkRect rect using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint::Style determines if rectangle is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness, and
        SkPaint::Join draws the corners rounded or square.

        @param rect   rectangle to draw
        @param paint  stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawRect
    */
    void drawRect(const SkRect& rect, const SkPaint& paint);

    /** Draws SkIRect rect using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint::Style determines if rectangle is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness, and
        SkPaint::Join draws the corners rounded or square.

        @param rect   rectangle to draw
        @param paint  stroke or fill, blend, color, and so on, used to draw
    */
    void drawIRect(const SkIRect& rect, const SkPaint& paint) {
        SkRect r;
        r.set(rect);    // promotes the ints to scalars
        this->drawRect(r, paint);
    }

    /** Draws SkRegion region using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint::Style determines if rectangle is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness, and
        SkPaint::Join draws the corners rounded or square.

        @param region  region to draw
        @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawRegion
    */
    void drawRegion(const SkRegion& region, const SkPaint& paint);

    /** Draws oval oval using clip, SkMatrix, and SkPaint.
        In paint: SkPaint::Style determines if oval is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.

        @param oval   SkRect bounds of oval
        @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawOval
    */
    void drawOval(const SkRect& oval, const SkPaint& paint);

    /** Draws SkRRect rrect using clip, SkMatrix, and SkPaint paint.
        In paint: SkPaint::Style determines if rrect is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.

        rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
        may have any combination of positive non-square radii for the four corners.

        @param rrect  SkRRect with up to eight corner radii to draw
        @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawRRect
    */
    void drawRRect(const SkRRect& rrect, const SkPaint& paint);

    /** Draws SkRRect outer and inner
        using clip, SkMatrix, and SkPaint paint.
        outer must contain inner or the drawing is undefined.
        In paint: SkPaint::Style determines if SkRRect is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.
        If stroked and SkRRect corner has zero length radii, SkPaint::Join can
        draw corners rounded or square.

        GPU-backed platforms optimize drawing when both outer and inner are
        concave and outer contains inner. These platforms may not be able to draw
        SkPath built with identical data as fast.

        @param outer  SkRRect outer bounds to draw
        @param inner  SkRRect inner bounds to draw
        @param paint  SkPaint stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawDRRect_a
        example: https://fiddle.skia.org/c/@Canvas_drawDRRect_b
    */
    void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);

    /** Draws circle at (cx, cy) with radius using clip, SkMatrix, and SkPaint paint.
        If radius is zero or less, nothing is drawn.
        In paint: SkPaint::Style determines if circle is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.

        @param cx      circle center on the x-axis
        @param cy      circle center on the y-axis
        @param radius  half the diameter of circle
        @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawCircle
    */
    void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);

    /** Draws circle at center with radius using clip, SkMatrix, and SkPaint paint.
        If radius is zero or less, nothing is drawn.
        In paint: SkPaint::Style determines if circle is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.

        @param center  circle center
        @param radius  half the diameter of circle
        @param paint   SkPaint stroke or fill, blend, color, and so on, used to draw
    */
    void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
        this->drawCircle(center.x(), center.y(), radius, paint);
    }

    /** Draws arc using clip, SkMatrix, and SkPaint paint.

        Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
        sweepAngle. startAngle and sweepAngle are in degrees.

        startAngle of zero places start point at the right middle edge of oval.
        A positive sweepAngle places arc end point clockwise from start point;
        a negative sweepAngle places arc end point counterclockwise from start point.
        sweepAngle may exceed 360 degrees, a full circle.
        If useCenter is true, draw a wedge that includes lines from oval
        center to arc end points. If useCenter is false, draw arc between end points.

        If SkRect oval is empty or sweepAngle is zero, nothing is drawn.

        @param oval        SkRect bounds of oval containing arc to draw
        @param startAngle  angle in degrees where arc begins
        @param sweepAngle  sweep angle in degrees; positive is clockwise
        @param useCenter   if true, include the center of the oval
        @param paint       SkPaint stroke or fill, blend, color, and so on, used to draw
    */
    void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
                 bool useCenter, const SkPaint& paint);

    /** Draws SkRRect bounded by SkRect rect, with corner radii (rx, ry) using clip,
        SkMatrix, and SkPaint paint.

        In paint: SkPaint::Style determines if SkRRect is stroked or filled;
        if stroked, SkPaint stroke width describes the line thickness.
        If rx or ry are less than zero, they are treated as if they are zero.
        If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
        If rx and ry are zero, SkRRect is drawn as SkRect and if stroked is affected by
        SkPaint::Join.

        @param rect   SkRect bounds of SkRRect to draw
        @param rx     axis length on x-axis of oval describing rounded corners
        @param ry     axis length on y-axis of oval describing rounded corners
        @param paint  stroke, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawRoundRect
    */
    void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);

    /** Draws SkPath path using clip, SkMatrix, and SkPaint paint.
        SkPath contains an array of path contour, each of which may be open or closed.

        In paint: SkPaint::Style determines if SkRRect is stroked or filled:
        if filled, SkPath::FillType determines whether path contour describes inside or
        outside of fill; if stroked, SkPaint stroke width describes the line thickness,
        SkPaint::Cap describes line ends, and SkPaint::Join describes how
        corners are drawn.

        @param path   SkPath to draw
        @param paint  stroke, blend, color, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawPath
    */
    void drawPath(const SkPath& path, const SkPaint& paint);

    /** Draws SkImage image, with its top-left corner at (left, top),
        using clip, SkMatrix, and optional SkPaint paint.

        This is equivalent to drawImageRect() using a dst rect at (x,y) with the
        same width and height of the image.

        @param image  uncompressed rectangular map of pixels
        @param left   left side of image
        @param top    top side of image
        @param paint  SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                      and so on; or nullptr
    */
    void drawImage(const SkImage* image, SkScalar left, SkScalar top,
                   const SkPaint* paint = nullptr);

    /** Draws SkImage image, with its top-left corner at (left, top),
        using clip, SkMatrix, and optional SkPaint paint.

        This is equivalent to drawImageRect() using a dst rect at (x,y) with the
        same width and height of the image.

        @param image  uncompressed rectangular map of pixels
        @param left   left side of image
        @param top    pop side of image
        @param paint  SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                      and so on; or nullptr
    */
    void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
                   const SkPaint* paint = nullptr) {
        this->drawImage(image.get(), left, top, paint);
    }

    /** \enum SkCanvas::SrcRectConstraint
        SrcRectConstraint controls the behavior at the edge of source SkRect,
        provided to drawImageRect(), trading off speed for precision.

        SkFilterQuality in SkPaint may sample multiple pixels in the image. Source SkRect
        restricts the bounds of pixels that may be read. SkFilterQuality may slow down if
        it cannot read outside the bounds, when sampling near the edge of source SkRect.
        SrcRectConstraint specifies whether an SkImageFilter is allowed to read pixels
        outside source SkRect.
    */
    enum SrcRectConstraint {
        kStrict_SrcRectConstraint, //!< sample only inside bounds; slower
        kFast_SrcRectConstraint,   //!< sample outside bounds; faster
    };

    /** Draws SkRect src of SkImage image, scaled and translated to fill SkRect dst.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst). The src rect is only used to access the provided image.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within src; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param image       SkImage containing pixels, dimensions, and format
        @param src         source SkRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within src or draw faster
    */
    void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
                       const SkPaint* paint,
                       SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /** Draws SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
        Note that isrc is on integer pixel boundaries; dst may include fractional
        boundaries. Additionally transform draw using clip, SkMatrix, and optional SkPaint
        paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst). The src rect is only used to access the provided image.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param image       SkImage containing pixels, dimensions, and format
        @param isrc        source SkIRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within isrc or draw faster
    */
    void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
                       const SkPaint* paint,
                       SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /** Draws SkImage image, scaled and translated to fill SkRect dst, using clip, SkMatrix,
        and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst).

        @param image       SkImage containing pixels, dimensions, and format
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr

        example: https://fiddle.skia.org/c/@Canvas_drawImageRect_3
    */
    void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint);

    /** Draws SkRect src of SkImage image, scaled and translated to fill SkRect dst.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst). The src rect is only used to access the provided image.

        @param image       SkImage containing pixels, dimensions, and format
        @param src         source SkRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within src or draw faster
    */
    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
                       const SkPaint* paint,
                       SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
        this->drawImageRect(image.get(), src, dst, paint, constraint);
    }

    /** Draws SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
        isrc is on integer pixel boundaries; dst may include fractional boundaries.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst). The src rect is only used to access the provided image.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within image; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param image       SkImage containing pixels, dimensions, and format
        @param isrc        source SkIRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within image or draw faster
    */
    void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
                       const SkPaint* paint,
                       SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
        this->drawImageRect(image.get(), isrc, dst, paint, constraint);
    }

    /** Draws SkImage image, scaled and translated to fill SkRect dst,
        using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        When using a shader or shader mask filter, its coordinate system is based on the
        current CTM, so will reflect the dst rect geometry and is equivalent to
        drawRect(dst).

        @param image       SkImage containing pixels, dimensions, and format
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
    */
    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint) {
        this->drawImageRect(image.get(), dst, paint);
    }

    void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkSamplingOptions&,
                   const SkPaint* = nullptr);
    void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst,
                       const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
    void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&,
                       const SkPaint*, SrcRectConstraint);

    /** Draws SkImage image stretched proportionally to fit into SkRect dst.
        SkIRect center divides the image into nine sections: four sides, four corners, and
        the center. Corners are unmodified or scaled down proportionately if their sides
        are larger than dst; center and four sides are scaled to fit remaining space, if any.

        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.
        Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.

        If generated mask extends beyond image bounds, replicate image edge colors, just
        as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
        replicates the image edge color when it samples outside of its bounds.

        @param image   SkImage containing pixels, dimensions, and format
        @param center  SkIRect edge of image corners and sides
        @param dst     destination SkRect of image to draw to
        @param filter  what technique to use when sampling the image
        @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                       and so on; or nullptr
    */
    void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
                       SkFilterMode filter, const SkPaint* paint = nullptr);

    // DEPRECATED -- pass filtermode explicitly
    void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
                       const SkPaint* paint = nullptr);

    // DEPRECATED -- pass filtermode explicitly
    void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
                       const SkPaint* paint = nullptr) {
        this->drawImageNine(image.get(), center, dst, paint);
    }

#ifdef SK_SUPPORT_LEGACY_DRAWBITMAP
public:
#else
private:
#endif
    /** Draws SkBitmap bitmap, with its top-left corner at (left, top),
        using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap bounds.

        If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
        just as SkShader made from SkShader::MakeBitmapShader with
        SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
        outside of its bounds.

        @param bitmap  SkBitmap containing pixels, dimensions, and format
        @param left    left side of bitmap
        @param top     top side of bitmap
        @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                       and so on; or nullptr
    */
    void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
                    const SkPaint* paint = nullptr);

    /** Draws SkRect src of SkBitmap bitmap, scaled and translated to fill SkRect dst.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap bounds.

        If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
        just as SkShader made from SkShader::MakeBitmapShader with
        SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
        outside of its bounds.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within src; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param bitmap      SkBitmap containing pixels, dimensions, and format
        @param src         source SkRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within src or draw faster
    */
    void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
                        const SkPaint* paint,
                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /** Draws SkIRect isrc of SkBitmap bitmap, scaled and translated to fill SkRect dst.
        isrc is on integer pixel boundaries; dst may include fractional boundaries.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap bounds.

        If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
        just as SkShader made from SkShader::MakeBitmapShader with
        SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
        outside of its bounds.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param bitmap      SkBitmap containing pixels, dimensions, and format
        @param isrc        source SkIRect of image to draw from
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  sample strictly within isrc, or draw faster
    */
    void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
                        const SkPaint* paint,
                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /** Draws SkBitmap bitmap, scaled and translated to fill SkRect dst.
        bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap bounds.

        If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
        just as SkShader made from SkShader::MakeBitmapShader with
        SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
        outside of its bounds.

        constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
        sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
        improve performance.

        @param bitmap      SkBitmap containing pixels, dimensions, and format
        @param dst         destination SkRect of image to draw to
        @param paint       SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                           and so on; or nullptr
        @param constraint  filter strictly within bitmap or draw faster
    */
    void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);
public:

    /** \struct SkCanvas::Lattice
        SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
        Grid entries on even columns and even rows are fixed; these entries are
        always drawn at their original size if the destination is large enough.
        If the destination side is too small to hold the fixed entries, all fixed
        entries are proportionately scaled down to fit.
        The grid entries not on even columns and rows are scaled to fit the
        remaining space, if any.
    */
    struct Lattice {

        /** \enum SkCanvas::Lattice::RectType
            Optional setting per rectangular grid entry to make it transparent,
            or to fill the grid entry with a color.
        */
        enum RectType : uint8_t {
            kDefault     = 0, //!< draws SkBitmap into lattice rectangle
            kTransparent,     //!< skips lattice rectangle by making it transparent
            kFixedColor,      //!< draws one of fColors into lattice rectangle
        };

        const int*      fXDivs;     //!< x-axis values dividing bitmap
        const int*      fYDivs;     //!< y-axis values dividing bitmap
        const RectType* fRectTypes; //!< array of fill types
        int             fXCount;    //!< number of x-coordinates
        int             fYCount;    //!< number of y-coordinates
        const SkIRect*  fBounds;    //!< source bounds to draw from
        const SkColor*  fColors;    //!< array of colors
    };

    /** Draws SkImage image stretched proportionally to fit into SkRect dst.

        SkCanvas::Lattice lattice divides image into a rectangular grid.
        Each intersection of an even-numbered row and column is fixed;
        fixed lattice elements never scale larger than their initial
        size and shrink proportionately when all fixed elements exceed the bitmap
        dimension. All other grid elements scale to fill the available space, if any.

        Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.

        If SkPaint paint is supplied, apply SkColorFilter, alpha, SkImageFilter, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.
        Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.

        If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
        just as SkShader made from SkShader::MakeBitmapShader with
        SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
        outside of its bounds.

        @param image    SkImage containing pixels, dimensions, and format
        @param lattice  division of bitmap into fixed and variable rectangles
        @param dst      destination SkRect of image to draw to
        @param filter   what technique to use when sampling the image
        @param paint    SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                        and so on; or nullptr
    */
    void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
                          SkFilterMode filter, const SkPaint* paint = nullptr);

    // DEPRECATED -- pass filtermode explicitly
    void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
                          const SkPaint* paint = nullptr);

    /**
     * Experimental. Controls anti-aliasing of each edge of images in an image-set.
     */
    enum QuadAAFlags : unsigned {
        kLeft_QuadAAFlag    = 0b0001,
        kTop_QuadAAFlag     = 0b0010,
        kRight_QuadAAFlag   = 0b0100,
        kBottom_QuadAAFlag  = 0b1000,

        kNone_QuadAAFlags   = 0b0000,
        kAll_QuadAAFlags    = 0b1111,
    };

    /** This is used by the experimental API below. */
    struct SK_API ImageSetEntry {
        ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
                      int matrixIndex, float alpha, unsigned aaFlags, bool hasClip);

        ImageSetEntry(sk_sp<const SkImage> image, const SkRect& srcRect, const SkRect& dstRect,
                      float alpha, unsigned aaFlags);

        ImageSetEntry();
        ~ImageSetEntry();
        ImageSetEntry(const ImageSetEntry&);
        ImageSetEntry& operator=(const ImageSetEntry&);

        sk_sp<const SkImage> fImage;
        SkRect fSrcRect;
        SkRect fDstRect;
        int fMatrixIndex = -1; // Index into the preViewMatrices arg, or < 0
        float fAlpha = 1.f;
        unsigned fAAFlags = kNone_QuadAAFlags; // QuadAAFlags
        bool fHasClip = false; // True to use next 4 points in dstClip arg as quad
    };

    /**
     * This is an experimental API for the SkiaRenderer Chromium project, and its API will surely
     * evolve if it is not removed outright.
     *
     * This behaves very similarly to drawRect() combined with a clipPath() formed by clip
     * quadrilateral. 'rect' and 'clip' are in the same coordinate space. If 'clip' is null, then it
     * is as if the rectangle was not clipped (or, alternatively, clipped to itself). If not null,
     * then it must provide 4 points.
     *
     * In addition to combining the draw and clipping into one operation, this function adds the
     * additional capability of controlling each of the rectangle's edges anti-aliasing
     * independently.  The edges of the clip will respect the per-edge AA flags. It is required that
     * 'clip' be contained inside 'rect'. In terms of mapping to edge labels, the 'clip' points
     * should be ordered top-left, top-right, bottom-right, bottom-left so that the edge between [0]
     * and [1] is "top", [1] and [2] is "right", [2] and [3] is "bottom", and [3] and [0] is "left".
     * This ordering matches SkRect::toQuad().
     *
     * This API only draws solid color, filled rectangles so it does not accept a full SkPaint.
     */
    void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
                                     const SkColor4f& color, SkBlendMode mode);
    void experimental_DrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
                                     SkColor color, SkBlendMode mode) {
        this->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, SkColor4f::FromColor(color), mode);
    }

    /**
     * This is an bulk variant of experimental_DrawEdgeAAQuad() that renders 'cnt' textured quads.
     * For each entry, 'fDstRect' is rendered with its clip (determined by entry's 'fHasClip' and
     * the current index in 'dstClip'). The entry's fImage is applied to the destination rectangle
     * by sampling from 'fSrcRect' sub-image.  The corners of 'fSrcRect' map to the corners of
     * 'fDstRect', just like in drawImageRect(), and they will be properly interpolated when
     * applying a clip.
     *
     * Like experimental_DrawEdgeAAQuad(), each entry can specify edge AA flags that apply to both
     * the destination rect and its clip.
     *
     * If provided, the 'dstClips' array must have length equal 4 * the number of entries with
     * fHasClip true. If 'dstClips' is null, every entry must have 'fHasClip' set to false. The
     * destination clip coordinates will be read consecutively with the image set entries, advancing
     * by 4 points every time an entry with fHasClip is passed.
     *
     * This entry point supports per-entry manipulations to the canvas's current matrix. If an
     * entry provides 'fMatrixIndex' >= 0, it will be drawn as if the canvas's CTM was
     * canvas->getTotalMatrix() * preViewMatrices[fMatrixIndex]. If 'fMatrixIndex' is less than 0,
     * the pre-view matrix transform is implicitly the identity, so it will be drawn using just the
     * current canvas matrix. The pre-view matrix modifies the canvas's view matrix, it does not
     * affect the local coordinates of each entry.
     *
     * An optional paint may be provided, which supports the same subset of features usable with
     * drawImageRect (i.e. assumed to be filled and no path effects). When a paint is provided, the
     * image set is drawn as if each image used the applied paint independently, so each is affected
     * by the image, color, and/or mask filter.
     */
    void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
                                         const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                         const SkSamplingOptions&, const SkPaint* paint = nullptr,
                                         SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    // DEPRECATED -- pass sampling directly
    void experimental_DrawEdgeAAImageSet(const ImageSetEntry imageSet[], int cnt,
                                         const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                         const SkPaint* paint = nullptr,
                                         SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /** Draws text, with origin at (x, y), using clip, SkMatrix, SkFont font,
        and SkPaint paint.

        When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
        SkTextEncoding::kUTF32, this function uses the default
        character-to-glyph mapping from the SkTypeface in font.  It does not
        perform typeface fallback for characters not found in the SkTypeface.
        It does not perform kerning or other complex shaping; glyphs are
        positioned based on their default advances.

        Text meaning depends on SkTextEncoding.

        Text size is affected by SkMatrix and SkFont text size. Default text
        size is 12 point.

        All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
        SkColorFilter, and SkImageFilter; apply to text. By
        default, draws filled black glyphs.

        @param text        character code points or glyphs drawn
        @param byteLength  byte length of text array
        @param encoding    text encoding used in the text array
        @param x           start of text on x-axis
        @param y           start of text on y-axis
        @param font        typeface, text size and so, used to describe the text
        @param paint       blend, color, and so on, used to draw
    */
    void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
                        SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint);

    /** Draws null terminated string, with origin at (x, y), using clip, SkMatrix,
        SkFont font, and SkPaint paint.

        This function uses the default character-to-glyph mapping from the
        SkTypeface in font.  It does not perform typeface fallback for
        characters not found in the SkTypeface.  It does not perform kerning;
        glyphs are positioned based on their default advances.

        String str is encoded as UTF-8.

        Text size is affected by SkMatrix and font text size. Default text
        size is 12 point.

        All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
        SkColorFilter, and SkImageFilter; apply to text. By
        default, draws filled black glyphs.

        @param str     character code points drawn,
                       ending with a char value of zero
        @param x       start of string on x-axis
        @param y       start of string on y-axis
        @param font    typeface, text size and so, used to describe the text
        @param paint   blend, color, and so on, used to draw
    */
    void drawString(const char str[], SkScalar x, SkScalar y, const SkFont& font,
                    const SkPaint& paint) {
        this->drawSimpleText(str, strlen(str), SkTextEncoding::kUTF8, x, y, font, paint);
    }

    /** Draws SkString, with origin at (x, y), using clip, SkMatrix, SkFont font,
        and SkPaint paint.

        This function uses the default character-to-glyph mapping from the
        SkTypeface in font.  It does not perform typeface fallback for
        characters not found in the SkTypeface.  It does not perform kerning;
        glyphs are positioned based on their default advances.

        SkString str is encoded as UTF-8.

        Text size is affected by SkMatrix and SkFont text size. Default text
        size is 12 point.

        All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
        SkColorFilter, and SkImageFilter; apply to text. By
        default, draws filled black glyphs.

        @param str     character code points drawn,
                       ending with a char value of zero
        @param x       start of string on x-axis
        @param y       start of string on y-axis
        @param font    typeface, text size and so, used to describe the text
        @param paint   blend, color, and so on, used to draw
    */
    void drawString(const SkString& str, SkScalar x, SkScalar y, const SkFont& font,
                    const SkPaint& paint) {
        this->drawSimpleText(str.c_str(), str.size(), SkTextEncoding::kUTF8, x, y, font, paint);
    }

    /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.

        blob contains glyphs, their positions, and paint attributes specific to text:
        SkTypeface, SkPaint text size, SkPaint text scale x,
        SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
        SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
        and SkPaint subpixel text.

        SkTextEncoding must be set to SkTextEncoding::kGlyphID.

        Elements of paint: anti-alias, SkBlendMode, color including alpha,
        SkColorFilter, SkPaint dither, SkMaskFilter, SkPathEffect, SkShader, and
        SkPaint::Style; apply to blob. If SkPaint contains SkPaint::kStroke_Style:
        SkPaint miter limit, SkPaint::Cap, SkPaint::Join, and SkPaint stroke width;
        apply to SkPath created from blob.

        @param blob   glyphs, positions, and their paints' text size, typeface, and so on
        @param x      horizontal offset applied to blob
        @param y      vertical offset applied to blob
        @param paint  blend, color, stroking, and so on, used to draw

        example: https://fiddle.skia.org/c/@Canvas_drawTextBlob
    */
    void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);

    /** Draws SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.

        blob contains glyphs, their positions, and paint attributes specific to text:
        SkTypeface, SkPaint text size, SkPaint text scale x,
        SkPaint text skew x, SkPaint::Align, SkPaint::Hinting, anti-alias, SkPaint fake bold,
        SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
        and SkPaint subpixel text.

        SkTextEncoding must be set to SkTextEncoding::kGlyphID.

        Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
        and SkImageFilter; apply to blob.

        @param blob   glyphs, positions, and their paints' text size, typeface, and so on
        @param x      horizontal offset applied to blob
        @param y      vertical offset applied to blob
        @param paint  blend, color, stroking, and so on, used to draw
    */
    void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
        this->drawTextBlob(blob.get(), x, y, paint);
    }

    /** Draws SkPicture picture, using clip and SkMatrix.
        Clip and SkMatrix are unchanged by picture contents, as if
        save() was called before and restore() was called after drawPicture().

        SkPicture records a series of draw commands for later playback.

        @param picture  recorded drawing commands to play
    */
    void drawPicture(const SkPicture* picture) {
        this->drawPicture(picture, nullptr, nullptr);
    }

    /** Draws SkPicture picture, using clip and SkMatrix.
        Clip and SkMatrix are unchanged by picture contents, as if
        save() was called before and restore() was called after drawPicture().

        SkPicture records a series of draw commands for later playback.

        @param picture  recorded drawing commands to play
    */
    void drawPicture(const sk_sp<SkPicture>& picture) {
        this->drawPicture(picture.get());
    }

    /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
        SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
        SkImageFilter, and SkBlendMode, if provided.

        If paint is non-null, then the picture is always drawn into a temporary layer before
        actually landing on the canvas. Note that drawing into a layer can also change its
        appearance if there are any non-associative blendModes inside any of the pictures elements.

        @param picture  recorded drawing commands to play
        @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
        @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr

        example: https://fiddle.skia.org/c/@Canvas_drawPicture_3
    */
    void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);

    /** Draws SkPicture picture, using clip and SkMatrix; transforming picture with
        SkMatrix matrix, if provided; and use SkPaint paint alpha, SkColorFilter,
        SkImageFilter, and SkBlendMode, if provided.

        If paint is non-null, then the picture is always drawn into a temporary layer before
        actually landing on the canvas. Note that drawing into a layer can also change its
        appearance if there are any non-associative blendModes inside any of the pictures elements.

        @param picture  recorded drawing commands to play
        @param matrix   SkMatrix to rotate, scale, translate, and so on; may be nullptr
        @param paint    SkPaint to apply transparency, filtering, and so on; may be nullptr
    */
    void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix,
                     const SkPaint* paint) {
        this->drawPicture(picture.get(), matrix, paint);
    }

    /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
        If paint contains an SkShader and vertices does not contain texCoords, the shader
        is mapped using the vertices' positions.

        If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
        SkBlendMode mode combines vertices colors with SkShader.

        @param vertices  triangle mesh to draw
        @param mode      combines vertices colors with SkShader, if both are present
        @param paint     specifies the SkShader, used as SkVertices texture; may be nullptr

        example: https://fiddle.skia.org/c/@Canvas_drawVertices
    */
    void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);

    /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
     *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
     */
    void drawVertices(const SkVertices* vertices, const SkPaint& paint) {
        this->drawVertices(vertices, SkBlendMode::kModulate, paint);
    }

    /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
        If paint contains an SkShader and vertices does not contain texCoords, the shader
        is mapped using the vertices' positions.

        If vertices colors are defined in vertices, and SkPaint paint contains SkShader,
        SkBlendMode mode combines vertices colors with SkShader.

        @param vertices  triangle mesh to draw
        @param mode      combines vertices colors with SkShader, if both are present
        @param paint     specifies the SkShader, used as SkVertices texture, may be nullptr

        example: https://fiddle.skia.org/c/@Canvas_drawVertices_2
    */
    void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);

    /** Variant of 3-parameter drawVertices, using the default of Modulate for the blend
     *  parameter. Note that SkVertices that include per-vertex-data ignore this mode parameter.
     */
    void drawVertices(const sk_sp<SkVertices>& vertices, const SkPaint& paint) {
        this->drawVertices(vertices, SkBlendMode::kModulate, paint);
    }

    /** Draws a Coons patch: the interpolation of four cubics with shared corners,
        associating a color, and optionally a texture SkPoint, with each corner.

        Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
        alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
        as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
        both are provided.

        SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
        in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
        first point.

        Color array color associates colors with corners in top-left, top-right,
        bottom-right, bottom-left order.

        If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
        corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
        nullptr, SkShader is mapped using positions (derived from cubics).

        @param cubics     SkPath cubic array, sharing common points
        @param colors     color array, one for each corner
        @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
                          may be nullptr
        @param mode       SkBlendMode for colors, and for SkShader if paint has one
        @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
    */
    void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                   const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);

    /** Draws SkPath cubic Coons patch: the interpolation of four cubics with shared corners,
        associating a color, and optionally a texture SkPoint, with each corner.

        Coons patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
        alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
        as Coons patch texture; SkBlendMode mode combines color colors and SkShader if
        both are provided.

        SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
        in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
        first point.

        Color array color associates colors with corners in top-left, top-right,
        bottom-right, bottom-left order.

        If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
        corners in top-left, top-right, bottom-right, bottom-left order. If texCoords is
        nullptr, SkShader is mapped using positions (derived from cubics).

        @param cubics     SkPath cubic array, sharing common points
        @param colors     color array, one for each corner
        @param texCoords  SkPoint array of texture coordinates, mapping SkShader to corners;
                          may be nullptr
        @param paint      SkShader, SkColorFilter, SkBlendMode, used to draw
    */
    void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                   const SkPoint texCoords[4], const SkPaint& paint) {
        this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
    }

    /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
        paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
        to draw, if present. For each entry in the array, SkRect tex locates sprite in
        atlas, and SkRSXform xform transforms it into destination space.

        xform, text, and colors if present, must contain count entries.
        Optional colors are applied for each sprite using SkBlendMode mode, treating
        sprite as source and colors as destination.
        Optional cullRect is a conservative bounds of all transformed sprites.
        If cullRect is outside of clip, canvas can skip drawing.

        If atlas is nullptr, this draws nothing.

        @param atlas     SkImage containing sprites
        @param xform     SkRSXform mappings for sprites in atlas
        @param tex       SkRect locations of sprites in atlas
        @param colors    one per sprite, blended with sprite using SkBlendMode; may be nullptr
        @param count     number of sprites to draw
        @param mode      SkBlendMode combining colors and sprites
        @param sampling  SkSamplingOptions used when sampling from the atlas image
        @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
        @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
    */
    void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
                   const SkColor colors[], int count, SkBlendMode mode,
                   const SkSamplingOptions& sampling, const SkRect* cullRect, const SkPaint* paint);

    // DEPRECATED -- pass sampling
    void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
                   const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
                   const SkPaint* paint);

    /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
        paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
        to draw, if present. For each entry in the array, SkRect tex locates sprite in
        atlas, and SkRSXform xform transforms it into destination space.

        xform, text, and colors if present, must contain count entries.
        Optional colors is applied for each sprite using SkBlendMode.
        Optional cullRect is a conservative bounds of all transformed sprites.
        If cullRect is outside of clip, canvas can skip drawing.

        @param atlas     SkImage containing sprites
        @param xform     SkRSXform mappings for sprites in atlas
        @param tex       SkRect locations of sprites in atlas
        @param colors    one per sprite, blended with sprite using SkBlendMode; may be nullptr
        @param count     number of sprites to draw
        @param mode      SkBlendMode combining colors and sprites
        @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
        @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
    */
    void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
                   const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
                   const SkPaint* paint) {
        this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
    }

    /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
        paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
        to draw, if present. For each entry in the array, SkRect tex locates sprite in
        atlas, and SkRSXform xform transforms it into destination space.

        xform and text must contain count entries.
        Optional cullRect is a conservative bounds of all transformed sprites.
        If cullRect is outside of clip, canvas can skip drawing.

        @param atlas     SkImage containing sprites
        @param xform     SkRSXform mappings for sprites in atlas
        @param tex       SkRect locations of sprites in atlas
        @param count     number of sprites to draw
        @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
        @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
    */
    void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
                   const SkRect* cullRect, const SkPaint* paint) {
        this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
    }

    /** Draws a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
        paint uses anti-alias, alpha, SkColorFilter, SkImageFilter, and SkBlendMode
        to draw, if present. For each entry in the array, SkRect tex locates sprite in
        atlas, and SkRSXform xform transforms it into destination space.

        xform and text must contain count entries.
        Optional cullRect is a conservative bounds of all transformed sprites.
        If cullRect is outside of clip, canvas can skip drawing.

        @param atlas     SkImage containing sprites
        @param xform     SkRSXform mappings for sprites in atlas
        @param tex       SkRect locations of sprites in atlas
        @param count     number of sprites to draw
        @param cullRect  bounds of transformed sprites for efficient clipping; may be nullptr
        @param paint     SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
    */
    void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
                   int count, const SkRect* cullRect, const SkPaint* paint) {
        this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
                        cullRect, paint);
    }

    /** Draws SkDrawable drawable using clip and SkMatrix, concatenated with
        optional matrix.

        If SkCanvas has an asynchronous implementation, as is the case
        when it is recording into SkPicture, then drawable will be referenced,
        so that SkDrawable::draw() can be called when the operation is finalized. To force
        immediate drawing, call SkDrawable::draw() instead.

        @param drawable  custom struct encapsulating drawing commands
        @param matrix    transformation applied to drawing; may be nullptr

        example: https://fiddle.skia.org/c/@Canvas_drawDrawable
    */
    void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);

    /** Draws SkDrawable drawable using clip and SkMatrix, offset by (x, y).

        If SkCanvas has an asynchronous implementation, as is the case
        when it is recording into SkPicture, then drawable will be referenced,
        so that SkDrawable::draw() can be called when the operation is finalized. To force
        immediate drawing, call SkDrawable::draw() instead.

        @param drawable  custom struct encapsulating drawing commands
        @param x         offset into SkCanvas writable pixels on x-axis
        @param y         offset into SkCanvas writable pixels on y-axis

        example: https://fiddle.skia.org/c/@Canvas_drawDrawable_2
    */
    void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);

    /** Associates SkRect on SkCanvas with an annotation; a key-value pair, where the key is
        a null-terminated UTF-8 string, and optional value is stored as SkData.

        Only some canvas implementations, such as recording to SkPicture, or drawing to
        document PDF, use annotations.

        @param rect   SkRect extent of canvas to annotate
        @param key    string used for lookup
        @param value  data holding value stored in annotation

        example: https://fiddle.skia.org/c/@Canvas_drawAnnotation_2
    */
    void drawAnnotation(const SkRect& rect, const char key[], SkData* value);

    /** Associates SkRect on SkCanvas when an annotation; a key-value pair, where the key is
        a null-terminated UTF-8 string, and optional value is stored as SkData.

        Only some canvas implementations, such as recording to SkPicture, or drawing to
        document PDF, use annotations.

        @param rect   SkRect extent of canvas to annotate
        @param key    string used for lookup
        @param value  data holding value stored in annotation
    */
    void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
        this->drawAnnotation(rect, key, value.get());
    }

    /** Returns true if clip is empty; that is, nothing will draw.

        May do work when called; it should not be called
        more often than needed. However, once called, subsequent calls perform no
        work until clip changes.

        @return  true if clip is empty

        example: https://fiddle.skia.org/c/@Canvas_isClipEmpty
    */
    virtual bool isClipEmpty() const;

    /** Returns true if clip is SkRect and not empty.
        Returns false if the clip is empty, or if it is not SkRect.

        @return  true if clip is SkRect and not empty

        example: https://fiddle.skia.org/c/@Canvas_isClipRect
    */
    virtual bool isClipRect() const;

    /** Returns the current transform from local coordinates to the 'device', which for most
     *  purposes means pixels.
     *
     *  @return transformation from local coordinates to device / pixels.
     */
    SkM44 getLocalToDevice() const;

    /**
     *  Throws away the 3rd row and column in the matrix, so be warned.
     */
    SkMatrix getLocalToDeviceAs3x3() const {
        return this->getLocalToDevice().asM33();
    }

#ifdef SK_SUPPORT_LEGACY_GETTOTALMATRIX
    /** DEPRECATED
     *  Legacy version of getLocalToDevice(), which strips away any Z information, and
     *  just returns a 3x3 version.
     *
     *  @return 3x3 version of getLocalToDevice()
     *
     *  example: https://fiddle.skia.org/c/@Canvas_getTotalMatrix
     *  example: https://fiddle.skia.org/c/@Clip
     */
    SkMatrix getTotalMatrix() const;
#endif

    ///////////////////////////////////////////////////////////////////////////

#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && SK_SUPPORT_GPU
    // These methods exist to support WebView in Android Framework.
    SkIRect topLayerBounds() const;
    GrBackendRenderTarget topLayerBackendRenderTarget() const;
#endif

    // TEMP helpers until we switch virtual over to const& for src-rect
    void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                              const SkPaint* paint,
                              SrcRectConstraint constraint = kStrict_SrcRectConstraint);

    /**
     *  Returns the global clip as a region. If the clip contains AA, then only the bounds
     *  of the clip may be returned.
     */
    void temporary_internal_getRgnClip(SkRegion* region);

    void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);


protected:
    // default impl defers to getDevice()->newSurface(info)
    virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);

    // default impl defers to its device
    virtual bool onPeekPixels(SkPixmap* pixmap);
    virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
    virtual SkImageInfo onImageInfo() const;
    virtual bool onGetProps(SkSurfaceProps* props) const;
    virtual void onFlush();

    // Subclass save/restore notifiers.
    // Overriders should call the corresponding INHERITED method up the inheritance chain.
    // getSaveLayerStrategy()'s return value may suppress full layer allocation.
    enum SaveLayerStrategy {
        kFullLayer_SaveLayerStrategy,
        kNoLayer_SaveLayerStrategy,
    };

    virtual void willSave() {}
    // Overriders should call the corresponding INHERITED method up the inheritance chain.
    virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
        return kFullLayer_SaveLayerStrategy;
    }

    // returns true if we should actually perform the saveBehind, or false if we should just save.
    virtual bool onDoSaveBehind(const SkRect*) { return true; }
    virtual void willRestore() {}
    virtual void didRestore() {}

    virtual void onMarkCTM(const char*) {}
    virtual void didConcat44(const SkM44&) {}
    virtual void didSetM44(const SkM44&) {}
    virtual void didTranslate(SkScalar, SkScalar) {}
    virtual void didScale(SkScalar, SkScalar) {}

    // NOTE: If you are adding a new onDraw virtual to SkCanvas, PLEASE add an override to
    // SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
    // that mechanism  will be required to implement the new function.
    virtual void onDrawPaint(const SkPaint& paint);
    virtual void onDrawBehind(const SkPaint& paint);
    virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
    virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
    virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
    virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
    virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
                           bool useCenter, const SkPaint& paint);
    virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
    virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);

    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                const SkPaint& paint);

    virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                           const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
    virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                              const SkPaint& paint);

#ifdef SK_SUPPORT_LEGACY_ONDRAWIMAGERECT
    virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
    virtual void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                                 const SkPaint* paint, SrcRectConstraint constraint);
    virtual void onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
                                    const SkPaint* paint);
    virtual void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
                             const SkColor colors[], int count, SkBlendMode mode,
                             const SkRect* cull, const SkPaint* paint);
    // never called -- remove from clients' subclasses
    virtual void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) {}
    virtual void onDrawEdgeAAImageSet(const ImageSetEntry imageSet[], int count,
                                      const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                      const SkPaint* paint, SrcRectConstraint constraint);
#endif
    virtual void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
                              const SkPaint*);
    virtual void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst,
                                  const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
    virtual void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect& dst,
                                     SkFilterMode, const SkPaint*);
    virtual void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect src[],
                              const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
                              const SkRect* cull, const SkPaint*);
    virtual void onDrawEdgeAAImageSet2(const ImageSetEntry imageSet[], int count,
                                       const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                       const SkSamplingOptions&, const SkPaint*,
                                       SrcRectConstraint);

    virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
                                      const SkPaint& paint);

    virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
    virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);

    virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
    virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                               const SkPaint* paint);

    virtual void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], QuadAAFlags aaFlags,
                                  const SkColor4f& color, SkBlendMode mode);

    enum ClipEdgeStyle {
        kHard_ClipEdgeStyle,
        kSoft_ClipEdgeStyle
    };

    virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
    virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
    virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
    virtual void onClipShader(sk_sp<SkShader>, SkClipOp);
    virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);

    virtual void onDiscard();

    // Clip rectangle bounds. Called internally by saveLayer.
    // returns false if the entire rectangle is entirely clipped out
    // If non-NULL, The imageFilter parameter will be used to expand the clip
    // and offscreen bounds for any margin required by the filter DAG.
    bool clipRectBounds(const SkRect* bounds, SkIRect* intersection,
                        const SkImageFilter* imageFilter = nullptr);

private:
    static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
                                     SkBaseDevice* dst, const SkIPoint& dstOrigin,
                                     const SkMatrix& ctm);

    enum ShaderOverrideOpacity {
        kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
        kOpaque_ShaderOverrideOpacity,      //!< the overriding shader is opaque
        kNotOpaque_ShaderOverrideOpacity,   //!< the overriding shader may not be opaque
    };

    // notify our surface (if we have one) that we are about to draw, so it
    // can perform copy-on-write or invalidate any cached images
    void predrawNotify(bool willOverwritesEntireSurface = false);
    void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);

    // The bottom-most device in the stack, only changed by init(). Image properties and the final
    // canvas pixels are determined by this device.
    SkBaseDevice* baseDevice() const {
        SkASSERT(fBaseDevice);
        return fBaseDevice.get();
    }

    // The top-most device in the stack, will change within saveLayer()'s. All drawing and clipping
    // operations should route to this device.
    SkBaseDevice* topDevice() const;
    virtual GrSurfaceDrawContext* topDeviceSurfaceDrawContext();

    class MCRec;

    SkDeque     fMCStack;
    // points to top of stack
    MCRec*      fMCRec;

    sk_sp<SkMarkerStack> fMarkerStack;

    // the first N recs that can fit here mean we won't call malloc
    static constexpr int kMCRecSize      = 96; // most recent measurement
    static constexpr int kMCRecCount     = 32; // common depth for save/restores

    intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];

    // Installed via init()
    sk_sp<SkBaseDevice> fBaseDevice;
    const SkSurfaceProps fProps;

    int         fSaveCount;         // value returned by getSaveCount()

    std::unique_ptr<SkRasterHandleAllocator> fAllocator;

    SkSurface_Base*  fSurfaceBase;
    SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
    void setSurfaceBase(SkSurface_Base* sb) {
        fSurfaceBase = sb;
    }
    friend class SkSurface_Base;
    friend class SkSurface_Gpu;

    SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();

    void doSave();
    void checkForDeferredSave();
    void internalSetMatrix(const SkM44&);

    friend class SkAndroidFrameworkUtils;
    friend class SkCanvasPriv;      // needs to expose android functions for testing outside android
    friend class AutoLayerForImageFilter;
    friend class SkSurface_Raster;  // needs getDevice()
    friend class SkNoDrawCanvas;    // needs resetForNextPicture()
    friend class SkPictureRecord;   // predrawNotify (why does it need it? <reed>)
    friend class SkOverdrawCanvas;
    friend class SkRasterHandleAllocator;
protected:
    // For use by SkNoDrawCanvas (via SkCanvasVirtualEnforcer, which can't be a friend)
    SkCanvas(const SkIRect& bounds);
private:
    SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
             SkRasterHandleAllocator::Handle);

    SkCanvas(SkCanvas&&) = delete;
    SkCanvas(const SkCanvas&) = delete;
    SkCanvas& operator=(SkCanvas&&) = delete;
    SkCanvas& operator=(const SkCanvas&) = delete;

    /** Experimental
     *  Saves the specified subset of the current pixels in the current layer,
     *  and then clears those pixels to transparent black.
     *  Restores the pixels on restore() by drawing them in SkBlendMode::kDstOver.
     *
     *  @param subset   conservative bounds of the area to be saved / restored.
     *  @return depth of save state stack before this call was made.
     */
    int only_axis_aligned_saveBehind(const SkRect* subset);

    /**
     *  Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
     *  If there is no active saveBehind, then this draws nothing.
     */
    void drawClippedToSaveBehind(const SkPaint&);

    void resetForNextPicture(const SkIRect& bounds);

    // needs gettotalclip()
    friend class SkCanvasStateUtils;

    void init(sk_sp<SkBaseDevice>);

    // All base onDrawX() functions should call this and skip drawing if it returns true.
    // If 'matrix' is non-null, it maps the paint's fast bounds before checking for quick rejection
    bool internalQuickReject(const SkRect& bounds, const SkPaint& paint,
                             const SkMatrix* matrix = nullptr);

    void internalDrawPaint(const SkPaint& paint);
    void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
    void internalSaveBehind(const SkRect*);
    void internalDrawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint*);

    void internalConcat44(const SkM44&);

    // shared by save() and saveLayer()
    void internalSave();
    void internalRestore();

    /*
     *  Returns true if drawing the specified rect (or all if it is null) with the specified
     *  paint (or default if null) would overwrite the entire root device of the canvas
     *  (i.e. the canvas' surface if it had one).
     */
    bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;

    /**
     *  Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
     */
    bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkSamplingOptions&,
                               const SkPaint&);

    /**
     *  Returns true if the clip (for any active layer) contains antialiasing.
     *  If the clip is empty, this will return false.
     */
    bool androidFramework_isClipAA() const;

    /**
     * Reset the clip to be just the intersection with the global-space 'rect'. This operates within
     * the save/restore stack of the canvas, so restore() will bring back any saved clip. However,
     * since 'rect' is already in global space, it is not modified by the canvas matrix.
     */
    void androidFramework_replaceClip(const SkIRect& rect);

    virtual SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const { return nullptr; }

    /**
     *  Keep track of the device clip bounds and if the matrix is scale-translate.  This allows
     *  us to do a fast quick reject in the common case.
     */
    bool   fIsScaleTranslate;
    SkRect fQuickRejectBounds;

    // Compute the clip's bounds based on all clipped SkDevice's reported device bounds transformed
    // into the canvas' global space.
    SkRect computeDeviceClipBounds() const;

    class AutoUpdateQRBounds;
    void validateClip() const;

    std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;

    using INHERITED = SkRefCnt;
};

/** \class SkAutoCanvasRestore
    Stack helper class calls SkCanvas::restoreToCount when SkAutoCanvasRestore
    goes out of scope. Use this to guarantee that the canvas is restored to a known
    state.
*/
class SkAutoCanvasRestore {
public:

    /** Preserves SkCanvas::save() count. Optionally saves SkCanvas clip and SkCanvas matrix.

        @param canvas  SkCanvas to guard
        @param doSave  call SkCanvas::save()
        @return        utility to restore SkCanvas state on destructor
    */
    SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
        if (fCanvas) {
            fSaveCount = canvas->getSaveCount();
            if (doSave) {
                canvas->save();
            }
        }
    }

    /** Restores SkCanvas to saved state. Destructor is called when container goes out of
        scope.
    */
    ~SkAutoCanvasRestore() {
        if (fCanvas) {
            fCanvas->restoreToCount(fSaveCount);
        }
    }

    /** Restores SkCanvas to saved state immediately. Subsequent calls and
        ~SkAutoCanvasRestore() have no effect.
    */
    void restore() {
        if (fCanvas) {
            fCanvas->restoreToCount(fSaveCount);
            fCanvas = nullptr;
        }
    }

private:
    SkCanvas*   fCanvas;
    int         fSaveCount;

    SkAutoCanvasRestore(SkAutoCanvasRestore&&) = delete;
    SkAutoCanvasRestore(const SkAutoCanvasRestore&) = delete;
    SkAutoCanvasRestore& operator=(SkAutoCanvasRestore&&) = delete;
    SkAutoCanvasRestore& operator=(const SkAutoCanvasRestore&) = delete;
};

#endif
