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