• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkAnimateBase()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 
~SkAnimateBase()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 
components()57 int SkAnimateBase::components() {
58     return 1;
59 }
60 
deepCopy(SkAnimateMaker * maker)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 
dirty()69 void SkAnimateBase::dirty() {
70     fChanged = true;
71 }
72 
73 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)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 #ifdef SK_CAN_USE_FLOAT
95         SkDebugf("begin=\"%g\" ", SkScalarToFloat(SkScalarDiv(begin,1000)));
96 #else
97         SkDebugf("begin=\"%x\" ", SkScalarDiv(begin,1000));
98 #endif
99     }
100 }
101 #endif
102 
getParent() const103 SkDisplayable* SkAnimateBase::getParent() const {
104     return (SkDisplayable*) fApply;
105 }
106 
getProperty(int index,SkScriptValue * value) const107 bool SkAnimateBase::getProperty(int index, SkScriptValue* value) const {
108     int boolResult;
109     switch (index) {
110         case SK_PROPERTY(dynamic):
111             boolResult = fDynamic;
112             goto returnBool;
113         case SK_PROPERTY(mirror):
114             boolResult = fMirror;
115             goto returnBool;
116         case SK_PROPERTY(reset):
117             boolResult = fReset;
118 returnBool:
119             value->fOperand.fS32 = SkToBool(boolResult);
120             value->fType = SkType_Boolean;
121             break;
122         case SK_PROPERTY(step):
123             if (fApply == NULL)
124                 return false;    // !!! notify there's an error?
125             fApply->getStep(value);
126             break;
127         case SK_PROPERTY(values):
128             value->fOperand.fString = (SkString*) &to;
129             value->fType = SkType_String;
130             break;
131         default:
132             SkASSERT(0);
133             return false;
134     }
135     return true;
136 }
137 
hasExecute() const138 bool SkAnimateBase::hasExecute() const
139 {
140     return false;
141 }
142 
onEndElement(SkAnimateMaker & maker)143 void SkAnimateBase::onEndElement(SkAnimateMaker& maker) {
144     fChanged = false;
145     setTarget(maker);
146     if (field.size()) {
147         SkASSERT(fTarget);
148         fFieldInfo = fTarget->getMember(field.c_str());
149         field.reset();
150     }
151     if (lval.size()) {
152         // lval must be of the form x[y]
153         const char* lvalStr = lval.c_str();
154         const char* arrayEnd = strchr(lvalStr, '[');
155         if (arrayEnd == NULL)
156             return; //should this return an error?
157         size_t arrayNameLen = arrayEnd - lvalStr;
158         SkString arrayStr(lvalStr, arrayNameLen);
159         SkASSERT(fTarget);  //this return an error?
160         fFieldInfo = fTarget->getMember(arrayStr.c_str());
161         SkString scriptStr(arrayEnd + 1, lval.size() - arrayNameLen - 2);
162         SkAnimatorScript::EvaluateInt(maker, this, scriptStr.c_str(), &fFieldOffset);
163     }
164 }
165 
packARGB(SkScalar array[],int count,SkTDOperandArray * converted)166 void SkAnimateBase::packARGB(SkScalar array[], int count, SkTDOperandArray* converted)
167 {
168     SkASSERT(count == 4);
169     converted->setCount(1);
170     SkColor color = SkColorSetARGB(SkScalarRound(array[0]), SkScalarRound(array[1]),
171         SkScalarRound(array[2]), SkScalarRound(array[3]));
172     (*converted)[0].fS32 = color;
173 }
174 
175 
176 
refresh(SkAnimateMaker &)177 void SkAnimateBase::refresh(SkAnimateMaker& ) {
178 }
179 
setParent(SkDisplayable * apply)180 bool SkAnimateBase::setParent(SkDisplayable* apply) {
181     SkASSERT(apply->isApply());
182     fApply = (SkApply*) apply;
183     return false;
184 }
185 
setProperty(int index,SkScriptValue & value)186 bool SkAnimateBase::setProperty(int index, SkScriptValue& value) {
187     bool boolValue = SkToBool(value.fOperand.fS32);
188     switch (index) {
189         case SK_PROPERTY(dynamic):
190             fDynamic = boolValue;
191             goto checkForBool;
192         case SK_PROPERTY(values):
193             fHasValues = true;
194             SkASSERT(value.fType == SkType_String);
195             to = *value.fOperand.fString;
196             break;
197         case SK_PROPERTY(mirror):
198             fMirror = boolValue;
199             goto checkForBool;
200         case SK_PROPERTY(reset):
201             fReset = boolValue;
202 checkForBool:
203             SkASSERT(value.fType == SkType_Boolean);
204             break;
205         default:
206             return false;
207     }
208     return true;
209 }
210 
setTarget(SkAnimateMaker & maker)211 void SkAnimateBase::setTarget(SkAnimateMaker& maker) {
212     if (target.size()) {
213         SkAnimatorScript engine(maker, this, SkType_Displayable);
214         const char* script = target.c_str();
215         SkScriptValue scriptValue;
216         bool success = engine.evaluateScript(&script, &scriptValue);
217         if (success && scriptValue.fType == SkType_Displayable)
218             fTarget = scriptValue.fOperand.fDrawable;
219         else if (maker.find(target.c_str(), (SkDisplayable**) &fTarget) == false) {
220             if (fApply->getMode() == SkApply::kMode_create)
221                 return; // may not be an error
222             if (engine.getError() != SkScriptEngine::kNoError)
223                 maker.setScriptError(engine);
224             else {
225                 maker.setErrorNoun(target);
226                 maker.setErrorCode(SkDisplayXMLParserError::kTargetIDNotFound);
227             }
228             return;
229         }
230         if (fApply && fApply->getMode() != SkApply::kMode_create)
231             target.reset();
232     }
233 }
234 
targetNeedsInitialization() const235 bool SkAnimateBase::targetNeedsInitialization() const {
236     return false;
237 }
238 
239 
240