Chromium Code Reviews| Index: src/effects/SkPictureImageFilter.cpp |
| diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp |
| index da5597d69905385bb4fc610cd22aa60735b72724..9d74816331f7b89fe4591af816f129092f1be2f8 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,6 +44,11 @@ SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer) |
| buffer.validate(!buffer.readBool()); |
| } |
| buffer.readRect(&fCropRect); |
| + if (buffer.isVersionLT(SkReadBuffer::kPictureImageFilterResolution_Version)) { |
| + fPictureResolution = kDeviceSpace_PictureResolution; |
| + } else { |
| + fPictureResolution = (PictureResolution)buffer.readInt(); |
| + } |
| } |
| #endif |
| @@ -57,7 +64,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); |
| } |
| @@ -72,6 +88,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, |
| @@ -98,17 +115,61 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Co |
| return false; |
| } |
| + if (kLocalSpace_PictureResolution == fPictureResolution && |
| + (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { |
| + drawPictureAtOriginalResolution(proxy, device.get(), bounds, ctx); |
| + } else { |
| + drawPictureAtNativeResolution(proxy, device.get(), bounds, ctx); |
| + } |
| + |
| + *result = device.get()->accessBitmap(false); |
| + offset->fX = bounds.fLeft; |
| + offset->fY = bounds.fTop; |
| + return true; |
| +} |
| + |
| +void SkPictureImageFilter::drawPictureAtNativeResolution(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::drawPictureAtOriginalResolution(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); |
|
Stephen White
2014/12/01 16:02:12
Commented-out code; please remove.
|
| } |