Home | History | Annotate | Download | only in core
      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 
     31 class SkBounder;
     32 class SkDevice;
     33 class SkDeviceFactory;
     34 class SkDraw;
     35 class SkDrawFilter;
     36 class SkPicture;
     37 class 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 */
     54 class SK_API SkCanvas : public SkRefCnt {
     55 public:
     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     /** Return the canvas' device object, which may be null. The device holds
     79         the bitmap of the pixels that the canvas draws into. The reference count
     80         of the returned device is not changed by this call.
     81     */
     82     SkDevice* getDevice() const;
     83 
     84     /** Specify a device for this canvas to draw into. If it is not null, its
     85         reference count is incremented. If the canvas was already holding a
     86         device, its reference count is decremented. The new device is returned.
     87     */
     88     SkDevice* setDevice(SkDevice* device);
     89 
     90     /**
     91      *  saveLayer() can create another device (which is later drawn onto
     92      *  the previous device). getTopDevice() returns the top-most device current
     93      *  installed. Note that this can change on other calls like save/restore,
     94      *  so do not access this device after subsequent canvas calls.
     95      *  The reference count of the device is not changed.
     96      */
     97     SkDevice* getTopDevice() const;
     98 
     99     /** May be overridden by subclasses. This returns a compatible device
    100         for this canvas, with the specified config/width/height. If the device
    101         is raster, the pixels will be allocated automatically.
    102      */
    103     virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
    104                                    bool isOpaque, bool forLayer = false);
    105 
    106     /**
    107      *  Create a new raster device and make it current. This also returns
    108      *  the new device.
    109      */
    110     SkDevice* setBitmapDevice(const SkBitmap& bitmap, bool forLayer = false);
    111 
    112     /**
    113      *  Return the current device factory, or NULL. The reference count of
    114      *  the returned factory is not changed.
    115      */
    116     SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; }
    117 
    118     /**
    119      *  Replace any existing factory with the specified factory, unrefing the
    120      *  previous (if any), and refing the new one (if any). For convenience,
    121      *  the factory parameter is also returned.
    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     /**
    382      *  This erases the entire drawing surface to the specified color,
    383      *  irrespective of the clip. It does not blend with the previous pixels,
    384      *  but always overwrites them.
    385      *
    386      *  It is roughly equivalent to the following:
    387      *      canvas.save();
    388      *      canvas.clipRect(hugeRect, kReplace_Op);
    389      *      paint.setColor(color);
    390      *      paint.setXfermodeMode(kSrc_Mode);
    391      *      canvas.drawPaint(paint);
    392      *      canvas.restore();
    393      *  though it is almost always much more efficient.
    394      */
    395     virtual void clear(SkColor);
    396 
    397     /**
    398      *  Fill the entire canvas' bitmap (restricted to the current clip) with the
    399      *  specified paint.
    400      *  @param paint    The paint used to fill the canvas
    401      */
    402     virtual void drawPaint(const SkPaint& paint);
    403 
    404     enum PointMode {
    405         /** drawPoints draws each point separately */
    406         kPoints_PointMode,
    407         /** drawPoints draws each pair of points as a line segment */
    408         kLines_PointMode,
    409         /** drawPoints draws the array of points as a polygon */
    410         kPolygon_PointMode
    411     };
    412 
    413     /** Draw a series of points, interpreted based on the PointMode mode. For
    414         all modes, the count parameter is interpreted as the total number of
    415         points. For kLine mode, count/2 line segments are drawn.
    416         For kPoint mode, each point is drawn centered at its coordinate, and its
    417         size is specified by the paint's stroke-width. It draws as a square,
    418         unless the paint's cap-type is round, in which the points are drawn as
    419         circles.
    420         For kLine mode, each pair of points is drawn as a line segment,
    421         respecting the paint's settings for cap/join/width.
    422         For kPolygon mode, the entire array is drawn as a series of connected
    423         line segments.
    424         Note that, while similar, kLine and kPolygon modes draw slightly
    425         differently than the equivalent path built with a series of moveto,
    426         lineto calls, in that the path will draw all of its contours at once,
    427         with no interactions if contours intersect each other (think XOR
    428         xfermode). drawPoints always draws each element one at a time.
    429         @param mode     PointMode specifying how to draw the array of points.
    430         @param count    The number of points in the array
    431         @param pts      Array of points to draw
    432         @param paint    The paint used to draw the points
    433     */
    434     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
    435                             const SkPaint& paint);
    436 
    437     /** Helper method for drawing a single point. See drawPoints() for a more
    438         details.
    439     */
    440     void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
    441 
    442     /** Draws a single pixel in the specified color.
    443         @param x        The X coordinate of which pixel to draw
    444         @param y        The Y coordiante of which pixel to draw
    445         @param color    The color to draw
    446     */
    447     void drawPoint(SkScalar x, SkScalar y, SkColor color);
    448 
    449     /** Draw a line segment with the specified start and stop x,y coordinates,
    450         using the specified paint. NOTE: since a line is always "framed", the
    451         paint's Style is ignored.
    452         @param x0    The x-coordinate of the start point of the line
    453         @param y0    The y-coordinate of the start point of the line
    454         @param x1    The x-coordinate of the end point of the line
    455         @param y1    The y-coordinate of the end point of the line
    456         @param paint The paint used to draw the line
    457     */
    458     void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
    459                   const SkPaint& paint);
    460 
    461     /** Draw the specified rectangle using the specified paint. The rectangle
    462         will be filled or stroked based on the Style in the paint.
    463         @param rect     The rect to be drawn
    464         @param paint    The paint used to draw the rect
    465     */
    466     virtual void drawRect(const SkRect& rect, const SkPaint& paint);
    467 
    468     /** Draw the specified rectangle using the specified paint. The rectangle
    469         will be filled or framed based on the Style in the paint.
    470         @param rect     The rect to be drawn
    471         @param paint    The paint used to draw the rect
    472     */
    473     void drawIRect(const SkIRect& rect, const SkPaint& paint)
    474     {
    475         SkRect r;
    476         r.set(rect);    // promotes the ints to scalars
    477         this->drawRect(r, paint);
    478     }
    479 
    480     /** Draw the specified rectangle using the specified paint. The rectangle
    481         will be filled or framed based on the Style in the paint.
    482         @param left     The left side of the rectangle to be drawn
    483         @param top      The top side of the rectangle to be drawn
    484         @param right    The right side of the rectangle to be drawn
    485         @param bottom   The bottom side of the rectangle to be drawn
    486         @param paint    The paint used to draw the rect
    487     */
    488     void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
    489                         SkScalar bottom, const SkPaint& paint);
    490 
    491     /** Draw the specified oval using the specified paint. The oval will be
    492         filled or framed based on the Style in the paint.
    493         @param oval     The rectangle bounds of the oval to be drawn
    494         @param paint    The paint used to draw the oval
    495     */
    496     void drawOval(const SkRect& oval, const SkPaint&);
    497 
    498     /** Draw the specified circle using the specified paint. If radius is <= 0,
    499         then nothing will be drawn. The circle will be filled
    500         or framed based on the Style in the paint.
    501         @param cx       The x-coordinate of the center of the cirle to be drawn
    502         @param cy       The y-coordinate of the center of the cirle to be drawn
    503         @param radius   The radius of the cirle to be drawn
    504         @param paint    The paint used to draw the circle
    505     */
    506     void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
    507                     const SkPaint& paint);
    508 
    509     /** Draw the specified arc, which will be scaled to fit inside the
    510         specified oval. If the sweep angle is >= 360, then the oval is drawn
    511         completely. Note that this differs slightly from SkPath::arcTo, which
    512         treats the sweep angle mod 360.
    513         @param oval The bounds of oval used to define the shape of the arc
    514         @param startAngle Starting angle (in degrees) where the arc begins
    515         @param sweepAngle Sweep angle (in degrees) measured clockwise
    516         @param useCenter true means include the center of the oval. For filling
    517                          this will draw a wedge. False means just use the arc.
    518         @param paint    The paint used to draw the arc
    519     */
    520     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
    521                  bool useCenter, const SkPaint& paint);
    522 
    523     /** Draw the specified round-rect using the specified paint. The round-rect
    524         will be filled or framed based on the Style in the paint.
    525         @param rect     The rectangular bounds of the roundRect to be drawn
    526         @param rx       The x-radius of the oval used to round the corners
    527         @param ry       The y-radius of the oval used to round the corners
    528         @param paint    The paint used to draw the roundRect
    529     */
    530     void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
    531                        const SkPaint& paint);
    532 
    533     /** Draw the specified path using the specified paint. The path will be
    534         filled or framed based on the Style in the paint.
    535         @param path     The path to be drawn
    536         @param paint    The paint used to draw the path
    537     */
    538     virtual void drawPath(const SkPath& path, const SkPaint& paint);
    539 
    540     /** Draw the specified bitmap, with its top/left corner at (x,y), using the
    541         specified paint, transformed by the current matrix. Note: if the paint
    542         contains a maskfilter that generates a mask which extends beyond the
    543         bitmap's original width/height, then the bitmap will be drawn as if it
    544         were in a Shader with CLAMP mode. Thus the color outside of the original
    545         width/height will be the edge color replicated.
    546         @param bitmap   The bitmap to be drawn
    547         @param left     The position of the left side of the bitmap being drawn
    548         @param top      The position of the top side of the bitmap being drawn
    549         @param paint    The paint used to draw the bitmap, or NULL
    550     */
    551     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
    552                             const SkPaint* paint = NULL);
    553 
    554     /** Draw the specified bitmap, with the specified matrix applied (before the
    555         canvas' matrix is applied).
    556         @param bitmap   The bitmap to be drawn
    557         @param src      Optional: specify the subset of the bitmap to be drawn
    558         @param dst      The destination rectangle where the scaled/translated
    559                         image will be drawn
    560         @param paint    The paint used to draw the bitmap, or NULL
    561     */
    562     virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
    563                                 const SkRect& dst, const SkPaint* paint = NULL);
    564 
    565     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
    566                                   const SkPaint* paint = NULL);
    567 
    568     /** Draw the specified bitmap, with its top/left corner at (x,y),
    569         NOT transformed by the current matrix. Note: if the paint
    570         contains a maskfilter that generates a mask which extends beyond the
    571         bitmap's original width/height, then the bitmap will be drawn as if it
    572         were in a Shader with CLAMP mode. Thus the color outside of the original
    573         width/height will be the edge color replicated.
    574         @param bitmap   The bitmap to be drawn
    575         @param left     The position of the left side of the bitmap being drawn
    576         @param top      The position of the top side of the bitmap being drawn
    577         @param paint    The paint used to draw the bitmap, or NULL
    578     */
    579     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
    580                             const SkPaint* paint = NULL);
    581 
    582     /** Draw the text, with origin at (x,y), using the specified paint.
    583         The origin is interpreted based on the Align setting in the paint.
    584         @param text The text to be drawn
    585         @param byteLength   The number of bytes to read from the text parameter
    586         @param x        The x-coordinate of the origin of the text being drawn
    587         @param y        The y-coordinate of the origin of the text being drawn
    588         @param paint    The paint used for the text (e.g. color, size, style)
    589     */
    590     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
    591                           SkScalar y, const SkPaint& paint);
    592 
    593     /** Draw the text, with each character/glyph origin specified by the pos[]
    594         array. The origin is interpreted by the Align setting in the paint.
    595         @param text The text to be drawn
    596         @param byteLength   The number of bytes to read from the text parameter
    597         @param pos      Array of positions, used to position each character
    598         @param paint    The paint used for the text (e.g. color, size, style)
    599         */
    600     virtual void drawPosText(const void* text, size_t byteLength,
    601                              const SkPoint pos[], const SkPaint& paint);
    602 
    603     /** Draw the text, with each character/glyph origin specified by the x
    604         coordinate taken from the xpos[] array, and the y from the constY param.
    605         The origin is interpreted by the Align setting in the paint.
    606         @param text The text to be drawn
    607         @param byteLength   The number of bytes to read from the text parameter
    608         @param xpos     Array of x-positions, used to position each character
    609         @param constY   The shared Y coordinate for all of the positions
    610         @param paint    The paint used for the text (e.g. color, size, style)
    611         */
    612     virtual void drawPosTextH(const void* text, size_t byteLength,
    613                               const SkScalar xpos[], SkScalar constY,
    614                               const SkPaint& paint);
    615 
    616     /** Draw the text, with origin at (x,y), using the specified paint, along
    617         the specified path. The paint's Align setting determins where along the
    618         path to start the text.
    619         @param text The text to be drawn
    620         @param byteLength   The number of bytes to read from the text parameter
    621         @param path         The path the text should follow for its baseline
    622         @param hOffset      The distance along the path to add to the text's
    623                             starting position
    624         @param vOffset      The distance above(-) or below(+) the path to
    625                             position the text
    626         @param paint        The paint used for the text
    627     */
    628     void drawTextOnPathHV(const void* text, size_t byteLength,
    629                           const SkPath& path, SkScalar hOffset,
    630                           SkScalar vOffset, const SkPaint& paint);
    631 
    632     /** Draw the text, with origin at (x,y), using the specified paint, along
    633         the specified path. The paint's Align setting determins where along the
    634         path to start the text.
    635         @param text The text to be drawn
    636         @param byteLength   The number of bytes to read from the text parameter
    637         @param path         The path the text should follow for its baseline
    638         @param matrix       (may be null) Applied to the text before it is
    639                             mapped onto the path
    640         @param paint        The paint used for the text
    641         */
    642     virtual void drawTextOnPath(const void* text, size_t byteLength,
    643                                 const SkPath& path, const SkMatrix* matrix,
    644                                 const SkPaint& paint);
    645 
    646 #ifdef ANDROID
    647     /** Draw the text on path, with each character/glyph origin specified by the pos[]
    648         array. The origin is interpreted by the Align setting in the paint.
    649         @param text The text to be drawn
    650         @param byteLength   The number of bytes to read from the text parameter
    651         @param pos      Array of positions, used to position each character
    652         @param paint    The paint used for the text (e.g. color, size, style)
    653         @param path The path to draw on
    654         @param matrix The canvas matrix
    655         */
    656     void drawPosTextOnPath(const void* text, size_t byteLength,
    657                            const SkPoint pos[], const SkPaint& paint,
    658                            const SkPath& path, const SkMatrix* matrix);
    659 #endif
    660 
    661     /** Draw the picture into this canvas. This method effective brackets the
    662         playback of the picture's draw calls with save/restore, so the state
    663         of this canvas will be unchanged after this call. This contrasts with
    664         the more immediate method SkPicture::draw(), which does not bracket
    665         the canvas with save/restore, thus the canvas may be left in a changed
    666         state after the call.
    667         @param picture The recorded drawing commands to playback into this
    668                        canvas.
    669     */
    670     virtual void drawPicture(SkPicture& picture);
    671 
    672     /** Draws the specified shape
    673      */
    674     virtual void drawShape(SkShape*);
    675 
    676     enum VertexMode {
    677         kTriangles_VertexMode,
    678         kTriangleStrip_VertexMode,
    679         kTriangleFan_VertexMode
    680     };
    681 
    682     /** Draw the array of vertices, interpreted as triangles (based on mode).
    683         @param vmode How to interpret the array of vertices
    684         @param vertexCount The number of points in the vertices array (and
    685                     corresponding texs and colors arrays if non-null)
    686         @param vertices Array of vertices for the mesh
    687         @param texs May be null. If not null, specifies the coordinate
    688                              in texture space for each vertex.
    689         @param colors May be null. If not null, specifies a color for each
    690                       vertex, to be interpolated across the triangle.
    691         @param xmode Used if both texs and colors are present. In this
    692                     case the colors are combined with the texture using mode,
    693                     before being drawn using the paint. If mode is null, then
    694                     kMultiply_Mode is used.
    695         @param indices If not null, array of indices to reference into the
    696                     vertex (texs, colors) array.
    697         @param indexCount number of entries in the indices array (if not null)
    698         @param paint Specifies the shader/texture if present.
    699     */
    700     virtual void drawVertices(VertexMode vmode, int vertexCount,
    701                               const SkPoint vertices[], const SkPoint texs[],
    702                               const SkColor colors[], SkXfermode* xmode,
    703                               const uint16_t indices[], int indexCount,
    704                               const SkPaint& paint);
    705 
    706     /** Send a blob of data to the canvas.
    707         For canvases that draw, this call is effectively a no-op, as the data
    708         is not parsed, but just ignored. However, this call exists for
    709         subclasses like SkPicture's recording canvas, that can store the data
    710         and then play it back later (via another call to drawData).
    711      */
    712     virtual void drawData(const void* data, size_t length);
    713 
    714     //////////////////////////////////////////////////////////////////////////
    715 
    716     /** Get the current bounder object.
    717         The bounder's reference count is unchaged.
    718         @return the canva's bounder (or NULL).
    719     */
    720     SkBounder*  getBounder() const { return fBounder; }
    721 
    722     /** Set a new bounder (or NULL).
    723         Pass NULL to clear any previous bounder.
    724         As a convenience, the parameter passed is also returned.
    725         If a previous bounder exists, its reference count is decremented.
    726         If bounder is not NULL, its reference count is incremented.
    727         @param bounder the new bounder (or NULL) to be installed in the canvas
    728         @return the set bounder object
    729     */
    730     virtual SkBounder* setBounder(SkBounder* bounder);
    731 
    732     /** Get the current filter object. The filter's reference count is not
    733         affected. The filter is saved/restored, just like the matrix and clip.
    734         @return the canvas' filter (or NULL).
    735     */
    736     SkDrawFilter* getDrawFilter() const;
    737 
    738     /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
    739         As a convenience, the parameter is returned. If an existing filter
    740         exists, its refcnt is decrement. If the new filter is not null, its
    741         refcnt is incremented. The filter is saved/restored, just like the
    742         matrix and clip.
    743         @param filter the new filter (or NULL)
    744         @return the new filter
    745     */
    746     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
    747 
    748     //////////////////////////////////////////////////////////////////////////
    749 
    750     /** Return the current matrix on the canvas.
    751         This does not account for the translate in any of the devices.
    752         @return The current matrix on the canvas.
    753     */
    754     const SkMatrix& getTotalMatrix() const;
    755 
    756     /** Return the current device clip (concatenation of all clip calls).
    757         This does not account for the translate in any of the devices.
    758         @return the current device clip (concatenation of all clip calls).
    759     */
    760     const SkRegion& getTotalClip() const;
    761 
    762     /**
    763      *  Return the current clipstack. This mirrors the result in getTotalClip()
    764      *  but is represented as a stack of geometric clips + region-ops.
    765      */
    766     const SkClipStack& getTotalClipStack() const;
    767 
    768     void setExternalMatrix(const SkMatrix* = NULL);
    769 
    770     ///////////////////////////////////////////////////////////////////////////
    771 
    772     /** After calling saveLayer(), there can be any number of devices that make
    773         up the top-most drawing area. LayerIter can be used to iterate through
    774         those devices. Note that the iterator is only valid until the next API
    775         call made on the canvas. Ownership of all pointers in the iterator stays
    776         with the canvas, so none of them should be modified or deleted.
    777     */
    778     class SK_API LayerIter /*: SkNoncopyable*/ {
    779     public:
    780         /** Initialize iterator with canvas, and set values for 1st device */
    781         LayerIter(SkCanvas*, bool skipEmptyClips);
    782         ~LayerIter();
    783 
    784         /** Return true if the iterator is done */
    785         bool done() const { return fDone; }
    786         /** Cycle to the next device */
    787         void next();
    788 
    789         // These reflect the current device in the iterator
    790 
    791         SkDevice*       device() const;
    792         const SkMatrix& matrix() const;
    793         const SkRegion& clip() const;
    794         const SkPaint&  paint() const;
    795         int             x() const;
    796         int             y() const;
    797 
    798     private:
    799         // used to embed the SkDrawIter object directly in our instance, w/o
    800         // having to expose that class def to the public. There is an assert
    801         // in our constructor to ensure that fStorage is large enough
    802         // (though needs to be a compile-time-assert!). We use intptr_t to work
    803         // safely with 32 and 64 bit machines (to ensure the storage is enough)
    804         intptr_t          fStorage[32];
    805         class SkDrawIter* fImpl;    // this points at fStorage
    806         SkPaint           fDefaultPaint;
    807         bool              fDone;
    808     };
    809 
    810 protected:
    811     // all of the drawBitmap variants call this guy
    812     virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*,
    813                                   const SkMatrix&, const SkPaint& paint);
    814 
    815 private:
    816     class MCRec;
    817 
    818     SkClipStack fClipStack;
    819     SkDeque     fMCStack;
    820     // points to top of stack
    821     MCRec*      fMCRec;
    822     // the first N recs that can fit here mean we won't call malloc
    823     uint32_t    fMCRecStorage[32];
    824 
    825     SkBounder*  fBounder;
    826     SkDevice*   fLastDeviceToGainFocus;
    827     SkDeviceFactory* fDeviceFactory;
    828 
    829     void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
    830                               const SkClipStack& clipStack);
    831 
    832     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
    833     void updateDeviceCMCache();
    834 
    835     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
    836 
    837     SkDevice* init(SkDevice*);
    838     void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
    839                                   const SkPaint* paint);
    840     void drawDevice(SkDevice*, int x, int y, const SkPaint*);
    841     // shared by save() and saveLayer()
    842     int internalSave(SaveFlags flags);
    843     void internalRestore();
    844 
    845     /*  These maintain a cache of the clip bounds in local coordinates,
    846         (converted to 2s-compliment if floats are slow).
    847      */
    848     mutable SkRectCompareType fLocalBoundsCompareType;
    849     mutable bool              fLocalBoundsCompareTypeDirty;
    850 
    851     mutable SkRectCompareType fLocalBoundsCompareTypeBW;
    852     mutable bool              fLocalBoundsCompareTypeDirtyBW;
    853 
    854     /* Get the local clip bounds with an anti-aliased edge.
    855      */
    856     const SkRectCompareType& getLocalClipBoundsCompareType() const {
    857         return getLocalClipBoundsCompareType(kAA_EdgeType);
    858     }
    859 
    860     const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const {
    861         if (et == kAA_EdgeType) {
    862             if (fLocalBoundsCompareTypeDirty) {
    863                 this->computeLocalClipBoundsCompareType(et);
    864                 fLocalBoundsCompareTypeDirty = false;
    865             }
    866             return fLocalBoundsCompareType;
    867         } else {
    868             if (fLocalBoundsCompareTypeDirtyBW) {
    869                 this->computeLocalClipBoundsCompareType(et);
    870                 fLocalBoundsCompareTypeDirtyBW = false;
    871             }
    872             return fLocalBoundsCompareTypeBW;
    873         }
    874     }
    875     void computeLocalClipBoundsCompareType(EdgeType et) const;
    876 
    877     SkMatrix    fExternalMatrix, fExternalInverse;
    878     bool        fUseExternalMatrix;
    879 
    880     class AutoValidateClip : ::SkNoncopyable {
    881     public:
    882         explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
    883             fCanvas->validateClip();
    884         }
    885         ~AutoValidateClip() { fCanvas->validateClip(); }
    886 
    887     private:
    888         const SkCanvas* fCanvas;
    889     };
    890 
    891 #ifdef SK_DEBUG
    892     void validateClip() const;
    893 #else
    894     void validateClip() const {}
    895 #endif
    896 };
    897 
    898 /** Stack helper class to automatically call restoreToCount() on the canvas
    899     when this object goes out of scope. Use this to guarantee that the canvas
    900     is restored to a known state.
    901 */
    902 class SkAutoCanvasRestore : SkNoncopyable {
    903 public:
    904     SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
    905         SkASSERT(canvas);
    906         fSaveCount = canvas->getSaveCount();
    907         if (doSave) {
    908             canvas->save();
    909         }
    910     }
    911     ~SkAutoCanvasRestore() {
    912         fCanvas->restoreToCount(fSaveCount);
    913     }
    914 
    915 private:
    916     SkCanvas*   fCanvas;
    917     int         fSaveCount;
    918 };
    919 
    920 #endif
    921 
    922