• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
SkDisplayable()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 
~SkDisplayable()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 
add(SkAnimateMaker &,SkDisplayable * child)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 
canContainDependents() const59 bool SkDisplayable::canContainDependents() const {
60     return false;
61 }
62 
childrenNeedDisposing() const63 bool SkDisplayable::childrenNeedDisposing() const {
64     return false;
65 }
66 
clearBounder()67 void SkDisplayable::clearBounder() {
68 }
69 
contains(SkDisplayable *)70 bool SkDisplayable::contains(SkDisplayable* ) {
71     return false;
72 }
73 
contains(const SkString &)74 SkDisplayable* SkDisplayable::contains(const SkString& ) {
75     return NULL;
76 }
77 
deepCopy(SkAnimateMaker * maker)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(copy);
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(this);
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 
dirty()141 void SkDisplayable::dirty() {
142 }
143 
144 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)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 
dumpAttrs(SkAnimateMaker * maker)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.fOperand, 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], blankValues[1]);
249     } while (true);
250     delete blankCopy;
251 }
252 
dumpBase(SkAnimateMaker * maker)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 
dumpChildren(SkAnimateMaker * maker,bool closedAngle)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(this);
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 
dumpEnd(SkAnimateMaker * maker)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 
dumpEvents()304 void SkDisplayable::dumpEvents() {
305 }
306 
dumpValues(const SkMemberInfo * info,SkDisplayTypes type,SkOperand op,SkOperand blankOp,SkOperand op2,SkOperand blankOp2)307 void SkDisplayable::dumpValues(const SkMemberInfo* info, SkDisplayTypes type, SkOperand 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 values 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 it 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 
enable(SkAnimateMaker &)413 bool SkDisplayable::enable( SkAnimateMaker& ) {
414     return false;
415 }
416 
enableBounder()417 void SkDisplayable::enableBounder() {
418 }
419 
executeFunction(SkDisplayable *,int index,SkTDArray<SkScriptValue> &,SkDisplayTypes,SkScriptValue *)420 void SkDisplayable::executeFunction(SkDisplayable* , int index,
421         SkTDArray<SkScriptValue>& , SkDisplayTypes, SkScriptValue*  ) {
422     SkASSERT(0);
423 }
424 
executeFunction(SkDisplayable * target,const SkMemberInfo * info,SkTypedArray * values,SkScriptValue * value)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 
executeFunction2(SkDisplayable *,int index,SkOpArray * params,SkDisplayTypes,SkOperand2 *)437 void SkDisplayable::executeFunction2(SkDisplayable* , int index,
438         SkOpArray* params, SkDisplayTypes, SkOperand2*  ) {
439     SkASSERT(0);
440 }
441 
getBounds(SkRect * rect)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 
getFunctionsParameters()448 const SkFunctionParamType* SkDisplayable::getFunctionsParameters() {
449     return NULL;
450 }
451 
getMember(int index)452 const SkMemberInfo* SkDisplayable::getMember(int index) {
453     return NULL;
454 }
455 
getMember(const char name[])456 const SkMemberInfo* SkDisplayable::getMember(const char name[]) {
457     return NULL;
458 }
459 
getParameters(const SkMemberInfo * info,int * paramCount)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 this 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 &params[offset - count];
480 }
481 
getParent() const482 SkDisplayable* SkDisplayable::getParent() const {
483     return NULL;
484 }
485 
getProperty(int index,SkScriptValue *) const486 bool SkDisplayable::getProperty(int index, SkScriptValue* ) const {
487 //  SkASSERT(0);
488     return false;
489 }
490 
getProperty2(int index,SkOperand2 * value) const491 bool SkDisplayable::getProperty2(int index, SkOperand2* value) const {
492     SkASSERT(0);
493     return false;
494 }
495 
getType() const496 SkDisplayTypes SkDisplayable::getType() const {
497     return SkType_Unknown;
498 }
499 
hasEnable() const500 bool SkDisplayable::hasEnable() const {
501     return false;
502 }
503 
isDrawable() const504 bool SkDisplayable::isDrawable() const {
505     return false;
506 }
507 
onEndElement(SkAnimateMaker &)508 void SkDisplayable::onEndElement(SkAnimateMaker& ) {}
509 
preferredChild(SkDisplayTypes type)510 const SkMemberInfo* SkDisplayable::preferredChild(SkDisplayTypes type) {
511     return NULL;
512 }
513 
resolveIDs(SkAnimateMaker & maker,SkDisplayable * original,SkApply * apply)514 bool SkDisplayable::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) {
515     return false;
516 }
517 
518 //SkDisplayable* SkDisplayable::resolveTarget(SkAnimateMaker& ) {
519 //  return this;
520 //}
521 
setChildHasID()522 void SkDisplayable::setChildHasID() {
523 }
524 
setParent(SkDisplayable *)525 bool SkDisplayable::setParent(SkDisplayable* ) {
526     return false;
527 }
528 
setProperty(int index,SkScriptValue &)529 bool SkDisplayable::setProperty(int index, SkScriptValue& ) {
530     //SkASSERT(0);
531     return false;
532 }
533 
setReference(const SkMemberInfo * info,SkDisplayable * displayable)534 void SkDisplayable::setReference(const SkMemberInfo* info, SkDisplayable* displayable) {
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.count() * 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
validate()562 void SkDisplayable::validate() {
563 }
564 #endif
565 
566 
567