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