aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/utils/SkPaintFilterCanvas.h9
-rw-r--r--src/utils/SkPaintFilterCanvas.cpp12
-rw-r--r--tests/CanvasTest.cpp36
3 files changed, 57 insertions, 0 deletions
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index da0333e7e6..d693758797 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -16,8 +16,17 @@
*/
class SK_API SkPaintFilterCanvas : public SkNWayCanvas {
public:
+ /**
+ * DEPRECATED: use the variant below.
+ */
SkPaintFilterCanvas(int width, int height);
+ /**
+ * The new SkPaintFilterCanvas is configured for forwarding to the
+ * specified canvas. Also copies the target canvas matrix and clip bounds.
+ */
+ SkPaintFilterCanvas(SkCanvas* canvas);
+
enum Type {
kPaint_Type,
kPoint_Type,
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index 0ff6ae04d1..dff1514acb 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -30,6 +30,18 @@ private:
SkPaintFilterCanvas::SkPaintFilterCanvas(int width, int height) : INHERITED(width, height) { }
+SkPaintFilterCanvas::SkPaintFilterCanvas(SkCanvas *canvas)
+ : INHERITED(canvas->imageInfo().width(), canvas->imageInfo().height()) {
+
+ // Transfer matrix & clip state before adding the target canvas.
+ SkIRect devClip;
+ canvas->getClipDeviceBounds(&devClip);
+ this->clipRect(SkRect::Make(devClip));
+ this->setMatrix(canvas->getTotalMatrix());
+
+ this->addCanvas(canvas);
+}
+
void SkPaintFilterCanvas::onDrawPaint(const SkPaint& paint) {
AutoPaintFilter apf(this, kPaint_Type, paint);
this->INHERITED::onDrawPaint(*apf.paint());
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index 0d5c862360..5aa3d46628 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -52,6 +52,7 @@
#include "SkMatrix.h"
#include "SkNWayCanvas.h"
#include "SkPaint.h"
+#include "SkPaintFilterCanvas.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkPictureRecord.h"
@@ -782,3 +783,38 @@ DEF_TEST(Canvas_ClipEmptyPath, reporter) {
canvas.clipPath(path); // should not assert here
canvas.restore();
}
+
+namespace {
+
+class MockFilterCanvas : public SkPaintFilterCanvas {
+public:
+ MockFilterCanvas(SkCanvas* canvas) : INHERITED(canvas) { }
+
+protected:
+ void onFilterPaint(SkPaint *paint, Type type) const override { }
+
+private:
+ typedef SkPaintFilterCanvas INHERITED;
+};
+
+} // anonymous namespace
+
+// SkPaintFilterCanvas should inherit the initial target canvas state.
+DEF_TEST(PaintFilterCanvas_ConsistentState, reporter) {
+ SkCanvas canvas(100, 100);
+ canvas.clipRect(SkRect::MakeXYWH(12.7f, 12.7f, 75, 75));
+ canvas.scale(0.5f, 0.75f);
+
+ SkRect clip1, clip2;
+
+ MockFilterCanvas filterCanvas(&canvas);
+ REPORTER_ASSERT(reporter, canvas.getTotalMatrix() == filterCanvas.getTotalMatrix());
+ REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2));
+ REPORTER_ASSERT(reporter, clip1 == clip2);
+
+ filterCanvas.clipRect(SkRect::MakeXYWH(30.5f, 30.7f, 100, 100));
+ filterCanvas.scale(0.75f, 0.5f);
+ REPORTER_ASSERT(reporter, canvas.getTotalMatrix() == filterCanvas.getTotalMatrix());
+ REPORTER_ASSERT(reporter, canvas.getClipBounds(&clip1) == filterCanvas.getClipBounds(&clip2));
+ REPORTER_ASSERT(reporter, clip1 == clip2);
+}