1 /* 2 * Copyright 2013 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 "SkPictureImageFilter.h" 9 #include "SkDevice.h" 10 #include "SkCanvas.h" 11 #include "SkReadBuffer.h" 12 #include "SkWriteBuffer.h" 13 #include "SkValidationUtils.h" 14 15 SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture) 16 : INHERITED(0, 0), 17 fPicture(picture), 18 fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0, 19 picture ? SkIntToScalar(picture->height()) : 0)) { 20 SkSafeRef(fPicture); 21 } 22 23 SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect) 24 : INHERITED(0, 0), 25 fPicture(picture), 26 fCropRect(cropRect) { 27 SkSafeRef(fPicture); 28 } 29 30 SkPictureImageFilter::~SkPictureImageFilter() { 31 SkSafeUnref(fPicture); 32 } 33 34 SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer) 35 : INHERITED(0, buffer), 36 fPicture(NULL) { 37 if (!buffer.isCrossProcess()) { 38 if (buffer.readBool()) { 39 fPicture = SkPicture::CreateFromBuffer(buffer); 40 } 41 } else { 42 buffer.validate(!buffer.readBool()); 43 } 44 buffer.readRect(&fCropRect); 45 } 46 47 void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { 48 this->INHERITED::flatten(buffer); 49 if (!buffer.isCrossProcess()) { 50 bool hasPicture = (fPicture != NULL); 51 buffer.writeBool(hasPicture); 52 if (hasPicture) { 53 fPicture->flatten(buffer); 54 } 55 } else { 56 buffer.writeBool(false); 57 } 58 buffer.writeRect(fCropRect); 59 } 60 61 bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, 62 SkBitmap* result, SkIPoint* offset) const { 63 if (!fPicture) { 64 offset->fX = offset->fY = 0; 65 return true; 66 } 67 68 SkRect floatBounds; 69 SkIRect bounds; 70 ctx.ctm().mapRect(&floatBounds, fCropRect); 71 floatBounds.roundOut(&bounds); 72 73 if (bounds.isEmpty()) { 74 offset->fX = offset->fY = 0; 75 return true; 76 } 77 78 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds.height())); 79 if (NULL == device.get()) { 80 return false; 81 } 82 83 SkCanvas canvas(device.get()); 84 SkPaint paint; 85 86 canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); 87 canvas.concat(ctx.ctm()); 88 canvas.drawPicture(fPicture); 89 90 *result = device.get()->accessBitmap(false); 91 offset->fX = bounds.fLeft; 92 offset->fY = bounds.fTop; 93 return true; 94 } 95 96 bool SkPictureImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 97 SkIRect* dst) const { 98 *dst = src; 99 return true; 100 } 101 102