diff options
author | 2013-12-06 15:59:03 +0000 | |
---|---|---|
committer | 2013-12-06 15:59:03 +0000 | |
commit | 094147d52227a0b230d7a894a69bcfeebe58b2ab (patch) | |
tree | 8506b8a696bffba155f7d506abf8b191db79fe70 /src/effects | |
parent | 80bd0c995d9ec6a70330d6dc3f2f8dd387701d1d (diff) |
Implement srcRect and dstRect functionality in SkBitmapSource. This is required for the "preserveAspectRatio" options of SVG's feImage. Covered by new GM "bitmapsource".
This also includes some changes to the xfermodeimagefilter and tileimagefilter GMs to properly handle the CTM. This worked before only because SkBitmapSource was ignoring the CTM. Now that it respects it, we need to give the correct transform. This also means the GMs now work while zoomed.
R=reed@google.com
Author: senorblanco@chromium.org
Review URL: https://codereview.chromium.org/106933002
git-svn-id: http://skia.googlecode.com/svn/trunk@12528 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkBitmapSource.cpp | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp index 72f51f8423..5e19744a26 100644 --- a/src/effects/SkBitmapSource.cpp +++ b/src/effects/SkBitmapSource.cpp @@ -6,24 +6,71 @@ */ #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) { + *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; } |