| Index: src/effects/SkPictureImageFilter.cpp
|
| diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
|
| index 5399ea7476c2b2e269d03b4047e571adf4cbbd19..e18600db6e24275b78b09fa4e4155c99cd02bc82 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);
|
| }
|
|
|