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

/* Generated by tools/bookmaker from include/core/SkCanvas.h and docs/SkCanvas_Reference.bmh
   on 2018-08-28 10:32:58. Additional documentation and examples can be found at:
   https://skia.org/user/api/SkCanvas_Reference

   You may edit either file directly. Structural changes to public interfaces require
   editing both files. After editing docs/SkCanvas_Reference.bmh, run:
       bookmaker -b docs -i include/core/SkCanvas.h -p
   to create an updated version of this file.
 */

#ifndef SkCanvas_DEFINED
#define SkCanvas_DEFINED

#include "../private/SkMacros.h"
#include "SkBlendMode.h"
#include "SkClipOp.h"
#include "SkDeque.h"
#include "SkFontTypes.h"
#include "SkPaint.h"
#include "SkRasterHandleAllocator.h"
#include "SkSurfaceProps.h"
#include "SkVertices.h"

class GrContext;
class GrRenderTargetContext;
class SkAndroidFrameworkUtils;
class SkBaseDevice;
class SkBitmap;
class SkData;
class SkDraw;
class SkDrawable;
struct SkDrawShadowRec;
class SkFont;
class SkGlyphRunBuilder;
class SkImage;
class SkImageFilter;
class SkPaintFilterCanvas;
class SkPath;
class SkPicture;
class SkPixmap;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkSurface;
class SkSurface_Base;
class SkTextBlob;

/** \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
    */
    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
    */
    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
    */
    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
    */
    SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);

    /** Draws saved layers, if any.
        Frees up resources used by SkCanvas.
    */
    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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    virtual GrContext* getGrContext();

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

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

        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 SkDebugCanvas.

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

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

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

        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
    */
    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
    */
    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
    */
    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
    */
    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, (no longer used)
        kInitWithPrevious_SaveLayerFlag = 1 << 2, //!< initializes with previous contents
        kMaskAgainstCoverage_EXPERIMENTAL_DONT_USE_SaveLayerFlag =
                                          1 << 3, //!< experimental: do not use

