OLD | NEW |
| (Empty) |
1 /* libs/graphics/animator/SkDrawGroup.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 "SkDrawGroup.h" | |
19 #include "SkAnimateMaker.h" | |
20 #include "SkAnimatorScript.h" | |
21 #include "SkCanvas.h" | |
22 #include "SkDisplayApply.h" | |
23 #include "SkPaint.h" | |
24 #ifdef SK_DEBUG | |
25 #include "SkDisplayList.h" | |
26 #endif | |
27 | |
28 #if SK_USE_CONDENSED_INFO == 0 | |
29 | |
30 const SkMemberInfo SkGroup::fInfo[] = { | |
31 SK_MEMBER(condition, String), | |
32 SK_MEMBER(enableCondition, String) | |
33 }; | |
34 | |
35 #endif | |
36 | |
37 DEFINE_GET_MEMBER(SkGroup); | |
38 | |
39 SkGroup::SkGroup() : fParentList(NULL), fOriginal(NULL) { | |
40 } | |
41 | |
42 SkGroup::~SkGroup() { | |
43 if (fOriginal) // has been copied | |
44 return; | |
45 int index = 0; | |
46 int max = fCopies.count() << 5; | |
47 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
48 if (index >= max || markedForDelete(index)) | |
49 delete *ptr; | |
50 // else { | |
51 // SkApply* apply = (SkApply*) *ptr; | |
52 // SkASSERT(apply->isApply()); | |
53 // SkASSERT(apply->getScope()); | |
54 // delete apply->getScope(); | |
55 // } | |
56 index++; | |
57 } | |
58 } | |
59 | |
60 bool SkGroup::add(SkAnimateMaker& , SkDisplayable* child) { | |
61 SkASSERT(child); | |
62 // SkASSERT(child->isDrawable()); | |
63 *fChildren.append() = (SkDrawable*) child; | |
64 if (child->isGroup()) { | |
65 SkGroup* groupie = (SkGroup*) child; | |
66 SkASSERT(groupie->fParentList == NULL); | |
67 groupie->fParentList = &fChildren; | |
68 } | |
69 return true; | |
70 } | |
71 | |
72 bool SkGroup::contains(SkDisplayable* match) { | |
73 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
74 SkDrawable* drawable = *ptr; | |
75 if (drawable == match || drawable->contains(match)) | |
76 return true; | |
77 } | |
78 return false; | |
79 } | |
80 | |
81 SkGroup* SkGroup::copy() { | |
82 SkGroup* result = new SkGroup(); | |
83 result->fOriginal = this; | |
84 result->fChildren = fChildren; | |
85 return result; | |
86 } | |
87 | |
88 SkBool SkGroup::copySet(int index) { | |
89 return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0; | |
90 } | |
91 | |
92 SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) { | |
93 SkDisplayable* copy = INHERITED::deepCopy(maker); | |
94 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
95 SkDisplayable* displayable = (SkDisplayable*)*ptr; | |
96 SkDisplayable* deeperCopy = displayable->deepCopy(maker); | |
97 ((SkGroup*)copy)->add(*maker, deeperCopy); | |
98 } | |
99 return copy; | |
100 } | |
101 | |
102 bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) { | |
103 bool handled = false; | |
104 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
105 SkDrawable* drawable = *ptr; | |
106 if (drawable->isDrawable() == false) | |
107 continue; | |
108 handled |= drawable->doEvent(kind, state); | |
109 } | |
110 return handled; | |
111 } | |
112 | |
113 bool SkGroup::draw(SkAnimateMaker& maker) { | |
114 bool conditionTrue = ifCondition(maker, this, condition); | |
115 bool result = false; | |
116 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
117 SkDrawable* drawable = *ptr; | |
118 if (drawable->isDrawable() == false) | |
119 continue; | |
120 if (conditionTrue == false) { | |
121 if (drawable->isApply()) | |
122 ((SkApply*) drawable)->disable(); | |
123 continue; | |
124 } | |
125 maker.validate(); | |
126 result |= drawable->draw(maker); | |
127 maker.validate(); | |
128 } | |
129 return result; | |
130 } | |
131 | |
132 #ifdef SK_DUMP_ENABLED | |
133 void SkGroup::dump(SkAnimateMaker* maker) { | |
134 dumpBase(maker); | |
135 if (condition.size() > 0) | |
136 SkDebugf("condition=\"%s\" ", condition.c_str()); | |
137 if (enableCondition.size() > 0) | |
138 SkDebugf("enableCondition=\"%s\" ", enableCondition.c_str()); | |
139 dumpDrawables(maker); | |
140 } | |
141 | |
142 void SkGroup::dumpDrawables(SkAnimateMaker* maker) { | |
143 SkDisplayList::fIndent += 4; | |
144 int save = SkDisplayList::fDumpIndex; | |
145 SkDisplayList::fDumpIndex = 0; | |
146 bool closedYet = false; | |
147 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
148 if (closedYet == false) { | |
149 closedYet = true; | |
150 SkDebugf(">\n"); | |
151 } | |
152 SkDrawable* drawable = *ptr; | |
153 drawable->dump(maker); | |
154 SkDisplayList::fDumpIndex++; | |
155 } | |
156 SkDisplayList::fIndent -= 4; | |
157 SkDisplayList::fDumpIndex = save; | |
158 if (closedYet) //we had children, now it's time to close the group | |
159 dumpEnd(maker); | |
160 else //no children | |
161 SkDebugf("/>\n"); | |
162 } | |
163 | |
164 void SkGroup::dumpEvents() { | |
165 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
166 SkDrawable* drawable = *ptr; | |
167 drawable->dumpEvents(); | |
168 } | |
169 } | |
170 #endif | |
171 | |
172 bool SkGroup::enable(SkAnimateMaker& maker ) { | |
173 reset(); | |
174 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
175 SkDrawable* drawable = *ptr; | |
176 if (ifCondition(maker, drawable, enableCondition) == false) | |
177 continue; | |
178 drawable->enable(maker); | |
179 } | |
180 return true; // skip add; already added so that scope is findable by chil
dren | |
181 } | |
182 | |
183 int SkGroup::findGroup(SkDrawable* match, SkTDDrawableArray** list, | |
184 SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandLis
t) { | |
185 *list = &fChildren; | |
186 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
187 SkDrawable* drawable = *ptr; | |
188 if (drawable->isGroup()) { | |
189 SkGroup* childGroup = (SkGroup*) drawable; | |
190 if (childGroup->fOriginal == match) | |
191 goto foundMatch; | |
192 } | |
193 if (drawable == match) { | |
194 foundMatch: | |
195 *parent = this; | |
196 return (int) (ptr - fChildren.begin()); | |
197 } | |
198 } | |
199 *grandList = &fChildren; | |
200 return SkDisplayList::SearchForMatch(match, list, parent, found, grandList); | |
201 } | |
202 | |
203 bool SkGroup::hasEnable() const { | |
204 return true; | |
205 } | |
206 | |
207 bool SkGroup::ifCondition(SkAnimateMaker& maker, SkDrawable* drawable, | |
208 SkString& conditionString) { | |
209 if (conditionString.size() == 0) | |
210 return true; | |
211 int32_t result; | |
212 bool success = SkAnimatorScript::EvaluateInt(maker, this, conditionString.c_
str(), &result); | |
213 #ifdef SK_DUMP_ENABLED | |
214 if (maker.fDumpGConditions) { | |
215 SkDebugf("group: "); | |
216 dumpBase(&maker); | |
217 SkDebugf("condition=%s ", conditionString.c_str()); | |
218 if (success == false) | |
219 SkDebugf("(script failed)\n"); | |
220 else | |
221 SkDebugf("success=%s\n", result != 0 ? "true" : "false"); | |
222 } | |
223 #endif | |
224 return success && result != 0; | |
225 } | |
226 | |
227 void SkGroup::initialize() { | |
228 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
229 SkDrawable* drawable = *ptr; | |
230 if (drawable->isDrawable() == false) | |
231 continue; | |
232 drawable->initialize(); | |
233 } | |
234 } | |
235 | |
236 void SkGroup::markCopyClear(int index) { | |
237 if (index < 0) | |
238 index = fChildren.count(); | |
239 fCopies[index >> 5] &= ~(1 << (index & 0x1f)); | |
240 } | |
241 | |
242 void SkGroup::markCopySet(int index) { | |
243 if (index < 0) | |
244 index = fChildren.count(); | |
245 fCopies[index >> 5] |= 1 << (index & 0x1f); | |
246 } | |
247 | |
248 void SkGroup::markCopySize(int index) { | |
249 if (index < 0) | |
250 index = fChildren.count() + 1; | |
251 int oldLongs = fCopies.count(); | |
252 int newLongs = (index >> 5) + 1; | |
253 if (oldLongs < newLongs) { | |
254 fCopies.setCount(newLongs); | |
255 memset(&fCopies[oldLongs], 0, (newLongs - oldLongs) << 2); | |
256 } | |
257 } | |
258 | |
259 void SkGroup::reset() { | |
260 if (fOriginal) // has been copied | |
261 return; | |
262 int index = 0; | |
263 int max = fCopies.count() << 5; | |
264 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
265 if (index >= max || copySet(index) == false) | |
266 continue; | |
267 SkApply* apply = (SkApply*) *ptr; | |
268 SkASSERT(apply->isApply()); | |
269 SkASSERT(apply->getScope()); | |
270 *ptr = apply->getScope(); | |
271 markCopyClear(index); | |
272 index++; | |
273 } | |
274 } | |
275 | |
276 bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* ap
ply) { | |
277 SkGroup* original = (SkGroup*) orig; | |
278 SkTDDrawableArray& originalChildren = original->fChildren; | |
279 SkDrawable** originalPtr = originalChildren.begin(); | |
280 SkDrawable** ptr = fChildren.begin(); | |
281 SkDrawable** end = fChildren.end(); | |
282 SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin(); | |
283 while (ptr < end) { | |
284 SkDrawable* drawable = *ptr++; | |
285 maker.resolveID(drawable, *origChild++); | |
286 if (drawable->resolveIDs(maker, *originalPtr++, apply) == true) | |
287 return true; // failed | |
288 } | |
289 return false; | |
290 } | |
291 | |
292 void SkGroup::setSteps(int steps) { | |
293 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
294 SkDrawable* drawable = *ptr; | |
295 if (drawable->isDrawable() == false) | |
296 continue; | |
297 drawable->setSteps(steps); | |
298 } | |
299 } | |
300 | |
301 #ifdef SK_DEBUG | |
302 void SkGroup::validate() { | |
303 for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { | |
304 SkDrawable* drawable = *ptr; | |
305 drawable->validate(); | |
306 } | |
307 } | |
308 #endif | |
309 | |
310 #if SK_USE_CONDENSED_INFO == 0 | |
311 | |
312 const SkMemberInfo SkSave::fInfo[] = { | |
313 SK_MEMBER_INHERITED | |
314 }; | |
315 | |
316 #endif | |
317 | |
318 DEFINE_GET_MEMBER(SkSave); | |
319 | |
320 bool SkSave::draw(SkAnimateMaker& maker) { | |
321 maker.fCanvas->save(); | |
322 SkPaint* save = maker.fPaint; | |
323 SkPaint local = SkPaint(*maker.fPaint); | |
324 maker.fPaint = &local; | |
325 bool result = INHERITED::draw(maker); | |
326 maker.fPaint = save; | |
327 maker.fCanvas->restore(); | |
328 return result; | |
329 } | |
330 | |
331 | |
OLD | NEW |