diff options
Diffstat (limited to 'src/animator/SkDrawGroup.cpp')
-rw-r--r-- | src/animator/SkDrawGroup.cpp | 331 |
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; +} + + |