#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.

            Implementation is not complete; has no effect if SkBaseDevice is GPU-backed.

            @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.
    */
    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.
    */
    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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    void concat(const SkMatrix& matrix);

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

        @param matrix  matrix to copy, replacing existing SkMatrix
    */
    void setMatrix(const SkMatrix& matrix);

    /** Sets SkMatrix to the identity matrix.
        Any prior matrix state is overwritten.
    */
    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
    */
    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
    */
    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
    */
    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);
    }

    /** Experimental. For testing only.
        Set to simplify clip stack using PathOps.
    */
    void setAllowSimplifyClip(bool allow) {
        fAllowSimplifyClip = allow;
    }

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

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

    /** Draws SkBitmap bitmap stretched proportionally to fit into SkRect dst.
        SkIRect center divides the bitmap 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 bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap 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 bitmap  SkBitmap 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 drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
                        const SkPaint* paint = nullptr);

    /** \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 SkBitmap bitmap stretched proportionally to fit into SkRect dst.

        SkCanvas::Lattice lattice divides bitmap 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 bitmap is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from bitmap 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 bitmap   SkBitmap 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 drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
                           const SkPaint* paint = nullptr);

    /** 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 ImageSetEntry {
        sk_sp<const SkImage> fImage;
        SkRect fSrcRect;
        SkRect fDstRect;
        float fAlpha;
        unsigned fAAFlags;  // QuadAAFlags
    };

    /**
     * This is an experimental API for the SkiaRenderer Chromium project. The signature will
     * surely evolve if this is not removed. It currently offers no performance advantage over
     * drawing images independently, though may in the future. The antialiasing flags are intended
     * to allow control over each edge's AA status, to allow perfect seaming for tile sets. The
     * current implementation only antialiases if all edges are flagged, however.
     * Results are undefined if an image's src rect is not within the image's bounds.
     */
    void experimental_DrawImageSetV1(const ImageSetEntry imageSet[], int cnt,
                                     SkFilterQuality quality, SkBlendMode mode);

    /**
     * This is an experimental API for the SkiaRenderer Chromium project. The signature will
     * surely evolve if this is not removed. The antialiasing flags are intended to allow control
     * over each edge's AA status, to allow perfect seaming for tile sets.
     *
     * When not fully supported, the implementation only antialiases if all edges are flagged.
     */
    void experimental_DrawEdgeAARectV1(const SkRect& r, QuadAAFlags edgeAA, SkColor color,
                                       SkBlendMode mode);

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

    /** Experimental.

        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), kUTF8_SkTextEncoding, x, y, font, paint);
    }

    /** Experimental.

        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(), kUTF8_SkTextEncoding, 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 kGlyphID_SkTextEncoding.

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

        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.

        matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
        paint use is equivalent to: saveLayer(), drawPicture(), restore().

        @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 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.

        matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
        paint use is equivalent to: saveLayer(), drawPicture(), restore().

        @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 vertices texs and 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
    */
    void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);

    /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix.
        If vertices texs and 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
    */
    void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);

    /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix. Bone data is used to
        deform vertices with bone weights.
        If vertices texs and vertices colors are defined in vertices, and SkPaint paint
        contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
        The first element of bones should be an object to world space transformation matrix that
        will be applied before performing mesh deformations. If no such transformation is needed,
        it should be the identity matrix.
        boneCount must be at most 80, and thus the size of bones should be at most 80.

        @param vertices   triangle mesh to draw
        @param bones      bone matrix data
        @param boneCount  number of bone matrices
        @param mode       combines vertices colors with SkShader, if both are present
        @param paint      specifies the SkShader, used as SkVertices texture, may be nullptr
    */
    void drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[], int boneCount,
                      SkBlendMode mode, const SkPaint& paint);

    /** Draws SkVertices vertices, a triangle mesh, using clip and SkMatrix. Bone data is used to
        deform vertices with bone weights.
        If vertices texs and vertices colors are defined in vertices, and SkPaint paint
        contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
        The first element of bones should be an object to world space transformation matrix that
        will be applied before performing mesh deformations. If no such transformation is needed,
        it should be the identity matrix.
        boneCount must be at most 80, and thus the size of bones should be at most 80.

        @param vertices   triangle mesh to draw
        @param bones      bone matrix data
        @param boneCount  number of bone matrices
        @param mode       combines vertices colors with SkShader, if both are present
        @param paint      specifies the SkShader, used as SkVertices texture, may be nullptr
    */
    void drawVertices(const sk_sp<SkVertices>& vertices, const SkVertices::Bone bones[],
                      int boneCount, SkBlendMode mode, const SkPaint& 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.

        @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.

        @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.

        @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
    */
    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
    */
    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
    */
    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
    */
    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
    */
    virtual bool isClipRect() const;

    /** Returns SkMatrix.
        This does not account for translation by SkBaseDevice or SkSurface.

        @return  SkMatrix in SkCanvas
    */
    const 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);
    void legacy_drawBitmapRect(const SkBitmap& bitmap, 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 didConcat(const SkMatrix& ) {}
    virtual void didSetMatrix(const SkMatrix& ) {}
    virtual void didTranslate(SkScalar dx, SkScalar dy) {
        this->didConcat(SkMatrix::MakeTrans(dx, dy));
    }

    // 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 onDrawEdgeAARect(const SkRect& rect, QuadAAFlags edgeAA, SkColor color,
                                  SkBlendMode mode);
    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);

    // TODO: Remove old signature
    virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
                                      const SkPaint& paint) {
        this->onDrawVerticesObject(vertices, nullptr, 0, mode, paint);
    }
    virtual void onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
                                      int boneCount, 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 onDrawImageSet(const ImageSetEntry imageSet[], int count, SkFilterQuality,
                                SkBlendMode);

    virtual void onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
                              const SkPaint* paint);
    virtual void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
                                  const SkPaint* paint, SrcRectConstraint constraint);
    virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
                                  const SkPaint* paint);
    virtual void onDrawBitmapLattice(const SkBitmap& bitmap, 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);

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

    // 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 AutoDrawLooper;
    friend class SkDebugCanvas;     // needs experimental fAllowSimplifyClip
    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;
    friend class ClipTileRenderer;  // GM needs getTopDevice() until API is in SkCanvas
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 internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
                                const SkRect& dst, const SkPaint* paint,
                                SrcRectConstraint);
    void internalDrawPaint(const SkPaint& paint);
    void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
    void internalSaveBehind(const SkRect*);
    void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, SkImage* clipImage,
                            const SkMatrix& clipMatrix);

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

    bool fAllowSoftClip;
    bool fAllowSimplifyClip;

    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
