/*
 * 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/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>

class GrContext;
class GrRenderTargetContext;
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 {
    enum PrivateSaveLayerFlags {
        kDontClipToLayer_PrivateSaveLayerFlag   = 1U << 31,
    };

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 SkSurfaceProps::kLegacyFontHost_InitType 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.
    */
    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_getGrContext
    */
    virtual GrContext* getGrContext();

    /** 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,
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
        kDontClipToLayer_Legacy_SaveLayerFlag =
           kDontClipToLayer_PrivateSaveLayerFlag, //!< deprecated
#endif
    };

    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)
        {}

        /** Experimental. Not ready for general use.
            Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
            clipMatrix uses alpha channel of image, transformed by clipMatrix, to clip
            layer when drawn to SkCanvas.

            @param bounds          layer dimensions; may be nullptr
            @param paint           graphics state 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 clipMask        clip applied to layer; may be nullptr
            @param clipMatrix      matrix applied to clipMask; may be nullptr to use
                                   identity matrix
            @param saveLayerFlags  SaveLayerRec options to modify layer
            @return                SaveLayerRec fully specified
        */
        SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
                     const SkImage* clipMask, const SkMatrix* clipMatrix,
                     SaveLayerFlags saveLayerFlags)
            : fBounds(bounds)
            , fPaint(paint)
            , fBackdrop(backdrop)
            , fClipMask(clipMask)
            , fClipMatrix(clipMatrix)
            , 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;

        /** clips layer with mask alpha */
        const SkImage*       fClipMask       = nullptr;

        /** transforms mask alpha used to clip */
        const SkMatrix*      fClipMatrix     = 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 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.

        @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);

    /** 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->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 SkMaskFilter, SkShader,
        SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
        SkPathEffect in paint is 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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);
    }

    /** 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,
        SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds. If paint
        SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
        other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
        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 paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                       and so on; or nullptr
    */
    void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
                       const SkPaint* paint = nullptr);

    /** 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 not scaled, 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,
        SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds. If paint
        SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
        other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
        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 paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                       and so on; or nullptr
    */
    void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
                       const SkPaint* paint = nullptr) {
        this->drawImageNine(image.get(), center, dst, paint);
    }

    /** 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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,
        SkBlendMode, and SkDrawLooper. 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);

    /** \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; like the corners
        of drawBitmapNine(), 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,
        SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds. If paint
        SkFilterQuality set to kNone_SkFilterQuality, disable pixel filtering. For all
        other values of paint SkFilterQuality, use kLow_SkFilterQuality to filter pixels.
        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 paint    SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
                        and so on; or nullptr
    */
    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 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, SkImageFilter, and SkDrawLooper; 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, SkImageFilter, and SkDrawLooper; 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, SkImageFilter, and SkDrawLooper; 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, SkDrawLooper, 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,
        SkImageFilter, and SkDrawLooper; 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 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 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;

    /** 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;

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

    // don't call
    virtual GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
    SkIRect internal_private_getTopLayerBounds() const { return getTopLayerBounds(); }

    // 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 didConcat(const SkMatrix& ) {}
    virtual void didSetMatrix(const SkMatrix& ) {}
    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);

    virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
                                      const SkPaint& paint);
    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 onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
                                 const SkPaint* paint);
    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);

    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);
    virtual void onDrawEdgeAAImageSet(const ImageSetEntry imageSet[], int count,
                                      const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                      const SkPaint* paint, SrcRectConstraint constraint);

    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, SaveLayerFlags flags, SkIRect* intersection,
                        const SkImageFilter* imageFilter = nullptr);

    SkBaseDevice* getTopDevice() const;

private:
    /** After calling saveLayer(), there can be any number of devices that make
     up the top-most drawing area. LayerIter can be used to iterate through
     those devices. Note that the iterator is only valid until the next API
     call made on the canvas. Ownership of all pointers in the iterator stays
     with the canvas, so none of them should be modified or deleted.
     */
    class LayerIter /*: SkNoncopyable*/ {
    public:
        /** Initialize iterator with canvas, and set values for 1st device */
        LayerIter(SkCanvas*);
        ~LayerIter();

        /** Return true if the iterator is done */
        bool done() const { return fDone; }
        /** Cycle to the next device */
        void next();

        // These reflect the current device in the iterator

        SkBaseDevice*   device() const;
        const SkMatrix& matrix() const;
        SkIRect clipBounds() const;
        const SkPaint&  paint() const;
        int             x() const;
        int             y() const;

    private:
        // used to embed the SkDrawIter object directly in our instance, w/o
        // having to expose that class def to the public. There is an assert
        // in our constructor to ensure that fStorage is large enough
        // (though needs to be a compile-time-assert!). We use intptr_t to work
        // safely with 32 and 64 bit machines (to ensure the storage is enough)
        intptr_t          fStorage[32];
        class SkDrawIter* fImpl;    // this points at fStorage
        SkPaint           fDefaultPaint;
        SkIPoint          fDeviceOrigin;
        bool              fDone;
    };

    static bool BoundsAffectsClip(SaveLayerFlags);

    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);
    void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
        this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
                                                                : kNotOpaque_ShaderOverrideOpacity);
    }

    SkBaseDevice* getDevice() const;

    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      = 128;  // most recent measurement
    static constexpr int kMCRecCount     = 32;   // common depth for save/restores
    static constexpr int kDeviceCMSize   = 224;  // most recent measurement

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

    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 SkMatrix&);

    friend class SkAndroidFrameworkUtils;
    friend class SkCanvasPriv;      // needs kDontClipToLayer_PrivateSaveLayerFlag
    friend class SkDrawIter;        // needs setupDrawForLayerDevice()
    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;

    // call this each time we attach ourselves to a device
    //  - constructor
    //  - internalSaveLayer
    void setupDevice(SkBaseDevice*);

    void init(sk_sp<SkBaseDevice>);

    /**
     * Gets the bounds of the top level layer in global canvas coordinates. We don't want this
     * to be public because it exposes decisions about layer sizes that are internal to the canvas.
     */
    SkIRect getTopLayerBounds() const;

    void internalDrawPaint(const SkPaint& paint);
    void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
    void internalSaveBehind(const SkRect*);
    void internalDrawDevice(SkBaseDevice*, const SkPaint*, SkImage* clipImage,
                            const SkMatrix& clipMatrix);

    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 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;

    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 fDeviceClipBounds;

    class AutoValidateClip {
    public:
        explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
            fCanvas->validateClip();
        }
        ~AutoValidateClip() { fCanvas->validateClip(); }

    private:
        const SkCanvas* fCanvas;

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

#ifdef SK_DEBUG
    void validateClip() const;
#else
    void validateClip() const {}
#endif

    std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;

    typedef SkRefCnt INHERITED;
};

/** \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;
};

// Private
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)

#endif
