diff options
Diffstat (limited to 'src/effects/SkPictureImageFilter.cpp')
-rw-r--r-- | src/effects/SkPictureImageFilter.cpp | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp index 5399ea7476..e18600db6e 100644 --- a/src/effects/SkPictureImageFilter.cpp +++ b/src/effects/SkPictureImageFilter.cpp @@ -16,14 +16,16 @@ SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID) : INHERITED(0, 0, NULL, uniqueID) , fPicture(SkSafeRef(picture)) - , fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty()) { + , fCropRect(picture ? picture->cullRect() : SkRect::MakeEmpty()) + , fPictureResolution(kDeviceSpace_PictureResolution) { } SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect, - uint32_t uniqueID) + uint32_t uniqueID, PictureResolution pictureResolution) : INHERITED(0, 0, NULL, uniqueID) , fPicture(SkSafeRef(picture)) - , fCropRect(cropRect) { + , fCropRect(cropRect) + , fPictureResolution(pictureResolution) { } SkPictureImageFilter::~SkPictureImageFilter() { @@ -42,7 +44,16 @@ SkFlattenable* SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) { buffer.validate(!buffer.readBool()); } buffer.readRect(&cropRect); + PictureResolution pictureResolution; + if (buffer.isVersionLT(SkReadBuffer::kPictureImageFilterResolution_Version)) { + pictureResolution = kDeviceSpace_PictureResolution; + } else { + pictureResolution = (PictureResolution)buffer.readInt(); + } + if (pictureResolution == kLocalSpace_PictureResolution) { + return CreateForLocalSpace(picture, cropRect); + } return Create(picture, cropRect); } @@ -57,6 +68,7 @@ void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeBool(false); } buffer.writeRect(fCropRect); + buffer.writeInt(fPictureResolution); } bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, @@ -83,17 +95,61 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Co return false; } + if (kLocalSpace_PictureResolution == fPictureResolution && + (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { + drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx); + } else { + drawPictureAtDeviceResolution(proxy, device.get(), bounds, ctx); + } + + *result = device.get()->accessBitmap(false); + offset->fX = bounds.fLeft; + offset->fY = bounds.fTop; + return true; +} + +void SkPictureImageFilter::drawPictureAtDeviceResolution(Proxy* proxy, SkBaseDevice* device, + const SkIRect& deviceBounds, + const Context& ctx) const { // Pass explicit surface props, as the simplified canvas constructor discards device properties. // FIXME: switch back to the public constructor (and unfriend) after // https://code.google.com/p/skia/issues/detail?id=3142 is fixed. - SkCanvas canvas(device.get(), proxy->surfaceProps(), SkCanvas::kDefault_InitFlags); + SkCanvas canvas(device, proxy->surfaceProps(), SkCanvas::kDefault_InitFlags); - canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); + canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop)); canvas.concat(ctx.ctm()); canvas.drawPicture(fPicture); +} - *result = device.get()->accessBitmap(false); - offset->fX = bounds.fLeft; - offset->fY = bounds.fTop; - return true; +void SkPictureImageFilter::drawPictureAtLocalResolution(Proxy* proxy, SkBaseDevice* device, + const SkIRect& deviceBounds, + const Context& ctx) const { + SkMatrix inverseCtm; + if (!ctx.ctm().invert(&inverseCtm)) + return; + SkRect localBounds = SkRect::Make(ctx.clipBounds()); + inverseCtm.mapRect(&localBounds); + if (!localBounds.intersect(fCropRect)) + return; + SkIRect localIBounds = localBounds.roundOut(); + SkAutoTUnref<SkBaseDevice> localDevice(proxy->createDevice(localIBounds.width(), localIBounds.height())); + + // Pass explicit surface props, as the simplified canvas constructor discards device properties. + // FIXME: switch back to the public constructor (and unfriend) after + // https://code.google.com/p/skia/issues/detail?id=3142 is fixed. + SkCanvas localCanvas(localDevice, proxy->surfaceProps(), SkCanvas::kDefault_InitFlags); + localCanvas.translate(-SkIntToScalar(localIBounds.fLeft), -SkIntToScalar(localIBounds.fTop)); + localCanvas.drawPicture(fPicture); + + // Pass explicit surface props, as the simplified canvas constructor discards device properties. + // FIXME: switch back to the public constructor (and unfriend) after + // https://code.google.com/p/skia/issues/detail?id=3142 is fixed. + SkCanvas canvas(device, proxy->surfaceProps(), SkCanvas::kDefault_InitFlags); + + canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBounds.fTop)); + canvas.concat(ctx.ctm()); + SkPaint paint; + paint.setFilterLevel(SkPaint::kLow_FilterLevel); + canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(localIBounds.fLeft), SkIntToScalar(localIBounds.fTop), &paint); + //canvas.drawPicture(fPicture); } |