diff options
-rw-r--r-- | include/utils/SkPaintFilterCanvas.h | 9 | ||||
-rw-r--r-- | src/utils/SkPaintFilterCanvas.cpp | 12 | ||||
-rw-r--r-- | tests/CanvasTest.cpp | 36 |
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); +} |