| Index: src/effects/SkBitmapSource.cpp
|
| diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp
|
| index 72f51f8423a0d06ec21ff4d104dec82bd7a579a5..ef5ea8692568b3c818d977aa885b5517aa53aea3 100644
|
| --- a/src/effects/SkBitmapSource.cpp
|
| +++ b/src/effects/SkBitmapSource.cpp
|
| @@ -6,24 +6,74 @@
|
| */
|
|
|
| #include "SkBitmapSource.h"
|
| +#include "SkDevice.h"
|
| +#include "SkCanvas.h"
|
| +#include "SkFlattenableBuffers.h"
|
| +#include "SkValidationUtils.h"
|
|
|
| SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap)
|
| : INHERITED(0, 0),
|
| - fBitmap(bitmap) {
|
| + fBitmap(bitmap),
|
| + fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()),
|
| + SkIntToScalar(bitmap.height()))),
|
| + fDstRect(fSrcRect) {
|
| +}
|
| +
|
| +SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect)
|
| + : INHERITED(0, 0),
|
| + fBitmap(bitmap),
|
| + fSrcRect(srcRect),
|
| + fDstRect(dstRect) {
|
| }
|
|
|
| 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) {
|
| + // No regions cropped out or resized; return entire bitmap.
|
| + *result = fBitmap;
|
| + return true;
|
| + }
|
| + SkIRect dstIRect;
|
| + dstRect.roundOut(&dstIRect);
|
| +
|
| + SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
|
| + if (NULL == device.get()) {
|
| + return false;
|
| + }
|
| +
|
| + SkCanvas canvas(device.get());
|
| + SkPaint paint;
|
| +
|
| + // Subtract off the integer component of the translation (will be applied in loc, below).
|
| + dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
|
| + 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, dstRect, &paint);
|
| +
|
| + *result = device.get()->accessBitmap(false);
|
| + offset->fX += dstIRect.fLeft;
|
| + offset->fY += dstIRect.fTop;
|
| return true;
|
| }
|
|
|