aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--expectations/gm/ignored-tests.txt31
-rw-r--r--include/core/SkDevice.h5
-rw-r--r--include/pdf/SkPDFDevice.h4
-rw-r--r--src/core/SkCanvas.cpp2
-rw-r--r--src/core/SkDevice.cpp4
-rw-r--r--src/core/SkDeviceImageFilterProxy.h2
-rw-r--r--src/pdf/SkPDFDevice.cpp10
-rw-r--r--tests/PDFPrimitivesTest.cpp52
8 files changed, 103 insertions, 7 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 86cc83ce21..5f16953307 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -57,3 +57,34 @@ imagefiltersbase
# jvanverth - adding color emoji to df text
dftext
+
+# senorblanco https://codereview.chromium.org/644323006/
+# PDF backend now supports image filters
+bitmapsource
+colorfilterimagefilter
+displacement
+dropshadowimagefilter
+imagealphathreshold
+imageblur
+imageblur2
+imageblur_large
+imageblurtiled
+imagefiltersbase
+imagefiltersclipped
+imagefilterscropexpand
+imagefilterscropped
+imagefiltersgraph
+imagefiltersscaled
+imagemagnifier
+imageresizetiled
+lighting
+matrixconvolution
+matriximagefilter
+morphology
+offsetimagefilter
+pictureimagefilter
+resizeimagefilter
+spritebitmap
+testimagefilters
+tileimagefilter
+xfermodeimagefilter
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index fb3c206e9e..5984681622 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -121,7 +121,8 @@ public:
protected:
enum Usage {
kGeneral_Usage,
- kSaveLayer_Usage // <! internal use only
+ kSaveLayer_Usage, // <! internal use only
+ kImageFilter_Usage // <! internal use only
};
struct TextFlags {
@@ -368,6 +369,8 @@ private:
void setOrigin(int x, int y) { fOrigin.set(x, y); }
// just called by SkCanvas for saveLayer
SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
+ // just called by SkCanvas for imagefilter
+ SkBaseDevice* createCompatibleDeviceForImageFilter(const SkImageInfo&);
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
return NULL;
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 0ada5312ae..f6f782b99a 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -213,10 +213,6 @@ protected:
return fLegacyBitmap;
}
- virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE {
- return false;
- }
-
virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;
private:
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 709cb4c0be..2f7fcf4d4b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -933,7 +933,7 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Save
if (paint && paint->getImageFilter()) {
device = this->getDevice();
if (device) {
- device = device->createCompatibleDevice(info);
+ device = device->createCompatibleDeviceForImageFilter(info);
}
} else {
device = this->createLayerDevice(info);
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 0623f9909e..b912e6aef0 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -36,6 +36,10 @@ SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo
return this->onCreateDevice(info, kSaveLayer_Usage);
}
+SkBaseDevice* SkBaseDevice::createCompatibleDeviceForImageFilter(const SkImageInfo& info) {
+ return this->onCreateDevice(info, kImageFilter_Usage);
+}
+
SkMetaData& SkBaseDevice::getMetaData() {
// metadata users are rare, so we lazily allocate it. If that changes we
// can decide to just make it a field in the device (rather than a ptr)
diff --git a/src/core/SkDeviceImageFilterProxy.h b/src/core/SkDeviceImageFilterProxy.h
index 5ee563484e..0b83b1a81e 100644
--- a/src/core/SkDeviceImageFilterProxy.h
+++ b/src/core/SkDeviceImageFilterProxy.h
@@ -15,7 +15,7 @@ public:
SkDeviceImageFilterProxy(SkBaseDevice* device) : fDevice(device) {}
virtual SkBaseDevice* createDevice(int w, int h) SK_OVERRIDE {
- return fDevice->createCompatibleDevice(SkImageInfo::MakeN32Premul(w, h));
+ return fDevice->createCompatibleDeviceForImageFilter(SkImageInfo::MakeN32Premul(w, h));
}
virtual bool canHandleImageFilter(const SkImageFilter* filter) SK_OVERRIDE {
return fDevice->canHandleImageFilter(filter);
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 736c50b9a6..8509de86fc 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -8,6 +8,7 @@
#include "SkPDFDevice.h"
#include "SkAnnotation.h"
+#include "SkBitmapDevice.h"
#include "SkColor.h"
#include "SkClipStack.h"
#include "SkData.h"
@@ -567,6 +568,15 @@ void GraphicStackState::updateDrawingState(const GraphicStateEntry& state) {
}
SkBaseDevice* SkPDFDevice::onCreateDevice(const SkImageInfo& info, Usage usage) {
+ // PDF does not support image filters, so render them on CPU.
+ // Note that this rendering is done at "screen" resolution (100dpi), not
+ // printer resolution.
+ // FIXME: It may be possible to express some filters natively using PDF
+ // to improve quality and file size (http://skbug.com/3043)
+ if (kImageFilter_Usage == usage) {
+ return SkBitmapDevice::Create(info);
+ }
+
SkMatrix initialTransform;
initialTransform.reset();
SkISize size = SkISize::Make(info.width(), info.height());
diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp
index b1d482ffa2..05677cd1ab 100644
--- a/tests/PDFPrimitivesTest.cpp
+++ b/tests/PDFPrimitivesTest.cpp
@@ -15,6 +15,7 @@
#include "SkPDFDevice.h"
#include "SkPDFStream.h"
#include "SkPDFTypes.h"
+#include "SkReadBuffer.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkTypes.h"
@@ -428,3 +429,54 @@ DEF_TEST(PDFPrimitives, reporter) {
TestImages(reporter);
}
+
+namespace {
+
+class DummyImageFilter : public SkImageFilter {
+public:
+ DummyImageFilter(bool visited = false) : SkImageFilter(0, NULL), fVisited(visited) {}
+ virtual ~DummyImageFilter() SK_OVERRIDE {}
+ virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
+ SkBitmap* result, SkIPoint* offset) const {
+ fVisited = true;
+ offset->fX = offset->fY = 0;
+ *result = src;
+ return true;
+ }
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyImageFilter)
+#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
+ explicit DummyImageFilter(SkReadBuffer& buffer) : SkImageFilter(0, NULL) {
+ fVisited = buffer.readBool();
+ }
+#endif
+ bool visited() const { return fVisited; }
+
+private:
+ mutable bool fVisited;
+};
+
+SkFlattenable* DummyImageFilter::CreateProc(SkReadBuffer& buffer) {
+ SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+ bool visited = buffer.readBool();
+ return SkNEW_ARGS(DummyImageFilter, (visited));
+}
+
+};
+
+// Check that PDF rendering of image filters successfully falls back to
+// CPU rasterization.
+DEF_TEST(PDFImageFilter, reporter) {
+ SkISize pageSize = SkISize::Make(100, 100);
+ SkAutoTUnref<SkPDFDevice> device(new SkPDFDevice(pageSize, pageSize, SkMatrix::I()));
+ SkCanvas canvas(device.get());
+ SkAutoTUnref<DummyImageFilter> filter(new DummyImageFilter());
+
+ // Filter just created; should be unvisited.
+ REPORTER_ASSERT(reporter, !filter->visited());
+ SkPaint paint;
+ paint.setImageFilter(filter.get());
+ canvas.drawRect(SkRect::MakeWH(100, 100), paint);
+
+ // Filter was used in rendering; should be visited.
+ REPORTER_ASSERT(reporter, filter->visited());
+}