Index: src/core/SkBitmapDevice.cpp |
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp |
index 09b3b605f85a3e4b36a28e77d88a75135abfae3b..86c5702f03845400a38fac4c6dd977fcbc8b136b 100644 |
--- a/src/core/SkBitmapDevice.cpp |
+++ b/src/core/SkBitmapDevice.cpp |
@@ -141,7 +141,58 @@ |
return NULL; |
} |
+static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, size_t bytesPerRow, |
+ int rowCount) { |
+ SkASSERT(bytesPerRow <= srcRB); |
+ SkASSERT(bytesPerRow <= dstRB); |
+ for (int i = 0; i < rowCount; ++i) { |
+ memcpy(dst, src, bytesPerRow); |
+ dst = (char*)dst + dstRB; |
+ src = (const char*)src + srcRB; |
+ } |
+} |
+ |
#include "SkConfig8888.h" |
+ |
+static bool copy_pixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, |
+ const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRowBytes) { |
+ if (srcInfo.dimensions() != dstInfo.dimensions()) { |
+ return false; |
+ } |
+ if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) { |
+ SkDstPixelInfo dstPI; |
+ dstPI.fColorType = dstInfo.colorType(); |
+ dstPI.fAlphaType = dstInfo.alphaType(); |
+ dstPI.fPixels = dstPixels; |
+ dstPI.fRowBytes = dstRowBytes; |
+ |
+ SkSrcPixelInfo srcPI; |
+ srcPI.fColorType = srcInfo.colorType(); |
+ srcPI.fAlphaType = srcInfo.alphaType(); |
+ srcPI.fPixels = srcPixels; |
+ srcPI.fRowBytes = srcRowBytes; |
+ |
+ return srcPI.convertPixelsTo(&dstPI, srcInfo.width(), srcInfo.height()); |
+ } |
+ if (srcInfo.colorType() == dstInfo.colorType()) { |
+ switch (srcInfo.colorType()) { |
+ case kRGB_565_SkColorType: |
+ case kAlpha_8_SkColorType: |
+ break; |
+ case kARGB_4444_SkColorType: |
+ if (srcInfo.alphaType() != dstInfo.alphaType()) { |
+ return false; |
+ } |
+ break; |
+ default: |
+ return false; |
+ } |
+ rect_memcpy(dstPixels, dstRowBytes, srcPixels, srcRowBytes, |
+ srcInfo.width() * srcInfo.bytesPerPixel(), srcInfo.height()); |
+ } |
+ // TODO: add support for more conversions as needed |
+ return false; |
+} |
bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels, |
size_t srcRowBytes, int x, int y) { |
@@ -157,7 +208,7 @@ |
void* dstPixels = fBitmap.getAddr(x, y); |
size_t dstRowBytes = fBitmap.rowBytes(); |
- if (SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) { |
+ if (copy_pixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) { |
fBitmap.notifyPixelsChanged(); |
return true; |
} |
@@ -166,7 +217,28 @@ |
bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, |
int x, int y) { |
- return fBitmap.readPixels(dstInfo, dstPixels, dstRowBytes, x, y); |
+ // since we don't stop creating un-pixeled devices yet, check for no pixels here |
+ if (NULL == fBitmap.getPixels()) { |
+ return false; |
+ } |
+ |
+ SkImageInfo srcInfo = fBitmap.info(); |
+ |
+ // perhaps can relax these in the future |
+ if (4 != dstInfo.bytesPerPixel()) { |
+ return false; |
+ } |
+ if (4 != srcInfo.bytesPerPixel()) { |
+ return false; |
+ } |
+ |
+ srcInfo.fWidth = dstInfo.width(); |
+ srcInfo.fHeight = dstInfo.height(); |
+ |
+ const void* srcPixels = fBitmap.getAddr(x, y); |
+ const size_t srcRowBytes = fBitmap.rowBytes(); |
+ |
+ return copy_pixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes); |
} |
/////////////////////////////////////////////////////////////////////////////// |