blob: 7fd502658480ae640864259ab72713919b7d6a5a [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkDisplayAdd.h"
11#include "SkAnimateMaker.h"
12#include "SkDisplayApply.h"
13#include "SkDisplayList.h"
14#include "SkDrawable.h"
15#include "SkDrawGroup.h"
16
17#if SK_USE_CONDENSED_INFO == 0
18
19const SkMemberInfo SkAdd::fInfo[] = {
20 SK_MEMBER(mode, AddMode),
21 SK_MEMBER(offset, Int),
22 SK_MEMBER(use, Drawable),
23 SK_MEMBER(where, Drawable)
24};
25
26#endif
27
28// start here;
29// add onEndElement to turn where string into f_Where
30// probably need new SkAnimateMaker::resolve flavor that takes
31// where="id", where="event-target" or not-specified
32// offset="#" (implements before, after, and index if no 'where')
33
34DEFINE_GET_MEMBER(SkAdd);
35
rmistry@google.comd6176b02012-08-23 18:14:13 +000036SkAdd::SkAdd() : mode(kMode_indirect),
reed@android.com8a1c16f2008-12-17 15:59:43 +000037 offset(SK_MaxS32), use(NULL), where(NULL) {
38}
39
40SkDisplayable* SkAdd::deepCopy(SkAnimateMaker* maker) {
41 SkDrawable* saveUse = use;
42 SkDrawable* saveWhere = where;
43 use = NULL;
44 where = NULL;
45 SkAdd* copy = (SkAdd*) INHERITED::deepCopy(maker);
46 copy->use = use = saveUse;
47 copy->where = where = saveWhere;
48 return copy;
49}
50
51bool SkAdd::draw(SkAnimateMaker& maker) {
52 SkASSERT(use);
53 SkASSERT(use->isDrawable());
54 if (mode == kMode_indirect)
55 use->draw(maker);
56 return false;
57}
58
59#ifdef SK_DUMP_ENABLED
60void SkAdd::dump(SkAnimateMaker* maker) {
61 dumpBase(maker);
62 dumpAttrs(maker);
63 if (where)
64 SkDebugf("where=\"%s\" ", where->id);
65 if (mode == kMode_immediate)
66 SkDebugf("mode=\"immediate\" ");
67 SkDebugf(">\n");
68 SkDisplayList::fIndent += 4;
69 int save = SkDisplayList::fDumpIndex;
70 if (use) //just in case
71 use->dump(maker);
72 SkDisplayList::fIndent -= 4;
73 SkDisplayList::fDumpIndex = save;
74 dumpEnd(maker);
75}
76#endif
77
78bool SkAdd::enable(SkAnimateMaker& maker ) {
79 SkDisplayTypes type = getType();
80 SkDisplayList& displayList = maker.fDisplayList;
81 SkTDDrawableArray* parentList = displayList.getDrawList();
82 if (type == SkType_Add) {
83 if (use == NULL) // not set in apply yet
84 return true;
85 }
86 bool skipAddToParent = true;
87 SkASSERT(type != SkType_Replace || where);
88 SkTDDrawableArray* grandList SK_INIT_TO_AVOID_WARNING;
89 SkGroup* parentGroup = NULL;
90 SkGroup* thisGroup = NULL;
91 int index = where ? displayList.findGroup(where, &parentList, &parentGroup,
92 &thisGroup, &grandList) : 0;
93 if (index < 0)
94 return true;
95 int max = parentList->count();
96 if (where == NULL && type == SkType_Move)
97 index = max;
98 if (offset != SK_MaxS32) {
99 index += offset;
100 if (index > max) {
101 maker.setErrorCode(SkDisplayXMLParserError::kIndexOutOfRange);
102 return true; // caller should not add
103 }
104 }
105 if (offset < 0 && where == NULL)
106 index += max + 1;
107 switch (type) {
108 case SkType_Add:
109 if (offset == SK_MaxS32 && where == NULL) {
110 if (use->isDrawable()) {
111 skipAddToParent = mode == kMode_immediate;
112 if (skipAddToParent) {
113 if (where == NULL) {
114 SkTDDrawableArray* useParentList;
115 index = displayList.findGroup(this, &useParentList, &parentGroup,
116 &thisGroup, &grandList);
117 if (index >= 0) {
118 parentGroup->markCopySize(index);
119 parentGroup->markCopySet(index);
120 useParentList->begin()[index] = use;
121 break;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000122 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000123 }
124 *parentList->append() = use;
125 }
126 }
127 break;
128 } else {
129 if (thisGroup)
130 thisGroup->markCopySize(index);
131 *parentList->insert(index) = use;
132 if (thisGroup)
133 thisGroup->markCopySet(index);
134 if (use->isApply())
135 ((SkApply*) use)->setEmbedded();
136 }
137 break;
138 case SkType_Move: {
139 int priorLocation = parentList->find(use);
140 if (priorLocation < 0)
141 break;
142 *parentList->insert(index) = use;
143 if (index < priorLocation)
144 priorLocation++;
145 parentList->remove(priorLocation);
146 } break;
147 case SkType_Remove: {
148 SkDisplayable* old = (*parentList)[index];
149 if (((SkRemove*)(this))->fDelete) {
150 delete old;
151 goto noHelperNeeded;
152 }
153 for (int inner = 0; inner < maker.fChildren.count(); inner++) {
154 SkDisplayable* child = maker.fChildren[inner];
155 if (child == old || child->contains(old))
156 goto noHelperNeeded;
157 }
158 if (maker.fHelpers.find(old) < 0)
159 maker.helperAdd(old);
160noHelperNeeded:
161 parentList->remove(index);
162 } break;
163 case SkType_Replace:
164 if (thisGroup) {
165 thisGroup->markCopySize(index);
166 if (thisGroup->markedForDelete(index)) {
167 SkDisplayable* old = (*parentList)[index];
168 if (maker.fHelpers.find(old) < 0)
169 maker.helperAdd(old);
170 }
171 }
172 (*parentList)[index] = use;
173 if (thisGroup)
174 thisGroup->markCopySet(index);
175 break;
176 default:
177 SkASSERT(0);
178 }
179 if (type == SkType_Remove)
180 return true;
181 if (use->hasEnable())
182 use->enable(maker);
183 return skipAddToParent; // append if indirect: *parentList->append() = this;
184}
185
186bool SkAdd::hasEnable() const {
187 return true;
188}
189
190void SkAdd::initialize() {
191 if (use)
192 use->initialize();
193}
194
195bool SkAdd::isDrawable() const {
196 return getType() == SkType_Add && mode == kMode_indirect && offset == SK_MaxS32 &&
197 where == NULL && use != NULL && use->isDrawable();
198}
199
200//SkDisplayable* SkAdd::resolveTarget(SkAnimateMaker& maker) {
201// return use;
202//}
203
204
205bool SkClear::enable(SkAnimateMaker& maker ) {
206 SkDisplayList& displayList = maker.fDisplayList;
207 displayList.clear();
208 return true;
209}
210
211
212#if SK_USE_CONDENSED_INFO == 0
213
214const SkMemberInfo SkMove::fInfo[] = {
215 SK_MEMBER_INHERITED
216};
217
218#endif
219
220DEFINE_GET_MEMBER(SkMove);
221
222#if SK_USE_CONDENSED_INFO == 0
223
224const SkMemberInfo SkRemove::fInfo[] = {
225 SK_MEMBER_ALIAS(delete, fDelete, Boolean), // !!! experimental
226 SK_MEMBER(offset, Int),
227 SK_MEMBER(where, Drawable)
228};
229
230#endif
231
232DEFINE_GET_MEMBER(SkRemove);
233
234SkRemove::SkRemove() : fDelete(false) {
235}
236
237#if SK_USE_CONDENSED_INFO == 0
238
239const SkMemberInfo SkReplace::fInfo[] = {
240 SK_MEMBER_INHERITED
241};
242
243#endif
244
245DEFINE_GET_MEMBER(SkReplace);
246