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