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
This commit is contained in:
robertphillips@google.com 2012-07-18 12:06:15 +00:00
Родитель f7751ae229
Коммит 5836b6dec5
2 изменённых файлов: 52 добавлений и 4 удалений

Просмотреть файл

@ -79,14 +79,22 @@ public:
const Clip* next();
const Clip* prev();
/**
* Moves the iterator to the last clip with the specified RegionOp
* and returns that clip. If no clip with that op is found,
* returns NULL.
*/
const Clip* skipToLast(SkRegion::Op op);
/**
* Restarts the iterator on a clip stack.
*/
void reset(const SkClipStack& stack, IterStart startLoc);
private:
Clip fClip;
SkDeque::Iter fIter;
const SkClipStack* fStack;
Clip fClip;
SkDeque::Iter fIter;
/**
* updateClip updates fClip to the current state of fIter. It unifies

Просмотреть файл

@ -202,7 +202,7 @@ void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) {
///////////////////////////////////////////////////////////////////////////////
SkClipStack::Iter::Iter() {
SkClipStack::Iter::Iter() : fStack(NULL) {
}
bool operator==(const SkClipStack::Iter::Clip& a,
@ -219,7 +219,8 @@ bool operator!=(const SkClipStack::Iter::Clip& a,
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 @@ const SkClipStack::Iter::Clip* SkClipStack::Iter::prev() {
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));
}