OLD | NEW |
| (Empty) |
1 /* libs/graphics/animator/SkDisplayable.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 "SkDisplayable.h" | |
19 #include "SkDisplayApply.h" | |
20 #include "SkParse.h" | |
21 #ifdef SK_DEBUG | |
22 #include "SkDisplayList.h" | |
23 #endif | |
24 #include "SkDisplayTypes.h" | |
25 | |
26 #ifdef SK_FIND_LEAKS | |
27 // int SkDisplayable::fAllocationCount; | |
28 SkTDDisplayableArray SkDisplayable::fAllocations; | |
29 #endif | |
30 | |
31 #ifdef SK_DEBUG | |
32 SkDisplayable::SkDisplayable() { | |
33 id = _id.c_str(); | |
34 #ifdef SK_FIND_LEAKS | |
35 // fAllocationCount++; | |
36 *fAllocations.append() = this; | |
37 #endif | |
38 } | |
39 #endif | |
40 | |
41 SkDisplayable::~SkDisplayable() { | |
42 #ifdef SK_FIND_LEAKS | |
43 // fAllocationCount--; | |
44 int index = fAllocations.find(this); | |
45 SkASSERT(index >= 0); | |
46 fAllocations.remove(index); | |
47 #endif | |
48 } | |
49 | |
50 bool SkDisplayable::add(SkAnimateMaker& , SkDisplayable* child) { | |
51 return false; | |
52 } | |
53 | |
54 //void SkDisplayable::apply(SkAnimateMaker& , const SkMemberInfo* , | |
55 // SkDisplayable* , SkScalar [], int count) { | |
56 // SkASSERT(0); | |
57 //} | |
58 | |
59 bool SkDisplayable::canContainDependents() const { | |
60 return false; | |
61 } | |
62 | |
63 bool SkDisplayable::childrenNeedDisposing() const { | |
64 return false; | |
65 } | |
66 | |
67 void SkDisplayable::clearBounder() { | |
68 } | |
69 | |
70 bool SkDisplayable::contains(SkDisplayable* ) { | |
71 return false; | |
72 } | |
73 | |
74 SkDisplayable* SkDisplayable::contains(const SkString& ) { | |
75 return NULL; | |
76 } | |
77 | |
78 SkDisplayable* SkDisplayable::deepCopy(SkAnimateMaker* maker) { | |
79 SkDisplayTypes type = getType(); | |
80 if (type == SkType_Unknown) { | |
81 SkASSERT(0); | |
82 return NULL; | |
83 } | |
84 SkDisplayable* copy = SkDisplayType::CreateInstance(maker, type); | |
85 int index = -1; | |
86 int propIndex = 0; | |
87 const SkMemberInfo* info; | |
88 do { | |
89 info = copy->getMember(++index); | |
90 if (info == NULL) | |
91 break; | |
92 if (info->fType == SkType_MemberProperty) { | |
93 SkScriptValue value; | |
94 if (getProperty(propIndex, &value)) | |
95 copy->setProperty(propIndex, value); | |
96 propIndex++; | |
97 continue; | |
98 } | |
99 if (info->fType == SkType_MemberFunction) | |
100 continue; | |
101 if (info->fType == SkType_Array) { | |
102 SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this)
; | |
103 int arrayCount; | |
104 if (array == NULL || (arrayCount = array->count()) == 0) | |
105 continue; | |
106 SkTDOperandArray* copyArray = (SkTDOperandArray*) info->memberData(c
opy); | |
107 copyArray->setCount(arrayCount); | |
108 SkDisplayTypes elementType; | |
109 if (type == SkType_Array) { | |
110 SkDisplayArray* dispArray = (SkDisplayArray*) this; | |
111 elementType = dispArray->values.getType(); | |
112 } else | |
113 elementType = info->arrayType(); | |
114 size_t elementSize = SkMemberInfo::GetSize(elementType); | |
115 size_t byteSize = elementSize * arrayCount; | |
116 memcpy(copyArray->begin(), array->begin(), byteSize); | |
117 continue; | |
118 } | |
119 if (SkDisplayType::IsDisplayable(maker, info->fType)) { | |
120 SkDisplayable** displayable = (SkDisplayable**) info->memberData(thi
s); | |
121 if (*displayable == NULL || *displayable == (SkDisplayable*) -1) | |
122 continue; | |
123 SkDisplayable* deeper = (*displayable)->deepCopy(maker); | |
124 info->setMemberData(copy, deeper, sizeof(deeper)); | |
125 continue; | |
126 } | |
127 if (info->fType == SkType_String || info->fType == SkType_DynamicString)
{ | |
128 SkString* string; | |
129 info->getString(this, &string); | |
130 info->setString(copy, string); | |
131 continue; | |
132 } | |
133 void* data = info->memberData(this); | |
134 size_t size = SkMemberInfo::GetSize(info->fType); | |
135 info->setMemberData(copy, data, size); | |
136 } while (true); | |
137 copy->dirty(); | |
138 return copy; | |
139 } | |
140 | |
141 void SkDisplayable::dirty() { | |
142 } | |
143 | |
144 #ifdef SK_DUMP_ENABLED | |
145 void SkDisplayable::dump(SkAnimateMaker* maker) { | |
146 dumpBase(maker); | |
147 #if SK_USE_CONDENSED_INFO == 0 | |
148 this->dumpAttrs(maker); | |
149 this->dumpChildren(maker); | |
150 #endif | |
151 } | |
152 | |
153 void SkDisplayable::dumpAttrs(SkAnimateMaker* maker) { | |
154 SkDisplayTypes type = getType(); | |
155 if (type == SkType_Unknown) { | |
156 //SkDebugf("/>\n"); | |
157 return; | |
158 } | |
159 SkDisplayable* blankCopy = SkDisplayType::CreateInstance(maker, type); | |
160 | |
161 int index = -1; | |
162 int propIndex = 0; | |
163 const SkMemberInfo* info; | |
164 const SkMemberInfo* blankInfo; | |
165 SkScriptValue value; | |
166 SkScriptValue blankValue; | |
167 SkOperand values[2]; | |
168 SkOperand blankValues[2]; | |
169 do { | |
170 info = this->getMember(++index); | |
171 if (NULL == info) { | |
172 //SkDebugf("\n"); | |
173 break; | |
174 } | |
175 if (SkType_MemberProperty == info->fType) { | |
176 if (getProperty(propIndex, &value)) { | |
177 blankCopy->getProperty(propIndex, &blankValue); | |
178 //last two are dummies | |
179 dumpValues(info, value.fType, value.fOperand, blankValue.fOperan
d, value.fOperand, blankValue.fOperand); | |
180 } | |
181 | |
182 propIndex++; | |
183 continue; | |
184 } | |
185 if (SkDisplayType::IsDisplayable(maker, info->fType)) { | |
186 continue; | |
187 } | |
188 | |
189 if (info->fType == SkType_MemberFunction) | |
190 continue; | |
191 | |
192 | |
193 if (info->fType == SkType_Array) { | |
194 SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this)
; | |
195 int arrayCount; | |
196 if (array == NULL || (arrayCount = array->count()) == 0) | |
197 continue; | |
198 SkDisplayTypes elementType; | |
199 if (type == SkType_Array) { | |
200 SkDisplayArray* dispArray = (SkDisplayArray*) this; | |
201 elementType = dispArray->values.getType(); | |
202 } else | |
203 elementType = info->arrayType(); | |
204 bool firstElem = true; | |
205 SkDebugf("%s=\"[", info->fName); | |
206 for (SkOperand* op = array->begin(); op < array->end(); op++) { | |
207 if (!firstElem) SkDebugf(","); | |
208 switch (elementType) { | |
209 case SkType_Displayable: | |
210 SkDebugf("%s", op->fDisplayable->id); | |
211 break; | |
212 case SkType_Int: | |
213 SkDebugf("%d", op->fS32); | |
214 break; | |
215 case SkType_Float: | |
216 #ifdef SK_CAN_USE_FLOAT | |
217 SkDebugf("%g", SkScalarToFloat(op->fScalar)); | |
218 #else | |
219 SkDebugf("%x", op->fScalar); | |
220 #endif | |
221 break; | |
222 case SkType_String: | |
223 case SkType_DynamicString: | |
224 SkDebugf("%s", op->fString->c_str()); | |
225 break; | |
226 default: | |
227 break; | |
228 } | |
229 firstElem = false; | |
230 } | |
231 SkDebugf("]\" "); | |
232 continue; | |
233 } | |
234 | |
235 if (info->fType == SkType_String || info->fType == SkType_DynamicString)
{ | |
236 SkString* string; | |
237 info->getString(this, &string); | |
238 if (string->isEmpty() == false) | |
239 SkDebugf("%s=\"%s\"\t", info->fName, string->c_str()); | |
240 continue; | |
241 } | |
242 | |
243 | |
244 blankInfo = blankCopy->getMember(index); | |
245 int i = info->fCount; | |
246 info->getValue(this, values, i); | |
247 blankInfo->getValue(blankCopy, blankValues, i); | |
248 dumpValues(info, info->fType, values[0], blankValues[0], values[1], blan
kValues[1]); | |
249 } while (true); | |
250 delete blankCopy; | |
251 } | |
252 | |
253 void SkDisplayable::dumpBase(SkAnimateMaker* maker) { | |
254 SkDisplayTypes type = getType(); | |
255 const char* elementName = "(unknown)"; | |
256 if (type != SkType_Unknown && type != SkType_Screenplay) | |
257 elementName = SkDisplayType::GetName(maker, type); | |
258 SkDebugf("%*s", SkDisplayList::fIndent, ""); | |
259 if (SkDisplayList::fDumpIndex != 0 && SkDisplayList::fIndent == 0) | |
260 SkDebugf("%d: ", SkDisplayList::fDumpIndex); | |
261 SkDebugf("<%s ", elementName); | |
262 if (strcmp(id,"") != 0) | |
263 SkDebugf("id=\"%s\" ", id); | |
264 } | |
265 | |
266 void SkDisplayable::dumpChildren(SkAnimateMaker* maker, bool closedAngle) { | |
267 | |
268 int index = -1; | |
269 const SkMemberInfo* info; | |
270 index = -1; | |
271 SkDisplayList::fIndent += 4; | |
272 do { | |
273 info = this->getMember(++index); | |
274 if (NULL == info) { | |
275 break; | |
276 } | |
277 if (SkDisplayType::IsDisplayable(maker, info->fType)) { | |
278 SkDisplayable** displayable = (SkDisplayable**) info->memberData(thi
s); | |
279 if (*displayable == NULL || *displayable == (SkDisplayable*) -1) | |
280 continue; | |
281 if (closedAngle == false) { | |
282 SkDebugf(">\n"); | |
283 closedAngle = true; | |
284 } | |
285 (*displayable)->dump(maker); | |
286 } | |
287 } while (true); | |
288 SkDisplayList::fIndent -= 4; | |
289 if (closedAngle) | |
290 dumpEnd(maker); | |
291 else | |
292 SkDebugf("/>\n"); | |
293 } | |
294 | |
295 void SkDisplayable::dumpEnd(SkAnimateMaker* maker) { | |
296 SkDisplayTypes type = getType(); | |
297 const char* elementName = "(unknown)"; | |
298 if (type != SkType_Unknown && type != SkType_Screenplay) | |
299 elementName = SkDisplayType::GetName(maker, type); | |
300 SkDebugf("%*s", SkDisplayList::fIndent, ""); | |
301 SkDebugf("</%s>\n", elementName); | |
302 } | |
303 | |
304 void SkDisplayable::dumpEvents() { | |
305 } | |
306 | |
307 void SkDisplayable::dumpValues(const SkMemberInfo* info, SkDisplayTypes type, Sk
Operand op, SkOperand blankOp, | |
308 SkOperand op2, SkOperand blankOp2) { | |
309 switch (type) { | |
310 case SkType_BitmapEncoding: | |
311 switch (op.fS32) { | |
312 case 0 : SkDebugf("type=\"jpeg\" "); | |
313 break; | |
314 case 1 : SkDebugf("type=\"png\" "); | |
315 break; | |
316 default: SkDebugf("type=\"UNDEFINED\" "); | |
317 } | |
318 break; | |
319 //should make this a separate case in dump attrs, rather than make dump valu
es have a larger signature | |
320 case SkType_Point: | |
321 if (op.fScalar != blankOp.fScalar || op2.fScalar != blankOp.fScalar) { | |
322 #ifdef SK_CAN_USE_FLOAT | |
323 SkDebugf("%s=\"[%g,%g]\" ", info->fName, SkScalarToFloat(op.fScalar)
, SkScalarToFloat(op2.fScalar)); | |
324 #else | |
325 SkDebugf("%s=\"[%x,%x]\" ", info->fName, op.fScalar, op2.fScalar); | |
326 #endif | |
327 } | |
328 break; | |
329 case SkType_FromPathMode: | |
330 switch (op.fS32) { | |
331 case 0: | |
332 //don't want to print anything for 0, just adding it to remove i
t from default: | |
333 break; | |
334 case 1: | |
335 SkDebugf("%s=\"%s\" ", info->fName, "angle"); | |
336 break; | |
337 case 2: | |
338 SkDebugf("%s=\"%s\" ", info->fName, "position"); | |
339 break; | |
340 default: | |
341 SkDebugf("%s=\"INVALID\" ", info->fName); | |
342 } | |
343 break; | |
344 case SkType_MaskFilterBlurStyle: | |
345 switch (op.fS32) { | |
346 case 0: | |
347 break; | |
348 case 1: | |
349 SkDebugf("%s=\"%s\" ", info->fName, "solid"); | |
350 break; | |
351 case 2: | |
352 SkDebugf("%s=\"%s\" ", info->fName, "outer"); | |
353 break; | |
354 case 3: | |
355 SkDebugf("%s=\"%s\" ", info->fName, "inner"); | |
356 break; | |
357 default: | |
358 SkDebugf("%s=\"INVALID\" ", info->fName); | |
359 } | |
360 break; | |
361 case SkType_FilterType: | |
362 if (op.fS32 == 1) | |
363 SkDebugf("%s=\"%s\" ", info->fName, "bilinear"); | |
364 break; | |
365 case SkType_PathDirection: | |
366 SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "cw" : "ccw"); | |
367 break; | |
368 case SkType_FillType: | |
369 SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "winding" : "evenOdd"
); | |
370 break; | |
371 case SkType_TileMode: | |
372 //correct to look at the S32? | |
373 if (op.fS32 != blankOp.fS32) | |
374 SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "clamp" : op.fS32
== 1 ? "repeat" : "mirror"); | |
375 break; | |
376 case SkType_Boolean: | |
377 if (op.fS32 != blankOp.fS32) | |
378 SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "false" : "true")
; | |
379 break; | |
380 case SkType_Int: | |
381 if (op.fS32 != blankOp.fS32) | |
382 SkDebugf(" %s=\"%d\" ", info->fName, op.fS32); | |
383 break; | |
384 case SkType_Float: | |
385 if (op.fScalar != blankOp.fScalar) { //or /65536? | |
386 #ifdef SK_CAN_USE_FLOAT | |
387 SkDebugf("%s=\"%g\" ", info->fName, SkScalarToFloat(op.fScalar)); | |
388 #else | |
389 SkDebugf("%s=\"%x\" ", info->fName, op.fScalar); | |
390 #endif | |
391 } | |
392 break; | |
393 case SkType_String: | |
394 case SkType_DynamicString: | |
395 if (op.fString->size() > 0) | |
396 SkDebugf("%s=\"%s\" ", info->fName, op.fString->c_str()); | |
397 break; | |
398 case SkType_MSec: | |
399 if (op.fS32 != blankOp.fS32) { | |
400 #ifdef SK_CAN_USE_FLOAT | |
401 SkDebugf(" %s=\"%g\" ", info->fName, SkScalarToFloat(SkScalarDiv(op
.fS32, 1000))); | |
402 #else | |
403 SkDebugf(" %s=\"%x\" ", info->fName, SkScalarDiv(op.fS32, 1000)); | |
404 #endif | |
405 } | |
406 default: | |
407 SkDebugf(""); | |
408 } | |
409 } | |
410 | |
411 #endif | |
412 | |
413 bool SkDisplayable::enable( SkAnimateMaker& ) { | |
414 return false; | |
415 } | |
416 | |
417 void SkDisplayable::enableBounder() { | |
418 } | |
419 | |
420 void SkDisplayable::executeFunction(SkDisplayable* , int index, | |
421 SkTDArray<SkScriptValue>& , SkDisplayTypes, SkScriptValue* ) { | |
422 SkASSERT(0); | |
423 } | |
424 | |
425 void SkDisplayable::executeFunction(SkDisplayable* target, | |
426 const SkMemberInfo* info, SkTypedArray* values, SkScriptValue* value) { | |
427 SkTDArray<SkScriptValue> typedValues; | |
428 for (SkOperand* op = values->begin(); op < values->end(); op++) { | |
429 SkScriptValue temp; | |
430 temp.fType = values->getType(); | |
431 temp.fOperand = *op; | |
432 *typedValues.append() = temp; | |
433 } | |
434 executeFunction(target, info->functionIndex(), typedValues, info->getType(),
value); | |
435 } | |
436 | |
437 void SkDisplayable::executeFunction2(SkDisplayable* , int index, | |
438 SkOpArray* params, SkDisplayTypes, SkOperand2* ) { | |
439 SkASSERT(0); | |
440 } | |
441 | |
442 void SkDisplayable::getBounds(SkRect* rect) { | |
443 SkASSERT(rect); | |
444 rect->fLeft = rect->fTop = SK_ScalarMax; | |
445 rect->fRight= rect->fBottom = -SK_ScalarMax; | |
446 } | |
447 | |
448 const SkFunctionParamType* SkDisplayable::getFunctionsParameters() { | |
449 return NULL; | |
450 } | |
451 | |
452 const SkMemberInfo* SkDisplayable::getMember(int index) { | |
453 return NULL; | |
454 } | |
455 | |
456 const SkMemberInfo* SkDisplayable::getMember(const char name[]) { | |
457 return NULL; | |
458 } | |
459 | |
460 const SkFunctionParamType* SkDisplayable::getParameters(const SkMemberInfo* info
, | |
461 int* paramCount) { | |
462 const SkFunctionParamType* params = getFunctionsParameters(); | |
463 SkASSERT(params != NULL); | |
464 int funcIndex = info->functionIndex(); | |
465 // !!! eventually break traversing params into an external function (maybe t
his whole function) | |
466 int index = funcIndex; | |
467 int offset = 0; | |
468 while (--index >= 0) { | |
469 while (params[offset] != 0) | |
470 offset++; | |
471 offset++; | |
472 } | |
473 int count = 0; | |
474 while (params[offset] != 0) { | |
475 count++; | |
476 offset++; | |
477 } | |
478 *paramCount = count; | |
479 return ¶ms[offset - count]; | |
480 } | |
481 | |
482 SkDisplayable* SkDisplayable::getParent() const { | |
483 return NULL; | |
484 } | |
485 | |
486 bool SkDisplayable::getProperty(int index, SkScriptValue* ) const { | |
487 // SkASSERT(0); | |
488 return false; | |
489 } | |
490 | |
491 bool SkDisplayable::getProperty2(int index, SkOperand2* value) const { | |
492 SkASSERT(0); | |
493 return false; | |
494 } | |
495 | |
496 SkDisplayTypes SkDisplayable::getType() const { | |
497 return SkType_Unknown; | |
498 } | |
499 | |
500 bool SkDisplayable::hasEnable() const { | |
501 return false; | |
502 } | |
503 | |
504 bool SkDisplayable::isDrawable() const { | |
505 return false; | |
506 } | |
507 | |
508 void SkDisplayable::onEndElement(SkAnimateMaker& ) {} | |
509 | |
510 const SkMemberInfo* SkDisplayable::preferredChild(SkDisplayTypes type) { | |
511 return NULL; | |
512 } | |
513 | |
514 bool SkDisplayable::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, S
kApply* apply) { | |
515 return false; | |
516 } | |
517 | |
518 //SkDisplayable* SkDisplayable::resolveTarget(SkAnimateMaker& ) { | |
519 // return this; | |
520 //} | |
521 | |
522 void SkDisplayable::setChildHasID() { | |
523 } | |
524 | |
525 bool SkDisplayable::setParent(SkDisplayable* ) { | |
526 return false; | |
527 } | |
528 | |
529 bool SkDisplayable::setProperty(int index, SkScriptValue& ) { | |
530 //SkASSERT(0); | |
531 return false; | |
532 } | |
533 | |
534 void SkDisplayable::setReference(const SkMemberInfo* info, SkDisplayable* displa
yable) { | |
535 if (info->fType == SkType_MemberProperty) { | |
536 SkScriptValue scriptValue; | |
537 scriptValue.fOperand.fDisplayable = displayable; | |
538 scriptValue.fType = displayable->getType(); | |
539 setProperty(info->propertyIndex(), scriptValue); | |
540 } else if (info->fType == SkType_Array) { | |
541 SkASSERT(displayable->getType() == SkType_Array); | |
542 SkDisplayArray* dispArray = (SkDisplayArray*) displayable; | |
543 SkTDScalarArray* array = (SkTDScalarArray* ) info->memberData(this); | |
544 array->setCount(dispArray->values.count()); | |
545 memcpy(array->begin(), dispArray->values.begin(), dispArray->values.coun
t() * sizeof(int)); | |
546 // | |
547 | |
548 // !!! need a way for interpreter engine to own array | |
549 // !!! probably need to replace all scriptable arrays with single bigger
array | |
550 // that has operand and type on every element -- or | |
551 // when array is dirtied, need to get parent to reparse to local array | |
552 } else { | |
553 void* storage = info->memberData(this); | |
554 memcpy(storage, &displayable, sizeof(SkDisplayable*)); | |
555 } | |
556 // !!! unclear why displayable is dirtied here | |
557 // if this is called, this breaks fromPath.xml | |
558 // displayable->dirty(); | |
559 } | |
560 | |
561 #ifdef SK_DEBUG | |
562 void SkDisplayable::validate() { | |
563 } | |
564 #endif | |
565 | |
566 | |
OLD | NEW |