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 #ifdef SK_CAN_USE_FLOAT
     95         SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000)));
     96 #else
     97         SkDebugf("begin=\"%x\" ", SkScalarDiv(begin,1000));
     98 #endif
     99     }
    100 }
    101 #endif
    102 
    103 SkDisplayable* SkAnimateBase::getParent() const {
    104     return (SkDisplayable*) fApply;
    105 }
    106 
    107 bool SkAnimateBase::getProperty(int index, SkScriptValue* value) const {
    108     int boolResult;
    109     switch (index) {
    110         case SK_PROPERTY(dynamic):
    111             boolResult = fDynamic;
    112             goto returnBool;
    113         case SK_PROPERTY(mirror):
    114             boolResult = fMirror;
    115             goto returnBool;
    116         case SK_PROPERTY(reset):
    117             boolResult = fReset;
    118 returnBool:
    119             value->fOperand.fS32 = SkToBool(boolResult);
    120             value->fType = SkType_Boolean;
    121             break;
    122         case SK_PROPERTY(step):
    123             if (fApply == NULL)
    124                 return false;    // !!! notify there's an error?
    125             fApply->getStep(value);
    126             break;
    127         case SK_PROPERTY(values):
    128             value->fOperand.fString = (SkString*) &to;
    129             value->fType = SkType_String;
    130             break;
    131         default:
    132             SkASSERT(0);
    133             return false;
    134     }
    135     return true;
    136 }
    137 
    138 bool SkAnimateBase::hasExecute() const
    139 {
    140     return false;
    141 }
    142 
    143 void SkAnimateBase::onEndElement(SkAnimateMaker& maker) {
    144     fChanged = false;
    145     setTarget(maker);
    146     if (field.size()) {
    147         SkASSERT(fTarget);
    148         fFieldInfo = fTarget->getMember(field.c_str());
    149         field.reset();
    150     }
    151     if (lval.size()) {
    152         // lval must be of the form x[y]
    153         const char* lvalStr = lval.c_str();
    154         const char* arrayEnd = strchr(lvalStr, '[');
    155         if (arrayEnd == NULL)
    156             return; //should this return an error?
    157         size_t arrayNameLen = arrayEnd - lvalStr;
    158         SkString arrayStr(lvalStr, arrayNameLen);
    159         SkASSERT(fTarget);  //this return an error?
    160         fFieldInfo = fTarget->getMember(arrayStr.c_str());
    161         SkString scriptStr(arrayEnd + 1, lval.size() - arrayNameLen - 2);
    162         SkAnimatorScript::EvaluateInt(maker, this, scriptStr.c_str(), &fFieldOffset);
    163     }
    164 }
    165 
    166 void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted)
    167 {
    168     SkASSERT(count == 4);
    169     converted->setCount(1);
    170     SkColor color = SkColorSetARGB(SkScalarRound(array[0]), SkScalarRound(array[1]),
    171         SkScalarRound(array[2]), SkScalarRound(array[3]));
    172     (*converted)[0].fS32 = color;
    173 }
    174 
    175 
    176 
    177 void SkAnimateBase::refresh(SkAnimateMaker& ) {
    178 }
    179 
    180 bool SkAnimateBase::setParent(SkDisplayable* apply) {
    181     SkASSERT(apply->isApply());
    182     fApply = (SkApply*) apply;
    183     return false;
    184 }
    185 
    186 bool SkAnimateBase::setProperty(int index, SkScriptValue& value) {
    187     bool boolValue = SkToBool(value.fOperand.fS32);
    188     switch (index) {
    189         case SK_PROPERTY(dynamic):
    190             fDynamic = boolValue;
    191             goto checkForBool;
    192         case SK_PROPERTY(values):
    193             fHasValues = true;
    194             SkASSERT(value.fType == SkType_String);
    195             to = *value.fOperand.fString;
    196             break;
    197         case SK_PROPERTY(mirror):
    198             fMirror = boolValue;
    199             goto checkForBool;
    200         case SK_PROPERTY(reset):
    201             fReset = boolValue;
    202 checkForBool:
    203             SkASSERT(value.fType == SkType_Boolean);
    204             break;
    205         default:
    206             return false;
    207     }
    208     return true;
    209 }
    210 
    211 void SkAnimateBase::setTarget(SkAnimateMaker& maker) {
    212     if (target.size()) {
    213         SkAnimatorScript engine(maker, this, SkType_Displayable);
    214         const char* script = target.c_str();
    215         SkScriptValue scriptValue;
    216         bool success = engine.evaluateScript(&script, &scriptValue);
    217         if (success && scriptValue.fType == SkType_Displayable)
    218             fTarget = scriptValue.fOperand.fDrawable;
    219         else if (maker.find(target.c_str(), (SkDisplayable**) &fTarget) == false) {
    220             if (fApply->getMode() == SkApply::kMode_create)
    221                 return; // may not be an error
    222             if (engine.getError() != SkScriptEngine::kNoError)
    223                 maker.setScriptError(engine);
    224             else {
    225                 maker.setErrorNoun(target);
    226                 maker.setErrorCode(SkDisplayXMLParserError::kTargetIDNotFound);
    227             }
    228             return;
    229         }
    230         if (fApply && fApply->getMode() != SkApply::kMode_create)
    231             target.reset();
    232     }
    233 }
    234 
    235 bool SkAnimateBase::targetNeedsInitialization() const {
    236     return false;
    237 }
    238 
    239 
    240