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 "SkDrawable.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(NULL), where(NULL) { 38 } 39 40 SkDisplayable* SkAdd::deepCopy(SkAnimateMaker* maker) { 41 SkDrawable* saveUse = use; 42 SkDrawable* saveWhere = where; 43 use = NULL; 44 where = NULL; 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 == NULL) // 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 = NULL; 90 SkGroup* thisGroup = NULL; 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 == NULL && 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 == NULL) 106 index += max + 1; 107 switch (type) { 108 case SkType_Add: 109 if (offset == SK_MaxS32 && where == NULL) { 110 if (use->isDrawable()) { 111 skipAddToParent = mode == kMode_immediate; 112 if (skipAddToParent) { 113 if (where == NULL) { 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 == NULL && use != NULL && 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