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

#ifndef SkCanvas_DEFINED
#define SkCanvas_DEFINED

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

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

#ifndef SK_SUPPORT_LEGACY_GETTOTALMATRIX
#define SK_SUPPORT_LEGACY_GETTOTALMATRIX
#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        Pixel buffer size should be height times rowBytes.

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

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

        @return  empty SkCanvas

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

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

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

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

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

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

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

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

        May be deprecated in the future.

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

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

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

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

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

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

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

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

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

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

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

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

        @return  dimensions and SkColorType of SkCanvas

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

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

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

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

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

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

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

        @return  integral width and height of base layer

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

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

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

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

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

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

        @return  GPU context, if available; nullptr otherwise

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

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

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

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

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

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

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

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

        @return  context of custom allocation

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

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

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

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

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

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

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

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

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

        The destination pixel storage must be allocated by the caller.

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

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

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

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

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

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

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

        Caller must allocate pixel storage in pixmap if needed.

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

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

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

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

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

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

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

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

        Caller must allocate pixel storage in bitmap if needed.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @return  depth of saved stack

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    typedef uint32_t SaveLayerFlags;

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

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

            @return  empty SaveLayerRec
        */
        SaveLayerRec() {}

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

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

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

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

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

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

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

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

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

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

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

        SaveLayerRec contains the state used to create the layer.

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

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

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

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

        Does nothing if the stack is empty.

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

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

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

        @return  depth of save state stack

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

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

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

        @param saveCount  depth of state stack to restore

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @param degrees  amount to rotate, in degrees

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

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

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

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

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

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

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

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

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

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

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

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

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

        @param matrix  matrix to premultiply with existing SkMatrix

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

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

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

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

        @param matrix  matrix to copy, replacing existing SkMatrix

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

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

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

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

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

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

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

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

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

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

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

    void clipIRect(const SkIRect& irect, SkClipOp op = SkClipOp::kIntersect) {
        this->clipRect(SkRect::Make(irect), op, false);
    }

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

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

        DEPRECATED: Replace usage with SkAndroidFrameworkUtils::replaceClip()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @return  bounds of clip in local coordinates

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

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

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

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

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

        Unlike getLocalClipBounds(), returned SkIRect is not outset.

        @return  bounds of clip in SkBaseDevice coordinates

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

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

        Unlike getLocalClipBounds(), bounds is not outset.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @param paint  graphics state used to fill SkCanvas

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    void drawImage(const SkImage* image, SkScalar left, SkScalar top) {
        this->drawImage(image, left, top, SkSamplingOptions(), nullptr);
    }
    void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top) {
        this->drawImage(image.get(), left, top, SkSamplingOptions(), nullptr);
    }

    /** \enum SkCanvas::SrcRectConstraint
        SrcRectConstraint controls the behavior at the edge of source SkRect,
        provided to drawImageRect() when there is any filtering. If kStrict is set,
        then extra code is used to ensure it nevers samples outside of the src-rect.
    */
    enum SrcRectConstraint {
        kStrict_SrcRectConstraint, //!< sample only inside bounds; slower
        kFast_SrcRectConstraint,   //!< sample outside bounds; faster
    };

    void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkSamplingOptions&,
                   const SkPaint* = nullptr);
    void drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
                   const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
        this->drawImage(image.get(), x, y, sampling, paint);
    }
    void drawImageRect(const SkImage*, const SkRect& src, const SkRect& dst,
                       const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
    void drawImageRect(const SkImage*, const SkRect& dst, const SkSamplingOptions&,
                       const SkPaint* = nullptr);
    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
                       const SkSamplingOptions& sampling, const SkPaint* paint,
                       SrcRectConstraint constraint) {
        this->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
    }
    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst,
                       const SkSamplingOptions& sampling, const SkPaint* paint = nullptr) {
        this->drawImageRect(image.get(), dst, sampling, 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, and
        SkBlendMode. If image is kAlpha_8_SkColorType, apply SkShader.
        If paint contains SkMaskFilter, generate mask from image bounds.
        Any SkMaskFilter on paint is ignored as is paint anti-aliasing state.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        Text meaning depends on SkTextEncoding.

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

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

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

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

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

        String str is encoded as UTF-8.

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

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

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

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

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

        SkString str is encoded as UTF-8.

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

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

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

    /** Draws count glyphs, at positions relative to origin styled with font and paint with
        supporting utf8 and cluster information.

       This function draw glyphs at the given positions relative to the given origin.
       It does not perform typeface fallback for glyphs not found in the SkTypeface in font.

       The drawing obeys the current transform matrix and clipping.

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

       @param count           number of glyphs to draw
       @param glyphs          the array of glyphIDs to draw
       @param positions       where to draw each glyph relative to origin
       @param clusters        array of size count of cluster information
       @param textByteCount   size of the utf8text
       @param utf8text        utf8text supporting information for the glyphs
       @param origin          the origin of all the positions
       @param font            typeface, text size and so, used to describe the text
       @param paint           blend, color, and so on, used to draw
    */
    void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
                    const uint32_t clusters[], int textByteCount, const char utf8text[],
                    SkPoint origin, const SkFont& font, const SkPaint& paint);

    /** Draws count glyphs, at positions relative to origin styled with font and paint.

        This function draw glyphs at the given positions relative to the given origin.
        It does not perform typeface fallback for glyphs not found in the SkTypeface in font.

        The drawing obeys the current transform matrix and clipping.

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

        @param count       number of glyphs to draw
        @param glyphs      the array of glyphIDs to draw
        @param positions   where to draw each glyph relative to origin
        @param origin      the origin of all the positions
        @param font        typeface, text size and so, used to describe the text
        @param paint       blend, color, and so on, used to draw
    */
    void drawGlyphs(int count, const SkGlyphID glyphs[], const SkPoint positions[],
                    SkPoint origin, const SkFont& font, const SkPaint& paint);

    /** Draws count glyphs, at positions relative to origin styled with font and paint.

        This function draw glyphs using the given scaling and rotations. They are positioned
        relative to the given origin. It does not perform typeface fallback for glyphs not found
        in the SkTypeface in font.

        The drawing obeys the current transform matrix and clipping.

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

        @param count    number of glyphs to draw
        @param glyphs   the array of glyphIDs to draw
        @param xforms   where to draw and orient each glyph
        @param origin   the origin of all the positions
        @param font     typeface, text size and so, used to describe the text
        @param paint    blend, color, and so on, used to draw
    */
    void drawGlyphs(int count, const SkGlyphID glyphs[], const SkRSXform xforms[],
                    SkPoint origin, const SkFont& font, const SkPaint& paint);

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

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

        SkTextEncoding must be set to SkTextEncoding::kGlyphID.

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

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

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

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

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

        SkTextEncoding must be set to SkTextEncoding::kGlyphID.

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

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

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

        SkPicture records a series of draw commands for later playback.

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

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

        SkPicture records a series of draw commands for later playback.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        If atlas is nullptr, this draws nothing.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @return  true if clip is empty

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

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

        @return  true if clip is SkRect and not empty

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

    virtual void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint);

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

    virtual void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
                              const SkPaint*);
    virtual void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst,
                                  const SkSamplingOptions&, const SkPaint*, SrcRectConstraint);
    virtual void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect& dst,
                                     SkFilterMode, const SkPaint*);
    virtual void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect src[],
                              const SkColor[], int count, SkBlendMode, const SkSamplingOptions&,
                              const SkRect* cull, const SkPaint*);
    virtual void onDrawEdgeAAImageSet2(const ImageSetEntry imageSet[], int count,
                                       const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                       const SkSamplingOptions&, const SkPaint*,
                                       SrcRectConstraint);

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

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

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

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

    enum ClipEdgeStyle {
        kHard_ClipEdgeStyle,
        kSoft_ClipEdgeStyle
    };

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

    virtual void onDiscard();

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

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

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

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

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

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

    class MCRec;

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

    sk_sp<SkMarkerStack> fMarkerStack;

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

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

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

    int         fSaveCount;         // value returned by getSaveCount()

    std::unique_ptr<SkRasterHandleAllocator> fAllocator;

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

    SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();

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

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

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

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

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

    void resetForNextPicture(const SkIRect& bounds);

    // needs gettotalclip()
    friend class SkCanvasStateUtils;

    void init(sk_sp<SkBaseDevice>);

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

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

    void internalConcat44(const SkM44&);

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

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

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

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

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

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

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

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

    class AutoUpdateQRBounds;
    void validateClip() const;

    std::unique_ptr<SkGlyphRunBuilder> fScratchGlyphRunBuilder;

    using INHERITED = SkRefCnt;
};

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

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

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

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

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

private:
    SkCanvas*   fCanvas;
    int         fSaveCount;

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

#endif
