gfx/skia/trunk/include/core/SkCanvas.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/include/core/SkCanvas.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1503 @@
     1.4 +/*
     1.5 + * Copyright 2006 The Android Open Source Project
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#ifndef SkCanvas_DEFINED
    1.12 +#define SkCanvas_DEFINED
    1.13 +
    1.14 +#include "SkTypes.h"
    1.15 +#include "SkBitmap.h"
    1.16 +#include "SkDeque.h"
    1.17 +#include "SkClipStack.h"
    1.18 +#include "SkPaint.h"
    1.19 +#include "SkRefCnt.h"
    1.20 +#include "SkPath.h"
    1.21 +#include "SkRegion.h"
    1.22 +#include "SkXfermode.h"
    1.23 +
    1.24 +// if not defined, we always assume ClipToLayer for saveLayer()
    1.25 +//#define SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
    1.26 +
    1.27 +
    1.28 +//#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
    1.29 +//#define SK_SUPPORT_LEGACY_GETCLIPTYPE
    1.30 +//#define SK_SUPPORT_LEGACY_GETTOTALCLIP
    1.31 +//#define SK_SUPPORT_LEGACY_GETTOPDEVICE
    1.32 +
    1.33 +class SkBounder;
    1.34 +class SkBaseDevice;
    1.35 +class SkDraw;
    1.36 +class SkDrawFilter;
    1.37 +class SkMetaData;
    1.38 +class SkPicture;
    1.39 +class SkRRect;
    1.40 +class SkSurface;
    1.41 +class SkSurface_Base;
    1.42 +class GrContext;
    1.43 +class GrRenderTarget;
    1.44 +
    1.45 +/** \class SkCanvas
    1.46 +
    1.47 +    A Canvas encapsulates all of the state about drawing into a device (bitmap).
    1.48 +    This includes a reference to the device itself, and a stack of matrix/clip
    1.49 +    values. For any given draw call (e.g. drawRect), the geometry of the object
    1.50 +    being drawn is transformed by the concatenation of all the matrices in the
    1.51 +    stack. The transformed geometry is clipped by the intersection of all of
    1.52 +    the clips in the stack.
    1.53 +
    1.54 +    While the Canvas holds the state of the drawing device, the state (style)
    1.55 +    of the object being drawn is held by the Paint, which is provided as a
    1.56 +    parameter to each of the draw() methods. The Paint holds attributes such as
    1.57 +    color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
    1.58 +    etc.
    1.59 +*/
    1.60 +class SK_API SkCanvas : public SkRefCnt {
    1.61 +public:
    1.62 +    SK_DECLARE_INST_COUNT(SkCanvas)
    1.63 +
    1.64 +    /**
    1.65 +     *  Attempt to allocate an offscreen raster canvas, matching the ImageInfo.
    1.66 +     *  On success, return a new canvas that will draw into that offscreen.
    1.67 +     *
    1.68 +     *  The caller can access the pixels after drawing into this canvas by
    1.69 +     *  calling readPixels() or peekPixels().
    1.70 +     *
    1.71 +     *  If the requested ImageInfo is opaque (either the colortype is
    1.72 +     *  intrinsically opaque like RGB_565, or the info's alphatype is kOpaque)
    1.73 +     *  then the pixel memory may be uninitialized. Otherwise, the pixel memory
    1.74 +     *  will be initialized to 0, which is interpreted as transparent.
    1.75 +     *
    1.76 +     *  On failure, return NULL. This can fail for several reasons:
    1.77 +     *  1. the memory allocation failed (e.g. request is too large)
    1.78 +     *  2. invalid ImageInfo (e.g. negative dimensions)
    1.79 +     *  3. unsupported ImageInfo for a canvas
    1.80 +     *      - kUnknown_SkColorType, kIndex_8_SkColorType
    1.81 +     *      - kIgnore_SkAlphaType
    1.82 +     *      - this list is not complete, so others may also be unsupported
    1.83 +     *
    1.84 +     *  Note: it is valid to request a supported ImageInfo, but with zero
    1.85 +     *  dimensions.
    1.86 +     */
    1.87 +    static SkCanvas* NewRaster(const SkImageInfo&);
    1.88 +
    1.89 +    static SkCanvas* NewRasterN32(int width, int height) {
    1.90 +        return NewRaster(SkImageInfo::MakeN32Premul(width, height));
    1.91 +    }
    1.92 +
    1.93 +    /**
    1.94 +     *  Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
    1.95 +     *  specified pixels. To access the pixels after drawing to them, the caller should call
    1.96 +     *  flush() or call peekPixels(...).
    1.97 +     *
    1.98 +     *  On failure, return NULL. This can fail for several reasons:
    1.99 +     *  1. invalid ImageInfo (e.g. negative dimensions)
   1.100 +     *  2. unsupported ImageInfo for a canvas
   1.101 +     *      - kUnknown_SkColorType, kIndex_8_SkColorType
   1.102 +     *      - kIgnore_SkAlphaType
   1.103 +     *      - this list is not complete, so others may also be unsupported
   1.104 +     *
   1.105 +     *  Note: it is valid to request a supported ImageInfo, but with zero
   1.106 +     *  dimensions.
   1.107 +     */
   1.108 +    static SkCanvas* NewRasterDirect(const SkImageInfo&, void*, size_t);
   1.109 +
   1.110 +    static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) {
   1.111 +        return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
   1.112 +    }
   1.113 +
   1.114 +    /**
   1.115 +     *  Creates an empty canvas with no backing device/pixels, and zero
   1.116 +     *  dimensions.
   1.117 +     */
   1.118 +    SkCanvas();
   1.119 +
   1.120 +    /**
   1.121 +     *  Creates a canvas of the specified dimensions, but explicitly not backed
   1.122 +     *  by any device/pixels. Typically this use used by subclasses who handle
   1.123 +     *  the draw calls in some other way.
   1.124 +     */
   1.125 +    SkCanvas(int width, int height);
   1.126 +
   1.127 +    /** Construct a canvas with the specified device to draw into.
   1.128 +
   1.129 +        @param device   Specifies a device for the canvas to draw into.
   1.130 +    */
   1.131 +    explicit SkCanvas(SkBaseDevice* device);
   1.132 +
   1.133 +    /** Construct a canvas with the specified bitmap to draw into.
   1.134 +        @param bitmap   Specifies a bitmap for the canvas to draw into. Its
   1.135 +                        structure are copied to the canvas.
   1.136 +    */
   1.137 +    explicit SkCanvas(const SkBitmap& bitmap);
   1.138 +    virtual ~SkCanvas();
   1.139 +
   1.140 +    SkMetaData& getMetaData();
   1.141 +
   1.142 +    /**
   1.143 +     *  Return ImageInfo for this canvas. If the canvas is not backed by pixels
   1.144 +     *  (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
   1.145 +     */
   1.146 +    SkImageInfo imageInfo() const;
   1.147 +
   1.148 +    ///////////////////////////////////////////////////////////////////////////
   1.149 +
   1.150 +    /**
   1.151 +     *  Trigger the immediate execution of all pending draw operations.
   1.152 +     */
   1.153 +    void flush();
   1.154 +
   1.155 +    /**
   1.156 +     * Gets the size of the base or root layer in global canvas coordinates. The
   1.157 +     * origin of the base layer is always (0,0). The current drawable area may be
   1.158 +     * smaller (due to clipping or saveLayer).
   1.159 +     */
   1.160 +    SkISize getBaseLayerSize() const;
   1.161 +
   1.162 +    /**
   1.163 +     *  DEPRECATED: call getBaseLayerSize
   1.164 +     */
   1.165 +    SkISize getDeviceSize() const { return this->getBaseLayerSize(); }
   1.166 +
   1.167 +    /**
   1.168 +     *  DEPRECATED.
   1.169 +     *  Return the canvas' device object, which may be null. The device holds
   1.170 +     *  the bitmap of the pixels that the canvas draws into. The reference count
   1.171 +     *  of the returned device is not changed by this call.
   1.172 +     */
   1.173 +    SkBaseDevice* getDevice() const;
   1.174 +
   1.175 +    /**
   1.176 +     *  saveLayer() can create another device (which is later drawn onto
   1.177 +     *  the previous device). getTopDevice() returns the top-most device current
   1.178 +     *  installed. Note that this can change on other calls like save/restore,
   1.179 +     *  so do not access this device after subsequent canvas calls.
   1.180 +     *  The reference count of the device is not changed.
   1.181 +     *
   1.182 +     * @param updateMatrixClip If this is true, then before the device is
   1.183 +     *        returned, we ensure that its has been notified about the current
   1.184 +     *        matrix and clip. Note: this happens automatically when the device
   1.185 +     *        is drawn to, but is optional here, as there is a small perf hit
   1.186 +     *        sometimes.
   1.187 +     */
   1.188 +#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE
   1.189 +private:
   1.190 +#endif
   1.191 +    SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
   1.192 +public:
   1.193 +
   1.194 +    /**
   1.195 +     *  Create a new surface matching the specified info, one that attempts to
   1.196 +     *  be maximally compatible when used with this canvas.
   1.197 +     */
   1.198 +    SkSurface* newSurface(const SkImageInfo&);
   1.199 +
   1.200 +    /**
   1.201 +     * Return the GPU context of the device that is associated with the canvas.
   1.202 +     * For a canvas with non-GPU device, NULL is returned.
   1.203 +     */
   1.204 +    GrContext* getGrContext();
   1.205 +
   1.206 +    ///////////////////////////////////////////////////////////////////////////
   1.207 +
   1.208 +    /**
   1.209 +     *  If the canvas has writable pixels in its top layer (and is not recording to a picture
   1.210 +     *  or other non-raster target) and has direct access to its pixels (i.e. they are in
   1.211 +     *  local RAM) return the address of those pixels, and if not null,
   1.212 +     *  return the ImageInfo and rowBytes. The returned address is only valid
   1.213 +     *  while the canvas object is in scope and unchanged. Any API calls made on
   1.214 +     *  canvas (or its parent surface if any) will invalidate the
   1.215 +     *  returned address (and associated information).
   1.216 +     *
   1.217 +     *  On failure, returns NULL and the info and rowBytes parameters are
   1.218 +     *  ignored.
   1.219 +     */
   1.220 +    void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes);
   1.221 +
   1.222 +    /**
   1.223 +     *  If the canvas has readable pixels in its base layer (and is not recording to a picture
   1.224 +     *  or other non-raster target) and has direct access to its pixels (i.e. they are in
   1.225 +     *  local RAM) return the const-address of those pixels, and if not null,
   1.226 +     *  return the ImageInfo and rowBytes. The returned address is only valid
   1.227 +     *  while the canvas object is in scope and unchanged. Any API calls made on
   1.228 +     *  canvas (or its parent surface if any) will invalidate the
   1.229 +     *  returned address (and associated information).
   1.230 +     *
   1.231 +     *  On failure, returns NULL and the info and rowBytes parameters are
   1.232 +     *  ignored.
   1.233 +     */
   1.234 +    const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
   1.235 +
   1.236 +    /**
   1.237 +     * This enum can be used with read/writePixels to perform a pixel ops to or
   1.238 +     * from an 8888 config other than Skia's native config (SkPMColor). There
   1.239 +     * are three byte orders supported: native, BGRA, and RGBA. Each has a
   1.240 +     * premultiplied and unpremultiplied variant.
   1.241 +     *
   1.242 +     * Components of a 8888 pixel can be packed/unpacked from a 32bit word using
   1.243 +     * either byte offsets or shift values. Byte offsets are endian-invariant
   1.244 +     * while shifts are not. BGRA and RGBA configs are defined by byte
   1.245 +     * orderings. The native config is defined by shift values (SK_A32_SHIFT,
   1.246 +     * ..., SK_B32_SHIFT).
   1.247 +     */
   1.248 +    enum Config8888 {
   1.249 +        /**
   1.250 +         * Skia's native order specified by:
   1.251 +         *      SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
   1.252 +         *
   1.253 +         * kNative_Premul_Config8888 is equivalent to SkPMColor
   1.254 +         * kNative_Unpremul_Config8888 has the same component order as SkPMColor
   1.255 +         * but is not premultiplied.
   1.256 +         */
   1.257 +        kNative_Premul_Config8888,
   1.258 +        kNative_Unpremul_Config8888,
   1.259 +        /**
   1.260 +         * low byte to high byte: B, G, R, A.
   1.261 +         */
   1.262 +        kBGRA_Premul_Config8888,
   1.263 +        kBGRA_Unpremul_Config8888,
   1.264 +        /**
   1.265 +         * low byte to high byte: R, G, B, A.
   1.266 +         */
   1.267 +        kRGBA_Premul_Config8888,
   1.268 +        kRGBA_Unpremul_Config8888
   1.269 +    };
   1.270 +
   1.271 +    /**
   1.272 +     *  On success (returns true), copy the canvas pixels into the bitmap.
   1.273 +     *  On failure, the bitmap parameter is left unchanged and false is
   1.274 +     *  returned.
   1.275 +     *
   1.276 +     *  The canvas' pixels are converted to the bitmap's config. The only
   1.277 +     *  supported config is kARGB_8888_Config, though this is likely to be
   1.278 +     *  relaxed in  the future. The meaning of config kARGB_8888_Config is
   1.279 +     *  modified by the enum param config8888. The default value interprets
   1.280 +     *  kARGB_8888_Config as SkPMColor
   1.281 +     *
   1.282 +     *  If the bitmap has pixels already allocated, the canvas pixels will be
   1.283 +     *  written there. If not, bitmap->allocPixels() will be called
   1.284 +     *  automatically. If the bitmap is backed by a texture readPixels will
   1.285 +     *  fail.
   1.286 +     *
   1.287 +     *  The actual pixels written is the intersection of the canvas' bounds, and
   1.288 +     *  the rectangle formed by the bitmap's width,height and the specified x,y.
   1.289 +     *  If bitmap pixels extend outside of that intersection, they will not be
   1.290 +     *  modified.
   1.291 +     *
   1.292 +     *  Other failure conditions:
   1.293 +     *    * If the canvas is backed by a non-raster device (e.g. PDF) then
   1.294 +     *       readPixels will fail.
   1.295 +     *    * If bitmap is texture-backed then readPixels will fail. (This may be
   1.296 +     *       relaxed in the future.)
   1.297 +     *
   1.298 +     *  Example that reads the entire canvas into a bitmap using the native
   1.299 +     *  SkPMColor:
   1.300 +     *    SkISize size = canvas->getDeviceSize();
   1.301 +     *    bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
   1.302 +     *                                                   size.fHeight);
   1.303 +     *    if (canvas->readPixels(bitmap, 0, 0)) {
   1.304 +     *       // use the pixels
   1.305 +     *    }
   1.306 +     */
   1.307 +    bool readPixels(SkBitmap* bitmap,
   1.308 +                    int x, int y,
   1.309 +                    Config8888 config8888 = kNative_Premul_Config8888);
   1.310 +
   1.311 +    /**
   1.312 +     * DEPRECATED: This will be removed as soon as webkit is no longer relying
   1.313 +     * on it. The bitmap is resized to the intersection of srcRect and the
   1.314 +     * canvas bounds. New pixels are always allocated on success. Bitmap is
   1.315 +     * unmodified on failure.
   1.316 +     */
   1.317 +    bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
   1.318 +
   1.319 +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
   1.320 +    /**
   1.321 +     *  DEPRECATED
   1.322 +     *  Similar to draw sprite, this method will copy the pixels in bitmap onto
   1.323 +     *  the canvas, with the top/left corner specified by (x, y). The canvas'
   1.324 +     *  pixel values are completely replaced: there is no blending.
   1.325 +     *
   1.326 +     *  Currently if bitmap is backed by a texture this is a no-op. This may be
   1.327 +     *  relaxed in the future.
   1.328 +     *
   1.329 +     *  If the bitmap has config kARGB_8888_Config then the config8888 param
   1.330 +     *  will determines how the pixel valuess are intepreted. If the bitmap is
   1.331 +     *  not kARGB_8888_Config then this parameter is ignored.
   1.332 +     *
   1.333 +     *  Note: If you are recording drawing commands on this canvas to
   1.334 +     *  SkPicture, writePixels() is ignored!
   1.335 +     */
   1.336 +    void writePixels(const SkBitmap& bitmap, int x, int y, Config8888 config8888);
   1.337 +#endif
   1.338 +
   1.339 +    /**
   1.340 +     *  This method affects the pixels in the base-layer, and operates in pixel coordinates,
   1.341 +     *  ignoring the matrix and clip.
   1.342 +     *
   1.343 +     *  The specified ImageInfo and (x,y) offset specifies a rectangle: target.
   1.344 +     *
   1.345 +     *      target.setXYWH(x, y, info.width(), info.height());
   1.346 +     *
   1.347 +     *  Target is intersected with the bounds of the base-layer. If this intersection is not empty,
   1.348 +     *  then we have two sets of pixels (of equal size), the "src" specified by info+pixels+rowBytes
   1.349 +     *  and the "dst" by the canvas' backend. Replace the dst pixels with the corresponding src
   1.350 +     *  pixels, performing any colortype/alphatype transformations needed (in the case where the
   1.351 +     *  src and dst have different colortypes or alphatypes).
   1.352 +     *
   1.353 +     *  This call can fail, returning false, for several reasons:
   1.354 +     *  - If the src colortype/alphatype cannot be converted to the canvas' types
   1.355 +     *  - If this canvas is not backed by pixels (e.g. picture or PDF)
   1.356 +     */
   1.357 +    bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y);
   1.358 +
   1.359 +    /**
   1.360 +     *  Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap
   1.361 +     *  is just wrapping a texture, returns false and does nothing.
   1.362 +     */
   1.363 +    bool writePixels(const SkBitmap& bitmap, int x, int y);
   1.364 +
   1.365 +    ///////////////////////////////////////////////////////////////////////////
   1.366 +
   1.367 +    enum SaveFlags {
   1.368 +        /** save the matrix state, restoring it on restore() */
   1.369 +        kMatrix_SaveFlag            = 0x01,
   1.370 +        /** save the clip state, restoring it on restore() */
   1.371 +        kClip_SaveFlag              = 0x02,
   1.372 +        /** the layer needs to support per-pixel alpha */
   1.373 +        kHasAlphaLayer_SaveFlag     = 0x04,
   1.374 +        /** the layer needs to support 8-bits per color component */
   1.375 +        kFullColorLayer_SaveFlag    = 0x08,
   1.376 +        /**
   1.377 +         *  the layer should clip against the bounds argument
   1.378 +         *
   1.379 +         *  if SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG is undefined, this is treated as always on.
   1.380 +         */
   1.381 +        kClipToLayer_SaveFlag       = 0x10,
   1.382 +
   1.383 +        // helper masks for common choices
   1.384 +        kMatrixClip_SaveFlag        = 0x03,
   1.385 +#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
   1.386 +        kARGB_NoClipLayer_SaveFlag  = 0x0F,
   1.387 +#endif
   1.388 +        kARGB_ClipLayer_SaveFlag    = 0x1F
   1.389 +    };
   1.390 +
   1.391 +    /** This call saves the current matrix, clip, and drawFilter, and pushes a
   1.392 +        copy onto a private stack. Subsequent calls to translate, scale,
   1.393 +        rotate, skew, concat or clipRect, clipPath, and setDrawFilter all
   1.394 +        operate on this copy.
   1.395 +        When the balancing call to restore() is made, the previous matrix, clip,
   1.396 +        and drawFilter are restored.
   1.397 +        @param flags The flags govern what portion of the Matrix/Clip/drawFilter
   1.398 +                     state the save (and matching restore) effect. For example,
   1.399 +                     if only kMatrix is specified, then only the matrix state
   1.400 +                     will be pushed and popped. Likewise for the clip if kClip
   1.401 +                     is specified.  However, the drawFilter is always affected
   1.402 +                     by calls to save/restore.
   1.403 +        @return The value to pass to restoreToCount() to balance this save()
   1.404 +    */
   1.405 +    int save(SaveFlags flags = kMatrixClip_SaveFlag);
   1.406 +
   1.407 +    /** This behaves the same as save(), but in addition it allocates an
   1.408 +        offscreen bitmap. All drawing calls are directed there, and only when
   1.409 +        the balancing call to restore() is made is that offscreen transfered to
   1.410 +        the canvas (or the previous layer).
   1.411 +        @param bounds (may be null) This rect, if non-null, is used as a hint to
   1.412 +                      limit the size of the offscreen, and thus drawing may be
   1.413 +                      clipped to it, though that clipping is not guaranteed to
   1.414 +                      happen. If exact clipping is desired, use clipRect().
   1.415 +        @param paint (may be null) This is copied, and is applied to the
   1.416 +                     offscreen when restore() is called
   1.417 +        @param flags  LayerFlags
   1.418 +        @return The value to pass to restoreToCount() to balance this save()
   1.419 +    */
   1.420 +    int saveLayer(const SkRect* bounds, const SkPaint* paint,
   1.421 +                  SaveFlags flags = kARGB_ClipLayer_SaveFlag);
   1.422 +
   1.423 +    /** This behaves the same as save(), but in addition it allocates an
   1.424 +        offscreen bitmap. All drawing calls are directed there, and only when
   1.425 +        the balancing call to restore() is made is that offscreen transfered to
   1.426 +        the canvas (or the previous layer).
   1.427 +        @param bounds (may be null) This rect, if non-null, is used as a hint to
   1.428 +                      limit the size of the offscreen, and thus drawing may be
   1.429 +                      clipped to it, though that clipping is not guaranteed to
   1.430 +                      happen. If exact clipping is desired, use clipRect().
   1.431 +        @param alpha  This is applied to the offscreen when restore() is called.
   1.432 +        @param flags  LayerFlags
   1.433 +        @return The value to pass to restoreToCount() to balance this save()
   1.434 +    */
   1.435 +    int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
   1.436 +                       SaveFlags flags = kARGB_ClipLayer_SaveFlag);
   1.437 +
   1.438 +    /** This call balances a previous call to save(), and is used to remove all
   1.439 +        modifications to the matrix/clip/drawFilter state since the last save
   1.440 +        call.
   1.441 +        It is an error to call restore() more times than save() was called.
   1.442 +    */
   1.443 +    void restore();
   1.444 +
   1.445 +    /** Returns the number of matrix/clip states on the SkCanvas' private stack.
   1.446 +        This will equal # save() calls - # restore() calls + 1. The save count on
   1.447 +        a new canvas is 1.
   1.448 +    */
   1.449 +    int getSaveCount() const;
   1.450 +
   1.451 +    /** Efficient way to pop any calls to save() that happened after the save
   1.452 +        count reached saveCount. It is an error for saveCount to be greater than
   1.453 +        getSaveCount(). To pop all the way back to the initial matrix/clip context
   1.454 +        pass saveCount == 1.
   1.455 +        @param saveCount    The number of save() levels to restore from
   1.456 +    */
   1.457 +    void restoreToCount(int saveCount);
   1.458 +
   1.459 +    /** Returns true if drawing is currently going to a layer (from saveLayer)
   1.460 +     *  rather than to the root device.
   1.461 +     */
   1.462 +    virtual bool isDrawingToLayer() const;
   1.463 +
   1.464 +    /** Preconcat the current matrix with the specified translation
   1.465 +        @param dx   The distance to translate in X
   1.466 +        @param dy   The distance to translate in Y
   1.467 +        returns true if the operation succeeded (e.g. did not overflow)
   1.468 +    */
   1.469 +    bool translate(SkScalar dx, SkScalar dy);
   1.470 +
   1.471 +    /** Preconcat the current matrix with the specified scale.
   1.472 +        @param sx   The amount to scale in X
   1.473 +        @param sy   The amount to scale in Y
   1.474 +        returns true if the operation succeeded (e.g. did not overflow)
   1.475 +    */
   1.476 +    bool scale(SkScalar sx, SkScalar sy);
   1.477 +
   1.478 +    /** Preconcat the current matrix with the specified rotation.
   1.479 +        @param degrees  The amount to rotate, in degrees
   1.480 +        returns true if the operation succeeded (e.g. did not overflow)
   1.481 +    */
   1.482 +    bool rotate(SkScalar degrees);
   1.483 +
   1.484 +    /** Preconcat the current matrix with the specified skew.
   1.485 +        @param sx   The amount to skew in X
   1.486 +        @param sy   The amount to skew in Y
   1.487 +        returns true if the operation succeeded (e.g. did not overflow)
   1.488 +    */
   1.489 +    bool skew(SkScalar sx, SkScalar sy);
   1.490 +
   1.491 +    /** Preconcat the current matrix with the specified matrix.
   1.492 +        @param matrix   The matrix to preconcatenate with the current matrix
   1.493 +        @return true if the operation succeeded (e.g. did not overflow)
   1.494 +    */
   1.495 +    bool concat(const SkMatrix& matrix);
   1.496 +
   1.497 +    /** Replace the current matrix with a copy of the specified matrix.
   1.498 +        @param matrix The matrix that will be copied into the current matrix.
   1.499 +    */
   1.500 +    void setMatrix(const SkMatrix& matrix);
   1.501 +
   1.502 +    /** Helper for setMatrix(identity). Sets the current matrix to identity.
   1.503 +    */
   1.504 +    void resetMatrix();
   1.505 +
   1.506 +    /**
   1.507 +     *  Modify the current clip with the specified rectangle.
   1.508 +     *  @param rect The rect to combine with the current clip
   1.509 +     *  @param op The region op to apply to the current clip
   1.510 +     *  @param doAntiAlias true if the clip should be antialiased
   1.511 +     */
   1.512 +    void clipRect(const SkRect& rect,
   1.513 +                  SkRegion::Op op = SkRegion::kIntersect_Op,
   1.514 +                  bool doAntiAlias = false);
   1.515 +
   1.516 +    /**
   1.517 +     *  Modify the current clip with the specified SkRRect.
   1.518 +     *  @param rrect The rrect to combine with the current clip
   1.519 +     *  @param op The region op to apply to the current clip
   1.520 +     *  @param doAntiAlias true if the clip should be antialiased
   1.521 +     */
   1.522 +    void clipRRect(const SkRRect& rrect,
   1.523 +                   SkRegion::Op op = SkRegion::kIntersect_Op,
   1.524 +                   bool doAntiAlias = false);
   1.525 +
   1.526 +    /**
   1.527 +     *  Modify the current clip with the specified path.
   1.528 +     *  @param path The path to combine with the current clip
   1.529 +     *  @param op The region op to apply to the current clip
   1.530 +     *  @param doAntiAlias true if the clip should be antialiased
   1.531 +     */
   1.532 +    void clipPath(const SkPath& path,
   1.533 +                  SkRegion::Op op = SkRegion::kIntersect_Op,
   1.534 +                  bool doAntiAlias = false);
   1.535 +
   1.536 +    /** EXPERIMENTAL -- only used for testing
   1.537 +        Set to false to force clips to be hard, even if doAntiAlias=true is
   1.538 +        passed to clipRect or clipPath.
   1.539 +     */
   1.540 +    void setAllowSoftClip(bool allow) {
   1.541 +        fAllowSoftClip = allow;
   1.542 +    }
   1.543 +
   1.544 +    /** EXPERIMENTAL -- only used for testing
   1.545 +        Set to simplify clip stack using path ops.
   1.546 +     */
   1.547 +    void setAllowSimplifyClip(bool allow) {
   1.548 +        fAllowSimplifyClip = allow;
   1.549 +    }
   1.550 +
   1.551 +    /** Modify the current clip with the specified region. Note that unlike
   1.552 +        clipRect() and clipPath() which transform their arguments by the current
   1.553 +        matrix, clipRegion() assumes its argument is already in device
   1.554 +        coordinates, and so no transformation is performed.
   1.555 +        @param deviceRgn    The region to apply to the current clip
   1.556 +        @param op The region op to apply to the current clip
   1.557 +    */
   1.558 +    void clipRegion(const SkRegion& deviceRgn,
   1.559 +                    SkRegion::Op op = SkRegion::kIntersect_Op);
   1.560 +
   1.561 +    /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
   1.562 +        specified region. This does not intersect or in any other way account
   1.563 +        for the existing clip region.
   1.564 +        @param deviceRgn The region to copy into the current clip.
   1.565 +    */
   1.566 +    void setClipRegion(const SkRegion& deviceRgn) {
   1.567 +        this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
   1.568 +    }
   1.569 +
   1.570 +    /** Return true if the specified rectangle, after being transformed by the
   1.571 +        current matrix, would lie completely outside of the current clip. Call
   1.572 +        this to check if an area you intend to draw into is clipped out (and
   1.573 +        therefore you can skip making the draw calls).
   1.574 +        @param rect the rect to compare with the current clip
   1.575 +        @return true if the rect (transformed by the canvas' matrix) does not
   1.576 +                     intersect with the canvas' clip
   1.577 +    */
   1.578 +    bool quickReject(const SkRect& rect) const;
   1.579 +
   1.580 +    /** Return true if the specified path, after being transformed by the
   1.581 +        current matrix, would lie completely outside of the current clip. Call
   1.582 +        this to check if an area you intend to draw into is clipped out (and
   1.583 +        therefore you can skip making the draw calls). Note, for speed it may
   1.584 +        return false even if the path itself might not intersect the clip
   1.585 +        (i.e. the bounds of the path intersects, but the path does not).
   1.586 +        @param path The path to compare with the current clip
   1.587 +        @return true if the path (transformed by the canvas' matrix) does not
   1.588 +                     intersect with the canvas' clip
   1.589 +    */
   1.590 +    bool quickReject(const SkPath& path) const;
   1.591 +
   1.592 +    /** Return true if the horizontal band specified by top and bottom is
   1.593 +        completely clipped out. This is a conservative calculation, meaning
   1.594 +        that it is possible that if the method returns false, the band may still
   1.595 +        in fact be clipped out, but the converse is not true. If this method
   1.596 +        returns true, then the band is guaranteed to be clipped out.
   1.597 +        @param top  The top of the horizontal band to compare with the clip
   1.598 +        @param bottom The bottom of the horizontal and to compare with the clip
   1.599 +        @return true if the horizontal band is completely clipped out (i.e. does
   1.600 +                     not intersect the current clip)
   1.601 +    */
   1.602 +    bool quickRejectY(SkScalar top, SkScalar bottom) const {
   1.603 +        SkASSERT(top <= bottom);
   1.604 +
   1.605 +#ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT
   1.606 +        // TODO: add a hasPerspective method similar to getLocalClipBounds. This
   1.607 +        // would cache the SkMatrix::hasPerspective result. Alternatively, have
   1.608 +        // the MC stack just set a hasPerspective boolean as it is updated.
   1.609 +        if (this->getTotalMatrix().hasPerspective()) {
   1.610 +            // TODO: consider implementing some half-plane test between the
   1.611 +            // two Y planes and the device-bounds (i.e., project the top and
   1.612 +            // bottom Y planes and then determine if the clip bounds is completely
   1.613 +            // outside either one).
   1.614 +            return false;
   1.615 +        }
   1.616 +#endif
   1.617 +
   1.618 +        const SkRect& clipR = this->getLocalClipBounds();
   1.619 +        // In the case where the clip is empty and we are provided with a
   1.620 +        // negative top and positive bottom parameter then this test will return
   1.621 +        // false even though it will be clipped. We have chosen to exclude that
   1.622 +        // check as it is rare and would result double the comparisons.
   1.623 +        return top >= clipR.fBottom || bottom <= clipR.fTop;
   1.624 +    }
   1.625 +
   1.626 +    /** Return the bounds of the current clip (in local coordinates) in the
   1.627 +        bounds parameter, and return true if it is non-empty. This can be useful
   1.628 +        in a way similar to quickReject, in that it tells you that drawing
   1.629 +        outside of these bounds will be clipped out.
   1.630 +    */
   1.631 +    virtual bool getClipBounds(SkRect* bounds) const;
   1.632 +
   1.633 +    /** Return the bounds of the current clip, in device coordinates; returns
   1.634 +        true if non-empty. Maybe faster than getting the clip explicitly and
   1.635 +        then taking its bounds.
   1.636 +    */
   1.637 +    virtual bool getClipDeviceBounds(SkIRect* bounds) const;
   1.638 +
   1.639 +
   1.640 +    /** Fill the entire canvas' bitmap (restricted to the current clip) with the
   1.641 +        specified ARGB color, using the specified mode.
   1.642 +        @param a    the alpha component (0..255) of the color to fill the canvas
   1.643 +        @param r    the red component (0..255) of the color to fill the canvas
   1.644 +        @param g    the green component (0..255) of the color to fill the canvas
   1.645 +        @param b    the blue component (0..255) of the color to fill the canvas
   1.646 +        @param mode the mode to apply the color in (defaults to SrcOver)
   1.647 +    */
   1.648 +    void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
   1.649 +                  SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
   1.650 +
   1.651 +    /** Fill the entire canvas' bitmap (restricted to the current clip) with the
   1.652 +        specified color and mode.
   1.653 +        @param color    the color to draw with
   1.654 +        @param mode the mode to apply the color in (defaults to SrcOver)
   1.655 +    */
   1.656 +    void drawColor(SkColor color,
   1.657 +                   SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
   1.658 +
   1.659 +    /**
   1.660 +     *  This erases the entire drawing surface to the specified color,
   1.661 +     *  irrespective of the clip. It does not blend with the previous pixels,
   1.662 +     *  but always overwrites them.
   1.663 +     *
   1.664 +     *  It is roughly equivalent to the following:
   1.665 +     *      canvas.save();
   1.666 +     *      canvas.clipRect(hugeRect, kReplace_Op);
   1.667 +     *      paint.setColor(color);
   1.668 +     *      paint.setXfermodeMode(kSrc_Mode);
   1.669 +     *      canvas.drawPaint(paint);
   1.670 +     *      canvas.restore();
   1.671 +     *  though it is almost always much more efficient.
   1.672 +     */
   1.673 +    virtual void clear(SkColor);
   1.674 +
   1.675 +    /**
   1.676 +     *  Fill the entire canvas' bitmap (restricted to the current clip) with the
   1.677 +     *  specified paint.
   1.678 +     *  @param paint    The paint used to fill the canvas
   1.679 +     */
   1.680 +    virtual void drawPaint(const SkPaint& paint);
   1.681 +
   1.682 +    enum PointMode {
   1.683 +        /** drawPoints draws each point separately */
   1.684 +        kPoints_PointMode,
   1.685 +        /** drawPoints draws each pair of points as a line segment */
   1.686 +        kLines_PointMode,
   1.687 +        /** drawPoints draws the array of points as a polygon */
   1.688 +        kPolygon_PointMode
   1.689 +    };
   1.690 +
   1.691 +    /** Draw a series of points, interpreted based on the PointMode mode. For
   1.692 +        all modes, the count parameter is interpreted as the total number of
   1.693 +        points. For kLine mode, count/2 line segments are drawn.
   1.694 +        For kPoint mode, each point is drawn centered at its coordinate, and its
   1.695 +        size is specified by the paint's stroke-width. It draws as a square,
   1.696 +        unless the paint's cap-type is round, in which the points are drawn as
   1.697 +        circles.
   1.698 +        For kLine mode, each pair of points is drawn as a line segment,
   1.699 +        respecting the paint's settings for cap/join/width.
   1.700 +        For kPolygon mode, the entire array is drawn as a series of connected
   1.701 +        line segments.
   1.702 +        Note that, while similar, kLine and kPolygon modes draw slightly
   1.703 +        differently than the equivalent path built with a series of moveto,
   1.704 +        lineto calls, in that the path will draw all of its contours at once,
   1.705 +        with no interactions if contours intersect each other (think XOR
   1.706 +        xfermode). drawPoints always draws each element one at a time.
   1.707 +        @param mode     PointMode specifying how to draw the array of points.
   1.708 +        @param count    The number of points in the array
   1.709 +        @param pts      Array of points to draw
   1.710 +        @param paint    The paint used to draw the points
   1.711 +    */
   1.712 +    virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
   1.713 +                            const SkPaint& paint);
   1.714 +
   1.715 +    /** Helper method for drawing a single point. See drawPoints() for a more
   1.716 +        details.
   1.717 +    */
   1.718 +    void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
   1.719 +
   1.720 +    /** Draws a single pixel in the specified color.
   1.721 +        @param x        The X coordinate of which pixel to draw
   1.722 +        @param y        The Y coordiante of which pixel to draw
   1.723 +        @param color    The color to draw
   1.724 +    */
   1.725 +    void drawPoint(SkScalar x, SkScalar y, SkColor color);
   1.726 +
   1.727 +    /** Draw a line segment with the specified start and stop x,y coordinates,
   1.728 +        using the specified paint. NOTE: since a line is always "framed", the
   1.729 +        paint's Style is ignored.
   1.730 +        @param x0    The x-coordinate of the start point of the line
   1.731 +        @param y0    The y-coordinate of the start point of the line
   1.732 +        @param x1    The x-coordinate of the end point of the line
   1.733 +        @param y1    The y-coordinate of the end point of the line
   1.734 +        @param paint The paint used to draw the line
   1.735 +    */
   1.736 +    void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1,
   1.737 +                  const SkPaint& paint);
   1.738 +
   1.739 +    /** Draw the specified rectangle using the specified paint. The rectangle
   1.740 +        will be filled or stroked based on the Style in the paint.
   1.741 +        @param rect     The rect to be drawn
   1.742 +        @param paint    The paint used to draw the rect
   1.743 +    */
   1.744 +    virtual void drawRect(const SkRect& rect, const SkPaint& paint);
   1.745 +
   1.746 +    /** Draw the specified rectangle using the specified paint. The rectangle
   1.747 +        will be filled or framed based on the Style in the paint.
   1.748 +        @param rect     The rect to be drawn
   1.749 +        @param paint    The paint used to draw the rect
   1.750 +    */
   1.751 +    void drawIRect(const SkIRect& rect, const SkPaint& paint) {
   1.752 +        SkRect r;
   1.753 +        r.set(rect);    // promotes the ints to scalars
   1.754 +        this->drawRect(r, paint);
   1.755 +    }
   1.756 +
   1.757 +    /** Draw the specified rectangle using the specified paint. The rectangle
   1.758 +        will be filled or framed based on the Style in the paint.
   1.759 +        @param left     The left side of the rectangle to be drawn
   1.760 +        @param top      The top side of the rectangle to be drawn
   1.761 +        @param right    The right side of the rectangle to be drawn
   1.762 +        @param bottom   The bottom side of the rectangle to be drawn
   1.763 +        @param paint    The paint used to draw the rect
   1.764 +    */
   1.765 +    void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
   1.766 +                        SkScalar bottom, const SkPaint& paint);
   1.767 +
   1.768 +    /** Draw the specified oval using the specified paint. The oval will be
   1.769 +        filled or framed based on the Style in the paint.
   1.770 +        @param oval     The rectangle bounds of the oval to be drawn
   1.771 +        @param paint    The paint used to draw the oval
   1.772 +    */
   1.773 +    virtual void drawOval(const SkRect& oval, const SkPaint&);
   1.774 +
   1.775 +    /**
   1.776 +     *  Draw the specified RRect using the specified paint The rrect will be filled or stroked
   1.777 +     *  based on the Style in the paint.
   1.778 +     *
   1.779 +     *  @param rrect    The round-rect to draw
   1.780 +     *  @param paint    The paint used to draw the round-rect
   1.781 +     */
   1.782 +    virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint);
   1.783 +
   1.784 +    /**
   1.785 +     *  Draw the annulus formed by the outer and inner rrects. The results
   1.786 +     *  are undefined if the outer does not contain the inner.
   1.787 +     */
   1.788 +    void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&);
   1.789 +
   1.790 +    /** Draw the specified circle using the specified paint. If radius is <= 0,
   1.791 +        then nothing will be drawn. The circle will be filled
   1.792 +        or framed based on the Style in the paint.
   1.793 +        @param cx       The x-coordinate of the center of the cirle to be drawn
   1.794 +        @param cy       The y-coordinate of the center of the cirle to be drawn
   1.795 +        @param radius   The radius of the cirle to be drawn
   1.796 +        @param paint    The paint used to draw the circle
   1.797 +    */
   1.798 +    void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius,
   1.799 +                    const SkPaint& paint);
   1.800 +
   1.801 +    /** Draw the specified arc, which will be scaled to fit inside the
   1.802 +        specified oval. If the sweep angle is >= 360, then the oval is drawn
   1.803 +        completely. Note that this differs slightly from SkPath::arcTo, which
   1.804 +        treats the sweep angle mod 360.
   1.805 +        @param oval The bounds of oval used to define the shape of the arc
   1.806 +        @param startAngle Starting angle (in degrees) where the arc begins
   1.807 +        @param sweepAngle Sweep angle (in degrees) measured clockwise
   1.808 +        @param useCenter true means include the center of the oval. For filling
   1.809 +                         this will draw a wedge. False means just use the arc.
   1.810 +        @param paint    The paint used to draw the arc
   1.811 +    */
   1.812 +    void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
   1.813 +                 bool useCenter, const SkPaint& paint);
   1.814 +
   1.815 +    /** Draw the specified round-rect using the specified paint. The round-rect
   1.816 +        will be filled or framed based on the Style in the paint.
   1.817 +        @param rect     The rectangular bounds of the roundRect to be drawn
   1.818 +        @param rx       The x-radius of the oval used to round the corners
   1.819 +        @param ry       The y-radius of the oval used to round the corners
   1.820 +        @param paint    The paint used to draw the roundRect
   1.821 +    */
   1.822 +    void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
   1.823 +                       const SkPaint& paint);
   1.824 +
   1.825 +    /** Draw the specified path using the specified paint. The path will be
   1.826 +        filled or framed based on the Style in the paint.
   1.827 +        @param path     The path to be drawn
   1.828 +        @param paint    The paint used to draw the path
   1.829 +    */
   1.830 +    virtual void drawPath(const SkPath& path, const SkPaint& paint);
   1.831 +
   1.832 +    /** Draw the specified bitmap, with its top/left corner at (x,y), using the
   1.833 +        specified paint, transformed by the current matrix. Note: if the paint
   1.834 +        contains a maskfilter that generates a mask which extends beyond the
   1.835 +        bitmap's original width/height, then the bitmap will be drawn as if it
   1.836 +        were in a Shader with CLAMP mode. Thus the color outside of the original
   1.837 +        width/height will be the edge color replicated.
   1.838 +
   1.839 +        If a shader is present on the paint it will be ignored, except in the
   1.840 +        case where the bitmap is kA8_Config. In that case, the color is
   1.841 +        generated by the shader.
   1.842 +
   1.843 +        @param bitmap   The bitmap to be drawn
   1.844 +        @param left     The position of the left side of the bitmap being drawn
   1.845 +        @param top      The position of the top side of the bitmap being drawn
   1.846 +        @param paint    The paint used to draw the bitmap, or NULL
   1.847 +    */
   1.848 +    virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
   1.849 +                            const SkPaint* paint = NULL);
   1.850 +
   1.851 +    enum DrawBitmapRectFlags {
   1.852 +        kNone_DrawBitmapRectFlag            = 0x0,
   1.853 +        /**
   1.854 +         *  When filtering is enabled, allow the color samples outside of
   1.855 +         *  the src rect (but still in the src bitmap) to bleed into the
   1.856 +         *  drawn portion
   1.857 +         */
   1.858 +        kBleed_DrawBitmapRectFlag           = 0x1,
   1.859 +    };
   1.860 +
   1.861 +    /** Draw the specified bitmap, with the specified matrix applied (before the
   1.862 +        canvas' matrix is applied).
   1.863 +        @param bitmap   The bitmap to be drawn
   1.864 +        @param src      Optional: specify the subset of the bitmap to be drawn
   1.865 +        @param dst      The destination rectangle where the scaled/translated
   1.866 +                        image will be drawn
   1.867 +        @param paint    The paint used to draw the bitmap, or NULL
   1.868 +    */
   1.869 +    virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
   1.870 +                                      const SkRect& dst,
   1.871 +                                      const SkPaint* paint = NULL,
   1.872 +                                      DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag);
   1.873 +
   1.874 +    void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
   1.875 +                        const SkPaint* paint = NULL) {
   1.876 +        this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
   1.877 +    }
   1.878 +
   1.879 +    void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc,
   1.880 +                        const SkRect& dst, const SkPaint* paint = NULL,
   1.881 +                        DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) {
   1.882 +        SkRect realSrcStorage;
   1.883 +        SkRect* realSrcPtr = NULL;
   1.884 +        if (isrc) {
   1.885 +            realSrcStorage.set(*isrc);
   1.886 +            realSrcPtr = &realSrcStorage;
   1.887 +        }
   1.888 +        this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags);
   1.889 +    }
   1.890 +
   1.891 +    virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
   1.892 +                                  const SkPaint* paint = NULL);
   1.893 +
   1.894 +    /**
   1.895 +     *  Draw the bitmap stretched differentially to fit into dst.
   1.896 +     *  center is a rect within the bitmap, and logically divides the bitmap
   1.897 +     *  into 9 sections (3x3). For example, if the middle pixel of a [5x5]
   1.898 +     *  bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
   1.899 +     *
   1.900 +     *  If the dst is >= the bitmap size, then...
   1.901 +     *  - The 4 corners are not stretched at all.
   1.902 +     *  - The sides are stretched in only one axis.
   1.903 +     *  - The center is stretched in both axes.
   1.904 +     * Else, for each axis where dst < bitmap,
   1.905 +     *  - The corners shrink proportionally
   1.906 +     *  - The sides (along the shrink axis) and center are not drawn
   1.907 +     */
   1.908 +    virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
   1.909 +                                const SkRect& dst, const SkPaint* paint = NULL);
   1.910 +
   1.911 +    /** Draw the specified bitmap, with its top/left corner at (x,y),
   1.912 +        NOT transformed by the current matrix. Note: if the paint
   1.913 +        contains a maskfilter that generates a mask which extends beyond the
   1.914 +        bitmap's original width/height, then the bitmap will be drawn as if it
   1.915 +        were in a Shader with CLAMP mode. Thus the color outside of the original
   1.916 +        width/height will be the edge color replicated.
   1.917 +        @param bitmap   The bitmap to be drawn
   1.918 +        @param left     The position of the left side of the bitmap being drawn
   1.919 +        @param top      The position of the top side of the bitmap being drawn
   1.920 +        @param paint    The paint used to draw the bitmap, or NULL
   1.921 +    */
   1.922 +    virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
   1.923 +                            const SkPaint* paint = NULL);
   1.924 +
   1.925 +    /** Draw the text, with origin at (x,y), using the specified paint.
   1.926 +        The origin is interpreted based on the Align setting in the paint.
   1.927 +        @param text The text to be drawn
   1.928 +        @param byteLength   The number of bytes to read from the text parameter
   1.929 +        @param x        The x-coordinate of the origin of the text being drawn
   1.930 +        @param y        The y-coordinate of the origin of the text being drawn
   1.931 +        @param paint    The paint used for the text (e.g. color, size, style)
   1.932 +    */
   1.933 +    virtual void drawText(const void* text, size_t byteLength, SkScalar x,
   1.934 +                          SkScalar y, const SkPaint& paint);
   1.935 +
   1.936 +    /** Draw the text, with each character/glyph origin specified by the pos[]
   1.937 +        array. The origin is interpreted by the Align setting in the paint.
   1.938 +        @param text The text to be drawn
   1.939 +        @param byteLength   The number of bytes to read from the text parameter
   1.940 +        @param pos      Array of positions, used to position each character
   1.941 +        @param paint    The paint used for the text (e.g. color, size, style)
   1.942 +        */
   1.943 +    virtual void drawPosText(const void* text, size_t byteLength,
   1.944 +                             const SkPoint pos[], const SkPaint& paint);
   1.945 +
   1.946 +    /** Draw the text, with each character/glyph origin specified by the x
   1.947 +        coordinate taken from the xpos[] array, and the y from the constY param.
   1.948 +        The origin is interpreted by the Align setting in the paint.
   1.949 +        @param text The text to be drawn
   1.950 +        @param byteLength   The number of bytes to read from the text parameter
   1.951 +        @param xpos     Array of x-positions, used to position each character
   1.952 +        @param constY   The shared Y coordinate for all of the positions
   1.953 +        @param paint    The paint used for the text (e.g. color, size, style)
   1.954 +        */
   1.955 +    virtual void drawPosTextH(const void* text, size_t byteLength,
   1.956 +                              const SkScalar xpos[], SkScalar constY,
   1.957 +                              const SkPaint& paint);
   1.958 +
   1.959 +    /** Draw the text, with origin at (x,y), using the specified paint, along
   1.960 +        the specified path. The paint's Align setting determins where along the
   1.961 +        path to start the text.
   1.962 +        @param text The text to be drawn
   1.963 +        @param byteLength   The number of bytes to read from the text parameter
   1.964 +        @param path         The path the text should follow for its baseline
   1.965 +        @param hOffset      The distance along the path to add to the text's
   1.966 +                            starting position
   1.967 +        @param vOffset      The distance above(-) or below(+) the path to
   1.968 +                            position the text
   1.969 +        @param paint        The paint used for the text
   1.970 +    */
   1.971 +    void drawTextOnPathHV(const void* text, size_t byteLength,
   1.972 +                          const SkPath& path, SkScalar hOffset,
   1.973 +                          SkScalar vOffset, const SkPaint& paint);
   1.974 +
   1.975 +    /** Draw the text, with origin at (x,y), using the specified paint, along
   1.976 +        the specified path. The paint's Align setting determins where along the
   1.977 +        path to start the text.
   1.978 +        @param text The text to be drawn
   1.979 +        @param byteLength   The number of bytes to read from the text parameter
   1.980 +        @param path         The path the text should follow for its baseline
   1.981 +        @param matrix       (may be null) Applied to the text before it is
   1.982 +                            mapped onto the path
   1.983 +        @param paint        The paint used for the text
   1.984 +        */
   1.985 +    virtual void drawTextOnPath(const void* text, size_t byteLength,
   1.986 +                                const SkPath& path, const SkMatrix* matrix,
   1.987 +                                const SkPaint& paint);
   1.988 +
   1.989 +    /** PRIVATE / EXPERIMENTAL -- do not call
   1.990 +        Perform back-end analysis/optimization of a picture. This may attach
   1.991 +        optimization data to the picture which can be used by a later
   1.992 +        drawPicture call.
   1.993 +        @param picture The recorded drawing commands to analyze/optimize
   1.994 +    */
   1.995 +    void EXPERIMENTAL_optimize(SkPicture* picture);
   1.996 +
   1.997 +    /** Draw the picture into this canvas. This method effective brackets the
   1.998 +        playback of the picture's draw calls with save/restore, so the state
   1.999 +        of this canvas will be unchanged after this call.
  1.1000 +        @param picture The recorded drawing commands to playback into this
  1.1001 +                       canvas.
  1.1002 +    */
  1.1003 +    virtual void drawPicture(SkPicture& picture);
  1.1004 +
  1.1005 +    enum VertexMode {
  1.1006 +        kTriangles_VertexMode,
  1.1007 +        kTriangleStrip_VertexMode,
  1.1008 +        kTriangleFan_VertexMode
  1.1009 +    };
  1.1010 +
  1.1011 +    /** Draw the array of vertices, interpreted as triangles (based on mode).
  1.1012 +        @param vmode How to interpret the array of vertices
  1.1013 +        @param vertexCount The number of points in the vertices array (and
  1.1014 +                    corresponding texs and colors arrays if non-null)
  1.1015 +        @param vertices Array of vertices for the mesh
  1.1016 +        @param texs May be null. If not null, specifies the coordinate
  1.1017 +                    in _texture_ space (not uv space) for each vertex.
  1.1018 +        @param colors May be null. If not null, specifies a color for each
  1.1019 +                      vertex, to be interpolated across the triangle.
  1.1020 +        @param xmode Used if both texs and colors are present. In this
  1.1021 +                    case the colors are combined with the texture using mode,
  1.1022 +                    before being drawn using the paint. If mode is null, then
  1.1023 +                    kModulate_Mode is used.
  1.1024 +        @param indices If not null, array of indices to reference into the
  1.1025 +                    vertex (texs, colors) array.
  1.1026 +        @param indexCount number of entries in the indices array (if not null)
  1.1027 +        @param paint Specifies the shader/texture if present.
  1.1028 +    */
  1.1029 +    virtual void drawVertices(VertexMode vmode, int vertexCount,
  1.1030 +                              const SkPoint vertices[], const SkPoint texs[],
  1.1031 +                              const SkColor colors[], SkXfermode* xmode,
  1.1032 +                              const uint16_t indices[], int indexCount,
  1.1033 +                              const SkPaint& paint);
  1.1034 +
  1.1035 +    /** Send a blob of data to the canvas.
  1.1036 +        For canvases that draw, this call is effectively a no-op, as the data
  1.1037 +        is not parsed, but just ignored. However, this call exists for
  1.1038 +        subclasses like SkPicture's recording canvas, that can store the data
  1.1039 +        and then play it back later (via another call to drawData).
  1.1040 +     */
  1.1041 +    virtual void drawData(const void* data, size_t length) {
  1.1042 +        // do nothing. Subclasses may do something with the data
  1.1043 +    }
  1.1044 +
  1.1045 +    /** Add comments. beginCommentGroup/endCommentGroup open/close a new group.
  1.1046 +        Each comment added via addComment is notionally attached to its
  1.1047 +        enclosing group. Top-level comments simply belong to no group.
  1.1048 +     */
  1.1049 +    virtual void beginCommentGroup(const char* description) {
  1.1050 +        // do nothing. Subclasses may do something
  1.1051 +    }
  1.1052 +    virtual void addComment(const char* kywd, const char* value) {
  1.1053 +        // do nothing. Subclasses may do something
  1.1054 +    }
  1.1055 +    virtual void endCommentGroup() {
  1.1056 +        // do nothing. Subclasses may do something
  1.1057 +    }
  1.1058 +
  1.1059 +    /**
  1.1060 +     *  With this call the client asserts that subsequent draw operations (up to the
  1.1061 +     *  matching popCull()) are fully contained within the given bounding box. The assertion
  1.1062 +     *  is not enforced, but the information might be used to quick-reject command blocks,
  1.1063 +     *  so an incorrect bounding box may result in incomplete rendering.
  1.1064 +     */
  1.1065 +    void pushCull(const SkRect& cullRect) {
  1.1066 +        ++fCullCount;
  1.1067 +        this->onPushCull(cullRect);
  1.1068 +    }
  1.1069 +
  1.1070 +    /**
  1.1071 +     *  Terminates the current culling block, and restores the previous one (if any).
  1.1072 +     */
  1.1073 +    void popCull() {
  1.1074 +        if (fCullCount > 0) {
  1.1075 +            --fCullCount;
  1.1076 +            this->onPopCull();
  1.1077 +        }
  1.1078 +    }
  1.1079 +    //////////////////////////////////////////////////////////////////////////
  1.1080 +
  1.1081 +    /** Get the current bounder object.
  1.1082 +        The bounder's reference count is unchaged.
  1.1083 +        @return the canva's bounder (or NULL).
  1.1084 +    */
  1.1085 +    SkBounder*  getBounder() const { return fBounder; }
  1.1086 +
  1.1087 +    /** Set a new bounder (or NULL).
  1.1088 +        Pass NULL to clear any previous bounder.
  1.1089 +        As a convenience, the parameter passed is also returned.
  1.1090 +        If a previous bounder exists, its reference count is decremented.
  1.1091 +        If bounder is not NULL, its reference count is incremented.
  1.1092 +        @param bounder the new bounder (or NULL) to be installed in the canvas
  1.1093 +        @return the set bounder object
  1.1094 +    */
  1.1095 +    virtual SkBounder* setBounder(SkBounder* bounder);
  1.1096 +
  1.1097 +    /** Get the current filter object. The filter's reference count is not
  1.1098 +        affected. The filter is saved/restored, just like the matrix and clip.
  1.1099 +        @return the canvas' filter (or NULL).
  1.1100 +    */
  1.1101 +    SkDrawFilter* getDrawFilter() const;
  1.1102 +
  1.1103 +    /** Set the new filter (or NULL). Pass NULL to clear any existing filter.
  1.1104 +        As a convenience, the parameter is returned. If an existing filter
  1.1105 +        exists, its refcnt is decrement. If the new filter is not null, its
  1.1106 +        refcnt is incremented. The filter is saved/restored, just like the
  1.1107 +        matrix and clip.
  1.1108 +        @param filter the new filter (or NULL)
  1.1109 +        @return the new filter
  1.1110 +    */
  1.1111 +    virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
  1.1112 +
  1.1113 +    //////////////////////////////////////////////////////////////////////////
  1.1114 +
  1.1115 +    /**
  1.1116 +     *  Return true if the current clip is empty (i.e. nothing will draw).
  1.1117 +     *  Note: this is not always a free call, so it should not be used
  1.1118 +     *  more often than necessary. However, once the canvas has computed this
  1.1119 +     *  result, subsequent calls will be cheap (until the clip state changes,
  1.1120 +     *  which can happen on any clip..() or restore() call.
  1.1121 +     */
  1.1122 +    virtual bool isClipEmpty() const;
  1.1123 +
  1.1124 +    /**
  1.1125 +     *  Returns true if the current clip is just a (non-empty) rectangle.
  1.1126 +     *  Returns false if the clip is empty, or if it is complex.
  1.1127 +     */
  1.1128 +    virtual bool isClipRect() const;
  1.1129 +
  1.1130 +    /** Return the current matrix on the canvas.
  1.1131 +        This does not account for the translate in any of the devices.
  1.1132 +        @return The current matrix on the canvas.
  1.1133 +    */
  1.1134 +    const SkMatrix& getTotalMatrix() const;
  1.1135 +
  1.1136 +#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE
  1.1137 +    enum ClipType {
  1.1138 +        kEmpty_ClipType = 0,
  1.1139 +        kRect_ClipType,
  1.1140 +        kComplex_ClipType
  1.1141 +    };
  1.1142 +    /** Returns a description of the total clip; may be cheaper than
  1.1143 +        getting the clip and querying it directly.
  1.1144 +    */
  1.1145 +    virtual ClipType getClipType() const;
  1.1146 +#endif
  1.1147 +
  1.1148 +#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP
  1.1149 +    /** DEPRECATED -- need to move this guy to private/friend
  1.1150 +     *  Return the current device clip (concatenation of all clip calls).
  1.1151 +     *  This does not account for the translate in any of the devices.
  1.1152 +     *  @return the current device clip (concatenation of all clip calls).
  1.1153 +     */
  1.1154 +    const SkRegion& getTotalClip() const;
  1.1155 +#endif
  1.1156 +
  1.1157 +    /** Return the clip stack. The clip stack stores all the individual
  1.1158 +     *  clips organized by the save/restore frame in which they were
  1.1159 +     *  added.
  1.1160 +     *  @return the current clip stack ("list" of individual clip elements)
  1.1161 +     */
  1.1162 +    const SkClipStack* getClipStack() const {
  1.1163 +        return &fClipStack;
  1.1164 +    }
  1.1165 +
  1.1166 +    class ClipVisitor {
  1.1167 +    public:
  1.1168 +        virtual ~ClipVisitor();
  1.1169 +        virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
  1.1170 +        virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
  1.1171 +        virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
  1.1172 +    };
  1.1173 +
  1.1174 +    /**
  1.1175 +     *  Replays the clip operations, back to front, that have been applied to
  1.1176 +     *  the canvas, calling the appropriate method on the visitor for each
  1.1177 +     *  clip. All clips have already been transformed into device space.
  1.1178 +     */
  1.1179 +    void replayClips(ClipVisitor*) const;
  1.1180 +
  1.1181 +    ///////////////////////////////////////////////////////////////////////////
  1.1182 +
  1.1183 +    /** After calling saveLayer(), there can be any number of devices that make
  1.1184 +        up the top-most drawing area. LayerIter can be used to iterate through
  1.1185 +        those devices. Note that the iterator is only valid until the next API
  1.1186 +        call made on the canvas. Ownership of all pointers in the iterator stays
  1.1187 +        with the canvas, so none of them should be modified or deleted.
  1.1188 +    */
  1.1189 +    class SK_API LayerIter /*: SkNoncopyable*/ {
  1.1190 +    public:
  1.1191 +        /** Initialize iterator with canvas, and set values for 1st device */
  1.1192 +        LayerIter(SkCanvas*, bool skipEmptyClips);
  1.1193 +        ~LayerIter();
  1.1194 +
  1.1195 +        /** Return true if the iterator is done */
  1.1196 +        bool done() const { return fDone; }
  1.1197 +        /** Cycle to the next device */
  1.1198 +        void next();
  1.1199 +
  1.1200 +        // These reflect the current device in the iterator
  1.1201 +
  1.1202 +        SkBaseDevice*   device() const;
  1.1203 +        const SkMatrix& matrix() const;
  1.1204 +        const SkRegion& clip() const;
  1.1205 +        const SkPaint&  paint() const;
  1.1206 +        int             x() const;
  1.1207 +        int             y() const;
  1.1208 +
  1.1209 +    private:
  1.1210 +        // used to embed the SkDrawIter object directly in our instance, w/o
  1.1211 +        // having to expose that class def to the public. There is an assert
  1.1212 +        // in our constructor to ensure that fStorage is large enough
  1.1213 +        // (though needs to be a compile-time-assert!). We use intptr_t to work
  1.1214 +        // safely with 32 and 64 bit machines (to ensure the storage is enough)
  1.1215 +        intptr_t          fStorage[32];
  1.1216 +        class SkDrawIter* fImpl;    // this points at fStorage
  1.1217 +        SkPaint           fDefaultPaint;
  1.1218 +        bool              fDone;
  1.1219 +    };
  1.1220 +
  1.1221 +    // don't call
  1.1222 +    const SkRegion& internal_private_getTotalClip() const;
  1.1223 +    // don't call
  1.1224 +    void internal_private_getTotalClipAsPath(SkPath*) const;
  1.1225 +    // don't call
  1.1226 +    GrRenderTarget* internal_private_accessTopLayerRenderTarget();
  1.1227 +
  1.1228 +protected:
  1.1229 +    // default impl defers to getDevice()->newSurface(info)
  1.1230 +    virtual SkSurface* onNewSurface(const SkImageInfo&);
  1.1231 +
  1.1232 +    // default impl defers to its device
  1.1233 +    virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes);
  1.1234 +    virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes);
  1.1235 +
  1.1236 +    // Subclass save/restore notifiers.
  1.1237 +    // Overriders should call the corresponding INHERITED method up the inheritance chain.
  1.1238 +    // willSaveLayer()'s return value may suppress full layer allocation.
  1.1239 +    enum SaveLayerStrategy {
  1.1240 +        kFullLayer_SaveLayerStrategy,
  1.1241 +        kNoLayer_SaveLayerStrategy
  1.1242 +    };
  1.1243 +    virtual void willSave(SaveFlags);
  1.1244 +    virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags);
  1.1245 +    virtual void willRestore();
  1.1246 +
  1.1247 +    virtual void didTranslate(SkScalar, SkScalar);
  1.1248 +    virtual void didScale(SkScalar, SkScalar);
  1.1249 +    virtual void didRotate(SkScalar);
  1.1250 +    virtual void didSkew(SkScalar, SkScalar);
  1.1251 +    virtual void didConcat(const SkMatrix&);
  1.1252 +    virtual void didSetMatrix(const SkMatrix&);
  1.1253 +
  1.1254 +    virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
  1.1255 +
  1.1256 +    enum ClipEdgeStyle {
  1.1257 +        kHard_ClipEdgeStyle,
  1.1258 +        kSoft_ClipEdgeStyle
  1.1259 +    };
  1.1260 +
  1.1261 +    virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
  1.1262 +    virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
  1.1263 +    virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle);
  1.1264 +    virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op);
  1.1265 +
  1.1266 +    // Returns the canvas to be used by DrawIter. Default implementation
  1.1267 +    // returns this. Subclasses that encapsulate an indirect canvas may
  1.1268 +    // need to overload this method. The impl must keep track of this, as it
  1.1269 +    // is not released or deleted by the caller.
  1.1270 +    virtual SkCanvas* canvasForDrawIter();
  1.1271 +
  1.1272 +    // Clip rectangle bounds. Called internally by saveLayer.
  1.1273 +    // returns false if the entire rectangle is entirely clipped out
  1.1274 +    // If non-NULL, The imageFilter parameter will be used to expand the clip
  1.1275 +    // and offscreen bounds for any margin required by the filter DAG.
  1.1276 +    bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
  1.1277 +                        SkIRect* intersection,
  1.1278 +                        const SkImageFilter* imageFilter = NULL);
  1.1279 +
  1.1280 +    // Called by child classes that override clipPath and clipRRect to only
  1.1281 +    // track fast conservative clip bounds, rather than exact clips.
  1.1282 +    void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op,
  1.1283 +                                             bool inverseFilled);
  1.1284 +
  1.1285 +    // notify our surface (if we have one) that we are about to draw, so it
  1.1286 +    // can perform copy-on-write or invalidate any cached images
  1.1287 +    void predrawNotify();
  1.1288 +
  1.1289 +    virtual void onPushCull(const SkRect& cullRect);
  1.1290 +    virtual void onPopCull();
  1.1291 +
  1.1292 +private:
  1.1293 +    class MCRec;
  1.1294 +
  1.1295 +    SkClipStack fClipStack;
  1.1296 +    SkDeque     fMCStack;
  1.1297 +    // points to top of stack
  1.1298 +    MCRec*      fMCRec;
  1.1299 +    // the first N recs that can fit here mean we won't call malloc
  1.1300 +    uint32_t    fMCRecStorage[32];
  1.1301 +
  1.1302 +    SkBounder*  fBounder;
  1.1303 +    int         fSaveLayerCount;    // number of successful saveLayer calls
  1.1304 +    int         fCullCount;         // number of active culls
  1.1305 +
  1.1306 +    SkMetaData* fMetaData;
  1.1307 +
  1.1308 +    SkSurface_Base*  fSurfaceBase;
  1.1309 +    SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
  1.1310 +    void setSurfaceBase(SkSurface_Base* sb) {
  1.1311 +        fSurfaceBase = sb;
  1.1312 +    }
  1.1313 +    friend class SkSurface_Base;
  1.1314 +    friend class SkSurface_Gpu;
  1.1315 +
  1.1316 +    bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
  1.1317 +    void updateDeviceCMCache();
  1.1318 +
  1.1319 +    friend class SkDrawIter;        // needs setupDrawForLayerDevice()
  1.1320 +    friend class AutoDrawLooper;
  1.1321 +    friend class SkLua;             // needs top layer size and offset
  1.1322 +    friend class SkDeferredDevice;  // needs getTopDevice()
  1.1323 +
  1.1324 +    SkBaseDevice* createLayerDevice(const SkImageInfo&);
  1.1325 +
  1.1326 +    SkBaseDevice* init(SkBaseDevice*);
  1.1327 +
  1.1328 +    /**
  1.1329 +     *  DEPRECATED
  1.1330 +     *
  1.1331 +     *  Specify a device for this canvas to draw into. If it is not null, its
  1.1332 +     *  reference count is incremented. If the canvas was already holding a
  1.1333 +     *  device, its reference count is decremented. The new device is returned.
  1.1334 +     */
  1.1335 +    SkBaseDevice* setRootDevice(SkBaseDevice* device);
  1.1336 +
  1.1337 +    /**
  1.1338 +     * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this
  1.1339 +     * to be public because it exposes decisions about layer sizes that are internal to the canvas.
  1.1340 +     */
  1.1341 +    SkISize getTopLayerSize() const;
  1.1342 +    SkIPoint getTopLayerOrigin() const;
  1.1343 +
  1.1344 +    // internal methods are not virtual, so they can safely be called by other
  1.1345 +    // canvas apis, without confusing subclasses (like SkPictureRecording)
  1.1346 +    void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint);
  1.1347 +    void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
  1.1348 +                                const SkRect& dst, const SkPaint* paint,
  1.1349 +                                DrawBitmapRectFlags flags);
  1.1350 +    void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
  1.1351 +                                const SkRect& dst, const SkPaint* paint);
  1.1352 +    void internalDrawPaint(const SkPaint& paint);
  1.1353 +    int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
  1.1354 +                          SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy);
  1.1355 +    void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
  1.1356 +
  1.1357 +    // shared by save() and saveLayer()
  1.1358 +    int internalSave(SaveFlags flags);
  1.1359 +    void internalRestore();
  1.1360 +    static void DrawRect(const SkDraw& draw, const SkPaint& paint,
  1.1361 +                         const SkRect& r, SkScalar textSize);
  1.1362 +    static void DrawTextDecorations(const SkDraw& draw, const SkPaint& paint,
  1.1363 +                                    const char text[], size_t byteLength,
  1.1364 +                                    SkScalar x, SkScalar y);
  1.1365 +
  1.1366 +    /*  These maintain a cache of the clip bounds in local coordinates,
  1.1367 +        (converted to 2s-compliment if floats are slow).
  1.1368 +     */
  1.1369 +    mutable SkRect fCachedLocalClipBounds;
  1.1370 +    mutable bool   fCachedLocalClipBoundsDirty;
  1.1371 +    bool fAllowSoftClip;
  1.1372 +    bool fAllowSimplifyClip;
  1.1373 +
  1.1374 +    const SkRect& getLocalClipBounds() const {
  1.1375 +        if (fCachedLocalClipBoundsDirty) {
  1.1376 +            if (!this->getClipBounds(&fCachedLocalClipBounds)) {
  1.1377 +                fCachedLocalClipBounds.setEmpty();
  1.1378 +            }
  1.1379 +            fCachedLocalClipBoundsDirty = false;
  1.1380 +        }
  1.1381 +        return fCachedLocalClipBounds;
  1.1382 +    }
  1.1383 +
  1.1384 +    class AutoValidateClip : ::SkNoncopyable {
  1.1385 +    public:
  1.1386 +        explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
  1.1387 +            fCanvas->validateClip();
  1.1388 +        }
  1.1389 +        ~AutoValidateClip() { fCanvas->validateClip(); }
  1.1390 +
  1.1391 +    private:
  1.1392 +        const SkCanvas* fCanvas;
  1.1393 +    };
  1.1394 +
  1.1395 +#ifdef SK_DEBUG
  1.1396 +    void validateClip() const;
  1.1397 +#else
  1.1398 +    void validateClip() const {}
  1.1399 +#endif
  1.1400 +
  1.1401 +    typedef SkRefCnt INHERITED;
  1.1402 +};
  1.1403 +
  1.1404 +/** Stack helper class to automatically call restoreToCount() on the canvas
  1.1405 +    when this object goes out of scope. Use this to guarantee that the canvas
  1.1406 +    is restored to a known state.
  1.1407 +*/
  1.1408 +class SkAutoCanvasRestore : SkNoncopyable {
  1.1409 +public:
  1.1410 +    SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
  1.1411 +        if (fCanvas) {
  1.1412 +            fSaveCount = canvas->getSaveCount();
  1.1413 +            if (doSave) {
  1.1414 +                canvas->save();
  1.1415 +            }
  1.1416 +        }
  1.1417 +    }
  1.1418 +    ~SkAutoCanvasRestore() {
  1.1419 +        if (fCanvas) {
  1.1420 +            fCanvas->restoreToCount(fSaveCount);
  1.1421 +        }
  1.1422 +    }
  1.1423 +
  1.1424 +    /**
  1.1425 +     *  Perform the restore now, instead of waiting for the destructor. Will
  1.1426 +     *  only do this once.
  1.1427 +     */
  1.1428 +    void restore() {
  1.1429 +        if (fCanvas) {
  1.1430 +            fCanvas->restoreToCount(fSaveCount);
  1.1431 +            fCanvas = NULL;
  1.1432 +        }
  1.1433 +    }
  1.1434 +
  1.1435 +private:
  1.1436 +    SkCanvas*   fCanvas;
  1.1437 +    int         fSaveCount;
  1.1438 +};
  1.1439 +#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
  1.1440 +
  1.1441 +/** Stack helper class to automatically open and close a comment block
  1.1442 + */
  1.1443 +class SkAutoCommentBlock : SkNoncopyable {
  1.1444 +public:
  1.1445 +    SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
  1.1446 +        fCanvas = canvas;
  1.1447 +        if (NULL != fCanvas) {
  1.1448 +            fCanvas->beginCommentGroup(description);
  1.1449 +        }
  1.1450 +    }
  1.1451 +
  1.1452 +    ~SkAutoCommentBlock() {
  1.1453 +        if (NULL != fCanvas) {
  1.1454 +            fCanvas->endCommentGroup();
  1.1455 +        }
  1.1456 +    }
  1.1457 +
  1.1458 +private:
  1.1459 +    SkCanvas* fCanvas;
  1.1460 +};
  1.1461 +#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock)
  1.1462 +
  1.1463 +/**
  1.1464 + *  If the caller wants read-only access to the pixels in a canvas, it can just
  1.1465 + *  call canvas->peekPixels(), since that is the fastest way to "peek" at the
  1.1466 + *  pixels on a raster-backed canvas.
  1.1467 + *
  1.1468 + *  If the canvas has pixels, but they are not readily available to the CPU
  1.1469 + *  (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will
  1.1470 + *  succeed (though be slower, since it will return a copy of the pixels).
  1.1471 + *
  1.1472 + *  SkAutoROCanvasPixels encapsulates these two techniques, trying first to call
  1.1473 + *  peekPixels() (for performance), but if that fails, calling readPixels() and
  1.1474 + *  storing the copy locally.
  1.1475 + *
  1.1476 + *  The caller must respect the restrictions associated with peekPixels(), since
  1.1477 + *  that may have been called: The returned information is invalidated if...
  1.1478 + *      - any API is called on the canvas (or its parent surface if present)
  1.1479 + *      - the canvas goes out of scope
  1.1480 + */
  1.1481 +class SkAutoROCanvasPixels : SkNoncopyable {
  1.1482 +public:
  1.1483 +    SkAutoROCanvasPixels(SkCanvas* canvas);
  1.1484 +
  1.1485 +    // returns NULL on failure
  1.1486 +    const void* addr() const { return fAddr; }
  1.1487 +
  1.1488 +    // undefined if addr() == NULL
  1.1489 +    size_t rowBytes() const { return fRowBytes; }
  1.1490 +
  1.1491 +    // undefined if addr() == NULL
  1.1492 +    const SkImageInfo& info() const { return fInfo; }
  1.1493 +
  1.1494 +    // helper that, if returns true, installs the pixels into the bitmap. Note
  1.1495 +    // that the bitmap may reference the address returned by peekPixels(), so
  1.1496 +    // the caller must respect the restrictions associated with peekPixels().
  1.1497 +    bool asROBitmap(SkBitmap*) const;
  1.1498 +
  1.1499 +private:
  1.1500 +    SkBitmap    fBitmap;    // used if peekPixels() fails
  1.1501 +    const void* fAddr;      // NULL on failure
  1.1502 +    SkImageInfo fInfo;
  1.1503 +    size_t      fRowBytes;
  1.1504 +};
  1.1505 +
  1.1506 +#endif

mercurial