aboutsummaryrefslogtreecommitdiffstats
path: root/src/animator/SkDrawGroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/animator/SkDrawGroup.cpp')
-rw-r--r--src/animator/SkDrawGroup.cpp331
1 files changed, 331 insertions, 0 deletions
diff --git a/src/animator/SkDrawGroup.cpp b/src/animator/SkDrawGroup.cpp
new file mode 100644
index 0000000..aa53564
--- /dev/null
+++ b/src/animator/SkDrawGroup.cpp
@@ -0,0 +1,331 @@
+/* libs/graphics/animator/SkDrawGroup.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkDrawGroup.h"
+#include "SkAnimateMaker.h"
+#include "SkAnimatorScript.h"
+#include "SkCanvas.h"
+#include "SkDisplayApply.h"
+#include "SkPaint.h"
+#ifdef SK_DEBUG
+#include "SkDisplayList.h"
+#endif
+
+#if SK_USE_CONDENSED_INFO == 0
+
+const SkMemberInfo SkGroup::fInfo[] = {
+ SK_MEMBER(condition, String),
+ SK_MEMBER(enableCondition, String)
+};
+
+#endif
+
+DEFINE_GET_MEMBER(SkGroup);
+
+SkGroup::SkGroup() : fParentList(NULL), fOriginal(NULL) {
+}
+
+SkGroup::~SkGroup() {
+ if (fOriginal) // has been copied
+ return;
+ int index = 0;
+ int max = fCopies.count() << 5;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ if (index >= max || markedForDelete(index))
+ delete *ptr;
+// else {
+// SkApply* apply = (SkApply*) *ptr;
+// SkASSERT(apply->isApply());
+// SkASSERT(apply->getScope());
+// delete apply->getScope();
+// }
+ index++;
+ }
+}
+
+bool SkGroup::add(SkAnimateMaker& , SkDisplayable* child) {
+ SkASSERT(child);
+// SkASSERT(child->isDrawable());
+ *fChildren.append() = (SkDrawable*) child;
+ if (child->isGroup()) {
+ SkGroup* groupie = (SkGroup*) child;
+ SkASSERT(groupie->fParentList == NULL);
+ groupie->fParentList = &fChildren;
+ }
+ return true;
+}
+
+bool SkGroup::contains(SkDisplayable* match) {
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable == match || drawable->contains(match))
+ return true;
+ }
+ return false;
+}
+
+SkGroup* SkGroup::copy() {
+ SkGroup* result = new SkGroup();
+ result->fOriginal = this;
+ result->fChildren = fChildren;
+ return result;
+}
+
+SkBool SkGroup::copySet(int index) {
+ return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0;
+}
+
+SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) {
+ SkDisplayable* copy = INHERITED::deepCopy(maker);
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDisplayable* displayable = (SkDisplayable*)*ptr;
+ SkDisplayable* deeperCopy = displayable->deepCopy(maker);
+ ((SkGroup*)copy)->add(*maker, deeperCopy);
+ }
+ return copy;
+}
+
+bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
+ bool handled = false;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable->isDrawable() == false)
+ continue;
+ handled |= drawable->doEvent(kind, state);
+ }
+ return handled;
+}
+
+bool SkGroup::draw(SkAnimateMaker& maker) {
+ bool conditionTrue = ifCondition(maker, this, condition);
+ bool result = false;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable->isDrawable() == false)
+ continue;
+ if (conditionTrue == false) {
+ if (drawable->isApply())
+ ((SkApply*) drawable)->disable();
+ continue;
+ }
+ maker.validate();
+ result |= drawable->draw(maker);
+ maker.validate();
+ }
+ return result;
+}
+
+#ifdef SK_DUMP_ENABLED
+void SkGroup::dump(SkAnimateMaker* maker) {
+ dumpBase(maker);
+ if (condition.size() > 0)
+ SkDebugf("condition=\"%s\" ", condition.c_str());
+ if (enableCondition.size() > 0)
+ SkDebugf("enableCondition=\"%s\" ", enableCondition.c_str());
+ dumpDrawables(maker);
+}
+
+void SkGroup::dumpDrawables(SkAnimateMaker* maker) {
+ SkDisplayList::fIndent += 4;
+ int save = SkDisplayList::fDumpIndex;
+ SkDisplayList::fDumpIndex = 0;
+ bool closedYet = false;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ if (closedYet == false) {
+ closedYet = true;
+ SkDebugf(">\n");
+ }
+ SkDrawable* drawable = *ptr;
+ drawable->dump(maker);
+ SkDisplayList::fDumpIndex++;
+ }
+ SkDisplayList::fIndent -= 4;
+ SkDisplayList::fDumpIndex = save;
+ if (closedYet) //we had children, now it's time to close the group
+ dumpEnd(maker);
+ else //no children
+ SkDebugf("/>\n");
+}
+
+void SkGroup::dumpEvents() {
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ drawable->dumpEvents();
+ }
+}
+#endif
+
+bool SkGroup::enable(SkAnimateMaker& maker ) {
+ reset();
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (ifCondition(maker, drawable, enableCondition) == false)
+ continue;
+ drawable->enable(maker);
+ }
+ return true; // skip add; already added so that scope is findable by children
+}
+
+int SkGroup::findGroup(SkDrawable* match, SkTDDrawableArray** list,
+ SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
+ *list = &fChildren;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable->isGroup()) {
+ SkGroup* childGroup = (SkGroup*) drawable;
+ if (childGroup->fOriginal == match)
+ goto foundMatch;
+ }
+ if (drawable == match) {
+foundMatch:
+ *parent = this;
+ return (int) (ptr - fChildren.begin());
+ }
+ }
+ *grandList = &fChildren;
+ return SkDisplayList::SearchForMatch(match, list, parent, found, grandList);
+}
+
+bool SkGroup::hasEnable() const {
+ return true;
+}
+
+bool SkGroup::ifCondition(SkAnimateMaker& maker, SkDrawable* drawable,
+ SkString& conditionString) {
+ if (conditionString.size() == 0)
+ return true;
+ int32_t result;
+ bool success = SkAnimatorScript::EvaluateInt(maker, this, conditionString.c_str(), &result);
+#ifdef SK_DUMP_ENABLED
+ if (maker.fDumpGConditions) {
+ SkDebugf("group: ");
+ dumpBase(&maker);
+ SkDebugf("condition=%s ", conditionString.c_str());
+ if (success == false)
+ SkDebugf("(script failed)\n");
+ else
+ SkDebugf("success=%s\n", result != 0 ? "true" : "false");
+ }
+#endif
+ return success && result != 0;
+}
+
+void SkGroup::initialize() {
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable->isDrawable() == false)
+ continue;
+ drawable->initialize();
+ }
+}
+
+void SkGroup::markCopyClear(int index) {
+ if (index < 0)
+ index = fChildren.count();
+ fCopies[index >> 5] &= ~(1 << (index & 0x1f));
+}
+
+void SkGroup::markCopySet(int index) {
+ if (index < 0)
+ index = fChildren.count();
+ fCopies[index >> 5] |= 1 << (index & 0x1f);
+}
+
+void SkGroup::markCopySize(int index) {
+ if (index < 0)
+ index = fChildren.count() + 1;
+ int oldLongs = fCopies.count();
+ int newLongs = (index >> 5) + 1;
+ if (oldLongs < newLongs) {
+ fCopies.setCount(newLongs);
+ memset(&fCopies[oldLongs], 0, (newLongs - oldLongs) << 2);
+ }
+}
+
+void SkGroup::reset() {
+ if (fOriginal) // has been copied
+ return;
+ int index = 0;
+ int max = fCopies.count() << 5;
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ if (index >= max || copySet(index) == false)
+ continue;
+ SkApply* apply = (SkApply*) *ptr;
+ SkASSERT(apply->isApply());
+ SkASSERT(apply->getScope());
+ *ptr = apply->getScope();
+ markCopyClear(index);
+ index++;
+ }
+}
+
+bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) {
+ SkGroup* original = (SkGroup*) orig;
+ SkTDDrawableArray& originalChildren = original->fChildren;
+ SkDrawable** originalPtr = originalChildren.begin();
+ SkDrawable** ptr = fChildren.begin();
+ SkDrawable** end = fChildren.end();
+ SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin();
+ while (ptr < end) {
+ SkDrawable* drawable = *ptr++;
+ maker.resolveID(drawable, *origChild++);
+ if (drawable->resolveIDs(maker, *originalPtr++, apply) == true)
+ return true; // failed
+ }
+ return false;
+}
+
+void SkGroup::setSteps(int steps) {
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ if (drawable->isDrawable() == false)
+ continue;
+ drawable->setSteps(steps);
+ }
+}
+
+#ifdef SK_DEBUG
+void SkGroup::validate() {
+ for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
+ SkDrawable* drawable = *ptr;
+ drawable->validate();
+ }
+}
+#endif
+
+#if SK_USE_CONDENSED_INFO == 0
+
+const SkMemberInfo SkSave::fInfo[] = {
+ SK_MEMBER_INHERITED
+};
+
+#endif
+
+DEFINE_GET_MEMBER(SkSave);
+
+bool SkSave::draw(SkAnimateMaker& maker) {
+ maker.fCanvas->save();
+ SkPaint* save = maker.fPaint;
+ SkPaint local = SkPaint(*maker.fPaint);
+ maker.fPaint = &local;
+ bool result = INHERITED::draw(maker);
+ maker.fPaint = save;
+ maker.fCanvas->restore();
+ return result;
+}
+
+