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
SkAnimateBase()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
~SkAnimateBase()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
components()65 int SkAnimateBase::components() {
66 return 1;
67 }
68
deepCopy(SkAnimateMaker * maker)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
dirty()77 void SkAnimateBase::dirty() {
78 fChanged = true;
79 }
80
81 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)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
getParent() const111 SkDisplayable* SkAnimateBase::getParent() const {
112 return (SkDisplayable*) fApply;
113 }
114
getProperty(int index,SkScriptValue * value) const115 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
hasExecute() const146 bool SkAnimateBase::hasExecute() const
147 {
148 return false;
149 }
150
onEndElement(SkAnimateMaker & maker)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
packARGB(SkScalar array[],int count,SkTDOperandArray * converted)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
refresh(SkAnimateMaker &)185 void SkAnimateBase::refresh(SkAnimateMaker& ) {
186 }
187
setParent(SkDisplayable * apply)188 bool SkAnimateBase::setParent(SkDisplayable* apply) {
189 SkASSERT(apply->isApply());
190 fApply = (SkApply*) apply;
191 return false;
192 }
193
setProperty(int index,SkScriptValue & value)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
setTarget(SkAnimateMaker & maker)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
targetNeedsInitialization() const243 bool SkAnimateBase::targetNeedsInitialization() const {
244 return false;
245 }
246
247
248