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 "SkOffsetImageFilter.h" 9 #include "SkBitmap.h" 10 #include "SkCanvas.h" 11 #include "SkDevice.h" 12 #include "SkFlattenableBuffers.h" 13 #include "SkMatrix.h" 14 #include "SkPaint.h" 15 16 bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, 17 const SkMatrix& matrix, 18 SkBitmap* result, 19 SkIPoint* loc) { 20 SkImageFilter* input = getInput(0); 21 SkBitmap src = source; 22 #ifdef SK_DISABLE_OFFSETIMAGEFILTER_OPTIMIZATION 23 if (false) { 24 #else 25 if (!cropRectIsSet()) { 26 #endif 27 if (input && !input->filterImage(proxy, source, matrix, &src, loc)) { 28 return false; 29 } 30 31 SkVector vec; 32 matrix.mapVectors(&vec, &fOffset, 1); 33 34 loc->fX += SkScalarRoundToInt(vec.fX); 35 loc->fY += SkScalarRoundToInt(vec.fY); 36 *result = src; 37 } else { 38 SkIPoint srcOffset = SkIPoint::Make(0, 0); 39 if (input && !input->filterImage(proxy, source, matrix, &src, &srcOffset)) { 40 return false; 41 } 42 43 SkIRect bounds; 44 src.getBounds(&bounds); 45 46 if (!applyCropRect(&bounds, matrix)) { 47 return false; 48 } 49 50 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height())); 51 if (NULL == device.get()) { 52 return false; 53 } 54 SkCanvas canvas(device); 55 SkPaint paint; 56 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 57 canvas.drawBitmap(src, fOffset.fX - bounds.left(), fOffset.fY - bounds.top(), &paint); 58 *result = device->accessBitmap(false); 59 loc->fX += bounds.left(); 60 loc->fY += bounds.top(); 61 } 62 return true; 63 } 64 65 bool SkOffsetImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 66 SkIRect* dst) { 67 SkVector vec; 68 ctm.mapVectors(&vec, &fOffset, 1); 69 70 *dst = src; 71 dst->offset(SkScalarRoundToInt(vec.fX), SkScalarRoundToInt(vec.fY)); 72 return true; 73 } 74 75 void SkOffsetImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { 76 this->INHERITED::flatten(buffer); 77 buffer.writePoint(fOffset); 78 } 79 80 SkOffsetImageFilter::SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, 81 const CropRect* cropRect) : INHERITED(input, cropRect) { 82 fOffset.set(dx, dy); 83 } 84 85 SkOffsetImageFilter::SkOffsetImageFilter(SkFlattenableReadBuffer& buffer) 86 : INHERITED(1, buffer) { 87 buffer.readPoint(&fOffset); 88 buffer.validate(SkScalarIsFinite(fOffset.fX) && 89 SkScalarIsFinite(fOffset.fY)); 90 } 91