Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkCanvas_DEFINED
      9 #define SkCanvas_DEFINED
     10 
     11 #include "SkBlendMode.h"
     12 #include "SkClipOp.h"
     13 #include "SkDeque.h"
     14 #include "SkPaint.h"
     15 #include "SkRasterHandleAllocator.h"
     16 #include "SkSurfaceProps.h"
     17 
     18 class GrContext;
     19 class GrRenderTargetContext;
     20 class SkBaseDevice;
     21 class SkBitmap;
     22 class SkClipStack;
     23 class SkData;
     24 class SkDraw;
     25 class SkDrawable;
     26 class SkDrawFilter;
     27 struct SkDrawShadowRec;
     28 class SkImage;
     29 class SkImageFilter;
     30 class SkLights;
     31 class SkMetaData;
     32 class SkPath;
     33 class SkPicture;
     34 class SkPixmap;
     35 class SkRasterClip;
     36 class SkRegion;
     37 class SkRRect;
     38 struct SkRSXform;
     39 class SkSurface;
     40 class SkSurface_Base;
     41 class SkTextBlob;
     42 class SkVertices;
     43 
     44 /** \class SkCanvas
     45 
     46     A Canvas encapsulates all of the state about drawing into a device (bitmap).
     47     This includes a reference to the device itself, and a stack of matrix/clip
     48     values. For any given draw call (e.g. drawRect), the geometry of the object
     49     being drawn is transformed by the concatenation of all the matrices in the
     50     stack. The transformed geometry is clipped by the intersection of all of
     51     the clips in the stack.
     52 
     53     While the Canvas holds the state of the drawing device, the state (style)
     54     of the object being drawn is held by the Paint, which is provided as a
     55     parameter to each of the draw() methods. The Paint holds attributes such as
     56     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
     57     etc.
     58 */
     59 class SK_API SkCanvas : SkNoncopyable {
     60     enum PrivateSaveLayerFlags {
     61         kDontClipToLayer_PrivateSaveLayerFlag   = 1U << 31,
     62     };
     63 
     64 public:
     65     /**
     66      *  Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
     67      *  specified pixels. To access the pixels after drawing to them, the caller should call
     68      *  flush() or call peekPixels(...).
     69      *
     70      *  On failure, return NULL. This can fail for several reasons:
     71      *  1. invalid ImageInfo (e.g. negative dimensions)
     72      *  2. unsupported ImageInfo for a canvas
     73      *      - kUnknown_SkColorType, kIndex_8_SkColorType
     74      *      - kUnknown_SkAlphaType
     75      *      - this list is not complete, so others may also be unsupported
     76      *
     77      *  Note: it is valid to request a supported ImageInfo, but with zero
     78      *  dimensions.
     79      */
     80     static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
     81                                                       size_t rowBytes);
     82 
     83     static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
     84                                                          size_t rowBytes) {
     85         return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
     86     }
     87 
     88     /**
     89      *  Creates an empty canvas with no backing device/pixels, and zero
     90      *  dimensions.
     91      */
     92     SkCanvas();
     93 
     94     /**
     95      *  Creates a canvas of the specified dimensions, but explicitly not backed
     96      *  by any device/pixels. Typically this use used by subclasses who handle
     97      *  the draw calls in some other way.
     98      */
     99     SkCanvas(int width, int height, const SkSurfaceProps* props = NULL);
    100 
    101     /** Construct a canvas with the specified device to draw into.
    102 
    103         @param device   Specifies a device for the canvas to draw into.
    104     */
    105     explicit SkCanvas(SkBaseDevice* device);
    106 
    107     /** Construct a canvas with the specified bitmap to draw into.
    108         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
    109                         structure are copied to the canvas.
    110     */
    111     explicit SkCanvas(const SkBitmap& bitmap);
    112 
    113 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    114     enum class ColorBehavior {
    115         kLegacy,
    116     };
    117 
    118     /**
    119      *  Android framework only constructor.
    120      *  Allows the creation of a legacy SkCanvas even though the |bitmap|
    121      *  and its pixel ref may have an SkColorSpace.
    122      */
    123     SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
    124 #endif
    125 
    126     /** Construct a canvas with the specified bitmap to draw into.
    127         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
    128                         structure are copied to the canvas.
    129         @param props    New canvas surface properties.
    130     */
    131     SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
    132 
    133     virtual ~SkCanvas();
    134 
    135     SkMetaData& getMetaData();
    136 
    137     /**
    138      *  Return ImageInfo for this canvas. If the canvas is not backed by pixels
    139      *  (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
    140      */
    141     SkImageInfo imageInfo() const;
    142 
    143     /**
    144      *  If the canvas is backed by pixels (cpu or gpu), this writes a copy of the SurfaceProps
    145      *  for the canvas to the location supplied by the caller, and returns true. Otherwise,
    146      *  return false and leave the supplied props unchanged.
    147      */
    148     bool getProps(SkSurfaceProps* props) const;
    149 
    150     ///////////////////////////////////////////////////////////////////////////
    151 
    152     /**
    153      *  Trigger the immediate execution of all pending draw operations. For the GPU
    154      *  backend this will resolve all rendering to the GPU surface backing the
    155      *  SkSurface that owns this canvas.
    156      */
    157     void flush();
    158 
    159     /**
    160      * Gets the size of the base or root layer in global canvas coordinates. The
    161      * origin of the base layer is always (0,0). The current drawable area may be
    162      * smaller (due to clipping or saveLayer).
    163      */
    164     virtual SkISize getBaseLayerSize() const;
    165 
    166     /**
    167      *  Create a new surface matching the specified info, one that attempts to
    168      *  be maximally compatible when used with this canvas. If there is no matching Surface type,
    169      *  NULL is returned.
    170      *
    171      *  If surfaceprops is specified, those are passed to the new surface, otherwise the new surface
    172      *  inherits the properties of the surface that owns this canvas. If this canvas has no parent
    173      *  surface, then the new surface is created with default properties.
    174      */
    175     sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);
    176 
    177     /**
    178      * Return the GPU context of the device that is associated with the canvas.
    179      * For a canvas with non-GPU device, NULL is returned.
    180      */
    181     virtual GrContext* getGrContext();
    182 
    183     ///////////////////////////////////////////////////////////////////////////
    184 
    185     /**
    186      *  If the canvas has writable pixels in its top layer (and is not recording to a picture
    187      *  or other non-raster target) and has direct access to its pixels (i.e. they are in
    188      *  local RAM) return the address of those pixels, and if not null,
    189      *  return the ImageInfo, rowBytes and origin. The returned address is only valid
    190      *  while the canvas object is in scope and unchanged. Any API calls made on
    191      *  canvas (or its parent surface if any) will invalidate the
    192      *  returned address (and associated information).
    193      *
    194      *  On failure, returns NULL and the info, rowBytes, and origin parameters are ignored.
    195      */
    196     void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
    197 
    198     SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
    199 
    200     /**
    201      *  If the canvas has readable pixels in its base layer (and is not recording to a picture
    202      *  or other non-raster target) and has direct access to its pixels (i.e. they are in
    203      *  local RAM) return true, and if not null, return in the pixmap parameter information about
    204      *  the pixels. The pixmap's pixel address is only valid
    205      *  while the canvas object is in scope and unchanged. Any API calls made on
    206      *  canvas (or its parent surface if any) will invalidate the pixel address
    207      *  (and associated information).
    208      *
    209      *  On failure, returns false and the pixmap parameter will be ignored.
    210      */
    211     bool peekPixels(SkPixmap* pixmap);
    212 
    213     /**
    214      *  Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
    215      *  converting them into the requested format (SkImageInfo). The base-layer pixels are read
    216      *  starting at the specified (srcX,srcY) location in the coordinate system of the base-layer.
    217      *
    218      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
    219      *
    220      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
    221      *
    222      *  srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
    223      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
    224      *  corresponding src pixels, performing any colortype/alphatype transformations needed
    225      *  (in the case where the src and dst have different colortypes or alphatypes).
    226      *
    227      *  This call can fail, returning false, for several reasons:
    228      *  - If srcR does not intersect the base-layer bounds.
    229      *  - If the requested colortype/alphatype cannot be converted from the base-layer's types.
    230      *  - If this canvas is not backed by pixels (e.g. picture or PDF)
    231      */
    232     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
    233                     int srcX, int srcY);
    234     bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);
    235     bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);
    236 
    237     /**
    238      *  This method affects the pixels in the base-layer, and operates in pixel coordinates,
    239      *  ignoring the matrix and clip.
    240      *
    241      *  The specified ImageInfo and (x,y) offset specifies a rectangle: target.
    242      *
    243      *      target.setXYWH(x, y, info.width(), info.height());
    244      *
    245      *  Target is intersected with the bounds of the base-layer. If this intersection is not empty,
    246      *  then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
    247      *  and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
    248      *  pixels, performing any colortype/alphatype transformations needed (in the case where the
    249      *  src and dst have different colortypes or alphatypes).
    250      *
    251      *  This call can fail, returning false, for several reasons:
    252      *  - If the src colortype/alphatype cannot be converted to the canvas' types
    253      *  - If this canvas is not backed by pixels (e.g. picture or PDF)
    254      */
    255     bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);
    256 
    257     /**
    258      *  Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
    259      *  is just wrapping a texture, returns false and does nothing.
    260      */
    261     bool writePixels(const SkBitmap& bitmap, int x, int y);
    262 
    263     ///////////////////////////////////////////////////////////////////////////
    264 
    265     /** This call saves the current matrix, clip, and drawFilter, and pushes a
    266         copy onto a private stack. Subsequent calls to translate, scale,
    267         rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
    268         operate on this copy.
    269         When the balancing call to restore() is made, the previous matrix, clip,
    270         and drawFilter are restored.
    271 
    272         @return The value to pass to restoreToCount() to balance this save()
    273     */
    274     int save();
    275 
    276     /** This behaves the same as save(), but in addition it allocates an
    277         offscreen bitmap. All drawing calls are directed there, and only when
    278         the balancing call to restore() is made is that offscreen transfered to
    279         the canvas (or the previous layer).
    280         @param bounds (may be null) This rect, if non-null, is used as a hint to
    281                       limit the size of the offscreen, and thus drawing may be
    282                       clipped to it, though that clipping is not guaranteed to
    283                       happen. If exact clipping is desired, use clipRect().
    284         @param paint (may be null) This is copied, and is applied to the
    285                      offscreen when restore() is called
    286         @return The value to pass to restoreToCount() to balance this save()
    287     */
    288     int saveLayer(const SkRect* bounds, const SkPaint* paint);
    289     int saveLayer(const SkRect& bounds, const SkPaint* paint) {
    290         return this->saveLayer(&bounds, paint);
    291     }
    292 
    293     /**
    294      *  Temporary name.
    295      *  Will allow any requests for LCD text to be respected, so the caller must be careful to
    296      *  only draw on top of opaque sections of the layer to get good results.
    297      */
    298     int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint);
    299 
    300     /** This behaves the same as save(), but in addition it allocates an
    301         offscreen bitmap. All drawing calls are directed there, and only when
    302         the balancing call to restore() is made is that offscreen transfered to
    303         the canvas (or the previous layer).
    304         @param bounds (may be null) This rect, if non-null, is used as a hint to
    305                       limit the size of the offscreen, and thus drawing may be
    306                       clipped to it, though that clipping is not guaranteed to
    307                       happen. If exact clipping is desired, use clipRect().
    308         @param alpha  This is applied to the offscreen when restore() is called.
    309         @return The value to pass to restoreToCount() to balance this save()
    310     */
    311     int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
    312 
    313     enum {
    314         kIsOpaque_SaveLayerFlag         = 1 << 0,
    315         kPreserveLCDText_SaveLayerFlag  = 1 << 1,
    316 
    317         /** initialize the new layer with the contents of the previous layer */
    318         kInitWithPrevious_SaveLayerFlag = 1 << 2,
    319 
    320 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
    321         kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
    322 #endif
    323     };
    324     typedef uint32_t SaveLayerFlags;
    325 
    326     struct SaveLayerRec {
    327         SaveLayerRec() {}
    328         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
    329             : fBounds(bounds)
    330             , fPaint(paint)
    331             , fSaveLayerFlags(saveLayerFlags)
    332         {}
    333         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
    334                      SaveLayerFlags saveLayerFlags)
    335             : fBounds(bounds)
    336             , fPaint(paint)
    337             , fBackdrop(backdrop)
    338             , fSaveLayerFlags(saveLayerFlags)
    339         {}
    340 
    341         // EXPERIMENTAL: not ready for general use.
    342         SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
    343                      const SkImage* clipMask, const SkMatrix* clipMatrix,
    344                      SaveLayerFlags saveLayerFlags)
    345             : fBounds(bounds)
    346             , fPaint(paint)
    347             , fBackdrop(backdrop)
    348             , fClipMask(clipMask)
    349             , fClipMatrix(clipMatrix)
    350             , fSaveLayerFlags(saveLayerFlags)
    351         {}
    352 
    353         const SkRect*           fBounds = nullptr;      // optional
    354         const SkPaint*          fPaint = nullptr;       // optional
    355         const SkImageFilter*    fBackdrop = nullptr;    // optional
    356         const SkImage*          fClipMask = nullptr;    // optional
    357         const SkMatrix*         fClipMatrix = nullptr;  // optional -- only used with fClipMask
    358         SaveLayerFlags          fSaveLayerFlags = 0;
    359     };
    360 
    361     int saveLayer(const SaveLayerRec& layerRec);
    362 
    363     /** This call balances a previous call to save(), and is used to remove all
    364         modifications to the matrix/clip/drawFilter state since the last save
    365         call.
    366         It is an error to call restore() more times than save() was called.
    367     */
    368     void restore();
    369 
    370     /** Returns the number of matrix/clip states on the SkCanvas' private stack.
    371         This will equal # save() calls - # restore() calls + 1. The save count on
    372         a new canvas is 1.
    373     */
    374     int getSaveCount() const;
    375 
    376     /** Efficient way to pop any calls to save() that happened after the save
    377         count reached saveCount. It is an error for saveCount to be greater than
    378         getSaveCount(). To pop all the way back to the initial matrix/clip context
    379         pass saveCount == 1.
    380         @param saveCount    The number of save() levels to restore from
    381     */
    382     void restoreToCount(int saveCount);
    383 
    384     /** Preconcat the current matrix with the specified translation
    385         @param dx   The distance to translate in X
    386         @param dy   The distance to translate in Y
    387     */
    388     void translate(SkScalar dx, SkScalar dy);
    389 
    390     /** Preconcat the current matrix with the specified scale.
    391         @param sx   The amount to scale in X
    392         @param sy   The amount to scale in Y
    393     */
    394     void scale(SkScalar sx, SkScalar sy);
    395 
    396     /** Preconcat the current matrix with the specified rotation about the origin.
    397         @param degrees  The amount to rotate, in degrees
    398     */
    399     void rotate(SkScalar degrees);
    400 
    401     /** Preconcat the current matrix with the specified rotation about a given point.
    402         @param degrees  The amount to rotate, in degrees
    403         @param px  The x coordinate of the point to rotate about.
    404         @param py  The y coordinate of the point to rotate about.
    405     */
    406     void rotate(SkScalar degrees, SkScalar px, SkScalar py);
    407 
    408     /** Preconcat the current matrix with the specified skew.
    409         @param sx   The amount to skew in X
    410         @param sy   The amount to skew in Y
    411     */
    412     void skew(SkScalar sx, SkScalar sy);
    413 
    414     /** Preconcat the current matrix with the specified matrix.
    415         @param matrix   The matrix to preconcatenate with the current matrix
    416     */
    417     void concat(const SkMatrix& matrix);
    418 
    419     /** Replace the current matrix with a copy of the specified matrix.
    420         @param matrix The matrix that will be copied into the current matrix.
    421     */
    422     void setMatrix(const SkMatrix& matrix);
    423 
    424     /** Helper for setMatrix(identity). Sets the current matrix to identity.
    425     */
    426     void resetMatrix();
    427 
    428     /**
    429      *  Modify the current clip with the specified rectangle.
    430      *  @param rect The rect to combine with the current clip
    431      *  @param op The region op to apply to the current clip
    432      *  @param doAntiAlias true if the clip should be antialiased
    433      */
    434     void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);
    435     void clipRect(const SkRect& rect, SkClipOp op) {
    436         this->clipRect(rect, op, false);
    437     }
    438     void clipRect(const SkRect& rect, bool doAntiAlias = false) {
    439         this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
    440     }
    441 
    442     /**
    443      * Sets the max clip rectangle, which can be set by clipRect, clipRRect and
    444      * clipPath and intersect the current clip with the specified rect.
    445      * The max clip affects only future ops (it is not retroactive).
    446      * We DON'T record the clip restriction in pictures.
    447      * This is private API to be used only by Android framework.
    448      * @param rect   The maximum allowed clip in device coordinates.
    449      *               Empty rect means max clip is not enforced.
    450      */
    451     void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
    452 
    453     /**
    454      *  Modify the current clip with the specified SkRRect.
    455      *  @param rrect The rrect to combine with the current clip
    456      *  @param op The region op to apply to the current clip
    457      *  @param doAntiAlias true if the clip should be antialiased
    458      */
    459     void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
    460     void clipRRect(const SkRRect& rrect, SkClipOp op) {
    461         this->clipRRect(rrect, op, false);
    462     }
    463     void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
    464         this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
    465     }
    466 
    467     /**
    468      *  Modify the current clip with the specified path.
    469      *  @param path The path to combine with the current clip
    470      *  @param op The region op to apply to the current clip
    471      *  @param doAntiAlias true if the clip should be antialiased
    472      */
    473     void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
    474     void clipPath(const SkPath& path, SkClipOp op) {
    475         this->clipPath(path, op, false);
    476     }
    477     void clipPath(const SkPath& path, bool doAntiAlias = false) {
    478         this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
    479     }
    480 
    481     /** EXPERIMENTAL -- only used for testing
    482         Set to simplify clip stack using path ops.
    483      */
    484     void setAllowSimplifyClip(bool allow) {
    485         fAllowSimplifyClip = allow;
    486     }
    487 
    488     /** Modify the current clip with the specified region. Note that unlike
    489         clipRect() and clipPath() which transform their arguments by the current
    490         matrix, clipRegion() assumes its argument is already in device
    491         coordinates, and so no transformation is performed.
    492         @param deviceRgn    The region to apply to the current clip
    493         @param op The region op to apply to the current clip
    494     */
    495     void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
    496 
    497     /** Return true if the specified rectangle, after being transformed by the
    498         current matrix, would lie completely outside of the current clip. Call
    499         this to check if an area you intend to draw into is clipped out (and
    500         therefore you can skip making the draw calls).
    501         @param rect the rect to compare with the current clip
    502         @return true if the rect (transformed by the canvas' matrix) does not
    503                      intersect with the canvas' clip
    504     */
    505     bool quickReject(const SkRect& rect) const;
    506 
    507     /** Return true if the specified path, after being transformed by the
    508         current matrix, would lie completely outside of the current clip. Call
    509         this to check if an area you intend to draw into is clipped out (and
    510         therefore you can skip making the draw calls). Note, for speed it may
    511         return false even if the path itself might not intersect the clip
    512         (i.e. the bounds of the path intersects, but the path does not).
    513         @param path The path to compare with the current clip
    514         @return true if the path (transformed by the canvas' matrix) does not
    515                      intersect with the canvas' clip
    516     */
    517     bool quickReject(const SkPath& path) const;
    518 
    519     /**
    520      *  Return the bounds of the current clip in local coordinates. If the clip is empty,
    521      *  return { 0, 0, 0, 0 }.
    522      */
    523     SkRect getLocalClipBounds() const { return this->onGetLocalClipBounds(); }
    524 
    525     /**
    526      *  Returns true if the clip bounds are non-empty.
    527      */
    528     bool getLocalClipBounds(SkRect* bounds) const {
    529         *bounds = this->onGetLocalClipBounds();
    530         return !bounds->isEmpty();
    531     }
    532 
    533     /**
    534      *  Return the bounds of the current clip in device coordinates. If the clip is empty,
    535      *  return { 0, 0, 0, 0 }.
    536      */
    537     SkIRect getDeviceClipBounds() const { return this->onGetDeviceClipBounds(); }
    538 
    539     /**
    540      *  Returns true if the clip bounds are non-empty.
    541      */
    542     bool getDeviceClipBounds(SkIRect* bounds) const {
    543         *bounds = this->onGetDeviceClipBounds();
    544         return !bounds->isEmpty();
    545     }
    546 
    547     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
    548         specified color and mode.
    549         @param color    the color to draw with
    550         @param mode the mode to apply the color in (defaults to SrcOver)
    551     */
    552     void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
    553 
    554     /**
    555      *  Helper method for drawing a color in SRC mode, completely replacing all the pixels
    556      *  in the current clip with this color.
    557      */
    558     void clear(SkColor color) {
    559         this->drawColor(color, SkBlendMode::kSrc);
    560     }
    561 
    562     /**
    563      * This makes the contents of the canvas undefined. Subsequent calls that
    564      * require reading the canvas contents will produce undefined results. Examples
    565      * include blending and readPixels. The actual implementation is backend-
    566      * dependent and one legal implementation is to do nothing. This method
    567      * ignores the current clip.
    568      *
    569      * This function should only be called if the caller intends to subsequently
    570      * draw to the canvas. The canvas may do real work at discard() time in order
    571      * to optimize performance on subsequent draws. Thus, if you call this and then
    572      * never draw to the canvas subsequently you may pay a perfomance penalty.
    573      */
    574     void discard() { this->onDiscard(); }
    575 
    576     /**
    577      *  Fill the entire canvas (restricted to the current clip) with the
    578      *  specified paint.
    579      *  @param paint    The paint used to fill the canvas
    580      */
    581     void drawPaint(const SkPaint& paint);
    582 
    583     enum PointMode {
    584         /** drawPoints draws each point separately */
    585         kPoints_PointMode,
    586         /** drawPoints draws each pair of points as a line segment */
    587         kLines_PointMode,
    588         /** drawPoints draws the array of points as a polygon */
    589         kPolygon_PointMode
    590     };
    591 
    592     /** Draw a series of points, interpreted based on the PointMode mode. For
    593         all modes, the count parameter is interpreted as the total number of
    594         points. For kLine mode, count/2 line segments are drawn.
    595         For kPoint mode, each point is drawn centered at its coordinate, and its
    596         size is specified by the paint's stroke-width. It draws as a square,
    597         unless the paint's cap-type is round, in which the points are drawn as
    598         circles.
    599         For kLine mode, each pair of points is drawn as a line segment,
    600         respecting the paint's settings for cap/join/width.
    601         For kPolygon mode, the entire array is drawn as a series of connected
    602         line segments.
    603         Note that, while similar, kLine and kPolygon modes draw slightly
    604         differently than the equivalent path built with a series of moveto,
    605         lineto calls, in that the path will draw all of its contours at once,
    606         with no interactions if contours intersect each other (think XOR
    607         xfermode). drawPoints always draws each element one at a time.
    608         @param mode     PointMode specifying how to draw the array of points.
    609         @param count    The number of points in the array
    610         @param pts      Array of points to draw
    611         @param paint    The paint used to draw the points
    612     */
    613     void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
    614 
    615     /** Helper method for drawing a single point. See drawPoints() for more details.
    616      */
    617     void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
    618     void drawPoint(SkPoint p, const SkPaint& paint) {
    619         this->drawPoint(p.x(), p.y(), paint);
    620     }
    621 
    622     /** Draw a line segment with the specified start and stop x,y coordinates,
    623         using the specified paint. NOTE: since a line is always "framed", the
    624         paint's Style is ignored.
    625         @param x0    The x-coordinate of the start point of the line
    626         @param y0    The y-coordinate of the start point of the line
    627         @param x1    The x-coordinate of the end point of the line
    628         @param y1    The y-coordinate of the end point of the line
    629         @param paint The paint used to draw the line
    630     */
    631     void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
    632     void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
    633         this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
    634     }
    635 
    636     /** Draw the specified rectangle using the specified paint. The rectangle
    637         will be filled or stroked based on the Style in the paint.
    638         @param rect     The rect to be drawn
    639         @param paint    The paint used to draw the rect
    640     */
    641     void drawRect(const SkRect& rect, const SkPaint& paint);
    642 
    643     /** Draw the specified rectangle using the specified paint. The rectangle
    644         will be filled or framed based on the Style in the paint.
    645         @param rect     The rect to be drawn
    646         @param paint    The paint used to draw the rect
    647     */
    648     void drawIRect(const SkIRect& rect, const SkPaint& paint) {
    649         SkRect r;
    650         r.set(rect);    // promotes the ints to scalars
    651         this->drawRect(r, paint);
    652     }
    653 
    654     /** Draw the outline of the specified region using the specified paint.
    655         @param region   The region to be drawn
    656         @param paint    The paint used to draw the region
    657     */
    658     void drawRegion(const SkRegion& region, const SkPaint& paint);
    659 
    660     /** Draw the specified oval using the specified paint. The oval will be
    661         filled or framed based on the Style in the paint.
    662         @param oval     The rectangle bounds of the oval to be drawn
    663         @param paint    The paint used to draw the oval
    664     */
    665     void drawOval(const SkRect& oval, const SkPaint& paint);
    666 
    667     /**
    668      *  Draw the specified RRect using the specified paint The rrect will be filled or stroked
    669      *  based on the Style in the paint.
    670      *
    671      *  @param rrect    The round-rect to draw
    672      *  @param paint    The paint used to draw the round-rect
    673      */
    674     void drawRRect(const SkRRect& rrect, const SkPaint& paint);
    675 
    676     /**
    677      *  Draw the annulus formed by the outer and inner rrects. The results
    678      *  are undefined if the outer does not contain the inner.
    679      */
    680     void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
    681 
    682     /** Draw the specified circle using the specified paint. If radius is <= 0,
    683         then nothing will be drawn. The circle will be filled
    684         or framed based on the Style in the paint.
    685         @param cx       The x-coordinate of the center of the cirle to be drawn
    686         @param cy       The y-coordinate of the center of the cirle to be drawn
    687         @param radius   The radius of the cirle to be drawn
    688         @param paint    The paint used to draw the circle
    689     */
    690     void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
    691     void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
    692         this->drawCircle(center.x(), center.y(), radius, paint);
    693     }
    694 
    695     /** Draw the specified arc, which will be scaled to fit inside the
    696         specified oval. Sweep angles are not treated as modulo 360 and thus can
    697         exceed a full sweep of the oval. Note that this differs slightly from
    698         SkPath::arcTo, which treats the sweep angle mod 360. If the oval is empty
    699         or the sweep angle is zero nothing is drawn. If useCenter is true the oval
    700         center is inserted into the implied path before the arc and the path is
    701         closed back to the, center forming a wedge. Otherwise, the implied path
    702         contains just the arc and is not closed.
    703         @param oval The bounds of oval used to define the shape of the arc.
    704         @param startAngle Starting angle (in degrees) where the arc begins
    705         @param sweepAngle Sweep angle (in degrees) measured clockwise.
    706         @param useCenter true means include the center of the oval.
    707         @param paint    The paint used to draw the arc
    708     */
    709     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
    710                  bool useCenter, const SkPaint& paint);
    711 
    712     /** Draw the specified round-rect using the specified paint. The round-rect
    713         will be filled or framed based on the Style in the paint.
    714         @param rect     The rectangular bounds of the roundRect to be drawn
    715         @param rx       The x-radius of the oval used to round the corners
    716         @param ry       The y-radius of the oval used to round the corners
    717         @param paint    The paint used to draw the roundRect
    718     */
    719     void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
    720 
    721     /** Draw the specified path using the specified paint. The path will be
    722         filled or framed based on the Style in the paint.
    723         @param path     The path to be drawn
    724         @param paint    The paint used to draw the path
    725     */
    726     void drawPath(const SkPath& path, const SkPaint& paint);
    727 
    728     /** Draw the specified image, with its top/left corner at (x,y), using the
    729         specified paint, transformed by the current matrix.
    730 
    731         @param image    The image to be drawn
    732         @param left     The position of the left side of the image being drawn
    733         @param top      The position of the top side of the image being drawn
    734         @param paint    The paint used to draw the image, or NULL
    735      */
    736     void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL);
    737     void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
    738                    const SkPaint* paint = NULL) {
    739         this->drawImage(image.get(), left, top, paint);
    740     }
    741 
    742     /**
    743      *  Controls the behavior at the edge of the src-rect, when specified in drawImageRect,
    744      *  trading off speed for exactness.
    745      *
    746      *  When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around
    747      *  the pixels in the image. If there is a src-rect specified, it is intended to restrict the
    748      *  pixels that will be read. However, for performance reasons, some implementations may slow
    749      *  down if they cannot read 1-pixel past the src-rect boundary at times.
    750      *
    751      *  This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable.
    752      *  If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect
    753      *  must be strictly respected, the caller should pass kStrict.
    754      */
    755     enum SrcRectConstraint {
    756         /**
    757          *  If kStrict is specified, the implementation must respect the src-rect
    758          *  (if specified) strictly, and will never sample outside of those bounds during sampling
    759          *  even when filtering. This may be slower than kFast.
    760          */
    761         kStrict_SrcRectConstraint,
    762 
    763         /**
    764          *  If kFast is specified, the implementation may sample outside of the src-rect
    765          *  (if specified) by half the width of filter. This allows greater flexibility
    766          *  to the implementation and can make the draw much faster.
    767          */
    768         kFast_SrcRectConstraint,
    769     };
    770 
    771     /** Draw the specified image, scaling and translating so that it fills the specified
    772      *  dst rect. If the src rect is non-null, only that subset of the image is transformed
    773      *  and drawn.
    774      *
    775      *  @param image      The image to be drawn
    776      *  @param src        Optional: specify the subset of the image to be drawn
    777      *  @param dst        The destination rectangle where the scaled/translated
    778      *                    image will be drawn
    779      *  @param paint      The paint used to draw the image, or NULL
    780      *  @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
    781      */
    782     void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
    783                        const SkPaint* paint,
    784                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    785     // variant that takes src SkIRect
    786     void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
    787                        const SkPaint* paint,
    788                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    789     // variant that assumes src == image-bounds
    790     void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
    791                        SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    792 
    793     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
    794                        const SkPaint* paint,
    795                        SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
    796         this->drawImageRect(image.get(), src, dst, paint, constraint);
    797     }
    798     void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
    799                        const SkPaint* paint,
    800                        SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
    801         this->drawImageRect(image.get(), isrc, dst, paint, constraint);
    802     }
    803     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
    804                        SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
    805         this->drawImageRect(image.get(), dst, paint, constraint);
    806     }
    807 
    808     /**
    809      *  Draw the image stretched differentially to fit into dst.
    810      *  center is a rect within the image, and logically divides the image
    811      *  into 9 sections (3x3). For example, if the middle pixel of a [5x5]
    812      *  image is the "center", then the center-rect should be [2, 2, 3, 3].
    813      *
    814      *  If the dst is >= the image size, then...
    815      *  - The 4 corners are not stretched at all.
    816      *  - The sides are stretched in only one axis.
    817      *  - The center is stretched in both axes.
    818      * Else, for each axis where dst < image,
    819      *  - The corners shrink proportionally
    820      *  - The sides (along the shrink axis) and center are not drawn
    821      */
    822     void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
    823                        const SkPaint* paint = nullptr);
    824     void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
    825                        const SkPaint* paint = nullptr) {
    826         this->drawImageNine(image.get(), center, dst, paint);
    827     }
    828 
    829     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
    830         specified paint, transformed by the current matrix. Note: if the paint
    831         contains a maskfilter that generates a mask which extends beyond the
    832         bitmap's original width/height, then the bitmap will be drawn as if it
    833         were in a Shader with CLAMP mode. Thus the color outside of the original
    834         width/height will be the edge color replicated.
    835 
    836         If a shader is present on the paint it will be ignored, except in the
    837         case where the bitmap is kAlpha_8_SkColorType. In that case, the color is
    838         generated by the shader.
    839 
    840         @param bitmap   The bitmap to be drawn
    841         @param left     The position of the left side of the bitmap being drawn
    842         @param top      The position of the top side of the bitmap being drawn
    843         @param paint    The paint used to draw the bitmap, or NULL
    844     */
    845     void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
    846                     const SkPaint* paint = NULL);
    847 
    848     /** Draw the specified bitmap, scaling and translating so that it fills the specified
    849      *  dst rect. If the src rect is non-null, only that subset of the bitmap is transformed
    850      *  and drawn.
    851      *
    852      *  @param bitmap     The bitmap to be drawn
    853      *  @param src        Optional: specify the subset of the bitmap to be drawn
    854      *  @param dst        The destination rectangle where the scaled/translated
    855      *                    bitmap will be drawn
    856      *  @param paint      The paint used to draw the bitmap, or NULL
    857      *  @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect.
    858      */
    859     void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
    860                         const SkPaint* paint,
    861                         SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    862     // variant where src is SkIRect
    863     void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
    864                         const SkPaint* paint,
    865                         SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    866     void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
    867                         SrcRectConstraint constraint = kStrict_SrcRectConstraint);
    868 
    869     /**
    870      *  Draw the bitmap stretched or shrunk differentially to fit into dst.
    871      *  center is a rect within the bitmap, and logically divides the bitmap
    872      *  into 9 sections (3x3). For example, if the middle pixel of a [5x5]
    873      *  bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
    874      *
    875      *  If the dst is >= the bitmap size, then...
    876      *  - The 4 corners are not stretched at all.
    877      *  - The sides are stretched in only one axis.
    878      *  - The center is stretched in both axes.
    879      * Else, for each axis where dst < bitmap,
    880      *  - The corners shrink proportionally
    881      *  - The sides (along the shrink axis) and center are not drawn
    882      */
    883     void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
    884                         const SkPaint* paint = NULL);
    885 
    886     /**
    887      *  Specifies coordinates to divide a bitmap into (xCount*yCount) rects.
    888      *
    889      *  If the lattice divs or bounds are invalid, the entire lattice
    890      *  struct will be ignored on the draw call.
    891      */
    892     struct Lattice {
    893         enum Flags : uint8_t {
    894             // If set, indicates that we should not draw corresponding rect.
    895             kTransparent_Flags = 1 << 0,
    896         };
    897 
    898         // An array of x-coordinates that divide the bitmap vertically.
    899         // These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight).
    900         // Does not have ownership.
    901         const int*     fXDivs;
    902 
    903         // An array of y-coordinates that divide the bitmap horizontally.
    904         // These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom).
    905         // Does not have ownership.
    906         const int*     fYDivs;
    907 
    908         // If non-null, the length of this array must be equal to
    909         // (fXCount + 1) * (fYCount + 1).  Note that we allow the first rect
    910         // in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft).
    911         // In this case, the caller still must specify a flag (as a placeholder)
    912         // for these empty rects.
    913         // The flags correspond to the rects in the lattice, first moving
    914         // left to right and then top to bottom.
    915         const Flags*   fFlags;
    916 
    917         // The number of fXDivs.
    918         int            fXCount;
    919 
    920         // The number of fYDivs.
    921         int            fYCount;
    922 
    923         // The bound to draw from.  Must be contained by the src that is being drawn,
    924         // non-empty, and non-inverted.
    925         // If nullptr, the bounds are the entire src.
    926         const SkIRect* fBounds;
    927     };
    928 
    929     /**
    930      *  Draw the bitmap stretched or shrunk differentially to fit into dst.
    931      *
    932      *  Moving horizontally across the bitmap, alternating rects will be "scalable"
    933      *  (in the x-dimension) to fit into dst or must be left "fixed".  The first rect
    934      *  is treated as "fixed", but it's possible to specify an empty first rect by
    935      *  making lattice.fXDivs[0] = 0.
    936      *
    937      *  The scale factor for all "scalable" rects will be the same, and may be greater
    938      *  than or less than 1 (meaning we can stretch or shrink).  If the number of
    939      *  "fixed" pixels is greater than the width of the dst, we will collapse all of
    940      *  the "scalable" regions and appropriately downscale the "fixed" regions.
    941      *
    942      *  The same interpretation also applies to the y-dimension.
    943      */
    944     void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
    945                            const SkPaint* paint = nullptr);
    946     void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
    947                           const SkPaint* paint = nullptr);
    948 
    949     /** Draw the text, with origin at (x,y), using the specified paint.
    950         The origin is interpreted based on the Align setting in the paint.
    951         @param text The text to be drawn
    952         @param byteLength   The number of bytes to read from the text parameter
    953         @param x        The x-coordinate of the origin of the text being drawn
    954         @param y        The y-coordinate of the origin of the text being drawn
    955         @param paint    The paint used for the text (e.g. color, size, style)
    956     */
    957     void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    958                   const SkPaint& paint);
    959 
    960     /** Draw null-terminated UTF-8 string, with origin at (x,y), using the specified paint.
    961         The origin is interpreted based on the Align setting in the paint.
    962         @param string   The null-terminated string to be drawn
    963         @param x        The x-coordinate of the origin of the string being drawn
    964         @param y        The y-coordinate of the origin of the string being drawn
    965         @param paint    The paint used for the string (e.g. color, size, style)
    966     */
    967     void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint) {
    968         if (!string) {
    969             return;
    970         }
    971         this->drawText(string, strlen(string), x, y, paint);
    972     }
    973 
    974     /** Draw string, with origin at (x,y), using the specified paint.
    975         The origin is interpreted based on the Align setting in the paint.
    976         @param string   The string to be drawn
    977         @param x        The x-coordinate of the origin of the string being drawn
    978         @param y        The y-coordinate of the origin of the string being drawn
    979         @param paint    The paint used for the string (e.g. color, size, style)
    980     */
    981     void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint);
    982 
    983     /** Draw the text, with each character/glyph origin specified by the pos[]
    984         array. The origin is interpreted by the Align setting in the paint.
    985         @param text The text to be drawn
    986         @param byteLength   The number of bytes to read from the text parameter
    987         @param pos      Array of positions, used to position each character
    988         @param paint    The paint used for the text (e.g. color, size, style)
    989         */
    990     void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
    991                      const SkPaint& paint);
    992 
    993     /** Draw the text, with each character/glyph origin specified by the x
    994         coordinate taken from the xpos[] array, and the y from the constY param.
    995         The origin is interpreted by the Align setting in the paint.
    996         @param text The text to be drawn
    997         @param byteLength   The number of bytes to read from the text parameter
    998         @param xpos     Array of x-positions, used to position each character
    999         @param constY   The shared Y coordinate for all of the positions
   1000         @param paint    The paint used for the text (e.g. color, size, style)
   1001         */
   1002     void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
   1003                       const SkPaint& paint);
   1004 
   1005     /** Draw the text, with origin at (x,y), using the specified paint, along
   1006         the specified path. The paint's Align setting determins where along the
   1007         path to start the text.
   1008         @param text The text to be drawn
   1009         @param byteLength   The number of bytes to read from the text parameter
   1010         @param path         The path the text should follow for its baseline
   1011         @param hOffset      The distance along the path to add to the text's
   1012                             starting position
   1013         @param vOffset      The distance above(-) or below(+) the path to
   1014                             position the text
   1015         @param paint        The paint used for the text
   1016     */
   1017     void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
   1018                           SkScalar vOffset, const SkPaint& paint);
   1019 
   1020     /** Draw the text, with origin at (x,y), using the specified paint, along
   1021         the specified path. The paint's Align setting determins where along the
   1022         path to start the text.
   1023         @param text The text to be drawn
   1024         @param byteLength   The number of bytes to read from the text parameter
   1025         @param path         The path the text should follow for its baseline
   1026         @param matrix       (may be null) Applied to the text before it is
   1027                             mapped onto the path
   1028         @param paint        The paint used for the text
   1029         */
   1030     void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
   1031                         const SkMatrix* matrix, const SkPaint& paint);
   1032 
   1033     /**
   1034      *  Draw the text with each character/glyph individually transformed by its xform.
   1035      *  If cullRect is not null, it is a conservative bounds of what will be drawn
   1036      *  taking into account the xforms and the paint, and will be used to accelerate culling.
   1037      */
   1038     void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
   1039                          const SkRect* cullRect, const SkPaint& paint);
   1040 
   1041     /** Draw the text blob, offset by (x,y), using the specified paint.
   1042         @param blob     The text blob to be drawn
   1043         @param x        The x-offset of the text being drawn
   1044         @param y        The y-offset of the text being drawn
   1045         @param paint    The paint used for the text (e.g. color, size, style)
   1046     */
   1047     void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
   1048     void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
   1049         this->drawTextBlob(blob.get(), x, y, paint);
   1050     }
   1051 
   1052     /** Draw the picture into this canvas. This method effective brackets the
   1053         playback of the picture's draw calls with save/restore, so the state
   1054         of this canvas will be unchanged after this call.
   1055         @param picture The recorded drawing commands to playback into this
   1056                        canvas.
   1057     */
   1058     void drawPicture(const SkPicture* picture) {
   1059         this->drawPicture(picture, NULL, NULL);
   1060     }
   1061     void drawPicture(const sk_sp<SkPicture>& picture) {
   1062         this->drawPicture(picture.get());
   1063     }
   1064 
   1065     /**
   1066      *  Draw the picture into this canvas.
   1067      *
   1068      *  If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
   1069      *  logically equivalent to
   1070      *      save/concat/drawPicture/restore
   1071      *
   1072      *  If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
   1073      *  alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
   1074      *  This is logically equivalent to
   1075      *      saveLayer(paint)/drawPicture/restore
   1076      */
   1077     void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
   1078     void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint) {
   1079         this->drawPicture(picture.get(), matrix, paint);
   1080     }
   1081 
   1082     /** Draw vertices from an immutable SkVertices object.
   1083 
   1084         @param vertices The mesh to draw.
   1085         @param mode Used if both texs and colors are present and paint has a
   1086                     shader. In this case the colors are combined with the texture
   1087                     using mode, before being drawn using the paint.
   1088         @param paint Specifies the shader/texture if present.
   1089      */
   1090     void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
   1091     void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
   1092 
   1093     /**
   1094      Draw a cubic coons patch
   1095 
   1096      @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
   1097                     starting at the top left corner.
   1098      @param colors specifies the colors for the corners which will be bilerp across the patch,
   1099                     their order is clockwise starting at the top left corner.
   1100      @param texCoords specifies the texture coordinates that will be bilerp across the patch,
   1101                     their order is the same as the colors.
   1102      @param mode specifies how are the colors and the textures combined if both of them are
   1103                     present.
   1104      @param paint Specifies the shader/texture if present.
   1105      */
   1106     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
   1107                    const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
   1108     void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
   1109                    const SkPoint texCoords[4], const SkPaint& paint) {
   1110         this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
   1111     }
   1112 
   1113     /**
   1114      *  Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the
   1115      *  coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle
   1116      *  into a quad.
   1117      *
   1118      *      xform maps [0, 0, tex.width, tex.height] -> quad
   1119      *
   1120      *  The color array is optional. When specified, each color modulates the pixels in its
   1121      *  corresponding quad (via the specified SkBlendMode).
   1122      *
   1123      *  The cullRect is optional. When specified, it must be a conservative bounds of all of the
   1124      *  resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
   1125      *  intersect the current clip.
   1126      *
   1127      *  The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
   1128      *  and blendmode are used to affect each of the quads.
   1129      */
   1130     void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
   1131                    const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
   1132                    const SkPaint* paint);
   1133     void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
   1134                    const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
   1135                    const SkPaint* paint) {
   1136         this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
   1137     }
   1138     void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
   1139                    const SkRect* cullRect, const SkPaint* paint) {
   1140         this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
   1141     }
   1142     void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
   1143                    int count, const SkRect* cullRect, const SkPaint* paint) {
   1144         this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
   1145                         cullRect, paint);
   1146     }
   1147 
   1148     /**
   1149      *  Draw the contents of this drawable into the canvas. If the canvas is async
   1150      *  (e.g. it is recording into a picture) then the drawable will be referenced instead,
   1151      *  to have its draw() method called when the picture is finalized.
   1152      *
   1153      *  If the intent is to force the contents of the drawable into this canvas immediately,
   1154      *  then drawable->draw(canvas) may be called.
   1155      */
   1156     void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = NULL);
   1157     void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
   1158 
   1159     /**
   1160      *  Send an "annotation" to the canvas. The annotation is a key/value pair, where the key is
   1161      *  a null-terminated utf8 string, and the value is a blob of data stored in an SkData
   1162      *  (which may be null). The annotation is associated with the specified rectangle.
   1163      *
   1164      *  The caller still retains its ownership of the data (if any).
   1165      *
   1166      *  Note: on may canvas types, this information is ignored, but some canvases (e.g. recording
   1167      *  a picture or drawing to a PDF document) will pass on this information.
   1168      */
   1169     void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
   1170     void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
   1171         this->drawAnnotation(rect, key, value.get());
   1172     }
   1173 
   1174     //////////////////////////////////////////////////////////////////////////
   1175 
   1176 #ifdef SK_SUPPORT_LEGACY_DRAWFILTER
   1177     /** Get the current filter object. The filter's reference count is not
   1178         affected. The filter is saved/restored, just like the matrix and clip.
   1179         @return the canvas' filter (or NULL).
   1180     */
   1181     SkDrawFilter* getDrawFilter() const;
   1182 
   1183     /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
   1184         As a convenience, the parameter is returned. If an existing filter
   1185         exists, its refcnt is decrement. If the new filter is not null, its
   1186         refcnt is incremented. The filter is saved/restored, just like the
   1187         matrix and clip.
   1188         @param filter the new filter (or NULL)
   1189         @return the new filter
   1190     */
   1191     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
   1192 #endif
   1193     //////////////////////////////////////////////////////////////////////////
   1194 
   1195     /**
   1196      *  Return true if the current clip is empty (i.e. nothing will draw).
   1197      *  Note: this is not always a free call, so it should not be used
   1198      *  more often than necessary. However, once the canvas has computed this
   1199      *  result, subsequent calls will be cheap (until the clip state changes,
   1200      *  which can happen on any clip..() or restore() call.
   1201      */
   1202     virtual bool isClipEmpty() const;
   1203 
   1204     /**
   1205      *  Returns true if the current clip is just a (non-empty) rectangle.
   1206      *  Returns false if the clip is empty, or if it is complex.
   1207      */
   1208     virtual bool isClipRect() const;
   1209 
   1210     /** Return the current matrix on the canvas.
   1211         This does not account for the translate in any of the devices.
   1212         @return The current matrix on the canvas.
   1213     */
   1214     const SkMatrix& getTotalMatrix() const;
   1215 
   1216     ///////////////////////////////////////////////////////////////////////////
   1217 
   1218     // don't call
   1219     GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
   1220 
   1221     // don't call
   1222     static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
   1223     static bool Internal_Private_GetIgnoreSaveLayerBounds();
   1224     static void Internal_Private_SetTreatSpriteAsBitmap(bool);
   1225     static bool Internal_Private_GetTreatSpriteAsBitmap();
   1226 
   1227     // TEMP helpers until we switch virtual over to const& for src-rect
   1228     void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
   1229                               const SkPaint* paint,
   1230                               SrcRectConstraint constraint = kStrict_SrcRectConstraint);
   1231     void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
   1232                                const SkPaint* paint,
   1233                                SrcRectConstraint constraint = kStrict_SrcRectConstraint);
   1234 
   1235     /**
   1236      *  Returns the global clip as a region. If the clip contains AA, then only the bounds
   1237      *  of the clip may be returned.
   1238      */
   1239     void temporary_internal_getRgnClip(SkRegion* region);
   1240 
   1241     void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
   1242 
   1243 protected:
   1244     // default impl defers to getDevice()->newSurface(info)
   1245     virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
   1246 
   1247     // default impl defers to its device
   1248     virtual bool onPeekPixels(SkPixmap* pixmap);
   1249     virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
   1250     virtual SkImageInfo onImageInfo() const;
   1251     virtual bool onGetProps(SkSurfaceProps* props) const;
   1252     virtual void onFlush();
   1253 
   1254     // Subclass save/restore notifiers.
   1255     // Overriders should call the corresponding INHERITED method up the inheritance chain.
   1256     // getSaveLayerStrategy()'s return value may suppress full layer allocation.
   1257     enum SaveLayerStrategy {
   1258         kFullLayer_SaveLayerStrategy,
   1259         kNoLayer_SaveLayerStrategy,
   1260     };
   1261 
   1262     virtual void willSave() {}
   1263     // Overriders should call the corresponding INHERITED method up the inheritance chain.
   1264     virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
   1265         return kFullLayer_SaveLayerStrategy;
   1266     }
   1267     virtual void willRestore() {}
   1268     virtual void didRestore() {}
   1269     virtual void didConcat(const SkMatrix& ) {}
   1270     virtual void didSetMatrix(const SkMatrix& ) {}
   1271     virtual void didTranslate(SkScalar dx, SkScalar dy) {
   1272         this->didConcat(SkMatrix::MakeTrans(dx, dy));
   1273     }
   1274 
   1275     virtual SkRect onGetLocalClipBounds() const;
   1276     virtual SkIRect onGetDeviceClipBounds() const;
   1277 
   1278 
   1279     virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
   1280     virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
   1281 
   1282     virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
   1283                             SkScalar y, const SkPaint& paint);
   1284 
   1285     virtual void onDrawPosText(const void* text, size_t byteLength,
   1286                                const SkPoint pos[], const SkPaint& paint);
   1287 
   1288     virtual void onDrawPosTextH(const void* text, size_t byteLength,
   1289                                 const SkScalar xpos[], SkScalar constY,
   1290                                 const SkPaint& paint);
   1291 
   1292     virtual void onDrawTextOnPath(const void* text, size_t byteLength,
   1293                                   const SkPath& path, const SkMatrix* matrix,
   1294                                   const SkPaint& paint);
   1295     virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
   1296                                    const SkRect* cullRect, const SkPaint& paint);
   1297 
   1298     virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
   1299                                 const SkPaint& paint);
   1300 
   1301     virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
   1302                            const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
   1303 
   1304     virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
   1305 
   1306     virtual void onDrawPaint(const SkPaint& paint);
   1307     virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
   1308     virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
   1309     virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
   1310     virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
   1311                            bool useCenter, const SkPaint& paint);
   1312     virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
   1313     virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
   1314                               const SkPaint& paint);
   1315     virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
   1316                                       const SkPaint& paint);
   1317     virtual void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
   1318                              const SkColor colors[], int count, SkBlendMode mode,
   1319                              const SkRect* cull, const SkPaint* paint);
   1320     virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
   1321     virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
   1322     virtual void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
   1323                                  const SkPaint* paint, SrcRectConstraint constraint);
   1324     virtual void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
   1325                                  const SkPaint* paint);
   1326     virtual void onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
   1327                                     const SkPaint* paint);
   1328 
   1329     virtual void onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
   1330                               const SkPaint* paint);
   1331     virtual void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
   1332                                   const SkPaint* paint, SrcRectConstraint constraint);
   1333     virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
   1334                                   const SkPaint* paint);
   1335     virtual void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
   1336                                      const SkRect& dst, const SkPaint* paint);
   1337     virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
   1338 
   1339     enum ClipEdgeStyle {
   1340         kHard_ClipEdgeStyle,
   1341         kSoft_ClipEdgeStyle
   1342     };
   1343 
   1344     virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
   1345     virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
   1346     virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
   1347     virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
   1348 
   1349     virtual void onDiscard();
   1350 
   1351     virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
   1352                                const SkPaint* paint);
   1353 
   1354     // Clip rectangle bounds. Called internally by saveLayer.
   1355     // returns false if the entire rectangle is entirely clipped out
   1356     // If non-NULL, The imageFilter parameter will be used to expand the clip
   1357     // and offscreen bounds for any margin required by the filter DAG.
   1358     bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
   1359                         const SkImageFilter* imageFilter = NULL);
   1360 
   1361 private:
   1362     /** After calling saveLayer(), there can be any number of devices that make
   1363      up the top-most drawing area. LayerIter can be used to iterate through
   1364      those devices. Note that the iterator is only valid until the next API
   1365      call made on the canvas. Ownership of all pointers in the iterator stays
   1366      with the canvas, so none of them should be modified or deleted.
   1367      */
   1368     class LayerIter /*: SkNoncopyable*/ {
   1369     public:
   1370         /** Initialize iterator with canvas, and set values for 1st device */
   1371         LayerIter(SkCanvas*);
   1372         ~LayerIter();
   1373 
   1374         /** Return true if the iterator is done */
   1375         bool done() const { return fDone; }
   1376         /** Cycle to the next device */
   1377         void next();
   1378 
   1379         // These reflect the current device in the iterator
   1380 
   1381         SkBaseDevice*   device() const;
   1382         const SkMatrix& matrix() const;
   1383         void clip(SkRegion*) const;
   1384         const SkPaint&  paint() const;
   1385         int             x() const;
   1386         int             y() const;
   1387 
   1388     private:
   1389         // used to embed the SkDrawIter object directly in our instance, w/o
   1390         // having to expose that class def to the public. There is an assert
   1391         // in our constructor to ensure that fStorage is large enough
   1392         // (though needs to be a compile-time-assert!). We use intptr_t to work
   1393         // safely with 32 and 64 bit machines (to ensure the storage is enough)
   1394         intptr_t          fStorage[32];
   1395         class SkDrawIter* fImpl;    // this points at fStorage
   1396         SkPaint           fDefaultPaint;
   1397         bool              fDone;
   1398     };
   1399 
   1400     static bool BoundsAffectsClip(SaveLayerFlags);
   1401     static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
   1402 
   1403     static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
   1404                                      SkBaseDevice* dst, const SkIPoint& dstOrigin,
   1405                                      const SkMatrix& ctm);
   1406 
   1407     enum ShaderOverrideOpacity {
   1408         kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
   1409         kOpaque_ShaderOverrideOpacity,      //!< the overriding shader is opaque
   1410         kNotOpaque_ShaderOverrideOpacity,   //!< the overriding shader may not be opaque
   1411     };
   1412 
   1413     // notify our surface (if we have one) that we are about to draw, so it
   1414     // can perform copy-on-write or invalidate any cached images
   1415     void predrawNotify(bool willOverwritesEntireSurface = false);
   1416     void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
   1417     void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
   1418         this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
   1419                                                                 : kNotOpaque_ShaderOverrideOpacity);
   1420     }
   1421 
   1422     SkBaseDevice* getDevice() const;
   1423     SkBaseDevice* getTopDevice() const;
   1424 
   1425     class MCRec;
   1426 
   1427     SkDeque     fMCStack;
   1428     // points to top of stack
   1429     MCRec*      fMCRec;
   1430     // the first N recs that can fit here mean we won't call malloc
   1431     enum {
   1432         kMCRecSize      = 128,  // most recent measurement
   1433         kMCRecCount     = 32,   // common depth for save/restores
   1434         kDeviceCMSize   = 224,  // most recent measurement
   1435     };
   1436     intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
   1437     intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
   1438 
   1439     const SkSurfaceProps fProps;
   1440 
   1441     int         fSaveCount;         // value returned by getSaveCount()
   1442 
   1443     SkMetaData* fMetaData;
   1444     std::unique_ptr<SkRasterHandleAllocator> fAllocator;
   1445 
   1446     SkSurface_Base*  fSurfaceBase;
   1447     SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
   1448     void setSurfaceBase(SkSurface_Base* sb) {
   1449         fSurfaceBase = sb;
   1450     }
   1451     friend class SkSurface_Base;
   1452     friend class SkSurface_Gpu;
   1453 
   1454     SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
   1455 
   1456     void doSave();
   1457     void checkForDeferredSave();
   1458     void internalSetMatrix(const SkMatrix&);
   1459 
   1460     friend class SkDrawIter;        // needs setupDrawForLayerDevice()
   1461     friend class AutoDrawLooper;
   1462     friend class SkDebugCanvas;     // needs experimental fAllowSimplifyClip
   1463     friend class SkSurface_Raster;  // needs getDevice()
   1464     friend class SkNoDrawCanvas;    // InitFlags
   1465     friend class SkPictureImageFilter;  // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
   1466     friend class SkPictureRecord;   // predrawNotify (why does it need it? <reed>)
   1467     friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
   1468     friend class SkOverdrawCanvas;
   1469     friend class SkRasterHandleAllocator;
   1470 
   1471     enum InitFlags {
   1472         kDefault_InitFlags                  = 0,
   1473         kConservativeRasterClip_InitFlag    = 1 << 0,
   1474     };
   1475     SkCanvas(const SkIRect& bounds, InitFlags);
   1476     SkCanvas(SkBaseDevice* device, InitFlags);
   1477     SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
   1478              SkRasterHandleAllocator::Handle);
   1479 
   1480     void resetForNextPicture(const SkIRect& bounds);
   1481 
   1482     // needs gettotalclip()
   1483     friend class SkCanvasStateUtils;
   1484 
   1485     // call this each time we attach ourselves to a device
   1486     //  - constructor
   1487     //  - internalSaveLayer
   1488     void setupDevice(SkBaseDevice*);
   1489 
   1490     SkBaseDevice* init(SkBaseDevice*, InitFlags);
   1491 
   1492     /**
   1493      * Gets the bounds of the top level layer in global canvas coordinates. We don't want this
   1494      * to be public because it exposes decisions about layer sizes that are internal to the canvas.
   1495      */
   1496     SkIRect getTopLayerBounds() const;
   1497 
   1498     void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
   1499                                 const SkRect& dst, const SkPaint* paint,
   1500                                 SrcRectConstraint);
   1501     void internalDrawPaint(const SkPaint& paint);
   1502     void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
   1503     void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, SkImage* clipImage,
   1504                             const SkMatrix& clipMatrix);
   1505 
   1506     // shared by save() and saveLayer()
   1507     void internalSave();
   1508     void internalRestore();
   1509 
   1510     /*
   1511      *  Returns true if drawing the specified rect (or all if it is null) with the specified
   1512      *  paint (or default if null) would overwrite the entire root device of the canvas
   1513      *  (i.e. the canvas' surface if it had one).
   1514      */
   1515     bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
   1516 
   1517     /**
   1518      *  Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
   1519      */
   1520     bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
   1521 
   1522     /**
   1523      *  Returns true if the clip (for any active layer) contains antialiasing.
   1524      *  If the clip is empty, this will return false.
   1525      */
   1526     bool androidFramework_isClipAA() const;
   1527 
   1528     /**
   1529      *  Keep track of the device clip bounds and if the matrix is scale-translate.  This allows
   1530      *  us to do a fast quick reject in the common case.
   1531      */
   1532     bool   fIsScaleTranslate;
   1533     SkRect fDeviceClipBounds;
   1534 
   1535     bool fAllowSoftClip;
   1536     bool fAllowSimplifyClip;
   1537 
   1538     class AutoValidateClip : ::SkNoncopyable {
   1539     public:
   1540         explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
   1541             fCanvas->validateClip();
   1542         }
   1543         ~AutoValidateClip() { fCanvas->validateClip(); }
   1544 
   1545     private:
   1546         const SkCanvas* fCanvas;
   1547     };
   1548 
   1549 #ifdef SK_DEBUG
   1550     void validateClip() const;
   1551 #else
   1552     void validateClip() const {}
   1553 #endif
   1554 
   1555     typedef SkRefCnt INHERITED;
   1556 };
   1557 
   1558 /** Stack helper class to automatically call restoreToCount() on the canvas
   1559     when this object goes out of scope. Use this to guarantee that the canvas
   1560     is restored to a known state.
   1561 */
   1562 class SkAutoCanvasRestore : SkNoncopyable {
   1563 public:
   1564     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
   1565         if (fCanvas) {
   1566             fSaveCount = canvas->getSaveCount();
   1567             if (doSave) {
   1568                 canvas->save();
   1569             }
   1570         }
   1571     }
   1572     ~SkAutoCanvasRestore() {
   1573         if (fCanvas) {
   1574             fCanvas->restoreToCount(fSaveCount);
   1575         }
   1576     }
   1577 
   1578     /**
   1579      *  Perform the restore now, instead of waiting for the destructor. Will
   1580      *  only do this once.
   1581      */
   1582     void restore() {
   1583         if (fCanvas) {
   1584             fCanvas->restoreToCount(fSaveCount);
   1585             fCanvas = NULL;
   1586         }
   1587     }
   1588 
   1589 private:
   1590     SkCanvas*   fCanvas;
   1591     int         fSaveCount;
   1592 };
   1593 #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
   1594 
   1595 #endif
   1596