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