• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkGroup()39 SkGroup::SkGroup() : fParentList(NULL), fOriginal(NULL) {
40 }
41 
~SkGroup()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 
add(SkAnimateMaker &,SkDisplayable * child)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 
contains(SkDisplayable * match)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 
copy()81 SkGroup* SkGroup::copy() {
82     SkGroup* result = new SkGroup();
83     result->fOriginal = this;
84     result->fChildren = fChildren;
85     return result;
86 }
87 
copySet(int index)88 SkBool SkGroup::copySet(int index) {
89     return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0;
90 }
91 
deepCopy(SkAnimateMaker * maker)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 
doEvent(SkDisplayEvent::Kind kind,SkEventState * state)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 
draw(SkAnimateMaker & maker)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
dump(SkAnimateMaker * maker)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 
dumpDrawables(SkAnimateMaker * maker)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 
dumpEvents()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 
enable(SkAnimateMaker & maker)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 children
181 }
182 
findGroup(SkDrawable * match,SkTDDrawableArray ** list,SkGroup ** parent,SkGroup ** found,SkTDDrawableArray ** grandList)183 int SkGroup::findGroup(SkDrawable* match,  SkTDDrawableArray** list,
184                  SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
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 
hasEnable() const203 bool SkGroup::hasEnable() const {
204     return true;
205 }
206 
ifCondition(SkAnimateMaker & maker,SkDrawable * drawable,SkString & conditionString)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 
initialize()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 
markCopyClear(int index)236 void SkGroup::markCopyClear(int index) {
237     if (index < 0)
238         index = fChildren.count();
239     fCopies[index >> 5] &= ~(1 << (index & 0x1f));
240 }
241 
markCopySet(int index)242 void SkGroup::markCopySet(int index) {
243     if (index < 0)
244         index = fChildren.count();
245     fCopies[index >> 5] |= 1 << (index & 0x1f);
246 }
247 
markCopySize(int index)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 
reset()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 
resolveIDs(SkAnimateMaker & maker,SkDisplayable * orig,SkApply * apply)276 bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) {
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 
setSteps(int steps)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
validate()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 
draw(SkAnimateMaker & maker)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 
332