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