• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #ifndef SkCanvas_DEFINED
11 #define SkCanvas_DEFINED
12 
13 #include "SkTypes.h"
14 #include "SkBitmap.h"
15 #include "SkDeque.h"
16 #include "SkClipStack.h"
17 #include "SkPaint.h"
18 #include "SkRefCnt.h"
19 #include "SkPath.h"
20 #include "SkRegion.h"
21 #include "SkScalarCompare.h"
22 #include "SkXfermode.h"
23 
24 class SkBounder;
25 class SkDevice;
26 class SkDraw;
27 class SkDrawFilter;
28 class SkPicture;
29 
30 /** \class SkCanvas
31 
32     A Canvas encapsulates all of the state about drawing into a device (bitmap).
33     This includes a reference to the device itself, and a stack of matrix/clip
34     values. For any given draw call (e.g. drawRect), the geometry of the object
35     being drawn is transformed by the concatenation of all the matrices in the
36     stack. The transformed geometry is clipped by the intersection of all of
37     the clips in the stack.
38 
39     While the Canvas holds the state of the drawing device, the state (style)
40     of the object being drawn is held by the Paint, which is provided as a
41     parameter to each of the draw() methods. The Paint holds attributes such as
42     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
43     etc.
44 */
45 class SK_API SkCanvas : public SkRefCnt {
46 public:
47     SkCanvas();
48 
49     /** Construct a canvas with the specified device to draw into.
50 
51         @param device   Specifies a device for the canvas to draw into.
52     */
53     explicit SkCanvas(SkDevice* device);
54 
55     /** Deprecated - Construct a canvas with the specified bitmap to draw into.
56         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
57                         structure are copied to the canvas.
58     */
59     explicit SkCanvas(const SkBitmap& bitmap);
60     virtual ~SkCanvas();
61 
62     ///////////////////////////////////////////////////////////////////////////
63 
64     /**
65      *  Trigger the immediate execution of all pending draw operations.
66      */
67     void flush();
68 
69     /**
70      *  Return the width/height of the underlying device. The current drawable
71      *  area may be small (due to clipping or saveLayer). For a canvas with
72      *  no device, 0,0 will be returned.
73      */
74     SkISize getDeviceSize() const;
75 
76     /** Return the canvas' device object, which may be null. The device holds
77         the bitmap of the pixels that the canvas draws into. The reference count
78         of the returned device is not changed by this call.
79     */
80     SkDevice* getDevice() const;
81 
82     /** Specify a device for this canvas to draw into. If it is not null, its
83         reference count is incremented. If the canvas was already holding a
84         device, its reference count is decremented. The new device is returned.
85     */
86     virtual SkDevice* setDevice(SkDevice* device);
87 
88     /**
89      *  saveLayer() can create another device (which is later drawn onto
90      *  the previous device). getTopDevice() returns the top-most device current
91      *  installed. Note that this can change on other calls like save/restore,
92      *  so do not access this device after subsequent canvas calls.
93      *  The reference count of the device is not changed.
94      */
95     SkDevice* getTopDevice() const;
96 
97     /**
98      *  Create a new raster device and make it current. This also returns
99      *  the new device.
100      */
101     SkDevice* setBitmapDevice(const SkBitmap& bitmap);
102 
103     /**
104      *  Shortcut for getDevice()->createCompatibleDevice(...).
105      *  If getDevice() == NULL, this method does nothing, and returns NULL.
106      */
107     SkDevice* createCompatibleDevice(SkBitmap::Config config,
108                                     int width, int height,
109                                     bool isOpaque);
110 
111     ///////////////////////////////////////////////////////////////////////////
112 
113     /**
114      * This enum can be used with read/writePixels to perform a pixel ops to or
115      * from an 8888 config other than Skia's native config (SkPMColor). There
116      * are three byte orders supported: native, BGRA, and RGBA. Each has a
117      * premultiplied and unpremultiplied variant.
118      *
119      * Components of a 8888 pixel can be packed/unpacked from a 32bit word using
120      * either byte offsets or shift values. Byte offsets are endian-invariant
121      * while shifts are not. BGRA and RGBA configs are defined by byte
122      * orderings. The native config is defined by shift values (SK_A32_SHIFT,
123      * ..., SK_B32_SHIFT).
124      */
125     enum Config8888 {
126         /**
127          * Skia's native order specified by:
128          *      SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
129          *
130          * kNative_Premul_Config8888 is equivalent to SkPMColor
131          * kNative_Unpremul_Config8888 has the same component order as SkPMColor
132          * but is not premultiplied.
133          */
134         kNative_Premul_Config8888,
135         kNative_Unpremul_Config8888,
136         /**
137          * low byte to high byte: B, G, R, A.
138          */
139         kBGRA_Premul_Config8888,
140         kBGRA_Unpremul_Config8888,
141         /**
142          * low byte to high byte: R, G, B, A.
143          */
144         kRGBA_Premul_Config8888,
145         kRGBA_Unpremul_Config8888,
146     };
147 
148     /**
149      *  On success (returns true), copy the canvas pixels into the bitmap.
150      *  On failure, the bitmap parameter is left unchanged and false is
151      *  returned.
152      *
153      *  The canvas' pixels are converted to the bitmap's config. The only
154      *  supported config is kARGB_8888_Config, though this is likely to be
155      *  relaxed in  the future. The meaning of config kARGB_8888_Config is
156      *  modified by the enum param config8888. The default value interprets
157      *  kARGB_8888_Config as SkPMColor
158      *
159      *  If the bitmap has pixels already allocated, the canvas pixels will be
160      *  written there. If not, bitmap->allocPixels() will be called
161      *  automatically. If the bitmap is backed by a texture readPixels will
162      *  fail.
163      *
164      *  The actual pixels written is the intersection of the canvas' bounds, and
165      *  the rectangle formed by the bitmap's width,height and the specified x,y.
166      *  If bitmap pixels extend outside of that intersection, they will not be
167      *  modified.
168      *
169      *  Other failure conditions:
170      *    * If the canvas is backed by a non-raster device (e.g. PDF) then
171      *       readPixels will fail.
172      *    * If bitmap is texture-backed then readPixels will fail. (This may be
173      *       relaxed in the future.)
174      *
175      *  Example that reads the entire canvas into a bitmap using the native
176      *  SkPMColor:
177      *    SkISize size = canvas->getDeviceSize();
178      *    bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
179      *                                                   size.fHeight);
180      *    if (canvas->readPixels(bitmap, 0, 0)) {
181      *       // use the pixels
182      *    }
183      */
184     bool readPixels(SkBitmap* bitmap,
185                     int x, int y,
186                     Config8888 config8888 = kNative_Premul_Config8888);
187 
188     /**
189      * DEPRECATED: This will be removed as soon as webkit is no longer relying
190      * on it. The bitmap is resized to the intersection of srcRect and the
191      * canvas bounds. New pixels are always allocated on success. Bitmap is
192      * unmodified on failure.
193      */
194     bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
195 
196     /**
197      *  Similar to draw sprite, this method will copy the pixels in bitmap onto
198      *  the canvas, with the top/left corner specified by (x, y). The canvas'
199      *  pixel values are completely replaced: there is no blending.
200      *
201      *  Currently if bitmap is backed by a texture this is a no-op. This may be
202      *  relaxed in the future.
203      *
204      *  If the bitmap has config kARGB_8888_Config then the config8888 param
205      *  will determines how the pixel valuess are intepreted. If the bitmap is
206      *  not kARGB_8888_Config then this parameter is ignored.
207      *
208      *  Note: If you are recording drawing commands on this canvas to
209      *  SkPicture, writePixels() is ignored!
210      */
211     void writePixels(const SkBitmap& bitmap,
212                      int x, int y,
213                      Config8888 config8888 = kNative_Premul_Config8888);
214 
215     ///////////////////////////////////////////////////////////////////////////
216 
217     enum SaveFlags {
218         /** save the matrix state, restoring it on restore() */
219         kMatrix_SaveFlag            = 0x01,
220         /** save the clip state, restoring it on restore() */
221         kClip_SaveFlag              = 0x02,
222         /** the layer needs to support per-pixel alpha */
223         kHasAlphaLayer_SaveFlag     = 0x04,
224         /** the layer needs to support 8-bits per color component */
225         kFullColorLayer_SaveFlag    = 0x08,
226         /** the layer should clip against the bounds argument */
227         kClipToLayer_SaveFlag       = 0x10,
228 
229         // helper masks for common choices
230         kMatrixClip_SaveFlag        = 0x03,
231         kARGB_NoClipLayer_SaveFlag  = 0x0F,
232         kARGB_ClipLayer_SaveFlag    = 0x1F
233     };
234 
235     /** This call saves the current matrix, clip, and drawFilter, and pushes a
236         copy onto a private stack. Subsequent calls to translate, scale,
237         rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
238         operate on this copy.
239         When the balancing call to restore() is made, the previous matrix, clip,
240         and drawFilter are restored.
241         @return The value to pass to restoreToCount() to balance this save()
242     */
243     virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
244 
245     /** This behaves the same as save(), but in addition it allocates an
246         offscreen bitmap. All drawing calls are directed there, and only when
247         the balancing call to restore() is made is that offscreen transfered to
248         the canvas (or the previous layer).
249         @param bounds (may be null) This rect, if non-null, is used as a hint to
250                       limit the size of the offscreen, and thus drawing may be
251                       clipped to it, though that clipping is not guaranteed to
252                       happen. If exact clipping is desired, use clipRect().
253         @param paint (may be null) This is copied, and is applied to the
254                      offscreen when restore() is called
255         @param flags  LayerFlags
256         @return The value to pass to restoreToCount() to balance this save()
257     */
258     virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
259                           SaveFlags flags = kARGB_ClipLayer_SaveFlag);
260 
261     /** This behaves the same as save(), but in addition it allocates an
262         offscreen bitmap. All drawing calls are directed there, and only when
263         the balancing call to restore() is made is that offscreen transfered to
264         the canvas (or the previous layer).
265         @param bounds (may be null) This rect, if non-null, is used as a hint to
266                       limit the size of the offscreen, and thus drawing may be
267                       clipped to it, though that clipping is not guaranteed to
268                       happen. If exact clipping is desired, use clipRect().
269         @param alpha  This is applied to the offscreen when restore() is called.
270         @param flags  LayerFlags
271         @return The value to pass to restoreToCount() to balance this save()
272     */
273     int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
274                        SaveFlags flags = kARGB_ClipLayer_SaveFlag);
275 
276     /** This call balances a previous call to save(), and is used to remove all
277         modifications to the matrix/clip/drawFilter state since the last save
278         call.
279         It is an error to call restore() more times than save() was called.
280     */
281     virtual void restore();
282 
283     /** Returns the number of matrix/clip states on the SkCanvas' private stack.
284         This will equal # save() calls - # restore() calls.
285     */
286     int getSaveCount() const;
287 
288     /** Efficient way to pop any calls to save() that happened after the save
289         count reached saveCount. It is an error for saveCount to be less than
290         getSaveCount()
291         @param saveCount    The number of save() levels to restore from
292     */
293     void restoreToCount(int saveCount);
294 
295     /** Returns true if drawing is currently going to a layer (from saveLayer)
296      *  rather than to the root device.
297      */
298     virtual bool isDrawingToLayer() const;
299 
300     /** Preconcat the current matrix with the specified translation
301         @param dx   The distance to translate in X
302         @param dy   The distance to translate in Y
303         returns true if the operation succeeded (e.g. did not overflow)
304     */
305     virtual bool translate(SkScalar dx, SkScalar dy);
306 
307     /** Preconcat the current matrix with the specified scale.
308         @param sx   The amount to scale in X
309         @param sy   The amount to scale in Y
310         returns true if the operation succeeded (e.g. did not overflow)
311     */
312     virtual bool scale(SkScalar sx, SkScalar sy);
313 
314     /** Preconcat the current matrix with the specified rotation.
315         @param degrees  The amount to rotate, in degrees
316         returns true if the operation succeeded (e.g. did not overflow)
317     */
318     virtual bool rotate(SkScalar degrees);
319 
320     /** Preconcat the current matrix with the specified skew.
321         @param sx   The amount to skew in X
322         @param sy   The amount to skew in Y
323         returns true if the operation succeeded (e.g. did not overflow)
324     */
325     virtual bool skew(SkScalar sx, SkScalar sy);
326 
327     /** Preconcat the current matrix with the specified matrix.
328         @param matrix   The matrix to preconcatenate with the current matrix
329         @return true if the operation succeeded (e.g. did not overflow)
330     */
331     virtual bool concat(const SkMatrix& matrix);
332 
333     /** Replace the current matrix with a copy of the specified matrix.
334         @param matrix The matrix that will be copied into the current matrix.
335     */
336     virtual void setMatrix(const SkMatrix& matrix);
337 
338     /** Helper for setMatrix(identity). Sets the current matrix to identity.
339     */
340     void resetMatrix();
341 
342     /** Modify the current clip with the specified rectangle.
343         @param rect The rect to intersect with the current clip
344         @param op The region op to apply to the current clip
345         @return true if the canvas' clip is non-empty
346     */
347     virtual bool clipRect(const SkRect& rect,
348                           SkRegion::Op op = SkRegion::kIntersect_Op,
349                           bool doAntiAlias = false);
350 
351     /** Modify the current clip with the specified path.
352         @param path The path to apply to the current clip
353         @param op The region op to apply to the current clip
354         @return true if the canvas' new clip is non-empty
355     */
356     virtual bool clipPath(const SkPath& path,
357                           SkRegion::Op op = SkRegion::kIntersect_Op,
358                           bool doAntiAlias = false);
359 
360     /** Modify the current clip with the specified region. Note that unlike
361         clipRect() and clipPath() which transform their arguments by the current
362         matrix, clipRegion() assumes its argument is already in device
363         coordinates, and so no transformation is performed.
364         @param deviceRgn    The region to apply to the current clip
365         @param op The region op to apply to the current clip
366         @return true if the canvas' new clip is non-empty
367     */
368     virtual bool clipRegion(const SkRegion& deviceRgn,
369                             SkRegion::Op op = SkRegion::kIntersect_Op);
370 
371     /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
372         specified region. This does not intersect or in any other way account
373         for the existing clip region.
374         @param deviceRgn The region to copy into the current clip.
375         @return true if the new clip region is non-empty
376     */
setClipRegion(const SkRegion & deviceRgn)377     bool setClipRegion(const SkRegion& deviceRgn) {
378         return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
379     }
380 
381     /** Enum describing how to treat edges when performing quick-reject tests
382         of a geometry against the current clip. Treating them as antialiased
383         (kAA_EdgeType) will take into account the extra pixels that may be drawn
384         if the edge does not lie exactly on a device pixel boundary (after being
385         transformed by the current matrix).
386     */
387     enum EdgeType {
388         /** Treat the edges as B&W (not antialiased) for the purposes of testing
389             against the current clip
390         */
391         kBW_EdgeType,
392         /** Treat the edges as antialiased for the purposes of testing
393             against the current clip
394         */
395         kAA_EdgeType
396     };
397 
398     /** Return true if the specified rectangle, after being transformed by the
399         current matrix, would lie completely outside of the current clip. Call
400         this to check if an area you intend to draw into is clipped out (and
401         therefore you can skip making the draw calls).
402         @param rect the rect to compare with the current clip
403         @param et  specifies how to treat the edges (see EdgeType)
404         @return true if the rect (transformed by the canvas' matrix) does not
405                      intersect with the canvas' clip
406     */
407     bool quickReject(const SkRect& rect, EdgeType et) const;
408 
409     /** Return true if the specified path, after being transformed by the
410         current matrix, would lie completely outside of the current clip. Call
411         this to check if an area you intend to draw into is clipped out (and
412         therefore you can skip making the draw calls). Note, for speed it may
413         return false even if the path itself might not intersect the clip
414         (i.e. the bounds of the path intersects, but the path does not).
415         @param path The path to compare with the current clip
416         @param et  specifies how to treat the edges (see EdgeType)
417         @return true if the path (transformed by the canvas' matrix) does not
418                      intersect with the canvas' clip
419     */
420     bool quickReject(const SkPath& path, EdgeType et) const;
421 
422     /** Return true if the horizontal band specified by top and bottom is
423         completely clipped out. This is a conservative calculation, meaning
424         that it is possible that if the method returns false, the band may still
425         in fact be clipped out, but the converse is not true. If this method
426         returns true, then the band is guaranteed to be clipped out.
427         @param top  The top of the horizontal band to compare with the clip
428         @param bottom The bottom of the horizontal and to compare with the clip
429         @return true if the horizontal band is completely clipped out (i.e. does
430                      not intersect the current clip)
431     */
quickRejectY(SkScalar top,SkScalar bottom,EdgeType et)432     bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
433         SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
434         const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et);
435         // In the case where the clip is empty and we are provided with a
436         // negative top and positive bottom parameter then this test will return
437         // false even though it will be clipped. We have chosen to exclude that
438         // check as it is rare and would result double the comparisons.
439         return SkScalarToCompareType(top) >= clipR.fBottom
440             || SkScalarToCompareType(bottom) <= clipR.fTop;
441     }
442 
443     /** Return the bounds of the current clip (in local coordinates) in the
444         bounds parameter, and return true if it is non-empty. This can be useful
445         in a way similar to quickReject, in that it tells you that drawing
446         outside of these bounds will be clipped out.
447     */
448     bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
449 
450     /** Return the bounds of the current clip, in device coordinates; returns
451         true if non-empty. Maybe faster than getting the clip explicitly and
452         then taking its bounds.
453     */
454     bool getClipDeviceBounds(SkIRect* bounds) const;
455 
456 
457     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
458         specified ARGB color, using the specified mode.
459         @param a    the alpha component (0..255) of the color to fill the canvas
460         @param r    the red component (0..255) of the color to fill the canvas
461         @param g    the green component (0..255) of the color to fill the canvas
462         @param b    the blue component (0..255) of the color to fill the canvas
463         @param mode the mode to apply the color in (defaults to SrcOver)
464     */
465     void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
466                   SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
467 
468     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
469         specified color and mode.
470         @param color    the color to draw with
471         @param mode the mode to apply the color in (defaults to SrcOver)
472     */
473     void drawColor(SkColor color,
474                    SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
475 
476     /**
477      *  This erases the entire drawing surface to the specified color,
478      *  irrespective of the clip. It does not blend with the previous pixels,
479      *  but always overwrites them.
480      *
481      *  It is roughly equivalent to the following:
482      *      canvas.save();
483      *      canvas.clipRect(hugeRect, kReplace_Op);
484      *      paint.setColor(color);
485      *      paint.setXfermodeMode(kSrc_Mode);
486      *      canvas.drawPaint(paint);
487      *      canvas.restore();
488      *  though it is almost always much more efficient.
489      */
490     virtual void clear(SkColor);
491 
492     /**
493      *  Fill the entire canvas' bitmap (restricted to the current clip) with the
494      *  specified paint.
495      *  @param paint    The paint used to fill the canvas
496      */
497     virtual void drawPaint(const SkPaint& paint);
498 
499     enum PointMode {
500         /** drawPoints draws each point separately */
501         kPoints_PointMode,
502         /** drawPoints draws each pair of points as a line segment */
503         kLines_PointMode,
504         /** drawPoints draws the array of points as a polygon */
505         kPolygon_PointMode
506     };
507 
508     /** Draw a series of points, interpreted based on the PointMode mode. For
509         all modes, the count parameter is interpreted as the total number of
510         points. For kLine mode, count/2 line segments are drawn.
511         For kPoint mode, each point is drawn centered at its coordinate, and its
512         size is specified by the paint's stroke-width. It draws as a square,
513         unless the paint's cap-type is round, in which the points are drawn as
514         circles.
515         For kLine mode, each pair of points is drawn as a line segment,
516         respecting the paint's settings for cap/join/width.
517         For kPolygon mode, the entire array is drawn as a series of connected
518         line segments.
519         Note that, while similar, kLine and kPolygon modes draw slightly
520         differently than the equivalent path built with a series of moveto,
521         lineto calls, in that the path will draw all of its contours at once,
522         with no interactions if contours intersect each other (think XOR
523         xfermode). drawPoints always draws each element one at a time.
524         @param mode     PointMode specifying how to draw the array of points.
525         @param count    The number of points in the array
526         @param pts      Array of points to draw
527         @param paint    The paint used to draw the points
528     */
529     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
530                             const SkPaint& paint);
531 
532     /** Helper method for drawing a single point. See drawPoints() for a more
533         details.
534     */
535     void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
536 
537     /** Draws a single pixel in the specified color.
538         @param x        The X coordinate of which pixel to draw
539         @param y        The Y coordiante of which pixel to draw
540         @param color    The color to draw
541     */
542     void drawPoint(SkScalar x, SkScalar y, SkColor color);
543 
544     /** Draw a line segment with the specified start and stop x,y coordinates,
545         using the specified paint. NOTE: since a line is always "framed", the
546         paint's Style is ignored.
547         @param x0    The x-coordinate of the start point of the line
548         @param y0    The y-coordinate of the start point of the line
549         @param x1    The x-coordinate of the end point of the line
550         @param y1    The y-coordinate of the end point of the line
551         @param paint The paint used to draw the line
552     */
553     void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
554                   const SkPaint& paint);
555 
556     /** Draw the specified rectangle using the specified paint. The rectangle
557         will be filled or stroked based on the Style in the paint.
558         @param rect     The rect to be drawn
559         @param paint    The paint used to draw the rect
560     */
561     virtual void drawRect(const SkRect& rect, const SkPaint& paint);
562 
563     /** Draw the specified rectangle using the specified paint. The rectangle
564         will be filled or framed based on the Style in the paint.
565         @param rect     The rect to be drawn
566         @param paint    The paint used to draw the rect
567     */
drawIRect(const SkIRect & rect,const SkPaint & paint)568     void drawIRect(const SkIRect& rect, const SkPaint& paint)
569     {
570         SkRect r;
571         r.set(rect);    // promotes the ints to scalars
572         this->drawRect(r, paint);
573     }
574 
575     /** Draw the specified rectangle using the specified paint. The rectangle
576         will be filled or framed based on the Style in the paint.
577         @param left     The left side of the rectangle to be drawn
578         @param top      The top side of the rectangle to be drawn
579         @param right    The right side of the rectangle to be drawn
580         @param bottom   The bottom side of the rectangle to be drawn
581         @param paint    The paint used to draw the rect
582     */
583     void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
584                         SkScalar bottom, const SkPaint& paint);
585 
586     /** Draw the specified oval using the specified paint. The oval will be
587         filled or framed based on the Style in the paint.
588         @param oval     The rectangle bounds of the oval to be drawn
589         @param paint    The paint used to draw the oval
590     */
591     void drawOval(const SkRect& oval, const SkPaint&);
592 
593     /** Draw the specified circle using the specified paint. If radius is <= 0,
594         then nothing will be drawn. The circle will be filled
595         or framed based on the Style in the paint.
596         @param cx       The x-coordinate of the center of the cirle to be drawn
597         @param cy       The y-coordinate of the center of the cirle to be drawn
598         @param radius   The radius of the cirle to be drawn
599         @param paint    The paint used to draw the circle
600     */
601     void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
602                     const SkPaint& paint);
603 
604     /** Draw the specified arc, which will be scaled to fit inside the
605         specified oval. If the sweep angle is >= 360, then the oval is drawn
606         completely. Note that this differs slightly from SkPath::arcTo, which
607         treats the sweep angle mod 360.
608         @param oval The bounds of oval used to define the shape of the arc
609         @param startAngle Starting angle (in degrees) where the arc begins
610         @param sweepAngle Sweep angle (in degrees) measured clockwise
611         @param useCenter true means include the center of the oval. For filling
612                          this will draw a wedge. False means just use the arc.
613         @param paint    The paint used to draw the arc
614     */
615     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
616                  bool useCenter, const SkPaint& paint);
617 
618     /** Draw the specified round-rect using the specified paint. The round-rect
619         will be filled or framed based on the Style in the paint.
620         @param rect     The rectangular bounds of the roundRect to be drawn
621         @param rx       The x-radius of the oval used to round the corners
622         @param ry       The y-radius of the oval used to round the corners
623         @param paint    The paint used to draw the roundRect
624     */
625     void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
626                        const SkPaint& paint);
627 
628     /** Draw the specified path using the specified paint. The path will be
629         filled or framed based on the Style in the paint.
630         @param path     The path to be drawn
631         @param paint    The paint used to draw the path
632     */
633     virtual void drawPath(const SkPath& path, const SkPaint& paint);
634 
635     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
636         specified paint, transformed by the current matrix. Note: if the paint
637         contains a maskfilter that generates a mask which extends beyond the
638         bitmap's original width/height, then the bitmap will be drawn as if it
639         were in a Shader with CLAMP mode. Thus the color outside of the original
640         width/height will be the edge color replicated.
641         @param bitmap   The bitmap to be drawn
642         @param left     The position of the left side of the bitmap being drawn
643         @param top      The position of the top side of the bitmap being drawn
644         @param paint    The paint used to draw the bitmap, or NULL
645     */
646     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
647                             const SkPaint* paint = NULL);
648 
649     /** Draw the specified bitmap, with the specified matrix applied (before the
650         canvas' matrix is applied).
651         @param bitmap   The bitmap to be drawn
652         @param src      Optional: specify the subset of the bitmap to be drawn
653         @param dst      The destination rectangle where the scaled/translated
654                         image will be drawn
655         @param paint    The paint used to draw the bitmap, or NULL
656     */
657     virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
658                                 const SkRect& dst, const SkPaint* paint = NULL);
659 
660     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
661                                   const SkPaint* paint = NULL);
662 
663     /**
664      *  Draw the bitmap stretched differentially to fit into dst.
665      *  center is a rect within the bitmap, and logically divides the bitmap
666      *  into 9 sections (3x3). For example, if the middle pixel of a [5x5]
667      *  bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
668      *
669      *  If the dst is >= the bitmap size, then...
670      *  - The 4 corners are not stretch at all.
671      *  - The sides are stretch in only one axis.
672      *  - The center is stretch in both axes.
673      * Else, for each axis where dst < bitmap,
674      *  - The corners shrink proportionally
675      *  - The sides (along the shrink axis) and center are not drawn
676      */
677     virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
678                                 const SkRect& dst, const SkPaint* paint = NULL);
679 
680     /** Draw the specified bitmap, with its top/left corner at (x,y),
681         NOT transformed by the current matrix. Note: if the paint
682         contains a maskfilter that generates a mask which extends beyond the
683         bitmap's original width/height, then the bitmap will be drawn as if it
684         were in a Shader with CLAMP mode. Thus the color outside of the original
685         width/height will be the edge color replicated.
686         @param bitmap   The bitmap to be drawn
687         @param left     The position of the left side of the bitmap being drawn
688         @param top      The position of the top side of the bitmap being drawn
689         @param paint    The paint used to draw the bitmap, or NULL
690     */
691     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
692                             const SkPaint* paint = NULL);
693 
694     /** Draw the text, with origin at (x,y), using the specified paint.
695         The origin is interpreted based on the Align setting in the paint.
696         @param text The text to be drawn
697         @param byteLength   The number of bytes to read from the text parameter
698         @param x        The x-coordinate of the origin of the text being drawn
699         @param y        The y-coordinate of the origin of the text being drawn
700         @param paint    The paint used for the text (e.g. color, size, style)
701     */
702     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
703                           SkScalar y, const SkPaint& paint);
704 
705     /** Draw the text, with each character/glyph origin specified by the pos[]
706         array. The origin is interpreted by the Align setting in the paint.
707         @param text The text to be drawn
708         @param byteLength   The number of bytes to read from the text parameter
709         @param pos      Array of positions, used to position each character
710         @param paint    The paint used for the text (e.g. color, size, style)
711         */
712     virtual void drawPosText(const void* text, size_t byteLength,
713                              const SkPoint pos[], const SkPaint& paint);
714 
715     /** Draw the text, with each character/glyph origin specified by the x
716         coordinate taken from the xpos[] array, and the y from the constY param.
717         The origin is interpreted by the Align setting in the paint.
718         @param text The text to be drawn
719         @param byteLength   The number of bytes to read from the text parameter
720         @param xpos     Array of x-positions, used to position each character
721         @param constY   The shared Y coordinate for all of the positions
722         @param paint    The paint used for the text (e.g. color, size, style)
723         */
724     virtual void drawPosTextH(const void* text, size_t byteLength,
725                               const SkScalar xpos[], SkScalar constY,
726                               const SkPaint& paint);
727 
728     /** Draw the text, with origin at (x,y), using the specified paint, along
729         the specified path. The paint's Align setting determins where along the
730         path to start the text.
731         @param text The text to be drawn
732         @param byteLength   The number of bytes to read from the text parameter
733         @param path         The path the text should follow for its baseline
734         @param hOffset      The distance along the path to add to the text's
735                             starting position
736         @param vOffset      The distance above(-) or below(+) the path to
737                             position the text
738         @param paint        The paint used for the text
739     */
740     void drawTextOnPathHV(const void* text, size_t byteLength,
741                           const SkPath& path, SkScalar hOffset,
742                           SkScalar vOffset, const SkPaint& paint);
743 
744     /** Draw the text, with origin at (x,y), using the specified paint, along
745         the specified path. The paint's Align setting determins where along the
746         path to start the text.
747         @param text The text to be drawn
748         @param byteLength   The number of bytes to read from the text parameter
749         @param path         The path the text should follow for its baseline
750         @param matrix       (may be null) Applied to the text before it is
751                             mapped onto the path
752         @param paint        The paint used for the text
753         */
754     virtual void drawTextOnPath(const void* text, size_t byteLength,
755                                 const SkPath& path, const SkMatrix* matrix,
756                                 const SkPaint& paint);
757 
758 #ifdef SK_BUILD_FOR_ANDROID
759     /** Draw the text on path, with each character/glyph origin specified by the pos[]
760         array. The origin is interpreted by the Align setting in the paint.
761         @param text The text to be drawn
762         @param byteLength   The number of bytes to read from the text parameter
763         @param pos      Array of positions, used to position each character
764         @param paint    The paint used for the text (e.g. color, size, style)
765         @param path The path to draw on
766         @param matrix The canvas matrix
767         */
768     void drawPosTextOnPath(const void* text, size_t byteLength,
769                            const SkPoint pos[], const SkPaint& paint,
770                            const SkPath& path, const SkMatrix* matrix);
771 #endif
772 
773     /** Draw the picture into this canvas. This method effective brackets the
774         playback of the picture's draw calls with save/restore, so the state
775         of this canvas will be unchanged after this call. This contrasts with
776         the more immediate method SkPicture::draw(), which does not bracket
777         the canvas with save/restore, thus the canvas may be left in a changed
778         state after the call.
779         @param picture The recorded drawing commands to playback into this
780                        canvas.
781     */
782     virtual void drawPicture(SkPicture& picture);
783 
784     enum VertexMode {
785         kTriangles_VertexMode,
786         kTriangleStrip_VertexMode,
787         kTriangleFan_VertexMode
788     };
789 
790     /** Draw the array of vertices, interpreted as triangles (based on mode).
791         @param vmode How to interpret the array of vertices
792         @param vertexCount The number of points in the vertices array (and
793                     corresponding texs and colors arrays if non-null)
794         @param vertices Array of vertices for the mesh
795         @param texs May be null. If not null, specifies the coordinate
796                              in texture space for each vertex.
797         @param colors May be null. If not null, specifies a color for each
798                       vertex, to be interpolated across the triangle.
799         @param xmode Used if both texs and colors are present. In this
800                     case the colors are combined with the texture using mode,
801                     before being drawn using the paint. If mode is null, then
802                     kMultiply_Mode is used.
803         @param indices If not null, array of indices to reference into the
804                     vertex (texs, colors) array.
805         @param indexCount number of entries in the indices array (if not null)
806         @param paint Specifies the shader/texture if present.
807     */
808     virtual void drawVertices(VertexMode vmode, int vertexCount,
809                               const SkPoint vertices[], const SkPoint texs[],
810                               const SkColor colors[], SkXfermode* xmode,
811                               const uint16_t indices[], int indexCount,
812                               const SkPaint& paint);
813 
814     /** Send a blob of data to the canvas.
815         For canvases that draw, this call is effectively a no-op, as the data
816         is not parsed, but just ignored. However, this call exists for
817         subclasses like SkPicture's recording canvas, that can store the data
818         and then play it back later (via another call to drawData).
819      */
820     virtual void drawData(const void* data, size_t length);
821 
822     //////////////////////////////////////////////////////////////////////////
823 
824     /** Get the current bounder object.
825         The bounder's reference count is unchaged.
826         @return the canva's bounder (or NULL).
827     */
getBounder()828     SkBounder*  getBounder() const { return fBounder; }
829 
830     /** Set a new bounder (or NULL).
831         Pass NULL to clear any previous bounder.
832         As a convenience, the parameter passed is also returned.
833         If a previous bounder exists, its reference count is decremented.
834         If bounder is not NULL, its reference count is incremented.
835         @param bounder the new bounder (or NULL) to be installed in the canvas
836         @return the set bounder object
837     */
838     virtual SkBounder* setBounder(SkBounder* bounder);
839 
840     /** Get the current filter object. The filter's reference count is not
841         affected. The filter is saved/restored, just like the matrix and clip.
842         @return the canvas' filter (or NULL).
843     */
844     SkDrawFilter* getDrawFilter() const;
845 
846     /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
847         As a convenience, the parameter is returned. If an existing filter
848         exists, its refcnt is decrement. If the new filter is not null, its
849         refcnt is incremented. The filter is saved/restored, just like the
850         matrix and clip.
851         @param filter the new filter (or NULL)
852         @return the new filter
853     */
854     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
855 
856     //////////////////////////////////////////////////////////////////////////
857 
858     /** Return the current matrix on the canvas.
859         This does not account for the translate in any of the devices.
860         @return The current matrix on the canvas.
861     */
862     const SkMatrix& getTotalMatrix() const;
863 
864     enum ClipType {
865         kEmpty_ClipType = 0,
866         kRect_ClipType,
867         kComplex_ClipType
868     };
869 
870     /** Returns a description of the total clip; may be cheaper than
871         getting the clip and querying it directly.
872     */
873     ClipType getClipType() const;
874 
875     /** Return the current device clip (concatenation of all clip calls).
876         This does not account for the translate in any of the devices.
877         @return the current device clip (concatenation of all clip calls).
878     */
879     const SkRegion& getTotalClip() const;
880 
881     /**
882      *  Return true if the current clip is non-empty.
883      *
884      *  If bounds is not NULL, set it to the bounds of the current clip
885      *  in global coordinates.
886      */
887     bool getTotalClipBounds(SkIRect* bounds) const;
888 
889     /**
890      *  Return the current clipstack. This mirrors the result in getTotalClip()
891      *  but is represented as a stack of geometric clips + region-ops.
892      */
893     const SkClipStack& getTotalClipStack() const;
894 
895     void setExternalMatrix(const SkMatrix* = NULL);
896 
897     ///////////////////////////////////////////////////////////////////////////
898 
899     /** After calling saveLayer(), there can be any number of devices that make
900         up the top-most drawing area. LayerIter can be used to iterate through
901         those devices. Note that the iterator is only valid until the next API
902         call made on the canvas. Ownership of all pointers in the iterator stays
903         with the canvas, so none of them should be modified or deleted.
904     */
905     class SK_API LayerIter /*: SkNoncopyable*/ {
906     public:
907         /** Initialize iterator with canvas, and set values for 1st device */
908         LayerIter(SkCanvas*, bool skipEmptyClips);
909         ~LayerIter();
910 
911         /** Return true if the iterator is done */
done()912         bool done() const { return fDone; }
913         /** Cycle to the next device */
914         void next();
915 
916         // These reflect the current device in the iterator
917 
918         SkDevice*       device() const;
919         const SkMatrix& matrix() const;
920         const SkRegion& clip() const;
921         const SkPaint&  paint() const;
922         int             x() const;
923         int             y() const;
924 
925     private:
926         // used to embed the SkDrawIter object directly in our instance, w/o
927         // having to expose that class def to the public. There is an assert
928         // in our constructor to ensure that fStorage is large enough
929         // (though needs to be a compile-time-assert!). We use intptr_t to work
930         // safely with 32 and 64 bit machines (to ensure the storage is enough)
931         intptr_t          fStorage[32];
932         class SkDrawIter* fImpl;    // this points at fStorage
933         SkPaint           fDefaultPaint;
934         bool              fDone;
935     };
936 
937 protected:
938     // Returns the canvas to be used by DrawIter. Default implementation
939     // returns this. Subclasses that encapsulate an indirect canvas may
940     // need to overload this method. The impl must keep track of this, as it
941     // is not released or deleted by the caller.
942     virtual SkCanvas* canvasForDrawIter();
943 
944     // all of the drawBitmap variants call this guy
945     virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*,
946                                   const SkMatrix&, const SkPaint& paint);
947 
948     // Clip rectangle bounds. Called internally by saveLayer.
949     // returns false if the entire rectangle is entirely clipped out
950     bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
951                          SkIRect* intersection);
952 
953 private:
954     class MCRec;
955 
956     SkClipStack fClipStack;
957     SkDeque     fMCStack;
958     // points to top of stack
959     MCRec*      fMCRec;
960     // the first N recs that can fit here mean we won't call malloc
961     uint32_t    fMCRecStorage[32];
962 
963     SkBounder*  fBounder;
964     SkDevice*   fLastDeviceToGainFocus;
965     int         fLayerCount;    // number of successful saveLayer calls
966 
967     void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
968                               const SkClipStack& clipStack);
969 
970     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
971     void updateDeviceCMCache();
972 
973     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
974 
975     SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
976                                 bool isOpaque);
977 
978     SkDevice* init(SkDevice*);
979 
980     // internal methods are not virtual, so they can safely be called by other
981     // canvas apis, without confusing subclasses (like SkPictureRecording)
982     void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
983                                   const SkPaint* paint);
984     void internalDrawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
985                                 const SkRect& dst, const SkPaint* paint);
986     void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
987                                 const SkRect& dst, const SkPaint* paint);
988     void internalDrawPaint(const SkPaint& paint);
989 
990 
991     void drawDevice(SkDevice*, int x, int y, const SkPaint*);
992     // shared by save() and saveLayer()
993     int internalSave(SaveFlags flags);
994     void internalRestore();
995     static void DrawRect(const SkDraw& draw, const SkPaint& paint,
996                          const SkRect& r, SkScalar textSize);
997     static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
998                                     const char text[], size_t byteLength,
999                                     SkScalar x, SkScalar y);
1000 
1001     /*  These maintain a cache of the clip bounds in local coordinates,
1002         (converted to 2s-compliment if floats are slow).
1003      */
1004     mutable SkRectCompareType fLocalBoundsCompareType;
1005     mutable bool              fLocalBoundsCompareTypeDirty;
1006 
1007     mutable SkRectCompareType fLocalBoundsCompareTypeBW;
1008     mutable bool              fLocalBoundsCompareTypeDirtyBW;
1009 
1010     /* Get the local clip bounds with an anti-aliased edge.
1011      */
getLocalClipBoundsCompareType()1012     const SkRectCompareType& getLocalClipBoundsCompareType() const {
1013         return getLocalClipBoundsCompareType(kAA_EdgeType);
1014     }
1015 
getLocalClipBoundsCompareType(EdgeType et)1016     const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const {
1017         if (et == kAA_EdgeType) {
1018             if (fLocalBoundsCompareTypeDirty) {
1019                 this->computeLocalClipBoundsCompareType(et);
1020                 fLocalBoundsCompareTypeDirty = false;
1021             }
1022             return fLocalBoundsCompareType;
1023         } else {
1024             if (fLocalBoundsCompareTypeDirtyBW) {
1025                 this->computeLocalClipBoundsCompareType(et);
1026                 fLocalBoundsCompareTypeDirtyBW = false;
1027             }
1028             return fLocalBoundsCompareTypeBW;
1029         }
1030     }
1031     void computeLocalClipBoundsCompareType(EdgeType et) const;
1032 
1033     SkMatrix    fExternalMatrix, fExternalInverse;
1034     bool        fUseExternalMatrix;
1035 
1036     class AutoValidateClip : ::SkNoncopyable {
1037     public:
AutoValidateClip(SkCanvas * canvas)1038         explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
1039             fCanvas->validateClip();
1040         }
~AutoValidateClip()1041         ~AutoValidateClip() { fCanvas->validateClip(); }
1042 
1043     private:
1044         const SkCanvas* fCanvas;
1045     };
1046 
1047 #ifdef SK_DEBUG
1048     void validateClip() const;
1049 #else
validateClip()1050     void validateClip() const {}
1051 #endif
1052 };
1053 
1054 /** Stack helper class to automatically call restoreToCount() on the canvas
1055     when this object goes out of scope. Use this to guarantee that the canvas
1056     is restored to a known state.
1057 */
1058 class SkAutoCanvasRestore : SkNoncopyable {
1059 public:
SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)1060     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
1061         SkASSERT(canvas);
1062         fSaveCount = canvas->getSaveCount();
1063         if (doSave) {
1064             canvas->save();
1065         }
1066     }
~SkAutoCanvasRestore()1067     ~SkAutoCanvasRestore() {
1068         fCanvas->restoreToCount(fSaveCount);
1069     }
1070 
1071 private:
1072     SkCanvas*   fCanvas;
1073     int         fSaveCount;
1074 };
1075 
1076 #endif
1077