Add skipToLast method to SkClipStack
http://codereview.appspot.com/6411043/
git-svn-id: http://skia.googlecode.com/svn/trunk@4644 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 71b988d..f7ddc97 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -202,7 +202,7 @@
///////////////////////////////////////////////////////////////////////////////
-SkClipStack::Iter::Iter() {
+SkClipStack::Iter::Iter() : fStack(NULL) {
}
bool operator==(const SkClipStack::Iter::Clip& a,
@@ -219,7 +219,8 @@
return !(a == b);
}
-SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) {
+SkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc)
+ : fStack(&stack) {
this->reset(stack, startLoc);
}
@@ -262,6 +263,45 @@
return this->updateClip(rec);
}
+const SkClipStack::Iter::Clip* SkClipStack::Iter::skipToLast(SkRegion::Op op) {
+
+ if (NULL == fStack) {
+ return NULL;
+ }
+
+ fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart);
+
+ const SkClipStack::Rec* rec = NULL;
+
+ for (rec = (const SkClipStack::Rec*) fIter.prev();
+ NULL != rec;
+ rec = (const SkClipStack::Rec*) fIter.prev()) {
+
+ if (op == rec->fOp) {
+ // The Deque's iterator is actually one pace ahead of the
+ // returned value. So while "rec" is the element we want to
+ // return, the iterator is actually pointing at (and will
+ // return on the next "next" or "prev" call) the element
+ // in front of it in the deque. Bump the iterator forward a
+ // step so we get the expected result.
+ if (NULL == fIter.next()) {
+ // The reverse iterator has run off the front of the deque
+ // (i.e., the "op" clip is the first clip) and can't
+ // recover. Reset the iterator to start at the front.
+ fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart);
+ }
+ break;
+ }
+ }
+
+ if (NULL == rec) {
+ // There were no "op" clips
+ fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart);
+ }
+
+ return this->next();
+}
+
void SkClipStack::Iter::reset(const SkClipStack& stack, IterStart startLoc) {
fIter.reset(stack.fDeque, static_cast<SkDeque::Iter::IterStart>(startLoc));
}