1 /* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkBitmapSource.h" 9 #include "SkDevice.h" 10 #include "SkCanvas.h" 11 #include "SkFlattenableBuffers.h" 12 #include "SkValidationUtils.h" 13 14 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) 15 : INHERITED(0, 0), 16 fBitmap(bitmap), 17 fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()), 18 SkIntToScalar(bitmap.height()))), 19 fDstRect(fSrcRect) { 20 } 21 22 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect) 23 : INHERITED(0, 0), 24 fBitmap(bitmap), 25 fSrcRect(srcRect), 26 fDstRect(dstRect) { 27 } 28 29 SkBitmapSource::SkBitmapSource(SkFlattenableReadBuffer& buffer) 30 : INHERITED(0, buffer) { 31 fBitmap.unflatten(buffer); 32 buffer.readRect(&fSrcRect); 33 buffer.readRect(&fDstRect); 34 buffer.validate(SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect)); 35 } 36 37 void SkBitmapSource::flatten(SkFlattenableWriteBuffer& buffer) const { 38 this->INHERITED::flatten(buffer); 39 fBitmap.flatten(buffer); 40 buffer.writeRect(fSrcRect); 41 buffer.writeRect(fDstRect); 42 } 43 44 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix, 45 SkBitmap* result, SkIPoint* offset) { 46 SkRect bounds, dstRect; 47 fBitmap.getBounds(&bounds); 48 matrix.mapRect(&dstRect, fDstRect); 49 if (fSrcRect == bounds && dstRect == bounds) { 50 // No regions cropped out or resized; return entire bitmap. 51 *result = fBitmap; 52 return true; 53 } 54 SkIRect dstIRect; 55 dstRect.roundOut(&dstIRect); 56 57 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height())); 58 if (NULL == device.get()) { 59 return false; 60 } 61 62 SkCanvas canvas(device.get()); 63 SkPaint paint; 64 65 // Subtract off the integer component of the translation (will be applied in loc, below). 66 dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop)); 67 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 68 // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts 69 // None filtering when it's translate-only 70 paint.setFilterLevel( 71 fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? 72 SkPaint::kNone_FilterLevel : SkPaint::kMedium_FilterLevel); 73 canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); 74 75 *result = device.get()->accessBitmap(false); 76 offset->fX += dstIRect.fLeft; 77 offset->fY += dstIRect.fTop; 78 return true; 79 } 80