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