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