• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkCanvas_DEFINED
18 #define SkCanvas_DEFINED
19 
20 #include "SkTypes.h"
21 #include "SkBitmap.h"
22 #include "SkDeque.h"
23 #include "SkPaint.h"
24 #include "SkRefCnt.h"
25 #include "SkPath.h"
26 #include "SkRegion.h"
27 #include "SkScalarCompare.h"
28 #include "SkXfermode.h"
29 
30 class SkBounder;
31 class SkDevice;
32 class SkDraw;
33 class SkDrawFilter;
34 class SkPicture;
35 class SkShape;
36 
37 /** \class SkCanvas
38 
39     A Canvas encapsulates all of the state about drawing into a device (bitmap).
40     This includes a reference to the device itself, and a stack of matrix/clip
41     values. For any given draw call (e.g. drawRect), the geometry of the object
42     being drawn is transformed by the concatenation of all the matrices in the
43     stack. The transformed geometry is clipped by the intersection of all of
44     the clips in the stack.
45 
46     While the Canvas holds the state of the drawing device, the state (style)
47     of the object being drawn is held by the Paint, which is provided as a
48     parameter to each of the draw() methods. The Paint holds attributes such as
49     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
50     etc.
51 */
52 class SkCanvas : public SkRefCnt {
53 public:
54     /** Construct a canvas with the specified bitmap to draw into.
55         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
56                         structure are copied to the canvas.
57     */
58     explicit SkCanvas(const SkBitmap& bitmap);
59     /** Construct a canvas with the specified device to draw into.
60         @param device   Specifies a device for the canvas to draw into. The
61                         device may be null.
62     */
63     explicit SkCanvas(SkDevice* device = NULL);
64     virtual ~SkCanvas();
65 
66     ///////////////////////////////////////////////////////////////////////////
67 
68     /** If this subclass of SkCanvas supports GL viewports, return true and set
69         size (if not null) to the size of the viewport. If it is not supported,
70         ignore vp and return false.
71     */
72     virtual bool getViewport(SkIPoint* size) const;
73 
74     /** If this subclass of SkCanvas supports GL viewports, return true and set
75         the viewport to the specified x and y dimensions. If it is not
76         supported, ignore x and y and return false.
77     */
78     virtual bool setViewport(int x, int y);
79 
80     /** Return the canvas' device object, which may be null. The device holds
81         the bitmap of the pixels that the canvas draws into. The reference count
82         of the returned device is not changed by this call.
83     */
84     SkDevice* getDevice() const;
85 
86     /** Specify a device for this canvas to draw into. If it is not null, its
87         reference count is incremented. If the canvas was already holding a
88         device, its reference count is decremented. The new device is returned.
89     */
90     SkDevice* setDevice(SkDevice* device);
91 
92     /** Specify a bitmap for the canvas to draw into. This is a help method for
93         setDevice(), and it creates a device for the bitmap by calling
94         createDevice(). The structure of the bitmap is copied into the device.
95     */
96     virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap);
97 
98     ///////////////////////////////////////////////////////////////////////////
99 
100     enum SaveFlags {
101         /** save the matrix state, restoring it on restore() */
102         kMatrix_SaveFlag            = 0x01,
103         /** save the clip state, restoring it on restore() */
104         kClip_SaveFlag              = 0x02,
105         /** the layer needs to support per-pixel alpha */
106         kHasAlphaLayer_SaveFlag     = 0x04,
107         /** the layer needs to support 8-bits per color component */
108         kFullColorLayer_SaveFlag    = 0x08,
109         /** the layer should clip against the bounds argument */
110         kClipToLayer_SaveFlag       = 0x10,
111 
112         // helper masks for common choices
113         kMatrixClip_SaveFlag        = 0x03,
114         kARGB_NoClipLayer_SaveFlag  = 0x0F,
115         kARGB_ClipLayer_SaveFlag    = 0x1F
116     };
117 
118     /** This call saves the current matrix and clip information, and pushes a
119         copy onto a private stack. Subsequent calls to translate, scale,
120         rotate, skew, concat or clipRect, clipPath all operate on this copy.
121         When the balancing call to restore() is made, this copy is deleted and
122         the previous matrix/clip state is restored.
123         @return The value to pass to restoreToCount() to balance this save()
124     */
125     virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
126 
127     /** This behaves the same as save(), but in addition it allocates an
128         offscreen bitmap. All drawing calls are directed there, and only when
129         the balancing call to restore() is made is that offscreen transfered to
130         the canvas (or the previous layer). Subsequent calls to translate,
131         scale, rotate, skew, concat or clipRect, clipPath all operate on this
132         copy. When the balancing call to restore() is made, this copy is deleted
133         and the previous matrix/clip state is restored.
134         @param bounds (may be null) the maximum size the offscreen bitmap needs
135                       to be (in local coordinates)
136         @param paint (may be null) This is copied, and is applied to the
137                      offscreen when restore() is called
138         @param flags  LayerFlags
139         @return The value to pass to restoreToCount() to balance this save()
140     */
141     virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
142                           SaveFlags flags = kARGB_ClipLayer_SaveFlag);
143 
144     /** This behaves the same as save(), but in addition it allocates an
145         offscreen bitmap. All drawing calls are directed there, and only when
146         the balancing call to restore() is made is that offscreen transfered to
147         the canvas (or the previous layer). Subsequent calls to translate,
148         scale, rotate, skew, concat or clipRect, clipPath all operate on this
149         copy. When the balancing call to restore() is made, this copy is deleted
150         and the previous matrix/clip state is restored.
151         @param bounds (may be null) the maximum size the offscreen bitmap needs
152                       to be (in local coordinates)
153         @param alpha  This is applied to the offscreen when restore() is called.
154         @param flags  LayerFlags
155         @return The value to pass to restoreToCount() to balance this save()
156     */
157     int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
158                        SaveFlags flags = kARGB_ClipLayer_SaveFlag);
159 
160     /** This call balances a previous call to save(), and is used to remove all
161         modifications to the matrix/clip state since the last save call. It is
162         an error to call restore() more times than save() was called.
163     */
164     virtual void restore();
165 
166     /** Returns the number of matrix/clip states on the SkCanvas' private stack.
167         This will equal # save() calls - # restore() calls.
168     */
169     int getSaveCount() const;
170 
171     /** Efficient way to pop any calls to save() that happened after the save
172         count reached saveCount. It is an error for saveCount to be less than
173         getSaveCount()
174         @param saveCount    The number of save() levels to restore from
175     */
176     void restoreToCount(int saveCount);
177 
178     /** Preconcat the current matrix with the specified translation
179         @param dx   The distance to translate in X
180         @param dy   The distance to translate in Y
181         returns true if the operation succeeded (e.g. did not overflow)
182     */
183     virtual bool translate(SkScalar dx, SkScalar dy);
184 
185     /** Preconcat the current matrix with the specified scale.
186         @param sx   The amount to scale in X
187         @param sy   The amount to scale in Y
188         returns true if the operation succeeded (e.g. did not overflow)
189     */
190     virtual bool scale(SkScalar sx, SkScalar sy);
191 
192     /** Preconcat the current matrix with the specified rotation.
193         @param degrees  The amount to rotate, in degrees
194         returns true if the operation succeeded (e.g. did not overflow)
195     */
196     virtual bool rotate(SkScalar degrees);
197 
198     /** Preconcat the current matrix with the specified skew.
199         @param sx   The amount to skew in X
200         @param sy   The amount to skew in Y
201         returns true if the operation succeeded (e.g. did not overflow)
202     */
203     virtual bool skew(SkScalar sx, SkScalar sy);
204 
205     /** Preconcat the current matrix with the specified matrix.
206         @param matrix   The matrix to preconcatenate with the current matrix
207         @return true if the operation succeeded (e.g. did not overflow)
208     */
209     virtual bool concat(const SkMatrix& matrix);
210 
211     /** Replace the current matrix with a copy of the specified matrix.
212         @param matrix The matrix that will be copied into the current matrix.
213     */
214     virtual void setMatrix(const SkMatrix& matrix);
215 
216     /** Helper for setMatrix(identity). Sets the current matrix to identity.
217     */
218     void resetMatrix();
219 
220     /** Modify the current clip with the specified rectangle.
221         @param rect The rect to intersect with the current clip
222         @param op The region op to apply to the current clip
223         @return true if the canvas' clip is non-empty
224     */
225     virtual bool clipRect(const SkRect& rect,
226                           SkRegion::Op op = SkRegion::kIntersect_Op);
227 
228     /** Modify the current clip with the specified path.
229         @param path The path to apply to the current clip
230         @param op The region op to apply to the current clip
231         @return true if the canvas' new clip is non-empty
232     */
233     virtual bool clipPath(const SkPath& path,
234                           SkRegion::Op op = SkRegion::kIntersect_Op);
235 
236     /** Modify the current clip with the specified region. Note that unlike
237         clipRect() and clipPath() which transform their arguments by the current
238         matrix, clipRegion() assumes its argument is already in device
239         coordinates, and so no transformation is performed.
240         @param deviceRgn    The region to apply to the current clip
241         @param op The region op to apply to the current clip
242         @return true if the canvas' new clip is non-empty
243     */
244     virtual bool clipRegion(const SkRegion& deviceRgn,
245                             SkRegion::Op op = SkRegion::kIntersect_Op);
246 
247     /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
248         specified region. This does not intersect or in any other way account
249         for the existing clip region.
250         @param deviceRgn The region to copy into the current clip.
251         @return true if the new clip region is non-empty
252     */
setClipRegion(const SkRegion & deviceRgn)253     bool setClipRegion(const SkRegion& deviceRgn) {
254         return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
255     }
256 
257     /** Enum describing how to treat edges when performing quick-reject tests
258         of a geometry against the current clip. Treating them as antialiased
259         (kAA_EdgeType) will take into account the extra pixels that may be drawn
260         if the edge does not lie exactly on a device pixel boundary (after being
261         transformed by the current matrix).
262     */
263     enum EdgeType {
264         /** Treat the edges as B&W (not antialiased) for the purposes of testing
265             against the current clip
266         */
267         kBW_EdgeType,
268         /** Treat the edges as antialiased for the purposes of testing
269             against the current clip
270         */
271         kAA_EdgeType
272     };
273 
274     /** Return true if the specified rectangle, after being transformed by the
275         current matrix, would lie completely outside of the current clip. Call
276         this to check if an area you intend to draw into is clipped out (and
277         therefore you can skip making the draw calls).
278         @param rect the rect to compare with the current clip
279         @param et  specifies how to treat the edges (see EdgeType)
280         @return true if the rect (transformed by the canvas' matrix) does not
281                      intersect with the canvas' clip
282     */
283     bool quickReject(const SkRect& rect, EdgeType et) const;
284 
285     /** Return true if the specified path, after being transformed by the
286         current matrix, would lie completely outside of the current clip. Call
287         this to check if an area you intend to draw into is clipped out (and
288         therefore you can skip making the draw calls). Note, for speed it may
289         return false even if the path itself might not intersect the clip
290         (i.e. the bounds of the path intersects, but the path does not).
291         @param path The path to compare with the current clip
292         @param et  specifies how to treat the edges (see EdgeType)
293         @return true if the path (transformed by the canvas' matrix) does not
294                      intersect with the canvas' clip
295     */
296     bool quickReject(const SkPath& path, EdgeType et) const;
297 
298     /** Return true if the horizontal band specified by top and bottom is
299         completely clipped out. This is a conservative calculation, meaning
300         that it is possible that if the method returns false, the band may still
301         in fact be clipped out, but the converse is not true. If this method
302         returns true, then the band is guaranteed to be clipped out.
303         @param top  The top of the horizontal band to compare with the clip
304         @param bottom The bottom of the horizontal and to compare with the clip
305         @return true if the horizontal band is completely clipped out (i.e. does
306                      not intersect the current clip)
307     */
308     bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const;
309 
310     /** Return the bounds of the current clip (in local coordinates) in the
311         bounds parameter, and return true if it is non-empty. This can be useful
312         in a way similar to quickReject, in that it tells you that drawing
313         outside of these bounds will be clipped out.
314     */
315     bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
316 
317     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
318         specified ARGB color, using the specified mode.
319         @param a    the alpha component (0..255) of the color to fill the canvas
320         @param r    the red component (0..255) of the color to fill the canvas
321         @param g    the green component (0..255) of the color to fill the canvas
322         @param b    the blue component (0..255) of the color to fill the canvas
323         @param mode the mode to apply the color in (defaults to SrcOver)
324     */
325     void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
326                   SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
327 
328     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
329         specified color and mode.
330         @param color    the color to draw with
331         @param mode the mode to apply the color in (defaults to SrcOver)
332     */
333     void drawColor(SkColor color,
334                    SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
335 
336     /** Fill the entire canvas' bitmap (restricted to the current clip) with the
337         specified paint.
338         @param paint    The paint used to fill the canvas
339     */
340     virtual void drawPaint(const SkPaint& paint);
341 
342     enum PointMode {
343         /** drawPoints draws each point separately */
344         kPoints_PointMode,
345         /** drawPoints draws each pair of points as a line segment */
346         kLines_PointMode,
347         /** drawPoints draws the array of points as a polygon */
348         kPolygon_PointMode
349     };
350 
351     /** Draw a series of points, interpreted based on the PointMode mode. For
352         all modes, the count parameter is interpreted as the total number of
353         points. For kLine mode, count/2 line segments are drawn.
354         For kPoint mode, each point is drawn centered at its coordinate, and its
355         size is specified by the paint's stroke-width. It draws as a square,
356         unless the paint's cap-type is round, in which the points are drawn as
357         circles.
358         For kLine mode, each pair of points is drawn as a line segment,
359         respecting the paint's settings for cap/join/width.
360         For kPolygon mode, the entire array is drawn as a series of connected
361         line segments.
362         Note that, while similar, kLine and kPolygon modes draw slightly
363         differently than the equivalent path built with a series of moveto,
364         lineto calls, in that the path will draw all of its contours at once,
365         with no interactions if contours intersect each other (think XOR
366         xfermode). drawPoints always draws each element one at a time.
367         @param mode     PointMode specifying how to draw the array of points.
368         @param count    The number of points in the array
369         @param pts      Array of points to draw
370         @param paint    The paint used to draw the points
371     */
372     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
373                             const SkPaint& paint);
374 
375     /** Helper method for drawing a single point. See drawPoints() for a more
376         details.
377     */
378     void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
379 
380     /** Draws a single pixel in the specified color.
381         @param x        The X coordinate of which pixel to draw
382         @param y        The Y coordiante of which pixel to draw
383         @param color    The color to draw
384     */
385     void drawPoint(SkScalar x, SkScalar y, SkColor color);
386 
387     /** Draw a line segment with the specified start and stop x,y coordinates,
388         using the specified paint. NOTE: since a line is always "framed", the
389         paint's Style is ignored.
390         @param x0    The x-coordinate of the start point of the line
391         @param y0    The y-coordinate of the start point of the line
392         @param x1    The x-coordinate of the end point of the line
393         @param y1    The y-coordinate of the end point of the line
394         @param paint The paint used to draw the line
395     */
396     void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
397                   const SkPaint& paint);
398 
399     /** Draw the specified rectangle using the specified paint. The rectangle
400         will be filled or stroked based on the Style in the paint.
401         @param rect     The rect to be drawn
402         @param paint    The paint used to draw the rect
403     */
404     virtual void drawRect(const SkRect& rect, const SkPaint& paint);
405 
406     /** Draw the specified rectangle using the specified paint. The rectangle
407         will be filled or framed based on the Style in the paint.
408         @param rect     The rect to be drawn
409         @param paint    The paint used to draw the rect
410     */
drawIRect(const SkIRect & rect,const SkPaint & paint)411     void drawIRect(const SkIRect& rect, const SkPaint& paint)
412     {
413         SkRect r;
414         r.set(rect);    // promotes the ints to scalars
415         this->drawRect(r, paint);
416     }
417 
418     /** Draw the specified rectangle using the specified paint. The rectangle
419         will be filled or framed based on the Style in the paint.
420         @param left     The left side of the rectangle to be drawn
421         @param top      The top side of the rectangle to be drawn
422         @param right    The right side of the rectangle to be drawn
423         @param bottom   The bottom side of the rectangle to be drawn
424         @param paint    The paint used to draw the rect
425     */
426     void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
427                         SkScalar bottom, const SkPaint& paint);
428 
429     /** Draw the specified oval using the specified paint. The oval will be
430         filled or framed based on the Style in the paint.
431         @param oval     The rectangle bounds of the oval to be drawn
432         @param paint    The paint used to draw the oval
433     */
434     void drawOval(const SkRect& oval, const SkPaint&);
435 
436     /** Draw the specified circle using the specified paint. If radius is <= 0,
437         then nothing will be drawn. The circle will be filled
438         or framed based on the Style in the paint.
439         @param cx       The x-coordinate of the center of the cirle to be drawn
440         @param cy       The y-coordinate of the center of the cirle to be drawn
441         @param radius   The radius of the cirle to be drawn
442         @param paint    The paint used to draw the circle
443     */
444     void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
445                     const SkPaint& paint);
446 
447     /** Draw the specified arc, which will be scaled to fit inside the
448         specified oval. If the sweep angle is >= 360, then the oval is drawn
449         completely. Note that this differs slightly from SkPath::arcTo, which
450         treats the sweep angle mod 360.
451         @param oval The bounds of oval used to define the shape of the arc
452         @param startAngle Starting angle (in degrees) where the arc begins
453         @param sweepAngle Sweep angle (in degrees) measured clockwise
454         @param useCenter true means include the center of the oval. For filling
455                          this will draw a wedge. False means just use the arc.
456         @param paint    The paint used to draw the arc
457     */
458     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
459                  bool useCenter, const SkPaint& paint);
460 
461     /** Draw the specified round-rect using the specified paint. The round-rect
462         will be filled or framed based on the Style in the paint.
463         @param rect     The rectangular bounds of the roundRect to be drawn
464         @param rx       The x-radius of the oval used to round the corners
465         @param ry       The y-radius of the oval used to round the corners
466         @param paint    The paint used to draw the roundRect
467     */
468     void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
469                        const SkPaint& paint);
470 
471     /** Draw the specified path using the specified paint. The path will be
472         filled or framed based on the Style in the paint.
473         @param path     The path to be drawn
474         @param paint    The paint used to draw the path
475     */
476     virtual void drawPath(const SkPath& path, const SkPaint& paint);
477 
478     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
479         specified paint, transformed by the current matrix. Note: if the paint
480         contains a maskfilter that generates a mask which extends beyond the
481         bitmap's original width/height, then the bitmap will be drawn as if it
482         were in a Shader with CLAMP mode. Thus the color outside of the original
483         width/height will be the edge color replicated.
484         @param bitmap   The bitmap to be drawn
485         @param left     The position of the left side of the bitmap being drawn
486         @param top      The position of the top side of the bitmap being drawn
487         @param paint    The paint used to draw the bitmap, or NULL
488     */
489     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
490                             const SkPaint* paint = NULL);
491 
492     /** Draw the specified bitmap, with the specified matrix applied (before the
493         canvas' matrix is applied).
494         @param bitmap   The bitmap to be drawn
495         @param src      Optional: specify the subset of the bitmap to be drawn
496         @param dst      The destination rectangle where the scaled/translated
497                         image will be drawn
498         @param paint    The paint used to draw the bitmap, or NULL
499     */
500     virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
501                                 const SkRect& dst, const SkPaint* paint = NULL);
502 
503     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
504                                   const SkPaint* paint = NULL);
505 
506     /** Draw the specified bitmap, with its top/left corner at (x,y),
507         NOT transformed by the current matrix. Note: if the paint
508         contains a maskfilter that generates a mask which extends beyond the
509         bitmap's original width/height, then the bitmap will be drawn as if it
510         were in a Shader with CLAMP mode. Thus the color outside of the original
511         width/height will be the edge color replicated.
512         @param bitmap   The bitmap to be drawn
513         @param left     The position of the left side of the bitmap being drawn
514         @param top      The position of the top side of the bitmap being drawn
515         @param paint    The paint used to draw the bitmap, or NULL
516     */
517     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
518                             const SkPaint* paint = NULL);
519 
520     /** Draw the text, with origin at (x,y), using the specified paint.
521         The origin is interpreted based on the Align setting in the paint.
522         @param text The text to be drawn
523         @param byteLength   The number of bytes to read from the text parameter
524         @param x        The x-coordinate of the origin of the text being drawn
525         @param y        The y-coordinate of the origin of the text being drawn
526         @param paint    The paint used for the text (e.g. color, size, style)
527     */
528     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
529                           SkScalar y, const SkPaint& paint);
530 
531     /** Draw the text, with each character/glyph origin specified by the pos[]
532         array. The origin is interpreted by the Align setting in the paint.
533         @param text The text to be drawn
534         @param byteLength   The number of bytes to read from the text parameter
535         @param pos      Array of positions, used to position each character
536         @param paint    The paint used for the text (e.g. color, size, style)
537         */
538     virtual void drawPosText(const void* text, size_t byteLength,
539                              const SkPoint pos[], const SkPaint& paint);
540 
541     /** Draw the text, with each character/glyph origin specified by the x
542         coordinate taken from the xpos[] array, and the y from the constY param.
543         The origin is interpreted by the Align setting in the paint.
544         @param text The text to be drawn
545         @param byteLength   The number of bytes to read from the text parameter
546         @param xpos     Array of x-positions, used to position each character
547         @param constY   The shared Y coordinate for all of the positions
548         @param paint    The paint used for the text (e.g. color, size, style)
549         */
550     virtual void drawPosTextH(const void* text, size_t byteLength,
551                               const SkScalar xpos[], SkScalar constY,
552                               const SkPaint& paint);
553 
554     /** Draw the text, with origin at (x,y), using the specified paint, along
555         the specified path. The paint's Align setting determins where along the
556         path to start the text.
557         @param text The text to be drawn
558         @param byteLength   The number of bytes to read from the text parameter
559         @param path         The path the text should follow for its baseline
560         @param hOffset      The distance along the path to add to the text's
561                             starting position
562         @param vOffset      The distance above(-) or below(+) the path to
563                             position the text
564         @param paint        The paint used for the text
565     */
566     void drawTextOnPathHV(const void* text, size_t byteLength,
567                           const SkPath& path, SkScalar hOffset,
568                           SkScalar vOffset, const SkPaint& paint);
569 
570     /** Draw the text, with origin at (x,y), using the specified paint, along
571         the specified path. The paint's Align setting determins where along the
572         path to start the text.
573         @param text The text to be drawn
574         @param byteLength   The number of bytes to read from the text parameter
575         @param path         The path the text should follow for its baseline
576         @param matrix       (may be null) Applied to the text before it is
577                             mapped onto the path
578         @param paint        The paint used for the text
579         */
580     virtual void drawTextOnPath(const void* text, size_t byteLength,
581                                 const SkPath& path, const SkMatrix* matrix,
582                                 const SkPaint& paint);
583 
584     /** Draw the picture into this canvas. This method effective brackets the
585         playback of the picture's draw calls with save/restore, so the state
586         of this canvas will be unchanged after this call. This contrasts with
587         the more immediate method SkPicture::draw(), which does not bracket
588         the canvas with save/restore, thus the canvas may be left in a changed
589         state after the call.
590         @param picture The recorded drawing commands to playback into this
591                        canvas.
592     */
593     virtual void drawPicture(SkPicture& picture);
594 
595     /** Draws the specified shape
596      */
597     virtual void drawShape(SkShape*);
598 
599     enum VertexMode {
600         kTriangles_VertexMode,
601         kTriangleStrip_VertexMode,
602         kTriangleFan_VertexMode
603     };
604 
605     /** Draw the array of vertices, interpreted as triangles (based on mode).
606         @param vmode How to interpret the array of vertices
607         @param vertexCount The number of points in the vertices array (and
608                     corresponding texs and colors arrays if non-null)
609         @param vertices Array of vertices for the mesh
610         @param texs May be null. If not null, specifies the coordinate
611                              in texture space for each vertex.
612         @param colors May be null. If not null, specifies a color for each
613                       vertex, to be interpolated across the triangle.
614         @param xmode Used if both texs and colors are present. In this
615                     case the colors are combined with the texture using mode,
616                     before being drawn using the paint. If mode is null, then
617                     kMultiply_Mode is used.
618         @param indices If not null, array of indices to reference into the
619                     vertex (texs, colors) array.
620         @param indexCount number of entries in the indices array (if not null)
621         @param paint Specifies the shader/texture if present.
622     */
623     virtual void drawVertices(VertexMode vmode, int vertexCount,
624                               const SkPoint vertices[], const SkPoint texs[],
625                               const SkColor colors[], SkXfermode* xmode,
626                               const uint16_t indices[], int indexCount,
627                               const SkPaint& paint);
628 
629     //////////////////////////////////////////////////////////////////////////
630 
631     /** Get the current bounder object.
632         The bounder's reference count is unchaged.
633         @return the canva's bounder (or NULL).
634     */
getBounder()635     SkBounder*  getBounder() const { return fBounder; }
636 
637     /** Set a new bounder (or NULL).
638         Pass NULL to clear any previous bounder.
639         As a convenience, the parameter passed is also returned.
640         If a previous bounder exists, its reference count is decremented.
641         If bounder is not NULL, its reference count is incremented.
642         @param bounder the new bounder (or NULL) to be installed in the canvas
643         @return the set bounder object
644     */
645     virtual SkBounder* setBounder(SkBounder* bounder);
646 
647     /** Get the current filter object. The filter's reference count is not
648         affected. The filter is part of the state this is affected by
649         save/restore.
650         @return the canvas' filter (or NULL).
651     */
652     SkDrawFilter* getDrawFilter() const;
653 
654     /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
655         As a convenience, the parameter is returned. If an existing filter
656         exists, its refcnt is decrement. If the new filter is not null, its
657         refcnt is incremented. The filter is part of the state this is affected
658         by save/restore.
659         @param filter the new filter (or NULL)
660         @return the new filter
661     */
662     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
663 
664     //////////////////////////////////////////////////////////////////////////
665 
666     /** Return the current matrix on the canvas.
667         This does not account for the translate in any of the devices.
668         @return The current matrix on the canvas.
669     */
670     const SkMatrix& getTotalMatrix() const;
671 
672     /** Return the current device clip (concatenation of all clip calls).
673         This does not account for the translate in any of the devices.
674         @return the current device clip (concatenation of all clip calls).
675     */
676     const SkRegion& getTotalClip() const;
677 
678     /** May be overridden by subclasses. This returns a compatible device
679         for this canvas, with the specified config/width/height. If isOpaque
680         is true, then the underlying bitmap is optimized to assume that every
681         pixel will be drawn to, and thus it does not need to clear the alpha
682         channel ahead of time (assuming the specified config supports per-pixel
683         alpha.) If isOpaque is false, then the bitmap should clear its alpha
684         channel.
685     */
686     virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
687                                    bool isOpaque, bool isForLayer);
688 
689     ///////////////////////////////////////////////////////////////////////////
690 
691     /** After calling saveLayer(), there can be any number of devices that make
692         up the top-most drawing area. LayerIter can be used to iterate through
693         those devices. Note that the iterator is only valid until the next API
694         call made on the canvas. Ownership of all pointers in the iterator stays
695         with the canvas, so none of them should be modified or deleted.
696     */
697     class LayerIter /*: SkNoncopyable*/ {
698     public:
699         /** Initialize iterator with canvas, and set values for 1st device */
700         LayerIter(SkCanvas*, bool skipEmptyClips);
701         ~LayerIter();
702 
703         /** Return true if the iterator is done */
done()704         bool done() const { return fDone; }
705         /** Cycle to the next device */
706         void next();
707 
708         // These reflect the current device in the iterator
709 
710         SkDevice*       device() const;
711         const SkMatrix& matrix() const;
712         const SkRegion& clip() const;
713         const SkPaint&  paint() const;
714         int             x() const;
715         int             y() const;
716 
717     private:
718         // used to embed the SkDrawIter object directly in our instance, w/o
719         // having to expose that class def to the public. There is an assert
720         // in our constructor to ensure that fStorage is large enough
721         // (though needs to be a compile-time-assert!). We use intptr_t to work
722         // safely with 32 and 64 bit machines (to ensure the storage is enough)
723         intptr_t          fStorage[12];
724         class SkDrawIter* fImpl;    // this points at fStorage
725         SkPaint           fDefaultPaint;
726         bool              fDone;
727     };
728 
729 protected:
730     // all of the drawBitmap variants call this guy
731     virtual void commonDrawBitmap(const SkBitmap&, const SkMatrix& m,
732                                   const SkPaint& paint);
733 
734 private:
735     class MCRec;
736 
737     SkDeque     fMCStack;
738     // points to top of stack
739     MCRec*      fMCRec;
740     // the first N recs that can fit here mean we won't call malloc
741     uint32_t    fMCRecStorage[32];
742 
743     SkBounder*  fBounder;
744     SkDevice*   fLastDeviceToGainFocus;
745 
746     void prepareForDeviceDraw(SkDevice*);
747 
748     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
749     void updateDeviceCMCache();
750 
751     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
752 
753     SkDevice* init(SkDevice*);
754     void internalDrawBitmap(const SkBitmap&, const SkMatrix& m,
755                                   const SkPaint* paint);
756     void drawDevice(SkDevice*, int x, int y, const SkPaint*);
757     // shared by save() and saveLayer()
758     int internalSave(SaveFlags flags);
759     void internalRestore();
760 
761     /*  These maintain a cache of the clip bounds in local coordinates,
762         (converted to 2s-compliment if floats are slow).
763      */
764     mutable SkRectCompareType fLocalBoundsCompareType;
765     mutable bool              fLocalBoundsCompareTypeDirty;
766 
getLocalClipBoundsCompareType()767     const SkRectCompareType& getLocalClipBoundsCompareType() const {
768         if (fLocalBoundsCompareTypeDirty) {
769             this->computeLocalClipBoundsCompareType();
770             fLocalBoundsCompareTypeDirty = false;
771         }
772         return fLocalBoundsCompareType;
773     }
774     void computeLocalClipBoundsCompareType() const;
775 };
776 
777 /** Stack helper class to automatically call restoreToCount() on the canvas
778     when this object goes out of scope. Use this to guarantee that the canvas
779     is restored to a known state.
780 */
781 class SkAutoCanvasRestore : SkNoncopyable {
782 public:
SkAutoCanvasRestore(SkCanvas * canvas,bool doSave)783     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
784         SkASSERT(canvas);
785         fSaveCount = canvas->getSaveCount();
786         if (doSave) {
787             canvas->save();
788         }
789     }
~SkAutoCanvasRestore()790     ~SkAutoCanvasRestore() {
791         fCanvas->restoreToCount(fSaveCount);
792     }
793 
794 private:
795     SkCanvas*   fCanvas;
796     int         fSaveCount;
797 };
798 
799 #endif
800 
801