/*
 * 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 "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 SkMetaData;
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 storage to associate additional data with the canvas.
        The storage is freed when SkCanvas is deleted.

        @return  storage that can be read from and written to
    */
    SkMetaData& getMetaData();

    /** 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 a SkBitmap for subsequent drawing.
        LCD text is preserved when the layer is drawn to the prior layer.

        Calling restore() discards changes to SkMatrix and clip, and draws 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 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.

        Draw text on an opaque background so that LCD text blends correctly with the
        prior layer. LCD text drawn on a background with transparency may result in
        incorrect blending.

        @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 saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* 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, //!< creates layer for LCD text
        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        prior layer copied with SkImageFilter; may be nullptr
            @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        prior layer copied with SkImageFilter;
                                   may be nullptr
            @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;

        /** applies SkImageFilter to prior layer */
        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
    */
    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.

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

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

        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.

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

        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.

        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.

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

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

        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.

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

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

        text meaning depends on SkTextEncoding; by default, text is encoded as
        UTF-8.

        x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
        text draws left to right, positioning the first glyph left side bearing at x
        and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.

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

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

    // Experimental
    void drawSimpleText(const void* text, size_t byteLength, SkTextEncoding encoding,
                        SkScalar x, SkScalar y, const SkFont& font, const SkPaint& paint);

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

        string meaning depends on SkTextEncoding; by default, strings are encoded
        as UTF-8. Other values of SkTextEncoding are unlikely to produce the desired
        results, since zero bytes may be embedded in the string.

        x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
        string draws left to right, positioning the first glyph left side bearing at x
        and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.

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

        @param string  character code points or glyphs 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 paint   text size, blend, color, and so on, used to draw
    */
    void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint) {
        if (!string) {
            return;
        }
        this->drawText(string, strlen(string), x, y, paint);
    }

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

        string meaning depends on SkTextEncoding; by default, strings are encoded
        as UTF-8. Other values of SkTextEncoding are unlikely to produce the desired
        results, since zero bytes may be embedded in the string.

        x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
        string draws left to right, positioning the first glyph left side bearing at x
        and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.

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

        @param string  character code points or glyphs 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 paint   text size, blend, color, and so on, used to draw
    */
    void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint);

    /** Draws each glyph in text with the origin in pos array, using clip, SkMatrix, and
        SkPaint paint. The number of entries in pos array must match the number of glyphs
        described by byteLength of text.

        text meaning depends on SkTextEncoding; by default, text is encoded as
        UTF-8. pos elements meaning depends on SkPaint vertical text; by default
        glyph left side bearing and baseline are relative to SkPoint in pos array.
        Text size is affected by SkMatrix and SkPaint text size.

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

        Layout engines such as Harfbuzz typically position each glyph
        rather than using the font advance widths.

        @param text        character code points or glyphs drawn
        @param byteLength  byte length of text array
        @param pos         array of glyph origins
        @param paint       text size, blend, color, and so on, used to draw
    */
    void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
                     const SkPaint& paint);

    /** Draws each glyph in text with its origin composed from xpos array and
        constY, using clip, SkMatrix, and SkPaint paint. The number of entries in xpos array
        must match the number of glyphs described by byteLength of text.

        text meaning depends on SkTextEncoding; by default, text is encoded as
        UTF-8. xpos elements meaning depends on SkPaint vertical text;
        by default each glyph left side bearing is positioned at an xpos element and
        its baseline is positioned at constY. Text size is affected by SkMatrix and
        SkPaint text size.

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

        Layout engines such as Harfbuzz typically position each glyph
        rather than using the font advance widths if all glyphs share the same
        baseline.

        @param text        character code points or glyphs drawn
        @param byteLength  byte length of text array
        @param xpos        array of x-axis positions, used to position each glyph
        @param constY      shared y-axis value for all of x-axis positions
        @param paint       text size, blend, color, and so on, used to draw
    */
    void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
                      const SkPaint& paint);

    /** Draws text, transforming each glyph by the corresponding SkRSXform,
        using clip, SkMatrix, and SkPaint paint.

        SkRSXform xform array specifies a separate square scale, rotation, and translation
        for each glyph. xform does not affect paint SkShader.

        Optional SkRect cullRect is a conservative bounds of text, taking into account
        SkRSXform and paint. If cullRect is outside of clip, canvas can skip drawing.

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

        @param text        character code points or glyphs drawn
        @param byteLength  byte length of text array
        @param xform       SkRSXform rotates, scales, and translates each glyph individually
        @param cullRect    SkRect bounds of text for efficient clipping; or nullptr
        @param paint       text size, blend, color, and so on, used to draw
    */
    void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
                         const SkRect* cullRect, 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: 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;
    }
    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 onDrawRect(const SkRect& rect, const SkPaint& paint);
    virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
    virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
    virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
    virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
                           bool useCenter, const SkPaint& paint);
    virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
    virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);

    virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
                            SkScalar y, const SkPaint& paint);
    virtual void onDrawPosText(const void* text, size_t byteLength,
                               const SkPoint pos[], const SkPaint& paint);
    virtual void onDrawPosTextH(const void* text, size_t byteLength,
                                const SkScalar xpos[], SkScalar constY,
                                const SkPaint& paint);
    virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
                                   const SkRect* cullRect, 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()

    SkMetaData* fMetaData;
    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;

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;

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

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