Home | History | Annotate | Download | only in animator
      1 
      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  */
      8 
      9 
     10 #include "SkAnimateBase.h"
     11 #include "SkAnimateMaker.h"
     12 #include "SkAnimateProperties.h"
     13 #include "SkAnimatorScript.h"
     14 #include "SkDisplayApply.h"
     15 #include "SkDrawable.h"
     16 
     17 #if SK_USE_CONDENSED_INFO == 0
     18 
     19 const SkMemberInfo SkAnimateBase::fInfo[] = {
     20     SK_MEMBER(begin, MSec),
     21     SK_MEMBER_ARRAY(blend, Float),
     22     SK_MEMBER(dur, MSec),
     23     SK_MEMBER_PROPERTY(dynamic, Boolean),
     24     SK_MEMBER(field, String),   // name of member info in target
     25     SK_MEMBER(formula, DynamicString),
     26     SK_MEMBER(from, DynamicString),
     27     SK_MEMBER(lval, DynamicString),
     28     SK_MEMBER_PROPERTY(mirror, Boolean),
     29     SK_MEMBER(repeat, Float),
     30     SK_MEMBER_PROPERTY(reset, Boolean),
     31     SK_MEMBER_PROPERTY(step, Int),
     32     SK_MEMBER(target, DynamicString),
     33     SK_MEMBER(to, DynamicString),
     34     SK_MEMBER_PROPERTY(values, DynamicString)
     35 };
     36 
     37 #endif
     38 
     39 DEFINE_GET_MEMBER(SkAnimateBase);
     40 
     41 SkAnimateBase::SkAnimateBase() : begin(0), dur(1), repeat(SK_Scalar1),
     42         fApply(NULL), fFieldInfo(NULL), fFieldOffset(0), fStart((SkMSec) -1), fTarget(NULL),
     43         fChanged(0), fDelayed(0), fDynamic(0), fHasEndEvent(0), fHasValues(0),
     44         fMirror(0), fReset(0), fResetPending(0), fTargetIsScope(0) {
     45     blend.setCount(1);
     46     blend[0] = SK_Scalar1;
     47 }
     48 
     49 SkAnimateBase::~SkAnimateBase() {
     50     SkDisplayTypes type = fValues.getType();
     51     if (type == SkType_String || type == SkType_DynamicString) {
     52         SkASSERT(fValues.count() == 1);
     53         delete fValues[0].fString;
     54     }
     55 }
     56 
     57 int SkAnimateBase::components() {
     58     return 1;
     59 }
     60 
     61 SkDisplayable* SkAnimateBase::deepCopy(SkAnimateMaker* maker) {
     62     SkAnimateBase* result = (SkAnimateBase*) INHERITED::deepCopy(maker);
     63     result->fApply = fApply;
     64     result->fFieldInfo =fFieldInfo;
     65     result->fHasValues = false;
     66     return result;
     67 }
     68 
     69 void SkAnimateBase::dirty() {
     70     fChanged = true;
     71 }
     72 
     73 #ifdef SK_DUMP_ENABLED
     74 void SkAnimateBase::dump(SkAnimateMaker* maker) {
     75     dumpBase(maker);
     76     if (target.size() > 0)
     77         SkDebugf("target=\"%s\" ", target.c_str());
     78     else if (fTarget && strcmp(fTarget->id, ""))
     79         SkDebugf("target=\"%s\" ", fTarget->id);
     80     if (lval.size() > 0)
     81         SkDebugf("lval=\"%s\" ", lval.c_str());
     82     if (field.size() > 0)
     83         SkDebugf("field=\"%s\" ", field.c_str());
     84     else if (fFieldInfo)
     85         SkDebugf("field=\"%s\" ", fFieldInfo->fName);
     86     if (formula.size() > 0)
     87         SkDebugf("formula=\"%s\" ", formula.c_str());
     88     else {
     89         if (from.size() > 0)
     90             SkDebugf("from=\"%s\" ", from.c_str());
     91         SkDebugf("to=\"%s\" ", to.c_str());
     92     }
     93     if (begin != 0) {
     94         SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000)));
     95     }
     96 }
     97 #endif
     98 
     99 SkDisplayable* SkAnimateBase::getParent() const {
    100     return (SkDisplayable*) fApply;
    101 }
    102 
    103 bool SkAnimateBase::getProperty(int index, SkScriptValue* value) const {
    104     int boolResult;
    105     switch (index) {
    106         case SK_PROPERTY(dynamic):
    107             boolResult = fDynamic;
    108             goto returnBool;
    109         case SK_PROPERTY(mirror):
    110             boolResult = fMirror;
    111             goto returnBool;
    112         case SK_PROPERTY(reset):
    113             boolResult = fReset;
    114 returnBool:
    115             value->fOperand.fS32 = SkToBool(boolResult);
    116             value->fType = SkType_Boolean;
    117             break;
    118         case SK_PROPERTY(step):
    119             if (fApply == NULL)
    120                 return false;    // !!! notify there's an error?
    121             fApply->getStep(value);
    122             break;
    123         case SK_PROPERTY(values):
    124             value->fOperand.fString = (SkString*) &to;
    125             value->fType = SkType_String;
    126             break;
    127         default:
    128             SkASSERT(0);
    129             return false;
    130     }
    131     return true;
    132 }
    133 
    134 bool SkAnimateBase::hasExecute() const
    135 {
    136     return false;
    137 }
    138 
    139 void SkAnimateBase::onEndElement(SkAnimateMaker& maker) {
    140     fChanged = false;
    141     setTarget(maker);
    142     if (field.size()) {
    143         SkASSERT(fTarget);
    144         fFieldInfo = fTarget->getMember(field.c_str());
    145         field.reset();
    146     }
    147     if (lval.size()) {
    148         // lval must be of the form x[y]
    149         const char* lvalStr = lval.c_str();
    150         const char* arrayEnd = strchr(lvalStr, '[');
    151         if (arrayEnd == NULL)
    152             return; //should this return an error?
    153         size_t arrayNameLen = arrayEnd - lvalStr;
    154         SkString arrayStr(lvalStr, arrayNameLen);
    155         SkASSERT(fTarget);  //this return an error?
    156         fFieldInfo = fTarget->getMember(arrayStr.c_str());
    157         SkString scriptStr(arrayEnd + 1, lval.size() - arrayNameLen - 2);
    158         SkAnimatorScript::EvaluateInt(maker, this, scriptStr.c_str(), &fFieldOffset);
    159     }
    160 }
    161 
    162 void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted)
    163 {
    164     SkASSERT(count == 4);
    165     converted->setCount(1);
    166     SkColor color = SkColorSetARGB(SkScalarRoundToInt(array[0]),
    167                                    SkScalarRoundToInt(array[1]),
    168                                    SkScalarRoundToInt(array[2]),
    169                                    SkScalarRoundToInt(array[3]));
    170     (*converted)[0].fS32 = color;
    171 }
    172 
    173 
    174 
    175 void SkAnimateBase::refresh(SkAnimateMaker& ) {
    176 }
    177 
    178 bool SkAnimateBase::setParent(SkDisplayable* apply) {
    179     SkASSERT(apply->isApply());
    180     fApply = (SkApply*) apply;
    181     return false;
    182 }
    183 
    184 bool SkAnimateBase::setProperty(int index, SkScriptValue& value) {
    185     bool boolValue = SkToBool(value.fOperand.fS32);
    186     switch (index) {
    187         case SK_PROPERTY(dynamic):
    188             fDynamic = boolValue;
    189             goto checkForBool;
    190         case SK_PROPERTY(values):
    191             fHasValues = true;
    192             SkASSERT(value.fType == SkType_String);
    193             to = *value.fOperand.fString;
    194             break;
    195         case SK_PROPERTY(mirror):
    196             fMirror = boolValue;
    197             goto checkForBool;
    198         case SK_PROPERTY(reset):
    199             fReset = boolValue;
    200 checkForBool:
    201             SkASSERT(value.fType == SkType_Boolean);
    202             break;
    203         default:
    204             return false;
    205     }
    206     return true;
    207 }
    208 
    209 void SkAnimateBase::setTarget(SkAnimateMaker& maker) {
    210     if (target.size()) {
    211         SkAnimatorScript engine(maker, this, SkType_Displayable);
    212         const char* script = target.c_str();
    213         SkScriptValue scriptValue;
    214         bool success = engine.evaluateScript(&script, &scriptValue);
    215         if (success && scriptValue.fType == SkType_Displayable)
    216             fTarget = scriptValue.fOperand.fDrawable;
    217         else if (maker.find(target.c_str(), (SkDisplayable**) &fTarget) == false) {
    218             if (fApply->getMode() == SkApply::kMode_create)
    219                 return; // may not be an error
    220             if (engine.getError() != SkScriptEngine::kNoError)
    221                 maker.setScriptError(engine);
    222             else {
    223                 maker.setErrorNoun(target);
    224                 maker.setErrorCode(SkDisplayXMLParserError::kTargetIDNotFound);
    225             }
    226             return;
    227         }
    228         if (fApply && fApply->getMode() != SkApply::kMode_create)
    229             target.reset();
    230     }
    231 }
    232 
    233 bool SkAnimateBase::targetNeedsInitialization() const {
    234     return false;
    235 }
    236