aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-04-13 13:50:27 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-04-13 13:50:27 +0000
commit90c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cb (patch)
tree639c4244633bd0ae63819fcab794e97b3459d866
parent670ff9ae7f37356bff08b30a356bb0c52dc8d62e (diff)
replace getTotalClipStack() with replayClips()+ClipVisitor
git-svn-id: http://skia.googlecode.com/svn/trunk@3670 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkCanvas.h17
-rw-r--r--src/core/SkCanvas.cpp22
-rw-r--r--tests/CanvasTest.cpp30
3 files changed, 57 insertions, 12 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index a09a59261f..25cc94ab12 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -886,13 +886,20 @@ public:
*/
const SkRegion& getTotalClip() const;
+ void setExternalMatrix(const SkMatrix* = NULL);
+
+ class ClipVisitor {
+ public:
+ virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
+ virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
+ };
+
/**
- * Return the current clipstack. This mirrors the result in getTotalClip()
- * but is represented as a stack of geometric clips + region-ops.
+ * Replays the clip operations, back to front, that have been applied to
+ * the canvas, calling the appropriate method on the visitor for each
+ * clip. All clips have already been transformed into device space.
*/
- const SkClipStack& getTotalClipStack() const;
-
- void setExternalMatrix(const SkMatrix* = NULL);
+ void replayClips(ClipVisitor*) const;
///////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index c415a10207..56ac2da646 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -218,7 +218,7 @@ public:
fCanvas = canvas;
canvas->updateDeviceCMCache();
- fClipStack = &canvas->getTotalClipStack();
+ fClipStack = &canvas->fClipStack;
fBounder = canvas->getBounder();
fCurrLayer = canvas->fMCRec->fTopLayer;
fSkipEmptyClips = skipEmptyClips;
@@ -1210,6 +1210,22 @@ void SkCanvas::validateClip() const {
}
#endif
+void SkCanvas::replayClips(ClipVisitor* visitor) const {
+ SkClipStack::B2FIter iter(fClipStack);
+ const SkClipStack::B2FIter::Clip* clip;
+
+ SkRect empty = {};
+ while ((clip = iter.next()) != NULL) {
+ if (clip->fPath) {
+ visitor->clipPath(*clip->fPath, clip->fOp, clip->fDoAA);
+ } else if (clip->fRect) {
+ visitor->clipRect(*clip->fRect, clip->fOp, clip->fDoAA);
+ } else {
+ visitor->clipRect(empty, SkRegion::kIntersect_Op, false);
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
void SkCanvas::computeLocalClipBoundsCompareType(EdgeType et) const {
@@ -1342,10 +1358,6 @@ const SkRegion& SkCanvas::getTotalClip() const {
return fMCRec->fRasterClip->forceGetBW();
}
-const SkClipStack& SkCanvas::getTotalClipStack() const {
- return fClipStack;
-}
-
void SkCanvas::setExternalMatrix(const SkMatrix* matrix) {
if (NULL == matrix || matrix->isIdentity()) {
if (fUseExternalMatrix) {
diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp
index 65a3494791..b008a57bea 100644
--- a/tests/CanvasTest.cpp
+++ b/tests/CanvasTest.cpp
@@ -62,6 +62,34 @@
#include "SkTDArray.h"
#include "Test.h"
+class Canvas2CanvasClipVisitor : public SkCanvas::ClipVisitor {
+public:
+ Canvas2CanvasClipVisitor(SkCanvas* target) : fTarget(target) {}
+
+ virtual void clipRect(const SkRect& r, SkRegion::Op op, bool aa) {
+ fTarget->clipRect(r, op, aa);
+ }
+ virtual void clipPath(const SkPath& p, SkRegion::Op op, bool aa) {
+ fTarget->clipPath(p, op, aa);
+ }
+
+private:
+ SkCanvas* fTarget;
+};
+
+static void test_clipVisitor(skiatest::Reporter* reporter, SkCanvas* canvas) {
+ SkISize size = canvas->getDeviceSize();
+
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
+ SkCanvas c(bm);
+
+ Canvas2CanvasClipVisitor visitor(&c);
+ canvas->replayClips(&visitor);
+
+ REPORTER_ASSERT(reporter, c.getTotalClip() == canvas->getTotalClip());
+}
+
static const int kWidth = 2;
static const int kHeight = 2;
// Maximum stream length for picture serialization
@@ -436,8 +464,6 @@ static void AssertCanvasStatesEqual(skiatest::Reporter* reporter,
canvas2->getClipType(), testStep->assertMessage());
REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClip() ==
canvas2->getTotalClip(), testStep->assertMessage());
- REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClipStack() ==
- canvas2->getTotalClipStack(), testStep->assertMessage());
// The following test code is commented out because the test fails when
// the canvas is an SkPictureRecord or SkDeferredCanvas