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 "SkReadBuffer.h" 12 #include "SkWriteBuffer.h" 13 #include "SkValidationUtils.h" 14 15 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) 16 : INHERITED(0, 0), 17 fBitmap(bitmap), 18 fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()), 19 SkIntToScalar(bitmap.height()))), 20 fDstRect(fSrcRect) { 21 } 22 23 SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect) 24 : INHERITED(0, 0) 25 , fBitmap(bitmap) 26 , fSrcRect(srcRect) 27 , fDstRect(dstRect) {} 28 29 SkBitmapSource::SkBitmapSource(SkReadBuffer& buffer) : INHERITED(0, buffer) { 30 if (buffer.isVersionLT(SkReadBuffer::kNoMoreBitmapFlatten_Version)) { 31 fBitmap.legacyUnflatten(buffer); 32 } else { 33 buffer.readBitmap(&fBitmap); 34 } 35 buffer.readRect(&fSrcRect); 36 buffer.readRect(&fDstRect); 37 buffer.validate(buffer.isValid() && SkIsValidRect(fSrcRect) && SkIsValidRect(fDstRect)); 38 } 39 40 void SkBitmapSource::flatten(SkWriteBuffer& buffer) const { 41 this->INHERITED::flatten(buffer); 42 buffer.writeBitmap(fBitmap); 43 buffer.writeRect(fSrcRect); 44 buffer.writeRect(fDstRect); 45 } 46 47 bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, 48 SkBitmap* result, SkIPoint* offset) const { 49 SkRect bounds, dstRect; 50 fBitmap.getBounds(&bounds); 51 ctx.ctm().mapRect(&dstRect, fDstRect); 52 if (fSrcRect == bounds && dstRect == bounds) { 53 // No regions cropped out or resized; return entire bitmap. 54 *result = fBitmap; 55 offset->fX = offset->fY = 0; 56 return true; 57 } 58 SkIRect dstIRect; 59 dstRect.roundOut(&dstIRect); 60 61 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height())); 62 if (NULL == device.get()) { 63 return false; 64 } 65 66 SkCanvas canvas(device.get()); 67 SkPaint paint; 68 69 // Subtract off the integer component of the translation (will be applied in loc, below). 70 dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop)); 71 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 72 // FIXME: this probably shouldn't be necessary, but drawBitmapRectToRect asserts 73 // None filtering when it's translate-only 74 paint.setFilterLevel( 75 fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? 76 SkPaint::kNone_FilterLevel : SkPaint::kHigh_FilterLevel); 77 canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); 78 79 *result = device.get()->accessBitmap(false); 80 offset->fX = dstIRect.fLeft; 81 offset->fY = dstIRect.fTop; 82 return true; 83 } 84 85 void SkBitmapSource::computeFastBounds(const SkRect&, SkRect* dst) const { 86 *dst = fDstRect; 87 } 88 89 bool SkBitmapSource::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 90 SkIRect* dst) const { 91 *dst = src; 92 return true; 93 } 94