blob: 8467ce6f3582c1a36da5cb69b5f21cf4546db127 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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.com8a1c16f2008-12-17 15:59:43 +00009
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
19const 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
39DEFINE_GET_MEMBER(SkAnimateBase);
40
41SkAnimateBase::SkAnimateBase() : begin(0), dur(1), repeat(SK_Scalar1),
rmistry@google.comd6176b02012-08-23 18:14:13 +000042 fApply(NULL), fFieldInfo(NULL), fFieldOffset(0), fStart((SkMSec) -1), fTarget(NULL),
43 fChanged(0), fDelayed(0), fDynamic(0), fHasEndEvent(0), fHasValues(0),
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 fMirror(0), fReset(0), fResetPending(0), fTargetIsScope(0) {
45 blend.setCount(1);
46 blend[0] = SK_Scalar1;
47}
48
49SkAnimateBase::~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.comd6176b02012-08-23 18:14:13 +000057int SkAnimateBase::components() {
58 return 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +000059}
60
61SkDisplayable* 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
69void SkAnimateBase::dirty() {
70 fChanged = true;
71}
72
73#ifdef SK_DUMP_ENABLED
74void 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.com8a1c16f2008-12-17 15:59:43 +000094 SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000)));
reed@android.com8a1c16f2008-12-17 15:59:43 +000095 }
96}
97#endif
98
99SkDisplayable* SkAnimateBase::getParent() const {
100 return (SkDisplayable*) fApply;
101}
102
103bool 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;
114returnBool:
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.comd6176b02012-08-23 18:14:13 +0000134bool SkAnimateBase::hasExecute() const
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135{
rmistry@google.comd6176b02012-08-23 18:14:13 +0000136 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137}
138
139void 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.comd6176b02012-08-23 18:14:13 +0000162void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted)
163{
reed@android.com8a1c16f2008-12-17 15:59:43 +0000164 SkASSERT(count == 4);
165 converted->setCount(1);
reed@google.come1ca7052013-12-17 19:22:07 +0000166 SkColor color = SkColorSetARGB(SkScalarRoundToInt(array[0]),
167 SkScalarRoundToInt(array[1]),
168 SkScalarRoundToInt(array[2]),
169 SkScalarRoundToInt(array[3]));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000170 (*converted)[0].fS32 = color;
171}
172
173
174
175void SkAnimateBase::refresh(SkAnimateMaker& ) {
176}
177
178bool SkAnimateBase::setParent(SkDisplayable* apply) {
179 SkASSERT(apply->isApply());
180 fApply = (SkApply*) apply;
181 return false;
182}
183
184bool 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;
200checkForBool:
201 SkASSERT(value.fType == SkType_Boolean);
202 break;
203 default:
204 return false;
205 }
206 return true;
207}
208
209void 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.comd6176b02012-08-23 18:14:13 +0000233bool SkAnimateBase::targetNeedsInitialization() const {
234 return false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235}