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::addChild(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 nullptr;
     68 }
     69 
     70 SkDisplayable* SkDisplayable::deepCopy(SkAnimateMaker* maker) {
     71     SkDisplayTypes type = getType();
     72     if (type == SkType_Unknown) {
     73         SkASSERT(0);
     74         return nullptr;
     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 == nullptr)
     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 == nullptr || (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 == nullptr || *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 (nullptr == 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 == nullptr || (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                             SkDebugf("%g", SkScalarToFloat(op->fScalar));
    209                             break;
    210                         case SkType_String:
    211                         case SkType_DynamicString:
    212                             SkDebugf("%s", op->fString->c_str());
    213                             break;
    214                         default:
    215                             break;
    216                 }
    217                 firstElem = false;
    218             }
    219             SkDebugf("]\" ");
    220             continue;
    221         }
    222 
    223         if (info->fType == SkType_String || info->fType == SkType_DynamicString) {
    224             SkString* string;
    225             info->getString(this, &string);
    226             if (string->isEmpty() == false)
    227                 SkDebugf("%s=\"%s\"\t", info->fName, string->c_str());
    228             continue;
    229         }
    230 
    231 
    232         blankInfo = blankCopy->getMember(index);
    233         int i = info->fCount;
    234         info->getValue(this, values, i);
    235         blankInfo->getValue(blankCopy, blankValues, i);
    236         dumpValues(info, info->fType, values[0], blankValues[0], values[1], blankValues[1]);
    237     } while (true);
    238     delete blankCopy;
    239 }
    240 
    241 void SkDisplayable::dumpBase(SkAnimateMaker* maker) {
    242     SkDisplayTypes type = getType();
    243     const char* elementName = "(unknown)";
    244     if (type != SkType_Unknown && type != SkType_Screenplay)
    245         elementName = SkDisplayType::GetName(maker, type);
    246     SkDebugf("%*s", SkDisplayList::fIndent, "");
    247     if (SkDisplayList::fDumpIndex != 0 && SkDisplayList::fIndent == 0)
    248         SkDebugf("%d: ", SkDisplayList::fDumpIndex);
    249     SkDebugf("<%s ", elementName);
    250     if (strcmp(id,"") != 0)
    251         SkDebugf("id=\"%s\" ", id);
    252 }
    253 
    254 void SkDisplayable::dumpChildren(SkAnimateMaker* maker, bool closedAngle) {
    255 
    256     int index = -1;
    257     const SkMemberInfo* info;
    258     index = -1;
    259     SkDisplayList::fIndent += 4;
    260     do {
    261         info = this->getMember(++index);
    262         if (nullptr == info) {
    263             break;
    264         }
    265         if (SkDisplayType::IsDisplayable(maker, info->fType)) {
    266             SkDisplayable** displayable = (SkDisplayable**) info->memberData(this);
    267             if (*displayable == nullptr || *displayable == (SkDisplayable*) -1)
    268                 continue;
    269             if (closedAngle == false) {
    270                 SkDebugf(">\n");
    271                 closedAngle = true;
    272             }
    273             (*displayable)->dump(maker);
    274         }
    275     } while (true);
    276     SkDisplayList::fIndent -= 4;
    277     if (closedAngle)
    278         dumpEnd(maker);
    279     else
    280         SkDebugf("/>\n");
    281 }
    282 
    283 void SkDisplayable::dumpEnd(SkAnimateMaker* maker) {
    284     SkDisplayTypes type = getType();
    285     const char* elementName = "(unknown)";
    286     if (type != SkType_Unknown && type != SkType_Screenplay)
    287         elementName = SkDisplayType::GetName(maker, type);
    288     SkDebugf("%*s", SkDisplayList::fIndent, "");
    289     SkDebugf("</%s>\n", elementName);
    290 }
    291 
    292 void SkDisplayable::dumpEvents() {
    293 }
    294 
    295 void SkDisplayable::dumpValues(const SkMemberInfo* info, SkDisplayTypes type, SkOperand op, SkOperand blankOp,
    296     SkOperand op2, SkOperand blankOp2) {
    297     switch (type) {
    298     case SkType_BitmapEncoding:
    299         switch (op.fS32) {
    300             case 0 : SkDebugf("type=\"jpeg\" ");
    301                 break;
    302             case 1 : SkDebugf("type=\"png\" ");
    303                 break;
    304             default: SkDebugf("type=\"UNDEFINED\" ");
    305         }
    306         break;
    307     //should make this a separate case in dump attrs, rather than make dump values have a larger signature
    308     case SkType_Point:
    309         if (op.fScalar != blankOp.fScalar || op2.fScalar != blankOp.fScalar) {
    310             SkDebugf("%s=\"[%g,%g]\" ", info->fName, SkScalarToFloat(op.fScalar), SkScalarToFloat(op2.fScalar));
    311         }
    312         break;
    313     case SkType_FromPathMode:
    314         switch (op.fS32) {
    315             case 0:
    316                 //don't want to print anything for 0, just adding it to remove it from default:
    317                 break;
    318             case 1:
    319                 SkDebugf("%s=\"%s\" ", info->fName, "angle");
    320                 break;
    321             case 2:
    322                 SkDebugf("%s=\"%s\" ", info->fName, "position");
    323                 break;
    324             default:
    325                 SkDebugf("%s=\"INVALID\" ", info->fName);
    326         }
    327         break;
    328     case SkType_MaskFilterBlurStyle:
    329         switch (op.fS32) {
    330             case 0:
    331                 break;
    332             case 1:
    333                 SkDebugf("%s=\"%s\" ", info->fName, "solid");
    334                 break;
    335             case 2:
    336                 SkDebugf("%s=\"%s\" ", info->fName, "outer");
    337                 break;
    338             case 3:
    339                 SkDebugf("%s=\"%s\" ", info->fName, "inner");
    340                 break;
    341             default:
    342                 SkDebugf("%s=\"INVALID\" ", info->fName);
    343         }
    344         break;
    345     case SkType_FilterType:
    346         if (op.fS32 == 1)
    347             SkDebugf("%s=\"%s\" ", info->fName, "bilinear");
    348         break;
    349     case SkType_PathDirection:
    350         SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "cw" : "ccw");
    351         break;
    352     case SkType_FillType:
    353         SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "winding" : "evenOdd");
    354         break;
    355     case SkType_TileMode:
    356         //correct to look at the S32?
    357         if (op.fS32 != blankOp.fS32)
    358             SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "clamp" : op.fS32 == 1 ? "repeat" : "mirror");
    359         break;
    360     case SkType_Boolean:
    361         if (op.fS32 != blankOp.fS32)
    362             SkDebugf("%s=\"%s\" ", info->fName, op.fS32 == 0 ? "false" : "true");
    363         break;
    364     case SkType_Int:
    365         if (op.fS32 != blankOp.fS32)
    366             SkDebugf(" %s=\"%d\"  ", info->fName, op.fS32);
    367         break;
    368     case SkType_Float:
    369         if (op.fScalar != blankOp.fScalar) { //or /65536?
    370             SkDebugf("%s=\"%g\"  ", info->fName, SkScalarToFloat(op.fScalar));
    371         }
    372         break;
    373     case SkType_String:
    374     case SkType_DynamicString:
    375         if (op.fString->size() > 0)
    376             SkDebugf("%s=\"%s\" ", info->fName, op.fString->c_str());
    377         break;
    378     case SkType_MSec:
    379         if (op.fS32 != blankOp.fS32) {
    380             SkDebugf(" %s=\"%g\"  ", info->fName, op.fS32 * 0.001);
    381         }
    382     default:
    383         SkDebugf("");
    384     }
    385 }
    386 
    387 #endif
    388 
    389 bool SkDisplayable::enable( SkAnimateMaker& ) {
    390     return false;
    391 }
    392 
    393 void SkDisplayable::enableBounder() {
    394 }
    395 
    396 void SkDisplayable::executeFunction(SkDisplayable* , int index,
    397         SkTDArray<SkScriptValue>& , SkDisplayTypes, SkScriptValue*  ) {
    398     SkASSERT(0);
    399 }
    400 
    401 void SkDisplayable::executeFunction(SkDisplayable* target,
    402         const SkMemberInfo* info, SkTypedArray* values, SkScriptValue* value) {
    403     SkTDArray<SkScriptValue> typedValues;
    404     for (SkOperand* op = values->begin(); op < values->end(); op++) {
    405         SkScriptValue temp;
    406         temp.fType = values->getType();
    407         temp.fOperand = *op;
    408         *typedValues.append() = temp;
    409     }
    410     executeFunction(target, info->functionIndex(), typedValues, info->getType(), value);
    411 }
    412 
    413 void SkDisplayable::executeFunction2(SkDisplayable* , int index,
    414         SkOpArray* params, SkDisplayTypes, SkOperand2*  ) {
    415     SkASSERT(0);
    416 }
    417 
    418 void SkDisplayable::getBounds(SkRect* rect) {
    419     SkASSERT(rect);
    420     rect->fLeft = rect->fTop = SK_ScalarMax;
    421     rect->fRight= rect->fBottom = -SK_ScalarMax;
    422 }
    423 
    424 const SkFunctionParamType* SkDisplayable::getFunctionsParameters() {
    425     return nullptr;
    426 }
    427 
    428 const SkMemberInfo* SkDisplayable::getMember(int index) {
    429     return nullptr;
    430 }
    431 
    432 const SkMemberInfo* SkDisplayable::getMember(const char name[]) {
    433     return nullptr;
    434 }
    435 
    436 const SkFunctionParamType* SkDisplayable::getParameters(const SkMemberInfo* info,
    437         int* paramCount) {
    438     const SkFunctionParamType* params = getFunctionsParameters();
    439     SkASSERT(params != nullptr);
    440     int funcIndex = info->functionIndex();
    441     // !!! eventually break traversing params into an external function (maybe this whole function)
    442     int index = funcIndex;
    443     int offset = 0;
    444     while (--index >= 0) {
    445         while (params[offset] != 0)
    446             offset++;
    447         offset++;
    448     }
    449     int count = 0;
    450     while (params[offset] != 0) {
    451         count++;
    452         offset++;
    453     }
    454     *paramCount = count;
    455     return &params[offset - count];
    456 }
    457 
    458 SkDisplayable* SkDisplayable::getParent() const {
    459     return nullptr;
    460 }
    461 
    462 bool SkDisplayable::getProperty(int index, SkScriptValue* ) const {
    463 //  SkASSERT(0);
    464     return false;
    465 }
    466 
    467 bool SkDisplayable::getProperty2(int index, SkOperand2* value) const {
    468     SkASSERT(0);
    469     return false;
    470 }
    471 
    472 SkDisplayTypes SkDisplayable::getType() const {
    473     return SkType_Unknown;
    474 }
    475 
    476 bool SkDisplayable::hasEnable() const {
    477     return false;
    478 }
    479 
    480 bool SkDisplayable::isDrawable() const {
    481     return false;
    482 }
    483 
    484 void SkDisplayable::onEndElement(SkAnimateMaker& ) {}
    485 
    486 const SkMemberInfo* SkDisplayable::preferredChild(SkDisplayTypes type) {
    487     return nullptr;
    488 }
    489 
    490 bool SkDisplayable::resolveIDs(SkAnimateMaker& maker, SkDisplayable* original, SkApply* apply) {
    491     return false;
    492 }
    493 
    494 //SkDisplayable* SkDisplayable::resolveTarget(SkAnimateMaker& ) {
    495 //  return this;
    496 //}
    497 
    498 void SkDisplayable::setChildHasID() {
    499 }
    500 
    501 bool SkDisplayable::setParent(SkDisplayable* ) {
    502     return false;
    503 }
    504 
    505 bool SkDisplayable::setProperty(int index, SkScriptValue& ) {
    506     //SkASSERT(0);
    507     return false;
    508 }
    509 
    510 void SkDisplayable::setReference(const SkMemberInfo* info, SkDisplayable* displayable) {
    511     if (info->fType == SkType_MemberProperty) {
    512         SkScriptValue scriptValue;
    513         scriptValue.fOperand.fDisplayable = displayable;
    514         scriptValue.fType = displayable->getType();
    515         setProperty(info->propertyIndex(), scriptValue);
    516     } else if (info->fType == SkType_Array) {
    517         SkASSERT(displayable->getType() == SkType_Array);
    518         SkDisplayArray* dispArray = (SkDisplayArray*) displayable;
    519         SkTDScalarArray* array = (SkTDScalarArray* ) info->memberData(this);
    520         array->setCount(dispArray->values.count());
    521         memcpy(array->begin(), dispArray->values.begin(), dispArray->values.count() * sizeof(int));
    522         //
    523 
    524         // !!! need a way for interpreter engine to own array
    525         // !!! probably need to replace all scriptable arrays with single bigger array
    526         // that has operand and type on every element -- or
    527         // when array is dirtied, need to get parent to reparse to local array
    528     } else {
    529         void* storage = info->memberData(this);
    530         memcpy(storage, &displayable, sizeof(SkDisplayable*));
    531     }
    532 // !!! unclear why displayable is dirtied here
    533 // if this is called, this breaks fromPath.xml
    534 //  displayable->dirty();
    535 }
    536 
    537 #ifdef SK_DEBUG
    538 void SkDisplayable::validate() {
    539 }
    540 #endif
    541