Move SkBitmapDevice functions to their own file

https://codereview.chromium.org/23553006/



git-svn-id: http://skia.googlecode.com/svn/trunk/src@11022 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkBitmapDevice.cpp b/core/SkBitmapDevice.cpp
new file mode 100644
index 0000000..0c20259
--- /dev/null
+++ b/core/SkBitmapDevice.cpp
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBitmapDevice.h"
+#include "SkConfig8888.h"
+#include "SkDraw.h"
+#include "SkRasterClip.h"
+#include "SkShader.h"
+
+SK_DEFINE_INST_COUNT(SkBitmapDevice)
+
+#define CHECK_FOR_NODRAW_ANNOTATION(paint) \
+    do { if (paint.isNoDrawAnnotation()) { return; } } while (0)
+
+SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
+    : fBitmap(bitmap) {
+    SkASSERT(SkBitmap::kARGB_4444_Config != bitmap.config());
+}
+
+SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
+    : SkBaseDevice(deviceProperties)
+    , fBitmap(bitmap) {
+}
+
+SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
+    fBitmap.setConfig(config, width, height);
+    fBitmap.allocPixels();
+    fBitmap.setIsOpaque(isOpaque);
+    if (!isOpaque) {
+        fBitmap.eraseColor(SK_ColorTRANSPARENT);
+    }
+}
+
+SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
+                               const SkDeviceProperties& deviceProperties)
+    : SkBaseDevice(deviceProperties) {
+
+    fBitmap.setConfig(config, width, height);
+    fBitmap.allocPixels();
+    fBitmap.setIsOpaque(isOpaque);
+    if (!isOpaque) {
+        fBitmap.eraseColor(SK_ColorTRANSPARENT);
+    }
+}
+
+SkBitmapDevice::~SkBitmapDevice() {
+}
+
+void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
+    SkASSERT(bm.width() == fBitmap.width());
+    SkASSERT(bm.height() == fBitmap.height());
+    fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
+    fBitmap.lockPixels();
+}
+
+SkBaseDevice* SkBitmapDevice::onCreateCompatibleDevice(SkBitmap::Config config,
+                                                       int width, int height,
+                                                       bool isOpaque,
+                                                       Usage usage) {
+    return SkNEW_ARGS(SkBitmapDevice,(config, width, height, isOpaque,
+                                      this->getDeviceProperties()));
+}
+
+void SkBitmapDevice::lockPixels() {
+    if (fBitmap.lockPixelsAreWritable()) {
+        fBitmap.lockPixels();
+    }
+}
+
+void SkBitmapDevice::unlockPixels() {
+    if (fBitmap.lockPixelsAreWritable()) {
+        fBitmap.unlockPixels();
+    }
+}
+
+void SkBitmapDevice::getGlobalBounds(SkIRect* bounds) const {
+    if (NULL != bounds) {
+        const SkIPoint& origin = this->getOrigin();
+        bounds->setXYWH(origin.x(), origin.y(),
+                        fBitmap.width(), fBitmap.height());
+    }
+}
+
+void SkBitmapDevice::clear(SkColor color) {
+    fBitmap.eraseColor(color);
+}
+
+const SkBitmap& SkBitmapDevice::onAccessBitmap() {
+    return fBitmap;
+}
+
+bool SkBitmapDevice::canHandleImageFilter(SkImageFilter*) {
+    return false;
+}
+
+bool SkBitmapDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
+                                 const SkMatrix& ctm, SkBitmap* result,
+                                 SkIPoint* offset) {
+    return false;
+}
+
+bool SkBitmapDevice::allowImageFilter(SkImageFilter*) {
+    return true;
+}
+
+bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap,
+                                  int x, int y,
+                                  SkCanvas::Config8888 config8888) {
+    SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
+    SkASSERT(!bitmap.isNull());
+    SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, 
+                                                                          bitmap.width(), 
+                                                                          bitmap.height())));
+
+    SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height());
+    const SkBitmap& src = this->accessBitmap(false);
+
+    SkBitmap subset;
+    if (!src.extractSubset(&subset, srcRect)) {
+        return false;
+    }
+    if (SkBitmap::kARGB_8888_Config != subset.config()) {
+        // It'd be preferable to do this directly to bitmap.
+        subset.copyTo(&subset, SkBitmap::kARGB_8888_Config);
+    }
+    SkAutoLockPixels alp(bitmap);
+    uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
+    SkCopyBitmapToConfig8888(bmpPixels, bitmap.rowBytes(), config8888, subset);
+    return true;
+}
+
+void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
+                                 int x, int y,
+                                 SkCanvas::Config8888 config8888) {
+    if (bitmap.isNull() || bitmap.getTexture()) {
+        return;
+    }
+    const SkBitmap* sprite = &bitmap;
+    // check whether we have to handle a config8888 that doesn't match SkPMColor
+    if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
+        SkCanvas::kNative_Premul_Config8888 != config8888 &&
+        kPMColorAlias != config8888) {
+
+        // We're going to have to convert from a config8888 to the native config
+        // First we clip to the device bounds.
+        SkBitmap dstBmp = this->accessBitmap(true);
+        SkIRect spriteRect = SkIRect::MakeXYWH(x, y,
+                                               bitmap.width(), bitmap.height());
+        SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height());
+        if (!spriteRect.intersect(devRect)) {
+            return;
+        }
+
+        // write directly to the device if it has pixels and is SkPMColor
+        bool drawSprite;
+        if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) {
+            // we can write directly to the dst when doing the conversion
+            dstBmp.extractSubset(&dstBmp, spriteRect);
+            drawSprite = false;
+        } else {
+            // we convert to a temporary bitmap and draw that as a sprite
+            dstBmp.setConfig(SkBitmap::kARGB_8888_Config,
+                             spriteRect.width(),
+                             spriteRect.height());
+            if (!dstBmp.allocPixels()) {
+                return;
+            }
+            drawSprite = true;
+        }
+
+        // copy pixels to dstBmp and convert from config8888 to native config.
+        SkAutoLockPixels alp(bitmap);
+        uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x,
+                                               spriteRect.fTop - y);
+        SkCopyConfig8888ToBitmap(dstBmp,
+                                 srcPixels,
+                                 bitmap.rowBytes(),
+                                 config8888);
+
+        if (drawSprite) {
+            // we've clipped the sprite when we made a copy
+            x = spriteRect.fLeft;
+            y = spriteRect.fTop;
+            sprite = &dstBmp;
+        } else {
+            return;
+        }
+    }
+
+    SkPaint paint;
+    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+    SkRasterClip clip(SkIRect::MakeWH(fBitmap.width(), fBitmap.height()));
+    SkDraw  draw;
+    draw.fRC = &clip;
+    draw.fClip = &clip.bwRgn();
+    draw.fBitmap = &fBitmap; // canvas should have already called accessBitmap
+    draw.fMatrix = &SkMatrix::I();
+    this->drawSprite(draw, *sprite, x, y, paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
+    draw.drawPaint(paint);
+}
+
+void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
+                                const SkPoint pts[], const SkPaint& paint) {
+    CHECK_FOR_NODRAW_ANNOTATION(paint);
+    draw.drawPoints(mode, count, pts, paint);
+}
+
+void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
+    CHECK_FOR_NODRAW_ANNOTATION(paint);
+    draw.drawRect(r, paint);
+}
+
+void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+    CHECK_FOR_NODRAW_ANNOTATION(paint);
+
+    SkPath path;
+    path.addOval(oval);
+    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
+    // required to override drawOval.
+    this->drawPath(draw, path, paint, NULL, true);
+}
+
+void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
+    CHECK_FOR_NODRAW_ANNOTATION(paint);
+
+    SkPath  path;
+    path.addRRect(rrect);
+    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
+    // required to override drawRRect.
+    this->drawPath(draw, path, paint, NULL, true);
+}
+
+void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
+                              const SkPaint& paint, const SkMatrix* prePathMatrix,
+                              bool pathIsMutable) {
+    CHECK_FOR_NODRAW_ANNOTATION(paint);
+    draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
+}
+
+void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
+                                const SkMatrix& matrix, const SkPaint& paint) {
+    draw.drawBitmap(bitmap, matrix, paint);
+}
+
+void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+                                    const SkRect* src, const SkRect& dst,
+                                    const SkPaint& paint,
+                                    SkCanvas::DrawBitmapRectFlags flags) {
+    SkMatrix    matrix;
+    SkRect      bitmapBounds, tmpSrc, tmpDst;
+    SkBitmap    tmpBitmap;
+
+    bitmapBounds.isetWH(bitmap.width(), bitmap.height());
+
+    // Compute matrix from the two rectangles
+    if (src) {
+        tmpSrc = *src;
+    } else {
+        tmpSrc = bitmapBounds;
+    }
+    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
+
+    const SkRect* dstPtr = &dst;
+    const SkBitmap* bitmapPtr = &bitmap;
+
+    // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
+    // needed (if the src was clipped). No check needed if src==null.
+    if (src) {
+        if (!bitmapBounds.contains(*src)) {
+            if (!tmpSrc.intersect(bitmapBounds)) {
+                return; // nothing to draw
+            }
+            // recompute dst, based on the smaller tmpSrc
+            matrix.mapRect(&tmpDst, tmpSrc);
+            dstPtr = &tmpDst;
+        }
+
+        // since we may need to clamp to the borders of the src rect within
+        // the bitmap, we extract a subset.
+        SkIRect srcIR;
+        tmpSrc.roundOut(&srcIR);
+        if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
+            return;
+        }
+        bitmapPtr = &tmpBitmap;
+
+        // Since we did an extract, we need to adjust the matrix accordingly
+        SkScalar dx = 0, dy = 0;
+        if (srcIR.fLeft > 0) {
+            dx = SkIntToScalar(srcIR.fLeft);
+        }
+        if (srcIR.fTop > 0) {
+            dy = SkIntToScalar(srcIR.fTop);
+        }
+        if (dx || dy) {
+            matrix.preTranslate(dx, dy);
+        }
+
+        SkRect extractedBitmapBounds;
+        extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
+        if (extractedBitmapBounds == tmpSrc) {
+            // no fractional part in src, we can just call drawBitmap
+            goto USE_DRAWBITMAP;
+        }
+    } else {
+        USE_DRAWBITMAP:
+        // We can go faster by just calling drawBitmap, which will concat the
+        // matrix with the CTM, and try to call drawSprite if it can. If not,
+        // it will make a shader and call drawRect, as we do below.
+        this->drawBitmap(draw, *bitmapPtr, matrix, paint);
+        return;
+    }
+
+    // construct a shader, so we can call drawRect with the dst
+    SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
+                                               SkShader::kClamp_TileMode,
+                                               SkShader::kClamp_TileMode);
+    if (NULL == s) {
+        return;
+    }
+    s->setLocalMatrix(matrix);
+
+    SkPaint paintWithShader(paint);
+    paintWithShader.setStyle(SkPaint::kFill_Style);
+    paintWithShader.setShader(s)->unref();
+
+    // Call ourself, in case the subclass wanted to share this setup code
+    // but handle the drawRect code themselves.
+    this->drawRect(draw, *dstPtr, paintWithShader);
+}
+
+void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+                                int x, int y, const SkPaint& paint) {
+    draw.drawSprite(bitmap, x, y, paint);
+}
+
+void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
+                              SkScalar x, SkScalar y, const SkPaint& paint) {
+    draw.drawText((const char*)text, len, x, y, paint);
+}
+
+void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
+                                 const SkScalar xpos[], SkScalar y,
+                                 int scalarsPerPos, const SkPaint& paint) {
+    draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint);
+}
+
+void SkBitmapDevice::drawTextOnPath(const SkDraw& draw, const void* text,
+                                    size_t len, const SkPath& path,
+                                    const SkMatrix* matrix,
+                                    const SkPaint& paint) {
+    draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
+}
+
+#ifdef SK_BUILD_FOR_ANDROID
+void SkBitmapDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
+                                       const SkPoint pos[], const SkPaint& paint,
+                                       const SkPath& path, const SkMatrix* matrix) {
+    draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
+}
+#endif
+
+void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+                                  int vertexCount,
+                                  const SkPoint verts[], const SkPoint textures[],
+                                  const SkColor colors[], SkXfermode* xmode,
+                                  const uint16_t indices[], int indexCount,
+                                  const SkPaint& paint) {
+    draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
+                      indices, indexCount, paint);
+}
+
+void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
+                                int x, int y, const SkPaint& paint) {
+    const SkBitmap& src = device->accessBitmap(false);
+    draw.drawSprite(src, x, y, paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
+    if (!paint.isLCDRenderText() || !paint.isAntiAlias()) {
+        // we're cool with the paint as is
+        return false;
+    }
+
+    if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
+        paint.getRasterizer() ||
+        paint.getPathEffect() ||
+        paint.isFakeBoldText() ||
+        paint.getStyle() != SkPaint::kFill_Style ||
+        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) {
+        // turn off lcd
+        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
+        flags->fHinting = paint.getHinting();
+        return true;
+    }
+    // we're cool with the paint as is
+    return false;
+}
+
diff --git a/core/SkDevice.cpp b/core/SkDevice.cpp
index ff2f1cf..d53b8a2 100644
--- a/core/SkDevice.cpp
+++ b/core/SkDevice.cpp
@@ -5,32 +5,21 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-#include "SkBitmapDevice.h"
+
 #include "SkDevice.h"
