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