epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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), |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 42 | fApply(NULL), fFieldInfo(NULL), fFieldOffset(0), fStart((SkMSec) -1), fTarget(NULL), |
| 43 | fChanged(0), fDelayed(0), fDynamic(0), fHasEndEvent(0), fHasValues(0), |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 57 | int SkAnimateBase::components() { |
| 58 | return 1; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 94 | SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000))); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 134 | bool SkAnimateBase::hasExecute() const |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 135 | { |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 136 | return false; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 162 | void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted) |
| 163 | { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 164 | SkASSERT(count == 4); |
| 165 | converted->setCount(1); |
reed@google.com | e1ca705 | 2013-12-17 19:22:07 +0000 | [diff] [blame] | 166 | SkColor color = SkColorSetARGB(SkScalarRoundToInt(array[0]), |
| 167 | SkScalarRoundToInt(array[1]), |
| 168 | SkScalarRoundToInt(array[2]), |
| 169 | SkScalarRoundToInt(array[3])); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame] | 233 | bool SkAnimateBase::targetNeedsInitialization() const { |
| 234 | return false; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 235 | } |