Home | History | Annotate | Download | only in animator
      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(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 
    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.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 
    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(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 
    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, 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 
    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 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 
    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, SkApply* 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* 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
    562 void SkDisplayable::validate() {
    563 }
    564 #endif
    565 
    566 
    567