180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDisplayApply.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateActive.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateMaker.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimateSet.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAnimatorScript.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDisplayType.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDrawGroup.h"
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkParse.h"
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScript.h"
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkSystemEventTypes.h"
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTime.h"
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <ctype.h>
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruenum SkApply_Properties {
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_PROPERTY(animator),
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_PROPERTY(step),
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_PROPERTY(steps),
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_PROPERTY(time)
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if SK_USE_CONDENSED_INFO == 0
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// if no attibutes, enclosed displayable is both scope & target
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// only if both scope & target are specified, or if target and enclosed displayable, are scope and target different
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMemberInfo SkApply::fInfo[] = {
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER_PROPERTY(animator, Animate),
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(begin, MSec),
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(dontDraw, Boolean),
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(dynamicScope, String),
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(interval, MSec),  // recommended redraw interval
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(mode, ApplyMode),
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(pickup, Boolean),
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(restore, Boolean),
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(scope, Drawable), // thing that scopes animation (unnamed enclosed displayable goes here)
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER_PROPERTY(step, Int),
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER_PROPERTY(steps, Int),
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER_PROPERTY(time, MSec),
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_MEMBER(transition, ApplyTransition)
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruDEFINE_GET_MEMBER(SkApply);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkApply::SkApply() : begin(0), dontDraw(false), interval((SkMSec) -1), mode((Mode) -1), /*pickup(false), */
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    restore(false), scope(NULL), steps(-1), transition((Transition) -1), fActive(NULL), /*fCurrentScope(NULL),*/
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fLastTime(0), fAppended(false), fContainsScope(false), fDeleteScope(false), fEmbedded(false),
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fEnabled(false), fEnabling(false) {
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkApply::~SkApply() {
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++)
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete *curPtr;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fDeleteScope)
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete scope;
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // !!! caller must call maker.removeActive(fActive)
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    delete fActive;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::activate(SkAnimateMaker& maker) {
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive != NULL) {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fActive->fDrawIndex == 0 && fActive->fDrawMax == 0)
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return; // if only one use, nothing more to do
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (restore == false)
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return; // all share same state, regardless of instance number
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool save = fActive->initializeSave();
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->fixInterpolator(save);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive = new SkActive(*this, maker);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->init();
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maker.appendActive(fActive);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (restore) {
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fActive->initializeSave();
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int animators = fAnimators.count();
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int index = 0; index < animators; index++)
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fActive->saveInterpolatorValues(index);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::append(SkApply* apply) {
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive == NULL)
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int oldCount = fActive->fAnimators.count();
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fActive->append(apply);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (restore) {
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->appendSave(oldCount);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int newCount = fActive->fAnimators.count();
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int index = oldCount; index < newCount; index++)
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fActive->saveInterpolatorValues(index);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::applyValues(int animatorIndex, SkOperand* values, int count,
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     SkDisplayTypes valuesType, SkMSec time)
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase* animator = fActive->fAnimators[animatorIndex];
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMemberInfo * info = animator->fFieldInfo;
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(animator);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(info != NULL);
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayTypes type = (SkDisplayTypes) info->fType;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayable* target = getTarget(animator);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDisplayable* executor = animator->hasExecute() ? animator : target;
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (type != SkType_MemberProperty) {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkTDArray<SkScriptValue> typedValues;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int index = 0; index < count; index++) {
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkScriptValue temp;
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                temp.fType = valuesType;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                temp.fOperand = values[index];
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                *typedValues.append() = temp;
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScriptValue scriptValue;
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            scriptValue.fOperand = values[0];
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            scriptValue.fType = info->getType();
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            target->setProperty(info->propertyIndex(), scriptValue);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkTypedArray converted;
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (type == SkType_ARGB) {
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (count == 4) {
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // !!! assert that it is SkType_Float ?
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                animator->packARGB(&values->fScalar, count, &converted);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                values = converted.begin();
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                count = converted.count();
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkASSERT(count == 1);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable());
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (type == SkType_String || type == SkType_DynamicString)
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            info->setString(target, values->fString);
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else if (type == SkType_Drawable || type == SkType_Displayable)
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            target->setReference(info, values->fDisplayable);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        else
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            info->setValue(target, values, count);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::contains(SkDisplayable* child) {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++) {
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (*curPtr == child || (*curPtr)->contains(child))
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return fDeleteScope && scope == child;
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDisplayable* SkApply::deepCopy(SkAnimateMaker* maker) {
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDrawable* saveScope = scope;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scope = NULL;
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkApply* result = (SkApply*) INHERITED::deepCopy(maker);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    result->scope = scope = saveScope;
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase** end = fAnimators.end();
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < end; animPtr++) {
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* anim = (SkAnimateBase*) (*animPtr)->deepCopy(maker);
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *result->fAnimators.append() = anim;
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maker->helperAdd(anim);
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::disable() {
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //!!! this is the right thing to do, but has bad side effects because of other problems
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // currently, if an apply is in a g and scopes a statement in another g, it ends up as members
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // of both containers. The disabling here incorrectly disables both instances
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // maybe the fEnabled flag needs to be moved to the fActive data so that both
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // instances are not affected.
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  fEnabled = false;
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::draw(SkAnimateMaker& maker) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope ==NULL)
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope->isApply() || scope->isDrawable() == false)
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fEnabled == false)
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        enable(maker);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(scope);
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    activate(maker);
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_immediate)
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fActive->draw();
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool result = interpolate(maker, maker.getInTime());
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (dontDraw == false) {
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      if (scope->isDrawable())
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result |= scope->draw(maker);
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (restore) {
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int index = 0; index < fActive->fAnimators.count(); index++)
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            endSave(index);
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->advance();
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DUMP_ENABLED
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::dump(SkAnimateMaker* maker) {
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dumpBase(maker);
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (dynamicScope.isEmpty() == false)
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("dynamicScope=\"%s\" ", dynamicScope.c_str());
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (dontDraw)
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("dontDraw=\"true\" ");
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (begin != 0) //perhaps we want this no matter what?
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("begin=\"%g\" ", (float) begin/1000.0f);   //is this correct?
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (interval != (SkMSec) -1)
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("interval=\"%g\" ", (float) interval/1000.0f);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (steps != -1)
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("steps=\"%d\" ", steps);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (restore)
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("restore=\"true\" ");
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (transition == kTransition_reverse)
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("transition=\"reverse\" ");
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_immediate) {
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("mode=\"immediate\" ");
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else if (mode == kMode_create) {
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("mode=\"create\" ");
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool closedYet = false;
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayList::fIndent += 4;
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int save = SkDisplayList::fDumpIndex;
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope) {
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (closedYet == false) {
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDebugf(">\n");
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            closedYet = true;
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        scope->dump(maker);
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  if (fActive) {
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (index = 0; index < fAnimators.count(); index++) {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (closedYet == false) {
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkDebugf(">\n");
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                closedYet = true;
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAnimateBase* animator = fAnimators[index];
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animator->dump(maker);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      }
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayList::fIndent -= 4;
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayList::fDumpIndex = save;
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (closedYet)
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dumpEnd(maker);
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("/>\n");
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::enable(SkAnimateMaker& maker) {
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fEnabled = true;
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool initialized = fActive != NULL;
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (dynamicScope.size() > 0)
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        enableDynamic(maker);
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (maker.fError.hasError())
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fAnimators.count();
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int index;
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (index = 0; index < animators; index++) {
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animator = fAnimators[index];
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        animator->fStart = maker.fEnableTime;
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        animator->fResetPending = animator->fReset;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope && scope->isApply())
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        ((SkApply*) scope)->setEmbedded();
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  if (mode == kMode_once) {
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (scope) {
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            activate(maker);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            interpolate(maker, maker.fEnableTime);
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            inactivate(maker);
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }*/
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL)
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;   // !!! error?
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false);
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((mode == kMode_immediate && enableMe) || mode == kMode_create)
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        activate(maker);    // for non-drawables like post, prime them here
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_immediate && enableMe)
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->enable();
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_create && scope != NULL) {
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        enableCreate(maker);
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_immediate) {
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return scope->isApply() || scope->isDrawable() == false;
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    refresh(maker);
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayList& displayList = maker.fDisplayList;
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDrawable* drawable;
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString debugOut;
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec time = maker.getAppTime();
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    debugOut.appendS32(time - maker.fDebugTimeBase);
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    debugOut.append(" apply enable id=");
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    debugOut.append(_id);
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    debugOut.append("; start=");
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDebugf("%s\n", debugOut.c_str());
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) {
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        activate(maker);    // for non-drawables like post, prime them here
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (initialized) {
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            append(this);
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fEnabling = true;
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interpolate(maker, maker.fEnableTime);
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fEnabling = false;
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (scope != NULL && dontDraw == false)
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            scope->enable(maker);
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else if (initialized && restore == false)
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        append(this);
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool wasActive = inactivate(maker); // start fresh
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (wasActive) {
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        activate(maker);
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interpolate(maker, maker.fEnableTime);
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  start here;
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // now that one apply might embed another, only the parent apply should replace the scope
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // or get appended to the display list
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // similarly, an apply added by an add immediate has already been located in the display list
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // and should not get moved or added again here
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fEmbedded) {
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;   // already added to display list by embedder
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    drawable = (SkDrawable*) scope;
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDDrawableArray* parentList;
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDDrawableArray* grandList;
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGroup* parentGroup;
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkGroup* thisGroup;
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList);
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (old < 0)
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        goto append;
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    else if (fContainsScope) {
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if ((*parentList)[old] != this || restore) {
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruappend:
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (parentGroup)
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                parentGroup->markCopySize(old);
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (parentList->count() < 10000) {
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fAppended = true;
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                *parentList->append() = this;
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep);
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            old = -1;
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            reset();
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(old < parentList->count());
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if ((*parentList)[old]->isApply()) {
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkApply* apply = (SkApply*) (*parentList)[old];
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (apply != this && apply->fActive == NULL)
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                apply->activate(maker);
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            apply->append(this);
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            parentGroup = NULL;
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (parentGroup)
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                parentGroup->markCopySize(old);
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDrawable** newApplyLocation = &(*parentList)[old];
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkGroup* pGroup;
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList);
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (oldApply >= 0) {
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply);
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                parentGroup = NULL;
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fDeleteScope = true;
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *newApplyLocation = this;
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (parentGroup) {
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        parentGroup->markCopySet(old);
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fDeleteScope = dynamicScope.size() == 0;
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::enableCreate(SkAnimateMaker& maker) {
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkString newID;
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int step = 0; step <= steps; step++) {
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fLastTime = step * SK_MSec1;
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool success = maker.computeID(scope, this, &newID);
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (success == false)
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (maker.find(newID.c_str(), NULL))
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            continue;
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkApply* copy = (SkApply*) deepCopy(&maker); // work on copy of animator state
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (mode == kMode_create)
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            copy->mode = (Mode) -1;
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDrawable* copyScope = copy->scope = (SkDrawable*) scope->deepCopy(&maker);
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *fScopes.append() = copyScope;
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (copyScope->resolveIDs(maker, scope, this)) {
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            step = steps; // quit
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            goto next; // resolveIDs failed
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (newID.size() > 0)
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            maker.setID(copyScope, newID);
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (copy->resolveIDs(maker, this, this)) { // fix up all fields, including target
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            step = steps; // quit
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            goto next; // resolveIDs failed
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        copy->activate(maker);
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        copy->interpolate(maker, step * SK_MSec1);
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maker.removeActive(copy->fActive);
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    next:
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete copy;
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::enableDynamic(SkAnimateMaker& maker) {
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(mode != kMode_create); // create + dynamic are not currently compatible
42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayable* newScope;
42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool success = SkAnimatorScript::EvaluateDisplayable(maker, this, dynamicScope.c_str(),
42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        &newScope);
43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (success && scope != newScope) {
43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkTDDrawableArray* pList, * gList;
43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkGroup* pGroup = NULL, * found = NULL;
43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int old = maker.fDisplayList.findGroup(scope, &pList, &pGroup, &found, &gList);
43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (pList && old >= 0 && (*pList)[old]->isApply() && (*pList)[old] != this) {
43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (fAppended == false) {
43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (found != NULL) {
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SkDisplayable* oldChild = (*pList)[old];
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    if (oldChild->isApply() && found->copySet(old)) {
43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        found->markCopyClear(old);
44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //                  delete oldChild;
44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    }
44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                (*pList)[old] = scope;
44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else
44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                pList->remove(old);
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        scope = (SkDrawable*) newScope;
44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        onEndElement(maker);
44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maker.removeActive(fActive);
45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    delete fActive;
45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fActive = NULL;
45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::endSave(int index) {
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase* animate = fActive->fAnimators[index];
45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMemberInfo* info = animate->fFieldInfo;
45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayTypes type = (SkDisplayTypes) info->fType;
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (type == SkType_MemberFunction)
46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayable* target = getTarget(animate);
46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t size = info->getSize(target);
46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = (int) (size / sizeof(SkScalar));
46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int activeIndex = fActive->fDrawIndex + index;
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperand* last = new SkOperand[count];
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAutoTDelete<SkOperand> autoLast(last);
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (type != SkType_MemberProperty) {
46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        info->getValue(target, last, count);
46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkOperand* saveOperand = fActive->fSaveRestore[activeIndex];
47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (saveOperand)
47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            info->setValue(target, fActive->fSaveRestore[activeIndex], count);
47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScriptValue scriptValue;
474d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue);
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(success == true);
47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        last[0] = scriptValue.fOperand;
47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0];
47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        target->setProperty(info->propertyIndex(), scriptValue);
47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkOperand* save = fActive->fSaveRestore[activeIndex];
48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (save)
48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memcpy(save, last, count * sizeof(SkOperand));
48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::getProperty(int index, SkScriptValue* value) const {
48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (index) {
48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SK_PROPERTY(step):
48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fType = SkType_Int;
48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fOperand.fS32 = fLastTime / SK_MSec1;
49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SK_PROPERTY(steps):
49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fType = SkType_Int;
49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fOperand.fS32 = steps;
49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SK_PROPERTY(time):
49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fType = SkType_MSec;
49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            value->fOperand.fS32 = fLastTime;
49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        default:
50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      SkASSERT(0);
50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::getStep(SkScriptValue* value) {
50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    getProperty(SK_PROPERTY(step), value);
50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDrawable* SkApply::getTarget(SkAnimateBase* animate) {
51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (animate->fTargetIsScope == false || mode != kMode_create)
51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return animate->fTarget;
51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return scope;
51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::hasDelayedAnimator() const {
517096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkAnimateBase* const* animEnd = fAnimators.end();
518096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    for (SkAnimateBase* const* animPtr = fAnimators.begin(); animPtr < animEnd; animPtr++) {
519096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        SkAnimateBase* const animator = *animPtr;
52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animator->fDelayed)
52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::hasEnable() const {
52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::inactivate(SkAnimateMaker& maker) {
53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive == NULL)
53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maker.removeActive(fActive);
53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    delete fActive;
53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fActive = NULL;
53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkMSec lastTime = (SkMSec) -1;
54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) {
54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive == NULL)
54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool result = false;
54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMSec time = maker.getAppTime();
54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (lastTime == (SkMSec) -1)
55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        lastTime = rawTime - 1;
55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive != NULL &&
55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        strcmp(id, "a3") == 0 && rawTime > lastTime) {
55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        lastTime += 1000;
55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkString debugOut;
55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(time - maker.fDebugTimeBase);
55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(" apply id=");
55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(_id);
55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append("; ");
55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(fActive->fAnimators[0]->_id);
56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append("=");
56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.appendS32(rawTime - fActive->fState[0].fStartTime);
56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        debugOut.append(")");
56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("%s\n", debugOut.c_str());
56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fActive->start();
56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (restore)
56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->initializeSave();
56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int animators = fActive->fAnimators.count();
57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int inner = 0; inner < animators; inner++) {
57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = fActive->fAnimators[inner];
57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->fChanged) {
57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->fChanged = false;
57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->fStart = rawTime;
57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      SkTypedArray values;
57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      int count = animate->fValues.count();
57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      values.setCount(count);
57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count);
57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->onEndElement(maker);
58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) {
58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fActive->append(this);
58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fActive->start();
58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //      }
58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMSec time = fActive->getTime(rawTime, inner);
58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkActive::SkState& state = fActive->fState[inner];
58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (SkMSec_LT(rawTime, state.fStartTime)) {
58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (fEnabling) {
58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                animate->fDelayed = true;
59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                maker.delayEnable(this, state.fStartTime);
59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            continue;
59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else
59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            animate->fDelayed = false;
59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMSec innerTime = fLastTime = state.getRelativeTime(time);
59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (restore)
59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fActive->restoreInterpolatorValues(inner);
59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->fReset) {
59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (transition != SkApply::kTransition_reverse) {
60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) {
60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    if (animate->fResetPending) {
60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        innerTime = 0;
60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        animate->fResetPending = false;
60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    } else
60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        continue;
60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (innerTime == 0) {
60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    if (animate->fResetPending) {
60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        innerTime = state.fBegin + state.fDuration;
61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        animate->fResetPending = false;
61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    } else
61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        continue;
61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int count = animate->components();
61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAutoSTMalloc<16, SkOperand> values(count);
61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues(
61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            innerTime, values.get());
61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result);
62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result) ||
62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                (transition == SkApply::kTransition_reverse && fLastTime == 0)) && state.fUnpostedEndEvent) {
62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//          SkDEBUGF(("interpolate: post on end\n"));
62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            state.fUnpostedEndEvent = false;
62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            maker.postOnEnd(animate, state.fBegin + state.fDuration);
62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            maker.fAdjustedStart = 0;    // !!! left over from synchronizing animation days, undoubtably out of date (and broken)
62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (animate->formula.size() > 0) {
62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (fLastTime > animate->dur)
62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fLastTime = animate->dur;
63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkTypedArray formulaValues;
63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            formulaValues.setCount(count);
632d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL,
63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                animate->getValuesType(), animate->formula);
63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(success);
63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (restore)
63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                save(inner); // save existing value
63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime);
63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (restore)
64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                save(inner); // save existing value
64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            applyValues(inner, values.get(), count, animate->getValuesType(), innerTime);
64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::initialize() {
64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope == NULL)
64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope->isApply() || scope->isDrawable() == false)
65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    scope->initialize();
65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::onEndElement(SkAnimateMaker& maker)
65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDrawable* scopePtr = scope;
65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (scopePtr && scopePtr->isApply()) {
65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkApply* scopedApply = (SkApply*) scopePtr;
66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (scopedApply->scope == this) {
66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            maker.setErrorCode(SkDisplayXMLParserError::kApplyScopesItself);
66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return;
66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        scopePtr = scopedApply->scope;
66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mode == kMode_create)
66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (scope != NULL && steps >= 0 && scope->isApply() == false && scope->isDrawable())
66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        scope->setSteps(steps);
67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* anim = *animPtr;
67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        //for reusing apply statements with dynamic scope
67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (anim->fTarget == NULL || anim->fTargetIsScope) {
67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            anim->fTargetIsScope = true;
67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (scope)
67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                anim->fTarget = scope;
67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            else
67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                anim->setTarget(maker);
67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            anim->onEndElement(maker);  // allows animate->fFieldInfo to be set
68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (scope != NULL && steps >= 0 && anim->fTarget != scope && anim->fTarget->isDrawable())
68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            anim->fTarget->setSteps(steps);
68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMemberInfo* SkApply::preferredChild(SkDisplayTypes type) {
68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkDisplayType::IsAnimate(type) == false);
68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fContainsScope = true;
68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return getMember("scope"); // !!! cwap! need to refer to member through enum like kScope instead
69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::refresh(SkAnimateMaker& maker) {
69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animate = *animPtr;
69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        animate->onEndElement(maker);
69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
69780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive)
69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->resetInterpolators();
69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::reset() {
70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive)
70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->resetState();
70480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) { //   replace to/formula strings in animators of the form xxx.step with the step value, if xxx.step is in scope
70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (resolveField(maker, apply, &dynamicScope) == false)
70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;    // failed
70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase** endPtr = fAnimators.end();
71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase** origPtr = ((SkApply*) original)->fAnimators.begin();
71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < endPtr; ) {
71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAnimateBase* animator = *animPtr++;
71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        maker.resolveID(animator, *origPtr++);
71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (resolveField(maker, this, &animator->target) == false)
71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (resolveField(maker, this, &animator->from) == false)
71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (resolveField(maker, this, &animator->to) == false)
71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (resolveField(maker, this, &animator->formula) == false)
72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  setEmbedded();
72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    onEndElement(maker);
72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false; // succeeded
72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::resolveField(SkAnimateMaker& maker, SkDisplayable* parent, SkString* str) {
72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const char* script = str->c_str();
73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (str->startsWith("#string:") == false)
73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    script += sizeof("#string:") - 1;
73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkAnimatorScript::EvaluateString(maker, this, parent, script, str);
73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::save(int index) {
73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAnimateBase* animate = fActive->fAnimators[index];
73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMemberInfo * info = animate->fFieldInfo;
73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayable* target = getTarget(animate);
74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  if (animate->hasExecute())
74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//      info = animate->getResolvedInfo();
74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDisplayTypes type = (SkDisplayTypes) info->fType;
74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (type == SkType_MemberFunction)
74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return; // nothing to save
74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    size_t size = info->getSize(target);
74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = (int) (size / sizeof(SkScalar));
74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool useLast = true;
74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// !!! this all may be unneeded, at least in the dynamic case ??
74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int activeIndex = fActive->fDrawIndex + index;
75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkTDOperandArray last;
75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive->fSaveRestore[activeIndex] == NULL) {
75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->fSaveRestore[activeIndex] = new SkOperand[count];
75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        useLast = false;
75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        last.setCount(count);
75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand));
75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (type != SkType_MemberProperty) {
75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        info->getValue(target, fActive->fSaveRestore[activeIndex], count);
76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (useLast)
76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            info->setValue(target, last.begin(), count);
76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScriptValue scriptValue;
764d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue);
76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(success == true);
76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(scriptValue.fType == SkType_Float);
76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand;
76880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (useLast) {
76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkScriptValue scriptValue;
77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            scriptValue.fType = type;
77180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            scriptValue.fOperand = last[0];
77280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            target->setProperty(info->propertyIndex(), scriptValue);
77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
77480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
77580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// !!!  end of unneeded
77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
77880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkApply::setProperty(int index, SkScriptValue& scriptValue) {
77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (index) {
78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SK_PROPERTY(animator): {
78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAnimateBase* animate = (SkAnimateBase*) scriptValue.fOperand.fDisplayable;
78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkASSERT(animate->isAnimate());
78380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            *fAnimators.append() = animate;
78480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
78680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case SK_PROPERTY(steps):
78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            steps = scriptValue.fOperand.fS32;
78880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (fActive)
78980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                fActive->setSteps(steps);
79080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
79280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
79480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
79580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::setSteps(int _steps) {
79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    steps = _steps;
79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkApply::validate() {
80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fActive)
80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fActive->validate();
80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
805