|
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 SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000))); |
|
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 |
|
134 bool SkAnimateBase::hasExecute() const |
|
135 { |
|
136 return false; |
|
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 |
|
162 void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted) |
|
163 { |
|
164 SkASSERT(count == 4); |
|
165 converted->setCount(1); |
|
166 SkColor color = SkColorSetARGB(SkScalarRoundToInt(array[0]), |
|
167 SkScalarRoundToInt(array[1]), |
|
168 SkScalarRoundToInt(array[2]), |
|
169 SkScalarRoundToInt(array[3])); |
|
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 |
|
233 bool SkAnimateBase::targetNeedsInitialization() const { |
|
234 return false; |
|
235 } |