Index: src/image/SkImage.cpp |
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp |
index 1970c57839912db2d4288f8b32d9af5f780f72bb..8bf1f247b07a209d2598b1c7a65b2d52de022525 100644 |
--- a/src/image/SkImage.cpp |
+++ b/src/image/SkImage.cpp |
@@ -10,6 +10,7 @@ |
#include "SkCanvas.h" |
#include "SkData.h" |
#include "SkImageEncoder.h" |
+#include "SkImageFilter.h" |
#include "SkImageGenerator.h" |
#include "SkImagePriv.h" |
#include "SkImageShader.h" |
@@ -19,6 +20,7 @@ |
#include "SkPixelRef.h" |
#include "SkPixelSerializer.h" |
#include "SkReadPixelsRec.h" |
+#include "SkSpecialImage.h" |
#include "SkString.h" |
#include "SkSurface.h" |
@@ -342,6 +344,45 @@ sk_sp<SkImage> SkImage::MakeFromPicture(sk_sp<SkPicture> picture, const SkISize& |
matrix, paint)); |
} |
+sk_sp<SkImage> SkImage::makeWithFilter(const SkImageFilter* filter, const SkIRect& subset, |
+ const SkIRect& clipBounds, SkIRect* outSubset, |
+ SkIPoint* offset) const { |
+ if (!filter || !outSubset || !offset || !this->bounds().contains(subset)) { |
+ return nullptr; |
+ } |
+ sk_sp<SkSpecialImage> srcSpecialImage = SkSpecialImage::MakeFromImage( |
+ subset, sk_ref_sp(const_cast<SkImage*>(this))); |
+ if (!srcSpecialImage) { |
+ return nullptr; |
+ } |
+ |
+ // FIXME: build a cache here. |
+ SkImageFilter::Context context(SkMatrix::I(), clipBounds, nullptr); |
+ sk_sp<SkSpecialImage> result = |
+ filter->filterImage(srcSpecialImage.get(), context, offset); |
+ |
+ if (!result) { |
+ return nullptr; |
+ } |
+ |
+ SkIRect fullSize = SkIRect::MakeWH(result->width(), result->height()); |
+#if SK_SUPPORT_GPU |
+ if (result->isTextureBacked()) { |
+ GrContext* context = result->getContext(); |
+ sk_sp<GrTexture> texture = result->asTextureRef(context); |
+ fullSize = SkIRect::MakeWH(texture->width(), texture->height()); |
+ } |
+#endif |
+ *outSubset = SkIRect::MakeWH(result->width(), result->height()); |
+ if (!outSubset->intersect(clipBounds.makeOffset(-offset->x(), -offset->y()))) { |
+ return nullptr; |
+ } |
+ offset->fX += outSubset->x(); |
+ offset->fY += outSubset->y(); |
+ // This isn't really a "tight" subset, but includes any texture padding. |
+ return result->makeTightSubset(fullSize); |
+} |
+ |
bool SkImage::isLazyGenerated() const { |
return as_IB(this)->onIsLazyGenerated(); |
} |