LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkCanvas.h (source / functions) Hit Total Coverage
Test: output.info Lines: 38 85 44.7 %
Date: 2017-07-14 16:53:18 Functions: 17 32 53.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13