• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkAdd()44 SkAdd::SkAdd() : mode(kMode_indirect),
45     offset(SK_MaxS32), use(NULL), where(NULL) {
46 }
47 
deepCopy(SkAnimateMaker * maker)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 
draw(SkAnimateMaker & maker)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
dump(SkAnimateMaker * maker)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 
enable(SkAnimateMaker & maker)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 
hasEnable() const194 bool SkAdd::hasEnable() const {
195     return true;
196 }
197 
initialize()198 void SkAdd::initialize() {
199     if (use)
200         use->initialize();
201 }
202 
isDrawable() const203 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 
enable(SkAnimateMaker & maker)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 
SkRemove()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