Index: src/core/SkCanvas.cpp |
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
index 17e03c2373232bc2721c26f5bee1f246a3acbd1c..ef6a82d9bfc0747878f815c6db10d6683f32c719 100644 |
--- a/src/core/SkCanvas.cpp |
+++ b/src/core/SkCanvas.cpp |
@@ -667,6 +667,7 @@ SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { |
return device; |
} |
+#ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG |
bool SkCanvas::readPixels(SkBitmap* bitmap, |
int x, int y, |
Config8888 config8888) { |
@@ -676,28 +677,95 @@ bool SkCanvas::readPixels(SkBitmap* bitmap, |
} |
return device->readPixels(bitmap, x, y, config8888); |
} |
+#endif |
+ |
+bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { |
+ if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { |
+ return false; |
+ } |
+ |
+ bool weAllocated = false; |
+ if (NULL == bitmap->pixelRef()) { |
+ if (!bitmap->allocPixels()) { |
+ return false; |
+ } |
+ weAllocated = true; |
+ } |
+ |
+ SkBitmap bm(*bitmap); |
+ bm.lockPixels(); |
+ if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { |
+ return true; |
+ } |
+ |
+ if (weAllocated) { |
+ bitmap->setPixelRef(NULL); |
+ } |
+ return false; |
+} |
bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { |
- SkBaseDevice* device = this->getDevice(); |
- if (!device) { |
+ SkIRect r = srcRect; |
+ const SkISize size = this->getBaseLayerSize(); |
+ if (!r.intersect(0, 0, size.width(), size.height())) { |
+ bitmap->reset(); |
return false; |
} |
- SkIRect bounds; |
- bounds.set(0, 0, device->width(), device->height()); |
- if (!bounds.intersect(srcRect)) { |
+ if (!bitmap->allocN32Pixels(r.width(), r.height())) { |
+ // bitmap will already be reset. |
+ return false; |
+ } |
+ if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { |
+ bitmap->reset(); |
return false; |
} |
+ return true; |
+} |
- SkBitmap tmp; |
- tmp.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), |
- bounds.height()); |
- if (this->readPixels(&tmp, bounds.fLeft, bounds.fTop)) { |
- bitmap->swap(tmp); |
- return true; |
- } else { |
+bool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) { |
+ switch (origInfo.colorType()) { |
+ case kUnknown_SkColorType: |
+ case kIndex_8_SkColorType: |
+ return false; |
+ default: |
+ break; |
+ } |
+ if (NULL == dstP || rowBytes < origInfo.minRowBytes()) { |
+ return false; |
+ } |
+ if (0 == origInfo.width() || 0 == origInfo.height()) { |
+ return false; |
+ } |
+ |
+ SkBaseDevice* device = this->getDevice(); |
+ if (!device) { |
+ return false; |
+ } |
+ |
+ const SkISize size = this->getBaseLayerSize(); |
+ SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); |
+ if (!srcR.intersect(0, 0, size.width(), size.height())) { |
return false; |
} |
+ |
+ SkImageInfo info = origInfo; |
+ // the intersect may have shrunk info's logical size |
+ info.fWidth = srcR.width(); |
+ info.fHeight = srcR.height(); |
+ |
+ // if x or y are negative, then we have to adjust pixels |
+ if (x > 0) { |
+ x = 0; |
+ } |
+ if (y > 0) { |
+ y = 0; |
+ } |
+ // here x,y are either 0 or negative |
scroggo
2014/03/24 15:31:36
What's the use case for calling this function with
reed1
2014/03/24 15:53:05
We definitely support (in the public canvas versio
|
+ dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel()); |
+ |
+ // The device can assert that the requested area is always contained in its bounds |
+ return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y()); |
} |
bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { |
@@ -1063,12 +1131,9 @@ SkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { |
fAddr = canvas->peekPixels(&fInfo, &fRowBytes); |
if (NULL == fAddr) { |
fInfo = canvas->imageInfo(); |
- if (kUnknown_SkColorType == fInfo.colorType() || |
- !fBitmap.allocPixels(fInfo)) |
- { |
+ if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.allocPixels(fInfo)) { |
return; // failure, fAddr is NULL |
} |
- fBitmap.lockPixels(); |
if (!canvas->readPixels(&fBitmap, 0, 0)) { |
return; // failure, fAddr is NULL |
} |