Home | History | Annotate | Download | only in animator
      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
     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 
     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 
     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 
     51 bool SkDisplayable::canContainDependents() const {
     52     return false;
     53 }
     54 
     55 bool SkDisplayable::childrenNeedDisposing() const {
     56     return false;
     57 }
     58 
     59 void SkDisplayable::clearBounder() {
     60 }
     61 
     62 bool SkDisplayable::contains(SkDisplayable* ) {
     63     return false;
     64 }
     65 
     66 SkDisplayable* SkDisplayable::contains(const SkString& ) {
     67     return NULL;
     68 }
     69 
     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 
    133 void SkDisplayable::dirty() {
    134 }
    135 
    136 #ifdef SK_DUMP_ENABLED
    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 
    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 
    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 
    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 
    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 
    296 void SkDisplayable::dumpEvents() {
    297 }
    298 
    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 
    405 bool SkDisplayable::enable( SkAnimateMaker& ) {
    406     return false;
    407 }
    408 
    409 void SkDisplayable::enableBounder() {
    410 }
    411 
    412 void SkDisplayable::executeFunction(SkDisplayable* , int index,
    413         SkTDArray<SkScriptValue>& , SkDisplayTypes, SkScriptValue*  ) {
    414     SkASSERT(0);
    415 }
    416 
    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 
    429 void SkDisplayable::executeFunction2(SkDisplayable* , int index,
    430         SkOpArray* params, SkDisplayTypes, SkOperand2*  ) {
    431     SkASSERT(0);
    432 }
    433 
    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 
    440 const SkFunctionParamType* SkDisplayable::getFunctionsParameters() {
    441     return NULL;
    442 }
    443 
    444 const SkMemberInfo* SkDisplayable::getMember(int index) {
    445     return NULL;
    446 }
    447 
    448 const SkMemberInfo* SkDisplayable::getMember(const char name[]) {
    449     return NULL;
    450 }
    451 
    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 
    474 SkDisplayable* SkDisplayable::getParent() const {
    475     return NULL;
    476 }
    477 
    478 bool SkDisplayable::getProperty(int index, SkScriptValue* ) const {
    479 //  SkASSERT(0);
    480     return false;
    481 }
    482 
    483 bool SkDisplayable::getProperty2(int index, SkOperand2* value) const {
    484     SkASSERT(0);
    485     return false;
    486 }
    487 
    488 SkDisplayTypes SkDisplayable::getType() const {
    489     return SkType_Unknown;
    490 }
    491 
    492 bool SkDisplayable::hasEnable() const {
    493     return false;
    494 }
    495 
    496 bool SkDisplayable::isDrawable() const {
    497     return false;
    498 }
    499 
    500 void SkDisplayable::onEndElement(SkAnimateMaker& ) {}
    501 
    502 const SkMemberInfo* SkDisplayable::preferredChild(SkDisplayTypes type) {
    503     return NULL;
    504 }
    505 
    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 
    514 void SkDisplayable::setChildHasID() {
    515 }
    516 
    517 bool SkDisplayable::setParent(SkDisplayable* ) {
    518     return false;
    519 }
    520 
    521 bool SkDisplayable::setProperty(int index, SkScriptValue& ) {
    522     //SkASSERT(0);
    523     return false;
    524 }
    525 
    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
    554 void SkDisplayable::validate() {
    555 }
    556 #endif
    557 
    558 
    559