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