-#include "SkDeviceProperties.h"
-#include "SkDraw.h"
-#include "SkImageFilter.h"
 #include "SkMetaData.h"
-#include "SkRasterClip.h"
-#include "SkRect.h"
-#include "SkRRect.h"
-#include "SkShader.h"
 
 SK_DEFINE_INST_COUNT(SkBaseDevice)
-SK_DEFINE_INST_COUNT(SkBitmapDevice)
+
+#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
+    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888;
+#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
+    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888;
+#else
+    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1;
+#endif
 
 ///////////////////////////////////////////////////////////////////////////////
-
-#define CHECK_FOR_NODRAW_ANNOTATION(paint) \
-    do { if (paint.isNoDrawAnnotation()) { return; } } while (0)
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
-    : fBitmap(bitmap) {
-    SkASSERT(SkBitmap::kARGB_4444_Config != bitmap.config());
-}
-
 SkBaseDevice::SkBaseDevice()
     : fLeakyProperties(SkDeviceProperties::MakeDefault())
 #ifdef SK_DEBUG
@@ -41,11 +30,6 @@
     fMetaData = NULL;
 }
 
-SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties)
-    : SkBaseDevice(deviceProperties)
-    , fBitmap(bitmap) {
-}
-
 SkBaseDevice::SkBaseDevice(const SkDeviceProperties& deviceProperties)
     : fLeakyProperties(deviceProperties)
 #ifdef SK_DEBUG
