| #include "SkDrawing.h" |
| #include "SkCanvas.h" |
| |
| SkDrawing::SkDrawing() { |
| fMatrix.reset(); |
| fParent = fFirstChild = fNextSibling = fPrevSibling = NULL; |
| } |
| |
| SkDrawing::~SkDrawing() { |
| this->detachAllChildren(); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void SkDrawing::resetMatrix() { |
| fMatrix.reset(); |
| } |
| |
| void SkDrawing::getMatrix(SkMatrix* matrix) const { |
| if (matrix) { |
| *matrix = fMatrix; |
| } |
| } |
| |
| void SkDrawing::setMatrix(const SkMatrix& matrix) { |
| if (fMatrix != matrix) { |
| this->inval(); |
| fMatrix = matrix; |
| this->inval(); |
| } |
| } |
| |
| void SkDrawing::draw(SkCanvas* canvas) { |
| SkAutoCanvasRestore ar(canvas, false); |
| canvas->save(SkCanvas::kMatrix_SaveFlag); |
| canvas->concat(fMatrix); |
| |
| this->onDraw(canvas); |
| |
| B2FIter iter(this); |
| SkDrawing* child; |
| while ((child = iter.next()) != NULL) { |
| child->draw(canvas); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void SkDrawing::detachFromParent() { |
| SkDrawing* parent = fParent; |
| |
| if (NULL == parent) { |
| return; |
| } |
| |
| this->inval(); |
| |
| SkDrawing* next = NULL; |
| |
| if (fNextSibling != this) { // do we have any siblings |
| fNextSibling->fPrevSibling = fPrevSibling; |
| fPrevSibling->fNextSibling = fNextSibling; |
| next = fNextSibling; |
| } |
| |
| if (fParent->fFirstChild == this) { |
| fParent->fFirstChild = next; |
| } |
| |
| fParent = fNextSibling = fPrevSibling = NULL; |
| this->unref(); |
| } |
| |
| SkDrawing* SkDrawing::attachChildToBack(SkDrawing* child) { |
| SkASSERT(child != this); |
| |
| if (child == NULL || fFirstChild == child) { |
| return child; |
| } |
| |
| child->ref(); |
| child->detachFromParent(); |
| |
| if (fFirstChild == NULL) { |
| child->fNextSibling = child; |
| child->fPrevSibling = child; |
| } else { |
| child->fNextSibling = fFirstChild; |
| child->fPrevSibling = fFirstChild->fPrevSibling; |
| fFirstChild->fPrevSibling->fNextSibling = child; |
| fFirstChild->fPrevSibling = child; |
| } |
| |
| fFirstChild = child; |
| child->fParent = this; |
| child->inval(); |
| return child; |
| } |
| |
| SkDrawing* SkDrawing::attachChildToFront(SkDrawing* child) { |
| SkASSERT(child != this); |
| |
| if (child == NULL || fFirstChild && fFirstChild->fPrevSibling == child) { |
| return child; |
| } |
| |
| child->ref(); |
| child->detachFromParent(); |
| |
| if (fFirstChild == NULL) { |
| fFirstChild = child; |
| child->fNextSibling = child; |
| child->fPrevSibling = child; |
| } else { |
| child->fNextSibling = fFirstChild; |
| child->fPrevSibling = fFirstChild->fPrevSibling; |
| fFirstChild->fPrevSibling->fNextSibling = child; |
| fFirstChild->fPrevSibling = child; |
| } |
| |
| child->fParent = this; |
| child->inval(); |
| return child; |
| } |
| |
| void SkDrawing::detachAllChildren() { |
| while (fFirstChild) { |
| fFirstChild->detachFromParent(); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| SkDrawing::B2FIter::B2FIter(const SkDrawing* parent) { |
| fFirstChild = parent ? parent->fFirstChild : NULL; |
| fChild = fFirstChild; |
| } |
| |
| SkDrawing* SkDrawing::B2FIter::next() { |
| SkDrawing* curr = fChild; |
| |
| if (fChild) { |
| SkDrawing* next = fChild->fNextSibling; |
| if (next == fFirstChild) { |
| next = NULL; |
| } |
| fChild = next; |
| } |
| return curr; |
| } |
| |
| |