diff options
-rw-r--r-- | include/core/SkDrawable.h | 54 | ||||
-rw-r--r-- | src/core/SkDrawable.cpp | 152 | ||||
-rw-r--r-- | xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj | 4 |
3 files changed, 210 insertions, 0 deletions
diff --git a/include/core/SkDrawable.h b/include/core/SkDrawable.h new file mode 100644 index 0000000000..793534759a --- /dev/null +++ b/include/core/SkDrawable.h @@ -0,0 +1,54 @@ +#ifndef SkDrawable_DEFINED +#define SkDrawable_DEFINED + +#include "SkFlattenable.h" +#include "SkMatrix.h" + +class SkCanvas; +struct SkRect; + +class SkDrawable : public SkFlattenable { +public: + SkDrawable(); + virtual ~SkDrawable(); + + void getMatrix(SkMatrix*) const; + void setMatrix(const SkMatrix&); + void resetMatrix(); + + void draw(SkCanvas*); + + void inval() {} + + SkDrawable* attachChildToFront(SkDrawable* child); + SkDrawable* attachChildToBack(SkDrawable* child); + + SkDrawable* getParent() const { return fParent; } + void detachFromParent(); + void detachAllChildren(); + + class B2FIter { + public: + B2FIter(const SkDrawable* parent); + SkDrawable* next(); + private: + SkDrawable* fFirstChild; + SkDrawable* fChild; + }; + +protected: + virtual void onDraw(SkCanvas*) {} + +private: + SkMatrix fMatrix; + + SkDrawable* fParent; + SkDrawable* fFirstChild; + SkDrawable* fNextSibling; + SkDrawable* fPrevSibling; + + typedef SkFlattenable INHERITED; +}; + +#endif + diff --git a/src/core/SkDrawable.cpp b/src/core/SkDrawable.cpp new file mode 100644 index 0000000000..85f3175bdb --- /dev/null +++ b/src/core/SkDrawable.cpp @@ -0,0 +1,152 @@ +#include "SkDrawable.h" +#include "SkCanvas.h" + +SkDrawable::SkDrawable() { + fMatrix.reset(); + fParent = fFirstChild = fNextSibling = fPrevSibling = NULL; +} + +SkDrawable::~SkDrawable() { + this->detachAllChildren(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void SkDrawable::resetMatrix() { + fMatrix.reset(); +} + +void SkDrawable::getMatrix(SkMatrix* matrix) const { + if (matrix) { + *matrix = fMatrix; + } +} + +void SkDrawable::setMatrix(const SkMatrix& matrix) { + if (fMatrix != matrix) { + this->inval(); + fMatrix = matrix; + this->inval(); + } +} + +void SkDrawable::draw(SkCanvas* canvas) { + SkAutoCanvasRestore ar(canvas, false); + canvas->save(SkCanvas::kMatrix_SaveFlag); + canvas->concat(fMatrix); + + this->onDraw(canvas); + + B2FIter iter(this); + SkDrawable* child; + while ((child = iter.next()) != NULL) { + child->draw(canvas); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void SkDrawable::detachFromParent() { + SkDrawable* parent = fParent; + + if (NULL == parent) { + return; + } + + this->inval(); + + SkDrawable* 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(); +} + +SkDrawable* SkDrawable::attachChildToBack(SkDrawable* 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; +} + +SkDrawable* SkDrawable::attachChildToFront(SkDrawable* 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 SkDrawable::detachAllChildren() { + while (fFirstChild) { + fFirstChild->detachFromParent(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +SkDrawable::B2FIter::B2FIter(const SkDrawable* parent) { + fFirstChild = parent ? parent->fFirstChild : NULL; + fChild = fFirstChild; +} + +SkDrawable* SkDrawable::B2FIter::next() { + SkDrawable* curr = fChild; + + if (fChild) { + SkDrawable* next = fChild->fNextSibling; + if (next == fFirstChild) { + next = NULL; + } + fChild = next; + } + return curr; +} + + diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj index 3def3dae0e..e172db7628 100644 --- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj +++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj @@ -69,6 +69,7 @@ 00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; }; 0156F80407C56A3000C6122B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0156F80307C56A3000C6122B /* Foundation.framework */; }; 01FC44D507BD3BB800D228F4 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FC44D407BD3BB800D228F4 /* Quartz.framework */; }; + 2714E7960F7733EE00E95AE0 /* SkDrawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2714E7950F7733EE00E95AE0 /* SkDrawable.cpp */; }; 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; 8D0C4E8E0486CD37000505A6 /* main.nib in Resources */ = {isa = PBXBuildFile; fileRef = 02345980000FD03B11CA0E72 /* main.nib */; }; 8D0C4E920486CD37000505A6 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; }; @@ -187,6 +188,7 @@ 0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 1870340FFE93FCAF11CA0CD7 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/main.nib; sourceTree = "<group>"; }; 20286C33FDCF999611CA2CEA /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; }; + 2714E7950F7733EE00E95AE0 /* SkDrawable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkDrawable.cpp; path = ../../src/core/SkDrawable.cpp; sourceTree = SOURCE_ROOT; }; 32DBCF6D0370B57F00C91783 /* CICarbonSample_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CICarbonSample_Prefix.pch; sourceTree = "<group>"; }; 4A9504C8FFE6A3BC11CA0CBA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; }; 4A9504CAFFE6A41611CA0CBA /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; }; @@ -328,6 +330,7 @@ 002884490EFAA35C0083E387 /* core.xcodeproj */, 002884B40EFAB69F0083E387 /* maccore.xcodeproj */, 00003C8C0EFC230E000FF73A /* effects.xcodeproj */, + 2714E7950F7733EE00E95AE0 /* SkDrawable.cpp */, ); name = CICarbonSample; sourceTree = "<group>"; @@ -515,6 +518,7 @@ 007C785E0F3B4C230004B142 /* SamplePathClip.cpp in Sources */, 009CC9190F65918A002185BE /* SampleFontScalerTest.cpp in Sources */, 007A7CB30F01658C00A2D6EE /* SamplePicture.cpp in Sources */, + 2714E7960F7733EE00E95AE0 /* SkDrawable.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |