blob: 8a97a0606b3acb27f8b717e3f708eb9abb914365 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* 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
27const 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
42DEFINE_GET_MEMBER(SkAdd);
43
44SkAdd::SkAdd() : mode(kMode_indirect),
45 offset(SK_MaxS32), use(NULL), where(NULL) {
46}
47
48SkDisplayable* 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
59bool 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
68void 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
86bool 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);
168noHelperNeeded:
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
194bool SkAdd::hasEnable() const {
195 return true;
196}
197
198void SkAdd::initialize() {
199 if (use)
200 use->initialize();
201}
202
203bool 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
213bool 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
222const SkMemberInfo SkMove::fInfo[] = {
223 SK_MEMBER_INHERITED
224};
225
226#endif
227
228DEFINE_GET_MEMBER(SkMove);
229
230#if SK_USE_CONDENSED_INFO == 0
231
232const 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
240DEFINE_GET_MEMBER(SkRemove);
241
242SkRemove::SkRemove() : fDelete(false) {
243}
244
245#if SK_USE_CONDENSED_INFO == 0
246
247const SkMemberInfo SkReplace::fInfo[] = {
248 SK_MEMBER_INHERITED
249};
250
251#endif
252
253DEFINE_GET_MEMBER(SkReplace);
254