@@ -56,41 +40,10 @@
     fMetaData = NULL;
 }
 
-SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque) {
-    fBitmap.setConfig(config, width, height);
-    fBitmap.allocPixels();
-    fBitmap.setIsOpaque(isOpaque);
-    if (!isOpaque) {
-        fBitmap.eraseColor(SK_ColorTRANSPARENT);
-    }
-}
-
-SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
-                         const SkDeviceProperties& deviceProperties)
-    : SkBaseDevice(deviceProperties) {
-
-    fBitmap.setConfig(config, width, height);
-    fBitmap.allocPixels();
-    fBitmap.setIsOpaque(isOpaque);
-    if (!isOpaque) {
-        fBitmap.eraseColor(SK_ColorTRANSPARENT);
-    }
-}
-
 SkBaseDevice::~SkBaseDevice() {
     delete fMetaData;
 }
 
-SkBitmapDevice::~SkBitmapDevice() {
-}
-
-void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
-    SkASSERT(bm.width() == fBitmap.width());
-    SkASSERT(bm.height() == fBitmap.height());
-    fBitmap = bm;   // intent is to use bm's pixelRef (and rowbytes/config)
-    fBitmap.lockPixels();
-}
-
 SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config,
                                                    int width, int height,
                                                    bool isOpaque) {
@@ -105,14 +58,6 @@
                                           isOpaque, kSaveLayer_Usage);
 }
 
