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