OLD | NEW |
| (Empty) |
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_Max
S32 && | |
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 | |
OLD | NEW |