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