-SkBaseDevice* SkBitmapDevice::onCreateCompatibleDevice(SkBitmap::Config config,
-                                                       int width, int height,
-                                                       bool isOpaque,
-                                                       Usage usage) {
-    return SkNEW_ARGS(SkBitmapDevice,(config, width, height, isOpaque,
-                                      this->getDeviceProperties()));
-}
-
 SkMetaData& SkBaseDevice::getMetaData() {
     // metadata users are rare, so we lazily allocate it. If that changes we
     // can decide to just make it a field in the device (rather than a ptr)
@@ -122,18 +67,6 @@
     return *fMetaData;
 }
 
-void SkBitmapDevice::lockPixels() {
-    if (fBitmap.lockPixelsAreWritable()) {
-        fBitmap.lockPixels();
-    }
-}
-
-void SkBitmapDevice::unlockPixels() {
-    if (fBitmap.lockPixelsAreWritable()) {
-        fBitmap.unlockPixels();
-    }
-}
-
 const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
     const SkBitmap& bitmap = this->onAccessBitmap();
     if (changePixels) {
@@ -142,38 +75,6 @@
     return bitmap;
 }
 
-void SkBitmapDevice::getGlobalBounds(SkIRect* bounds) const {
-    if (bounds) {
-        const SkIPoint& origin = this->getOrigin();
-        bounds->setXYWH(origin.x(), origin.y(),
-                        fBitmap.width(), fBitmap.height());
-    }
-}
-
-void SkBitmapDevice::clear(SkColor color) {
-    fBitmap.eraseColor(color);
-}
-
-const SkBitmap& SkBitmapDevice::onAccessBitmap() {
-    return fBitmap;
-}
-
-bool SkBitmapDevice::canHandleImageFilter(SkImageFilter*) {
-    return false;
-}
-
-bool SkBitmapDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
-                                 const SkMatrix& ctm, SkBitmap* result,
-                                 SkIPoint* offset) {
-    return false;
-}
-
-bool SkBitmapDevice::allowImageFilter(SkImageFilter*) {
-    return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
                               SkCanvas::Config8888 config8888) {
     if (SkBitmap::kARGB_8888_Config != bitmap->config() ||
@@ -218,315 +119,3 @@
     return result;
 }
 
-#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
-    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias =
-        SkCanvas::kBGRA_Premul_Config8888;
-#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
-    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias =
-        SkCanvas::kRGBA_Premul_Config8888;
-#else
-    const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias =
-        (SkCanvas::Config8888) -1;
-#endif
-
-#include <SkConfig8888.h>
-
-bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap,
-                                  int x, int y,
-                                  SkCanvas::Config8888 config8888) {
-    SkASSERT(SkBitmap::kARGB_8888_Config == bitmap.config());
-    SkASSERT(!bitmap.isNull());
-    SkASSERT(SkIRect::MakeWH(this->width(), this->height()).contains(SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height())));
-
-    SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap.width(),
-                                              bitmap.height());
-    const SkBitmap& src = this->accessBitmap(false);
-
-    SkBitmap subset;
-    if (!src.extractSubset(&subset, srcRect)) {
-        return false;
-    }
-    if (SkBitmap::kARGB_8888_Config != subset.config()) {
-        // It'd be preferable to do this directly to bitmap.
-        subset.copyTo(&subset, SkBitmap::kARGB_8888_Config);
-    }
-    SkAutoLockPixels alp(bitmap);
-    uint32_t* bmpPixels = reinterpret_cast<uint32_t*>(bitmap.getPixels());
-    SkCopyBitmapToConfig8888(bmpPixels, bitmap.rowBytes(), config8888, subset);
-    return true;
-}
-
-void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
-                                 int x, int y,
-                                 SkCanvas::Config8888 config8888) {
-    if (bitmap.isNull() || bitmap.getTexture()) {
-        return;
-    }
-    const SkBitmap* sprite = &bitmap;
-    // check whether we have to handle a config8888 that doesn't match SkPMColor
-    if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
-        SkCanvas::kNative_Premul_Config8888 != config8888 &&
-        kPMColorAlias != config8888) {
-
-        // We're going to have to convert from a config8888 to the native config
-        // First we clip to the device bounds.
-        SkBitmap dstBmp = this->accessBitmap(true);
-        SkIRect spriteRect = SkIRect::MakeXYWH(x, y,
-                                               bitmap.width(), bitmap.height());
-        SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height());
-        if (!spriteRect.intersect(devRect)) {
-            return;
-        }
-
-        // write directly to the device if it has pixels and is SkPMColor
-        bool drawSprite;
-        if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) {
-            // we can write directly to the dst when doing the conversion
-            dstBmp.extractSubset(&dstBmp, spriteRect);
-            drawSprite = false;
-        } else {
-            // we convert to a temporary bitmap and draw that as a sprite
-            dstBmp.setConfig(SkBitmap::kARGB_8888_Config,
-                             spriteRect.width(),
-                             spriteRect.height());
-            if (!dstBmp.allocPixels()) {
-                return;
-            }
-            drawSprite = true;
-        }
-
-        // copy pixels to dstBmp and convert from config8888 to native config.
-        SkAutoLockPixels alp(bitmap);
-        uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x,
-                                               spriteRect.fTop - y);
-        SkCopyConfig8888ToBitmap(dstBmp,
-                                 srcPixels,
-                                 bitmap.rowBytes(),
-                                 config8888);
-
-        if (drawSprite) {
-            // we've clipped the sprite when we made a copy
-            x = spriteRect.fLeft;
-            y = spriteRect.fTop;
-            sprite = &dstBmp;
-        } else {
-            return;
-        }
-    }
-
-    SkPaint paint;
-    paint.setXfermodeMode(SkXfermode::kSrc_Mode);
-    SkRasterClip clip(SkIRect::MakeWH(fBitmap.width(), fBitmap.height()));
-    SkDraw  draw;
-    draw.fRC = &clip;
-    draw.fClip = &clip.bwRgn();
-    draw.fBitmap = &fBitmap; // canvas should have already called accessBitmap
-    draw.fMatrix = &SkMatrix::I();
-    this->drawSprite(draw, *sprite, x, y, paint);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
-    draw.drawPaint(paint);
-}
-
-void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
-                                const SkPoint pts[], const SkPaint& paint) {
-    CHECK_FOR_NODRAW_ANNOTATION(paint);
-    draw.drawPoints(mode, count, pts, paint);
-}
-
-void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
-    CHECK_FOR_NODRAW_ANNOTATION(paint);
-    draw.drawRect(r, paint);
-}
-
-void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
-    CHECK_FOR_NODRAW_ANNOTATION(paint);
-
-    SkPath path;
-    path.addOval(oval);
-    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
-    // required to override drawOval.
-    this->drawPath(draw, path, paint, NULL, true);
-}
-
-void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
-    CHECK_FOR_NODRAW_ANNOTATION(paint);
-
-    SkPath  path;
-    path.addRRect(rrect);
-    // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
-    // required to override drawRRect.
-    this->drawPath(draw, path, paint, NULL, true);
-}
-
-void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
-                              const SkPaint& paint, const SkMatrix* prePathMatrix,
-                              bool pathIsMutable) {
-    CHECK_FOR_NODRAW_ANNOTATION(paint);
-    draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
-}
-
-void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
-                                const SkMatrix& matrix, const SkPaint& paint) {
-    draw.drawBitmap(bitmap, matrix, paint);
-}
-
-void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
-                                    const SkRect* src, const SkRect& dst,
-                                    const SkPaint& paint,
-                                    SkCanvas::DrawBitmapRectFlags flags) {
-    SkMatrix    matrix;
-    SkRect      bitmapBounds, tmpSrc, tmpDst;
-    SkBitmap    tmpBitmap;
-
-    bitmapBounds.isetWH(bitmap.width(), bitmap.height());
-
-    // Compute matrix from the two rectangles
-    if (src) {
-        tmpSrc = *src;
-    } else {
-        tmpSrc = bitmapBounds;
-    }
-    matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
-
-    const SkRect* dstPtr = &dst;
-    const SkBitmap* bitmapPtr = &bitmap;
-
-    // clip the tmpSrc to the bounds of the bitmap, and recompute dstRect if
-    // needed (if the src was clipped). No check needed if src==null.
-    if (src) {
-        if (!bitmapBounds.contains(*src)) {
-            if (!tmpSrc.intersect(bitmapBounds)) {
-                return; // nothing to draw
-            }
-            // recompute dst, based on the smaller tmpSrc
-            matrix.mapRect(&tmpDst, tmpSrc);
-            dstPtr = &tmpDst;
-        }
-
-        // since we may need to clamp to the borders of the src rect within
-        // the bitmap, we extract a subset.
-        SkIRect srcIR;
-        tmpSrc.roundOut(&srcIR);
-        if (!bitmap.extractSubset(&tmpBitmap, srcIR)) {
-            return;
-        }
-        bitmapPtr = &tmpBitmap;
-
-        // Since we did an extract, we need to adjust the matrix accordingly
-        SkScalar dx = 0, dy = 0;
-        if (srcIR.fLeft > 0) {
-            dx = SkIntToScalar(srcIR.fLeft);
-        }
-        if (srcIR.fTop > 0) {
-            dy = SkIntToScalar(srcIR.fTop);
-        }
-        if (dx || dy) {
-            matrix.preTranslate(dx, dy);
-        }
-
-        SkRect extractedBitmapBounds;
-        extractedBitmapBounds.isetWH(bitmapPtr->width(), bitmapPtr->height());
-        if (extractedBitmapBounds == tmpSrc) {
-            // no fractional part in src, we can just call drawBitmap
-            goto USE_DRAWBITMAP;
-        }
-    } else {
-        USE_DRAWBITMAP:
-        // We can go faster by just calling drawBitmap, which will concat the
-        // matrix with the CTM, and try to call drawSprite if it can. If not,
-        // it will make a shader and call drawRect, as we do below.
-        this->drawBitmap(draw, *bitmapPtr, matrix, paint);
-        return;
-    }
-
-    // construct a shader, so we can call drawRect with the dst
-    SkShader* s = SkShader::CreateBitmapShader(*bitmapPtr,
-                                               SkShader::kClamp_TileMode,
-                                               SkShader::kClamp_TileMode);
-    if (NULL == s) {
-        return;
-    }
-    s->setLocalMatrix(matrix);
-
-    SkPaint paintWithShader(paint);
-    paintWithShader.setStyle(SkPaint::kFill_Style);
-    paintWithShader.setShader(s)->unref();
-
-    // Call ourself, in case the subclass wanted to share this setup code
-    // but handle the drawRect code themselves.
-    this->drawRect(draw, *dstPtr, paintWithShader);
-}
-
-void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
-                                int x, int y, const SkPaint& paint) {
-    draw.drawSprite(bitmap, x, y, paint);
-}
-
-void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
-                              SkScalar x, SkScalar y, const SkPaint& paint) {
-    draw.drawText((const char*)text, len, x, y, paint);
-}
-
-void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
-                                 const SkScalar xpos[], SkScalar y,
-                                 int scalarsPerPos, const SkPaint& paint) {
-    draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint);
-}
-
-void SkBitmapDevice::drawTextOnPath(const SkDraw& draw, const void* text,
-                                    size_t len, const SkPath& path,
-                                    const SkMatrix* matrix,
-                                    const SkPaint& paint) {
-    draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
-}
-
-#ifdef SK_BUILD_FOR_ANDROID
-void SkBitmapDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
-                                       const SkPoint pos[], const SkPaint& paint,
-                                       const SkPath& path, const SkMatrix* matrix) {
-    draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
-}
-#endif
-
-void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
-                                  int vertexCount,
-                                  const SkPoint verts[], const SkPoint textures[],
-                                  const SkColor colors[], SkXfermode* xmode,
-                                  const uint16_t indices[], int indexCount,
-                                  const SkPaint& paint) {
-    draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode,
-                      indices, indexCount, paint);
-}
-
-void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
-                                int x, int y, const SkPaint& paint) {
-    const SkBitmap& src = device->accessBitmap(false);
-    draw.drawSprite(src, x, y, paint);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
-    if (!paint.isLCDRenderText() || !paint.isAntiAlias()) {
-        // we're cool with the paint as is
-        return false;
-    }
-
-    if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
-        paint.getRasterizer() ||
-        paint.getPathEffect() ||
-        paint.isFakeBoldText() ||
-        paint.getStyle() != SkPaint::kFill_Style ||
-        !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) {
-        // turn off lcd
-        flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
-        flags->fHinting = paint.getHinting();
-        return true;
-    }
-    // we're cool with the paint as is
-    return false;
-}