|
1 |
|
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 |
|
9 |
|
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 |
|
19 const 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 |
|
34 DEFINE_GET_MEMBER(SkAdd); |
|
35 |
|
36 SkAdd::SkAdd() : mode(kMode_indirect), |
|
37 offset(SK_MaxS32), use(NULL), where(NULL) { |
|
38 } |
|
39 |
|
40 SkDisplayable* 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 |
|
51 bool 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 |
|
60 void 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 |
|
78 bool 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; |
|
122 } |
|
123 } |
|
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); |
|
160 noHelperNeeded: |
|
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 |
|
186 bool SkAdd::hasEnable() const { |
|
187 return true; |
|
188 } |
|
189 |
|
190 void SkAdd::initialize() { |
|
191 if (use) |
|
192 use->initialize(); |
|
193 } |
|
194 |
|
195 bool 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 |
|
205 bool 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 |
|
214 const SkMemberInfo SkMove::fInfo[] = { |
|
215 SK_MEMBER_INHERITED |
|
216 }; |
|
217 |
|
218 #endif |
|
219 |
|
220 DEFINE_GET_MEMBER(SkMove); |
|
221 |
|
222 #if SK_USE_CONDENSED_INFO == 0 |
|
223 |
|
224 const 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 |
|
232 DEFINE_GET_MEMBER(SkRemove); |
|
233 |
|
234 SkRemove::SkRemove() : fDelete(false) { |
|
235 } |
|
236 |
|
237 #if SK_USE_CONDENSED_INFO == 0 |
|
238 |
|
239 const SkMemberInfo SkReplace::fInfo[] = { |
|
240 SK_MEMBER_INHERITED |
|
241 }; |
|
242 |
|
243 #endif |
|
244 |
|
245 DEFINE_GET_MEMBER(SkReplace); |