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