Index: src/effects/SkBitmapSource.cpp |
diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp |
index 72f51f8423a0d06ec21ff4d104dec82bd7a579a5..a8709291c319dff491f8f0a1b2dd8539e9e59fa4 100644 |
--- a/src/effects/SkBitmapSource.cpp |
+++ b/src/effects/SkBitmapSource.cpp |
@@ -6,24 +6,57 @@ |
*/ |
#include "SkBitmapSource.h" |
+#include "SkDevice.h" |
+#include "SkCanvas.h" |
+#include "SkFlattenableBuffers.h" |
+#include "SkValidationUtils.h" |
-SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) |
+SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect* srcRect, const SkRect* dstRect) |
: INHERITED(0, 0), |
- fBitmap(bitmap) { |
+ fBitmap(bitmap), |
+ fSrcRect(srcRect ? *srcRect : SkRect::MakeWH(bitmap.width(), bitmap.height())), |
+ fDstRect(dstRect ? *dstRect : fSrcRect) { |
} |
SkBitmapSource::SkBitmapSource(SkFlattenableReadBuffer& buffer) |
: INHERITED(0, buffer) { |
fBitmap.unflatten(buffer); |
+ buffer.readRect(&fSrcRect); |
+ buffer.readRect(&fDstRect); |
+ buffer.validate(SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect)); |
} |
void SkBitmapSource::flatten(SkFlattenableWriteBuffer& buffer) const { |
this->INHERITED::flatten(buffer); |
fBitmap.flatten(buffer); |
+ buffer.writeRect(fSrcRect); |
+ buffer.writeRect(fDstRect); |
} |
-bool SkBitmapSource::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, |
+bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix, |
SkBitmap* result, SkIPoint* offset) { |
- *result = fBitmap; |
+ SkRect bounds, dstRect; |
+ fBitmap.getBounds(&bounds); |
+ matrix.mapRect(&dstRect, fDstRect); |
+ if (fSrcRect == bounds && dstRect == bounds) { |
+ *result = fBitmap; |
+ return true; |
+ } |
+ SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(SkScalarCeilToInt(dstRect.width()), SkScalarCeilToInt(dstRect.height()))); |
+ if (NULL == device.get()) { |
+ return false; |
+ } |
+ |
+ SkCanvas canvas(device.get()); |
+ SkPaint paint; |
+ |
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
+ // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts None filtering when it's translate-only |
+ paint.setFilterLevel(fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? SkPaint::kNone_FilterLevel : SkPaint::kMedium_FilterLevel); |
+ canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, SkRect::MakeWH(dstRect.width(), dstRect.height()), &paint); |
+ |
+ *result = device.get()->accessBitmap(false); |
+ offset->fX += dstRect.fLeft; |
+ offset->fY += dstRect.fTop; |
return true; |
} |