gfx/skia/trunk/src/animator/SkDisplayApply.cpp

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

     2 /*
     3  * Copyright 2006 The Android Open Source Project
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkDisplayApply.h"
    11 #include "SkAnimateActive.h"
    12 #include "SkAnimateMaker.h"
    13 #include "SkAnimateSet.h"
    14 #include "SkAnimatorScript.h"
    15 #include "SkDisplayType.h"
    16 #include "SkDrawGroup.h"
    17 #include "SkParse.h"
    18 #include "SkScript.h"
    19 #include "SkSystemEventTypes.h"
    20 #ifdef SK_DEBUG
    21 #include "SkTime.h"
    22 #endif
    23 #include <ctype.h>
    25 enum SkApply_Properties {
    26     SK_PROPERTY(animator),
    27     SK_PROPERTY(step),
    28     SK_PROPERTY(steps),
    29     SK_PROPERTY(time)
    30 };
    32 #if SK_USE_CONDENSED_INFO == 0
    34 // if no attibutes, enclosed displayable is both scope & target
    35 // only if both scope & target are specified, or if target and enclosed displayable, are scope and target different
    36 const SkMemberInfo SkApply::fInfo[] = {
    37     SK_MEMBER_PROPERTY(animator, Animate),
    38     SK_MEMBER(begin, MSec),
    39     SK_MEMBER(dontDraw, Boolean),
    40     SK_MEMBER(dynamicScope, String),
    41     SK_MEMBER(interval, MSec),  // recommended redraw interval
    42     SK_MEMBER(mode, ApplyMode),
    43 #if 0
    44     SK_MEMBER(pickup, Boolean),
    45 #endif
    46     SK_MEMBER(restore, Boolean),
    47     SK_MEMBER(scope, Drawable), // thing that scopes animation (unnamed enclosed displayable goes here)
    48     SK_MEMBER_PROPERTY(step, Int),
    49     SK_MEMBER_PROPERTY(steps, Int),
    50     SK_MEMBER_PROPERTY(time, MSec),
    51     SK_MEMBER(transition, ApplyTransition)
    52 };
    54 #endif
    56 DEFINE_GET_MEMBER(SkApply);
    58 SkApply::SkApply() : begin(0), dontDraw(false), interval((SkMSec) -1), mode((Mode) -1), /*pickup(false), */
    59     restore(false), scope(NULL), steps(-1), transition((Transition) -1), fActive(NULL), /*fCurrentScope(NULL),*/
    60     fLastTime(0), fAppended(false), fContainsScope(false), fDeleteScope(false), fEmbedded(false),
    61     fEnabled(false), fEnabling(false) {
    62 }
    64 SkApply::~SkApply() {
    65     for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++)
    66         delete *curPtr;
    67     if (fDeleteScope)
    68         delete scope;
    69     // !!! caller must call maker.removeActive(fActive)
    70     delete fActive;
    71 }
    73 void SkApply::activate(SkAnimateMaker& maker) {
    74     if (fActive != NULL) {
    75         if (fActive->fDrawIndex == 0 && fActive->fDrawMax == 0)
    76             return; // if only one use, nothing more to do
    77         if (restore == false)
    78             return; // all share same state, regardless of instance number
    79         bool save = fActive->initializeSave();
    80         fActive->fixInterpolator(save);
    81     } else {
    82         fActive = new SkActive(*this, maker);
    83         fActive->init();
    84         maker.appendActive(fActive);
    85         if (restore) {
    86             fActive->initializeSave();
    87             int animators = fAnimators.count();
    88             for (int index = 0; index < animators; index++)
    89                 fActive->saveInterpolatorValues(index);
    90         }
    91     }
    92 }
    94 void SkApply::append(SkApply* apply) {
    95     if (fActive == NULL)
    96         return;
    97     int oldCount = fActive->fAnimators.count();
    98     fActive->append(apply);
    99     if (restore) {
   100         fActive->appendSave(oldCount);
   101         int newCount = fActive->fAnimators.count();
   102         for (int index = oldCount; index < newCount; index++)
   103             fActive->saveInterpolatorValues(index);
   104     }
   105 }
   107 void SkApply::applyValues(int animatorIndex, SkOperand* values, int count,
   108      SkDisplayTypes valuesType, SkMSec time)
   109 {
   110     SkAnimateBase* animator = fActive->fAnimators[animatorIndex];
   111     const SkMemberInfo * info = animator->fFieldInfo;
   112     SkASSERT(animator);
   113     SkASSERT(info != NULL);
   114     SkDisplayTypes type = (SkDisplayTypes) info->fType;
   115     SkDisplayable* target = getTarget(animator);
   116     if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) {
   117         SkDisplayable* executor = animator->hasExecute() ? animator : target;
   118         if (type != SkType_MemberProperty) {
   119             SkTDArray<SkScriptValue> typedValues;
   120             for (int index = 0; index < count; index++) {
   121                 SkScriptValue temp;
   122                 temp.fType = valuesType;
   123                 temp.fOperand = values[index];
   124                 *typedValues.append() = temp;
   125             }
   126             executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL);
   127         } else {
   128             SkScriptValue scriptValue;
   129             scriptValue.fOperand = values[0];
   130             scriptValue.fType = info->getType();
   131             target->setProperty(info->propertyIndex(), scriptValue);
   132         }
   133     } else {
   134         SkTypedArray converted;
   135         if (type == SkType_ARGB) {
   136             if (count == 4) {
   137                 // !!! assert that it is SkType_Float ?
   138                 animator->packARGB(&values->fScalar, count, &converted);
   139                 values = converted.begin();
   140                 count = converted.count();
   141             } else {
   142                 SkASSERT(count == 1);
   143             }
   144         }
   145 //      SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable());
   146         if (type == SkType_String || type == SkType_DynamicString)
   147             info->setString(target, values->fString);
   148         else if (type == SkType_Drawable || type == SkType_Displayable)
   149             target->setReference(info, values->fDisplayable);
   150         else
   151             info->setValue(target, values, count);
   152     }
   153 }
   155 bool SkApply::contains(SkDisplayable* child) {
   156     for (SkDrawable** curPtr = fScopes.begin(); curPtr < fScopes.end(); curPtr++) {
   157         if (*curPtr == child || (*curPtr)->contains(child))
   158             return true;
   159     }
   160     return fDeleteScope && scope == child;
   161 }
   163 SkDisplayable* SkApply::deepCopy(SkAnimateMaker* maker) {
   164     SkDrawable* saveScope = scope;
   165     scope = NULL;
   166     SkApply* result = (SkApply*) INHERITED::deepCopy(maker);
   167     result->scope = scope = saveScope;
   168     SkAnimateBase** end = fAnimators.end();
   169     for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < end; animPtr++) {
   170         SkAnimateBase* anim = (SkAnimateBase*) (*animPtr)->deepCopy(maker);
   171         *result->fAnimators.append() = anim;
   172         maker->helperAdd(anim);
   173     }
   174     return result;
   175 }
   177 void SkApply::disable() {
   178     //!!! this is the right thing to do, but has bad side effects because of other problems
   179     // currently, if an apply is in a g and scopes a statement in another g, it ends up as members
   180     // of both containers. The disabling here incorrectly disables both instances
   181     // maybe the fEnabled flag needs to be moved to the fActive data so that both
   182     // instances are not affected.
   183 //  fEnabled = false;
   184 }
   186 bool SkApply::draw(SkAnimateMaker& maker) {
   187     if (scope ==NULL)
   188         return false;
   189     if (scope->isApply() || scope->isDrawable() == false)
   190         return false;
   191     if (fEnabled == false)
   192         enable(maker);
   193     SkASSERT(scope);
   194     activate(maker);
   195     if (mode == kMode_immediate)
   196         return fActive->draw();
   197     bool result = interpolate(maker, maker.getInTime());
   198     if (dontDraw == false) {
   199 //      if (scope->isDrawable())
   200             result |= scope->draw(maker);
   201     }
   202     if (restore) {
   203         for (int index = 0; index < fActive->fAnimators.count(); index++)
   204             endSave(index);
   205         fActive->advance();
   206     }
   207     return result;
   208 }
   210 #ifdef SK_DUMP_ENABLED
   211 void SkApply::dump(SkAnimateMaker* maker) {
   212     dumpBase(maker);
   213     if (dynamicScope.isEmpty() == false)
   214         SkDebugf("dynamicScope=\"%s\" ", dynamicScope.c_str());
   215     if (dontDraw)
   216         SkDebugf("dontDraw=\"true\" ");
   217     if (begin != 0) //perhaps we want this no matter what?
   218         SkDebugf("begin=\"%g\" ", (float) begin/1000.0f);   //is this correct?
   219     if (interval != (SkMSec) -1)
   220         SkDebugf("interval=\"%g\" ", (float) interval/1000.0f);
   221     if (steps != -1)
   222         SkDebugf("steps=\"%d\" ", steps);
   223     if (restore)
   224         SkDebugf("restore=\"true\" ");
   225     if (transition == kTransition_reverse)
   226         SkDebugf("transition=\"reverse\" ");
   227     if (mode == kMode_immediate) {
   228         SkDebugf("mode=\"immediate\" ");
   229     }
   230     else if (mode == kMode_create) {
   231         SkDebugf("mode=\"create\" ");
   232     }
   233     bool closedYet = false;
   234     SkDisplayList::fIndent += 4;
   235     int save = SkDisplayList::fDumpIndex;
   236     if (scope) {
   237         if (closedYet == false) {
   238             SkDebugf(">\n");
   239             closedYet = true;
   240         }
   241         scope->dump(maker);
   242     }
   243     int index;
   244 //  if (fActive) {
   245         for (index = 0; index < fAnimators.count(); index++) {
   246             if (closedYet == false) {
   247                 SkDebugf(">\n");
   248                 closedYet = true;
   249             }
   250             SkAnimateBase* animator = fAnimators[index];
   251             animator->dump(maker);
   252 //      }
   253     }
   254     SkDisplayList::fIndent -= 4;
   255     SkDisplayList::fDumpIndex = save;
   256     if (closedYet)
   257         dumpEnd(maker);
   258     else
   259         SkDebugf("/>\n");
   260 }
   261 #endif
   263 bool SkApply::enable(SkAnimateMaker& maker) {
   264     fEnabled = true;
   265     bool initialized = fActive != NULL;
   266     if (dynamicScope.size() > 0)
   267         enableDynamic(maker);
   268     if (maker.fError.hasError())
   269         return false;
   270     int animators = fAnimators.count();
   271     int index;
   272     for (index = 0; index < animators; index++) {
   273         SkAnimateBase* animator = fAnimators[index];
   274         animator->fStart = maker.fEnableTime;
   275         animator->fResetPending = animator->fReset;
   276     }
   277     if (scope && scope->isApply())
   278         ((SkApply*) scope)->setEmbedded();
   279 /*  if (mode == kMode_once) {
   280         if (scope) {
   281             activate(maker);
   282             interpolate(maker, maker.fEnableTime);
   283             inactivate(maker);
   284         }
   285         return true;
   286     }*/
   287     if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL)
   288         return false;   // !!! error?
   289     bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false);
   290     if ((mode == kMode_immediate && enableMe) || mode == kMode_create)
   291         activate(maker);    // for non-drawables like post, prime them here
   292     if (mode == kMode_immediate && enableMe)
   293         fActive->enable();
   294     if (mode == kMode_create && scope != NULL) {
   295         enableCreate(maker);
   296         return true;
   297     }
   298     if (mode == kMode_immediate) {
   299         return scope->isApply() || scope->isDrawable() == false;
   300     }
   301     refresh(maker);
   302     SkDisplayList& displayList = maker.fDisplayList;
   303     SkDrawable* drawable;
   304 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   305     SkString debugOut;
   306     SkMSec time = maker.getAppTime();
   307     debugOut.appendS32(time - maker.fDebugTimeBase);
   308     debugOut.append(" apply enable id=");
   309     debugOut.append(_id);
   310     debugOut.append("; start=");
   311     debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
   312     SkDebugf("%s\n", debugOut.c_str());
   313 #endif
   314     if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) {
   315         activate(maker);    // for non-drawables like post, prime them here
   316         if (initialized) {
   317             append(this);
   318         }
   319         fEnabling = true;
   320         interpolate(maker, maker.fEnableTime);
   321         fEnabling = false;
   322         if (scope != NULL && dontDraw == false)
   323             scope->enable(maker);
   324         return true;
   325     } else if (initialized && restore == false)
   326         append(this);
   327 #if 0
   328     bool wasActive = inactivate(maker); // start fresh
   329     if (wasActive) {
   330         activate(maker);
   331         interpolate(maker, maker.fEnableTime);
   332         return true;
   333     }
   334 #endif
   335 //  start here;
   336     // now that one apply might embed another, only the parent apply should replace the scope
   337     // or get appended to the display list
   338     // similarly, an apply added by an add immediate has already been located in the display list
   339     // and should not get moved or added again here
   340     if (fEmbedded) {
   341         return false;   // already added to display list by embedder
   342     }
   343     drawable = (SkDrawable*) scope;
   344     SkTDDrawableArray* parentList;
   345     SkTDDrawableArray* grandList;
   346     SkGroup* parentGroup;
   347     SkGroup* thisGroup;
   348     int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList);
   349     if (old < 0)
   350         goto append;
   351     else if (fContainsScope) {
   352         if ((*parentList)[old] != this || restore) {
   353 append:
   354             if (parentGroup)
   355                 parentGroup->markCopySize(old);
   356             if (parentList->count() < 10000) {
   357                 fAppended = true;
   358                 *parentList->append() = this;
   359             } else
   360                 maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep);
   361             old = -1;
   362         } else
   363             reset();
   364     } else {
   365         SkASSERT(old < parentList->count());
   366         if ((*parentList)[old]->isApply()) {
   367             SkApply* apply = (SkApply*) (*parentList)[old];
   368             if (apply != this && apply->fActive == NULL)
   369                 apply->activate(maker);
   370             apply->append(this);
   371             parentGroup = NULL;
   372         } else {
   373             if (parentGroup)
   374                 parentGroup->markCopySize(old);
   375             SkDrawable** newApplyLocation = &(*parentList)[old];
   376             SkGroup* pGroup;
   377             int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList);
   378             if (oldApply >= 0) {
   379                 (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply);
   380                 parentGroup = NULL;
   381                 fDeleteScope = true;
   382             }
   383             *newApplyLocation = this;
   384         }
   385     }
   386     if (parentGroup) {
   387         parentGroup->markCopySet(old);
   388         fDeleteScope = dynamicScope.size() == 0;
   389     }
   390     return true;
   391 }
   393 void SkApply::enableCreate(SkAnimateMaker& maker) {
   394     SkString newID;
   395     for (int step = 0; step <= steps; step++) {
   396         fLastTime = step * SK_MSec1;
   397         bool success = maker.computeID(scope, this, &newID);
   398         if (success == false)
   399             return;
   400         if (maker.find(newID.c_str(), NULL))
   401             continue;
   402         SkApply* copy = (SkApply*) deepCopy(&maker); // work on copy of animator state
   403         if (mode == kMode_create)
   404             copy->mode = (Mode) -1;
   405         SkDrawable* copyScope = copy->scope = (SkDrawable*) scope->deepCopy(&maker);
   406         *fScopes.append() = copyScope;
   407         if (copyScope->resolveIDs(maker, scope, this)) {
   408             step = steps; // quit
   409             goto next; // resolveIDs failed
   410         }
   411         if (newID.size() > 0)
   412             maker.setID(copyScope, newID);
   413         if (copy->resolveIDs(maker, this, this)) { // fix up all fields, including target
   414             step = steps; // quit
   415             goto next; // resolveIDs failed
   416         }
   417         copy->activate(maker);
   418         copy->interpolate(maker, step * SK_MSec1);
   419         maker.removeActive(copy->fActive);
   420     next:
   421         delete copy;
   422     }
   423 }
   425 void SkApply::enableDynamic(SkAnimateMaker& maker) {
   426     SkASSERT(mode != kMode_create); // create + dynamic are not currently compatible
   427     SkDisplayable* newScope;
   428     bool success = SkAnimatorScript::EvaluateDisplayable(maker, this, dynamicScope.c_str(),
   429         &newScope);
   430     if (success && scope != newScope) {
   431         SkTDDrawableArray* pList, * gList;
   432         SkGroup* pGroup = NULL, * found = NULL;
   433         int old = maker.fDisplayList.findGroup(scope, &pList, &pGroup, &found, &gList);
   434         if (pList && old >= 0 && (*pList)[old]->isApply() && (*pList)[old] != this) {
   435             if (fAppended == false) {
   436                 if (found != NULL) {
   437                     SkDisplayable* oldChild = (*pList)[old];
   438                     if (oldChild->isApply() && found->copySet(old)) {
   439                         found->markCopyClear(old);
   440     //                  delete oldChild;
   441                     }
   442                 }
   443                 (*pList)[old] = scope;
   444             } else
   445                 pList->remove(old);
   446         }
   447         scope = (SkDrawable*) newScope;
   448         onEndElement(maker);
   449     }
   450     maker.removeActive(fActive);
   451     delete fActive;
   452     fActive = NULL;
   453 }
   455 void SkApply::endSave(int index) {
   456     SkAnimateBase* animate = fActive->fAnimators[index];
   457     const SkMemberInfo* info = animate->fFieldInfo;
   458     SkDisplayTypes type = (SkDisplayTypes) info->fType;
   459     if (type == SkType_MemberFunction)
   460         return;
   461     SkDisplayable* target = getTarget(animate);
   462     size_t size = info->getSize(target);
   463     int count = (int) (size / sizeof(SkScalar));
   464     int activeIndex = fActive->fDrawIndex + index;
   465     SkOperand* last = new SkOperand[count];
   466     SkAutoTDelete<SkOperand> autoLast(last);
   467     if (type != SkType_MemberProperty) {
   468         info->getValue(target, last, count);
   469         SkOperand* saveOperand = fActive->fSaveRestore[activeIndex];
   470         if (saveOperand)
   471             info->setValue(target, fActive->fSaveRestore[activeIndex], count);
   472     } else {
   473         SkScriptValue scriptValue;
   474         SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue);
   475         SkASSERT(success == true);
   476         last[0] = scriptValue.fOperand;
   477         scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0];
   478         target->setProperty(info->propertyIndex(), scriptValue);
   479     }
   480     SkOperand* save = fActive->fSaveRestore[activeIndex];
   481     if (save)
   482         memcpy(save, last, count * sizeof(SkOperand));
   483 }
   485 bool SkApply::getProperty(int index, SkScriptValue* value) const {
   486     switch (index) {
   487         case SK_PROPERTY(step):
   488             value->fType = SkType_Int;
   489             value->fOperand.fS32 = fLastTime / SK_MSec1;
   490             break;
   491         case SK_PROPERTY(steps):
   492             value->fType = SkType_Int;
   493             value->fOperand.fS32 = steps;
   494             break;
   495         case SK_PROPERTY(time):
   496             value->fType = SkType_MSec;
   497             value->fOperand.fS32 = fLastTime;
   498             break;
   499         default:
   500     //      SkASSERT(0);
   501             return false;
   502     }
   503     return true;
   504 }
   506 void SkApply::getStep(SkScriptValue* value) {
   507     getProperty(SK_PROPERTY(step), value);
   508 }
   510 SkDrawable* SkApply::getTarget(SkAnimateBase* animate) {
   511     if (animate->fTargetIsScope == false || mode != kMode_create)
   512         return animate->fTarget;
   513     return scope;
   514 }
   516 bool SkApply::hasDelayedAnimator() const {
   517     SkAnimateBase* const* animEnd = fAnimators.end();
   518     for (SkAnimateBase* const* animPtr = fAnimators.begin(); animPtr < animEnd; animPtr++) {
   519         SkAnimateBase* const animator = *animPtr;
   520         if (animator->fDelayed)
   521             return true;
   522     }
   523     return false;
   524 }
   526 bool SkApply::hasEnable() const {
   527     return true;
   528 }
   530 bool SkApply::inactivate(SkAnimateMaker& maker) {
   531     if (fActive == NULL)
   532         return false;
   533     maker.removeActive(fActive);
   534     delete fActive;
   535     fActive = NULL;
   536     return true;
   537 }
   539 #ifdef SK_DEBUG
   540 SkMSec lastTime = (SkMSec) -1;
   541 #endif
   543 bool SkApply::interpolate(SkAnimateMaker& maker, SkMSec rawTime) {
   544     if (fActive == NULL)
   545         return false;
   546     bool result = false;
   547 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   548     SkMSec time = maker.getAppTime();
   549     if (lastTime == (SkMSec) -1)
   550         lastTime = rawTime - 1;
   551     if (fActive != NULL &&
   552         strcmp(id, "a3") == 0 && rawTime > lastTime) {
   553         lastTime += 1000;
   554         SkString debugOut;
   555         debugOut.appendS32(time - maker.fDebugTimeBase);
   556         debugOut.append(" apply id=");
   557         debugOut.append(_id);
   558         debugOut.append("; ");
   559         debugOut.append(fActive->fAnimators[0]->_id);
   560         debugOut.append("=");
   561         debugOut.appendS32(rawTime - fActive->fState[0].fStartTime);
   562         debugOut.append(")");
   563         SkDebugf("%s\n", debugOut.c_str());
   564     }
   565 #endif
   566     fActive->start();
   567     if (restore)
   568         fActive->initializeSave();
   569     int animators = fActive->fAnimators.count();
   570     for (int inner = 0; inner < animators; inner++) {
   571         SkAnimateBase* animate = fActive->fAnimators[inner];
   572         if (animate->fChanged) {
   573             animate->fChanged = false;
   574             animate->fStart = rawTime;
   575     //      SkTypedArray values;
   576     //      int count = animate->fValues.count();
   577     //      values.setCount(count);
   578     //      memcpy(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count);
   579             animate->onEndElement(maker);
   580     //      if (memcmp(values.begin(), animate->fValues.begin(), sizeof(SkOperand) * count) != 0) {
   581                 fActive->append(this);
   582                 fActive->start();
   583     //      }
   584         }
   585         SkMSec time = fActive->getTime(rawTime, inner);
   586         SkActive::SkState& state = fActive->fState[inner];
   587         if (SkMSec_LT(rawTime, state.fStartTime)) {
   588             if (fEnabling) {
   589                 animate->fDelayed = true;
   590                 maker.delayEnable(this, state.fStartTime);
   591             }
   592             continue;
   593         } else
   594             animate->fDelayed = false;
   595         SkMSec innerTime = fLastTime = state.getRelativeTime(time);
   596         if (restore)
   597             fActive->restoreInterpolatorValues(inner);
   598         if (animate->fReset) {
   599             if (transition != SkApply::kTransition_reverse) {
   600                 if (SkMSec_LT(state.fBegin + state.fDuration, innerTime)) {
   601                     if (animate->fResetPending) {
   602                         innerTime = 0;
   603                         animate->fResetPending = false;
   604                     } else
   605                         continue;
   606                 }
   607             } else if (innerTime == 0) {
   608                     if (animate->fResetPending) {
   609                         innerTime = state.fBegin + state.fDuration;
   610                         animate->fResetPending = false;
   611                     } else
   612                         continue;
   613             }
   614         }
   615         int count = animate->components();
   616         SkAutoSTMalloc<16, SkOperand> values(count);
   617         SkInterpolatorBase::Result interpResult = fActive->fInterpolators[inner]->timeToValues(
   618             innerTime, values.get());
   619         result |= (interpResult != SkInterpolatorBase::kFreezeEnd_Result);
   620         if (((transition != SkApply::kTransition_reverse && interpResult == SkInterpolatorBase::kFreezeEnd_Result) ||
   621                 (transition == SkApply::kTransition_reverse && fLastTime == 0)) && state.fUnpostedEndEvent) {
   622 //          SkDEBUGF(("interpolate: post on end\n"));
   623             state.fUnpostedEndEvent = false;
   624             maker.postOnEnd(animate, state.fBegin + state.fDuration);
   625             maker.fAdjustedStart = 0;    // !!! left over from synchronizing animation days, undoubtably out of date (and broken)
   626         }
   627         if (animate->formula.size() > 0) {
   628             if (fLastTime > animate->dur)
   629                 fLastTime = animate->dur;
   630             SkTypedArray formulaValues;
   631             formulaValues.setCount(count);
   632             SkDEBUGCODE(bool success = ) animate->fFieldInfo->setValue(maker, &formulaValues, 0, 0, NULL,
   633                 animate->getValuesType(), animate->formula);
   634             SkASSERT(success);
   635             if (restore)
   636                 save(inner); // save existing value
   637             applyValues(inner, formulaValues.begin(), count, animate->getValuesType(), innerTime);
   638         } else {
   639             if (restore)
   640                 save(inner); // save existing value
   641             applyValues(inner, values.get(), count, animate->getValuesType(), innerTime);
   642         }
   643     }
   644     return result;
   645 }
   647 void SkApply::initialize() {
   648     if (scope == NULL)
   649         return;
   650     if (scope->isApply() || scope->isDrawable() == false)
   651         return;
   652     scope->initialize();
   653 }
   655 void SkApply::onEndElement(SkAnimateMaker& maker)
   656 {
   657     SkDrawable* scopePtr = scope;
   658     while (scopePtr && scopePtr->isApply()) {
   659         SkApply* scopedApply = (SkApply*) scopePtr;
   660         if (scopedApply->scope == this) {
   661             maker.setErrorCode(SkDisplayXMLParserError::kApplyScopesItself);
   662             return;
   663         }
   664         scopePtr = scopedApply->scope;
   665     }
   666     if (mode == kMode_create)
   667         return;
   668     if (scope != NULL && steps >= 0 && scope->isApply() == false && scope->isDrawable())
   669         scope->setSteps(steps);
   670     for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
   671         SkAnimateBase* anim = *animPtr;
   672         //for reusing apply statements with dynamic scope
   673         if (anim->fTarget == NULL || anim->fTargetIsScope) {
   674             anim->fTargetIsScope = true;
   675             if (scope)
   676                 anim->fTarget = scope;
   677             else
   678                 anim->setTarget(maker);
   679             anim->onEndElement(maker);  // allows animate->fFieldInfo to be set
   680         }
   681         if (scope != NULL && steps >= 0 && anim->fTarget != scope && anim->fTarget->isDrawable())
   682             anim->fTarget->setSteps(steps);
   683     }
   684 }
   686 const SkMemberInfo* SkApply::preferredChild(SkDisplayTypes type) {
   687     SkASSERT(SkDisplayType::IsAnimate(type) == false);
   688     fContainsScope = true;
   689     return getMember("scope"); // !!! cwap! need to refer to member through enum like kScope instead
   690 }
   692 void SkApply::refresh(SkAnimateMaker& maker) {
   693     for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < fAnimators.end(); animPtr++) {
   694         SkAnimateBase* animate = *animPtr;
   695         animate->onEndElement(maker);
   696     }
   697     if (fActive)
   698         fActive->resetInterpolators();
   699 }
   701 void SkApply::reset() {
   702     if (fActive)
   703         fActive->resetState();
   704 }
   706 bool 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
   707     if (resolveField(maker, apply, &dynamicScope) == false)
   708         return true;    // failed
   709     SkAnimateBase** endPtr = fAnimators.end();
   710     SkAnimateBase** origPtr = ((SkApply*) original)->fAnimators.begin();
   711     for (SkAnimateBase** animPtr = fAnimators.begin(); animPtr < endPtr; ) {
   712         SkAnimateBase* animator = *animPtr++;
   713         maker.resolveID(animator, *origPtr++);
   714         if (resolveField(maker, this, &animator->target) == false)
   715             return true;
   716         if (resolveField(maker, this, &animator->from) == false)
   717             return true;
   718         if (resolveField(maker, this, &animator->to) == false)
   719             return true;
   720         if (resolveField(maker, this, &animator->formula) == false)
   721             return true;
   722     }
   723 //  setEmbedded();
   724     onEndElement(maker);
   725     return false; // succeeded
   726 }
   728 bool SkApply::resolveField(SkAnimateMaker& maker, SkDisplayable* parent, SkString* str) {
   729     const char* script = str->c_str();
   730     if (str->startsWith("#string:") == false)
   731         return true;
   732     script += sizeof("#string:") - 1;
   733     return SkAnimatorScript::EvaluateString(maker, this, parent, script, str);
   734 }
   736 void SkApply::save(int index) {
   737     SkAnimateBase* animate = fActive->fAnimators[index];
   738     const SkMemberInfo * info = animate->fFieldInfo;
   739     SkDisplayable* target = getTarget(animate);
   740 //  if (animate->hasExecute())
   741 //      info = animate->getResolvedInfo();
   742     SkDisplayTypes type = (SkDisplayTypes) info->fType;
   743     if (type == SkType_MemberFunction)
   744         return; // nothing to save
   745     size_t size = info->getSize(target);
   746     int count = (int) (size / sizeof(SkScalar));
   747     bool useLast = true;
   748 // !!! this all may be unneeded, at least in the dynamic case ??
   749     int activeIndex = fActive->fDrawIndex + index;
   750     SkTDOperandArray last;
   751     if (fActive->fSaveRestore[activeIndex] == NULL) {
   752         fActive->fSaveRestore[activeIndex] = new SkOperand[count];
   753         useLast = false;
   754     } else {
   755         last.setCount(count);
   756         memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand));
   757     }
   758     if (type != SkType_MemberProperty) {
   759         info->getValue(target, fActive->fSaveRestore[activeIndex], count);
   760         if (useLast)
   761             info->setValue(target, last.begin(), count);
   762     } else {
   763         SkScriptValue scriptValue;
   764         SkDEBUGCODE(bool success = ) target->getProperty(info->propertyIndex(), &scriptValue);
   765         SkASSERT(success == true);
   766         SkASSERT(scriptValue.fType == SkType_Float);
   767         fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand;
   768         if (useLast) {
   769             SkScriptValue scriptValue;
   770             scriptValue.fType = type;
   771             scriptValue.fOperand = last[0];
   772             target->setProperty(info->propertyIndex(), scriptValue);
   773         }
   774     }
   775 // !!!  end of unneeded
   776 }
   778 bool SkApply::setProperty(int index, SkScriptValue& scriptValue) {
   779     switch (index) {
   780         case SK_PROPERTY(animator): {
   781             SkAnimateBase* animate = (SkAnimateBase*) scriptValue.fOperand.fDisplayable;
   782             SkASSERT(animate->isAnimate());
   783             *fAnimators.append() = animate;
   784             return true;
   785         }
   786         case SK_PROPERTY(steps):
   787             steps = scriptValue.fOperand.fS32;
   788             if (fActive)
   789                 fActive->setSteps(steps);
   790             return true;
   791     }
   792     return false;
   793 }
   795 void SkApply::setSteps(int _steps) {
   796     steps = _steps;
   797 }
   799 #ifdef SK_DEBUG
   800 void SkApply::validate() {
   801     if (fActive)
   802         fActive->validate();
   803 }
   804 #endif

mercurial