| 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 |