Home | History | Annotate | Download | only in animator
      1 /* libs/graphics/animator/SkDisplayAdd.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 "SkDisplayAdd.h"
     19 #include "SkAnimateMaker.h"
     20 #include "SkDisplayApply.h"
     21 #include "SkDisplayList.h"
     22 #include "SkDrawable.h"
     23 #include "SkDrawGroup.h"
     24 
     25 #if SK_USE_CONDENSED_INFO == 0
     26 
     27 const SkMemberInfo SkAdd::fInfo[] = {
     28     SK_MEMBER(mode, AddMode),
     29     SK_MEMBER(offset, Int),
     30     SK_MEMBER(use, Drawable),
     31     SK_MEMBER(where, Drawable)
     32 };
     33 
     34 #endif
     35 
     36 // start here;
     37 // add onEndElement to turn where string into f_Where
     38 // probably need new SkAnimateMaker::resolve flavor that takes
     39 // where="id", where="event-target" or not-specified
     40 // offset="#" (implements before, after, and index if no 'where')
     41 
     42 DEFINE_GET_MEMBER(SkAdd);
     43 
     44 SkAdd::SkAdd() : mode(kMode_indirect),
     45     offset(SK_MaxS32), use(NULL), where(NULL) {
     46 }
     47 
     48 SkDisplayable* SkAdd::deepCopy(SkAnimateMaker* maker) {
     49     SkDrawable* saveUse = use;
     50     SkDrawable* saveWhere = where;
     51     use = NULL;
     52     where = NULL;
     53     SkAdd* copy = (SkAdd*) INHERITED::deepCopy(maker);
     54     copy->use = use = saveUse;
     55     copy->where = where = saveWhere;
     56     return copy;
     57 }
     58 
     59 bool SkAdd::draw(SkAnimateMaker& maker) {
     60     SkASSERT(use);
     61     SkASSERT(use->isDrawable());
     62     if (mode == kMode_indirect)
     63         use->draw(maker);
     64     return false;
     65 }
     66 
     67 #ifdef SK_DUMP_ENABLED
     68 void SkAdd::dump(SkAnimateMaker* maker) {
     69     dumpBase(maker);
     70     dumpAttrs(maker);
     71     if (where)
     72         SkDebugf("where=\"%s\" ", where->id);
     73     if (mode == kMode_immediate)
     74         SkDebugf("mode=\"immediate\" ");
     75     SkDebugf(">\n");
     76     SkDisplayList::fIndent += 4;
     77     int save = SkDisplayList::fDumpIndex;
     78     if (use)    //just in case
     79         use->dump(maker);
     80     SkDisplayList::fIndent -= 4;
     81     SkDisplayList::fDumpIndex = save;
     82     dumpEnd(maker);
     83 }
     84 #endif
     85 
     86 bool SkAdd::enable(SkAnimateMaker& maker ) {
     87     SkDisplayTypes type = getType();
     88     SkDisplayList& displayList = maker.fDisplayList;
     89     SkTDDrawableArray* parentList = displayList.getDrawList();
     90     if (type == SkType_Add) {
     91         if (use == NULL) // not set in apply yet
     92             return true;
     93     }
     94     bool skipAddToParent = true;
     95     SkASSERT(type != SkType_Replace || where);
     96     SkTDDrawableArray* grandList SK_INIT_TO_AVOID_WARNING;
     97     SkGroup* parentGroup = NULL;
     98     SkGroup* thisGroup = NULL;
     99     int index = where ? displayList.findGroup(where, &parentList, &parentGroup,
    100         &thisGroup, &grandList) : 0;
    101     if (index < 0)
    102         return true;
    103     int max = parentList->count();
    104     if (where == NULL && type == SkType_Move)
    105         index = max;
    106     if (offset != SK_MaxS32) {
    107         index += offset;
    108         if (index > max) {
    109             maker.setErrorCode(SkDisplayXMLParserError::kIndexOutOfRange);
    110             return true;    // caller should not add
    111         }
    112     }
    113     if (offset < 0 && where == NULL)
    114         index += max + 1;
    115     switch (type) {
    116         case SkType_Add:
    117             if (offset == SK_MaxS32 && where == NULL) {
    118                 if (use->isDrawable()) {
    119                     skipAddToParent = mode == kMode_immediate;
    120                     if (skipAddToParent) {
    121                         if (where == NULL) {
    122                             SkTDDrawableArray* useParentList;
    123                             index = displayList.findGroup(this, &useParentList, &parentGroup,
    124                                 &thisGroup, &grandList);
    125                             if (index >= 0) {
    126                                 parentGroup->markCopySize(index);
    127                                 parentGroup->markCopySet(index);
    128                                 useParentList->begin()[index] = use;
    129                                 break;
    130                             }
    131                         }
    132                         *parentList->append() = use;
    133                     }
    134                 }
    135                 break;
    136             } else {
    137                 if (thisGroup)
    138                     thisGroup->markCopySize(index);
    139                 *parentList->insert(index) = use;
    140                 if (thisGroup)
    141                     thisGroup->markCopySet(index);
    142                 if (use->isApply())
    143                     ((SkApply*) use)->setEmbedded();
    144             }
    145             break;
    146         case SkType_Move: {
    147             int priorLocation = parentList->find(use);
    148             if (priorLocation < 0)
    149                 break;
    150             *parentList->insert(index) = use;
    151             if (index < priorLocation)
    152                 priorLocation++;
    153             parentList->remove(priorLocation);
    154             } break;
    155         case SkType_Remove: {
    156             SkDisplayable* old = (*parentList)[index];
    157             if (((SkRemove*)(this))->fDelete) {
    158                 delete old;
    159                 goto noHelperNeeded;
    160             }
    161             for (int inner = 0; inner < maker.fChildren.count(); inner++) {
    162                 SkDisplayable* child = maker.fChildren[inner];
    163                 if (child == old || child->contains(old))
    164                     goto noHelperNeeded;
    165             }
    166             if (maker.fHelpers.find(old) < 0)
    167                 maker.helperAdd(old);
    168 noHelperNeeded:
    169             parentList->remove(index);
    170             } break;
    171         case SkType_Replace:
    172             if (thisGroup) {
    173                 thisGroup->markCopySize(index);
    174                 if (thisGroup->markedForDelete(index)) {
    175                     SkDisplayable* old = (*parentList)[index];
    176                     if (maker.fHelpers.find(old) < 0)
    177                         maker.helperAdd(old);
    178                 }
    179             }
    180             (*parentList)[index] = use;
    181             if (thisGroup)
    182                 thisGroup->markCopySet(index);
    183             break;
    184         default:
    185             SkASSERT(0);
    186     }
    187     if (type == SkType_Remove)
    188         return true;
    189     if (use->hasEnable())
    190         use->enable(maker);
    191     return skipAddToParent; // append if indirect: *parentList->append() = this;
    192 }
    193 
    194 bool SkAdd::hasEnable() const {
    195     return true;
    196 }
    197 
    198 void SkAdd::initialize() {
    199     if (use)
    200         use->initialize();
    201 }
    202 
    203 bool SkAdd::isDrawable() const {
    204     return getType() == SkType_Add && mode == kMode_indirect && offset == SK_MaxS32 &&
    205         where == NULL && use != NULL && use->isDrawable();
    206 }
    207 
    208 //SkDisplayable* SkAdd::resolveTarget(SkAnimateMaker& maker) {
    209 //  return use;
    210 //}
    211 
    212 
    213 bool SkClear::enable(SkAnimateMaker& maker ) {
    214     SkDisplayList& displayList = maker.fDisplayList;
    215     displayList.clear();
    216     return true;
    217 }
    218 
    219 
    220 #if SK_USE_CONDENSED_INFO == 0
    221 
    222 const SkMemberInfo SkMove::fInfo[] = {
    223     SK_MEMBER_INHERITED
    224 };
    225 
    226 #endif
    227 
    228 DEFINE_GET_MEMBER(SkMove);
    229 
    230 #if SK_USE_CONDENSED_INFO == 0
    231 
    232 const SkMemberInfo SkRemove::fInfo[] = {
    233     SK_MEMBER_ALIAS(delete, fDelete, Boolean),  // !!! experimental
    234     SK_MEMBER(offset, Int),
    235     SK_MEMBER(where, Drawable)
    236 };
    237 
    238 #endif
    239 
    240 DEFINE_GET_MEMBER(SkRemove);
    241 
    242 SkRemove::SkRemove() : fDelete(false) {
    243 }
    244 
    245 #if SK_USE_CONDENSED_INFO == 0
    246 
    247 const SkMemberInfo SkReplace::fInfo[] = {
    248     SK_MEMBER_INHERITED
    249 };
    250 
    251 #endif
    252 
    253 DEFINE_GET_MEMBER(SkReplace);
    254 
    255