SkDrawGroup.cpp revision 2880df2609eba09b555ca37be04b6ad89290c765
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 "SkDrawGroup.h" 11#include "SkAnimateMaker.h" 12#include "SkAnimatorScript.h" 13#include "SkCanvas.h" 14#include "SkDisplayApply.h" 15#include "SkPaint.h" 16#ifdef SK_DEBUG 17#include "SkDisplayList.h" 18#endif 19 20#if SK_USE_CONDENSED_INFO == 0 21 22const SkMemberInfo SkGroup::fInfo[] = { 23 SK_MEMBER(condition, String), 24 SK_MEMBER(enableCondition, String) 25}; 26 27#endif 28 29DEFINE_GET_MEMBER(SkGroup); 30 31SkGroup::SkGroup() : fParentList(nullptr), fOriginal(nullptr) { 32} 33 34SkGroup::~SkGroup() { 35 if (fOriginal) // has been copied 36 return; 37 int index = 0; 38 int max = fCopies.count() << 5; 39 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 40 if (index >= max || markedForDelete(index)) 41 delete *ptr; 42// else { 43// SkApply* apply = (SkApply*) *ptr; 44// SkASSERT(apply->isApply()); 45// SkASSERT(apply->getScope()); 46// delete apply->getScope(); 47// } 48 index++; 49 } 50} 51 52bool SkGroup::addChild(SkAnimateMaker& , SkDisplayable* child) { 53 SkASSERT(child); 54// SkASSERT(child->isDrawable()); 55 *fChildren.append() = (SkADrawable*) child; 56 if (child->isGroup()) { 57 SkGroup* groupie = (SkGroup*) child; 58 SkASSERT(groupie->fParentList == nullptr); 59 groupie->fParentList = &fChildren; 60 } 61 return true; 62} 63 64bool SkGroup::contains(SkDisplayable* match) { 65 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 66 SkADrawable* drawable = *ptr; 67 if (drawable == match || drawable->contains(match)) 68 return true; 69 } 70 return false; 71} 72 73SkGroup* SkGroup::copy() { 74 SkGroup* result = new SkGroup(); 75 result->fOriginal = this; 76 result->fChildren = fChildren; 77 return result; 78} 79 80SkBool SkGroup::copySet(int index) { 81 return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0; 82} 83 84SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) { 85 SkDisplayable* copy = INHERITED::deepCopy(maker); 86 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 87 SkDisplayable* displayable = (SkDisplayable*)*ptr; 88 SkDisplayable* deeperCopy = displayable->deepCopy(maker); 89 ((SkGroup*)copy)->addChild(*maker, deeperCopy); 90 } 91 return copy; 92} 93 94bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) { 95 bool handled = false; 96 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 97 SkADrawable* drawable = *ptr; 98 if (drawable->isDrawable() == false) 99 continue; 100 handled |= drawable->doEvent(kind, state); 101 } 102 return handled; 103} 104 105bool SkGroup::draw(SkAnimateMaker& maker) { 106 bool conditionTrue = ifCondition(maker, this, condition); 107 bool result = false; 108 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 109 SkADrawable* drawable = *ptr; 110 if (drawable->isDrawable() == false) 111 continue; 112 if (conditionTrue == false) { 113 if (drawable->isApply()) 114 ((SkApply*) drawable)->disable(); 115 continue; 116 } 117 maker.validate(); 118 result |= drawable->draw(maker); 119 maker.validate(); 120 } 121 return result; 122} 123 124#ifdef SK_DUMP_ENABLED 125void SkGroup::dump(SkAnimateMaker* maker) { 126 dumpBase(maker); 127 if (condition.size() > 0) 128 SkDebugf("condition=\"%s\" ", condition.c_str()); 129 if (enableCondition.size() > 0) 130 SkDebugf("enableCondition=\"%s\" ", enableCondition.c_str()); 131 dumpDrawables(maker); 132} 133 134void SkGroup::dumpDrawables(SkAnimateMaker* maker) { 135 SkDisplayList::fIndent += 4; 136 int save = SkDisplayList::fDumpIndex; 137 SkDisplayList::fDumpIndex = 0; 138 bool closedYet = false; 139 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 140 if (closedYet == false) { 141 closedYet = true; 142 SkDebugf(">\n"); 143 } 144 SkADrawable* drawable = *ptr; 145 drawable->dump(maker); 146 SkDisplayList::fDumpIndex++; 147 } 148 SkDisplayList::fIndent -= 4; 149 SkDisplayList::fDumpIndex = save; 150 if (closedYet) //we had children, now it's time to close the group 151 dumpEnd(maker); 152 else //no children 153 SkDebugf("/>\n"); 154} 155 156void SkGroup::dumpEvents() { 157 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 158 SkADrawable* drawable = *ptr; 159 drawable->dumpEvents(); 160 } 161} 162#endif 163 164bool SkGroup::enable(SkAnimateMaker& maker ) { 165 reset(); 166 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 167 SkADrawable* drawable = *ptr; 168 if (ifCondition(maker, drawable, enableCondition) == false) 169 continue; 170 drawable->enable(maker); 171 } 172 return true; // skip add; already added so that scope is findable by children 173} 174 175int SkGroup::findGroup(SkADrawable* match, SkTDDrawableArray** list, 176 SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) { 177 *list = &fChildren; 178 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 179 SkADrawable* drawable = *ptr; 180 if (drawable->isGroup()) { 181 SkGroup* childGroup = (SkGroup*) drawable; 182 if (childGroup->fOriginal == match) 183 goto foundMatch; 184 } 185 if (drawable == match) { 186foundMatch: 187 *parent = this; 188 return (int) (ptr - fChildren.begin()); 189 } 190 } 191 *grandList = &fChildren; 192 return SkDisplayList::SearchForMatch(match, list, parent, found, grandList); 193} 194 195bool SkGroup::hasEnable() const { 196 return true; 197} 198 199bool SkGroup::ifCondition(SkAnimateMaker& maker, SkADrawable*, 200 SkString& conditionString) { 201 if (conditionString.size() == 0) 202 return true; 203 int32_t result; 204 bool success = SkAnimatorScript::EvaluateInt(maker, this, conditionString.c_str(), &result); 205#ifdef SK_DUMP_ENABLED 206 if (maker.fDumpGConditions) { 207 SkDebugf("group: "); 208 dumpBase(&maker); 209 SkDebugf("condition=%s ", conditionString.c_str()); 210 if (success == false) 211 SkDebugf("(script failed)\n"); 212 else 213 SkDebugf("success=%s\n", result != 0 ? "true" : "false"); 214 } 215#endif 216 return success && result != 0; 217} 218 219void SkGroup::initialize() { 220 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 221 SkADrawable* drawable = *ptr; 222 if (drawable->isDrawable() == false) 223 continue; 224 drawable->initialize(); 225 } 226} 227 228void SkGroup::markCopyClear(int index) { 229 if (index < 0) 230 index = fChildren.count(); 231 fCopies[index >> 5] &= ~(1 << (index & 0x1f)); 232} 233 234void SkGroup::markCopySet(int index) { 235 if (index < 0) 236 index = fChildren.count(); 237 fCopies[index >> 5] |= 1 << (index & 0x1f); 238} 239 240void SkGroup::markCopySize(int index) { 241 if (index < 0) 242 index = fChildren.count() + 1; 243 int oldLongs = fCopies.count(); 244 int newLongs = (index >> 5) + 1; 245 if (oldLongs < newLongs) { 246 fCopies.setCount(newLongs); 247 memset(&fCopies[oldLongs], 0, (newLongs - oldLongs) << 2); 248 } 249} 250 251void SkGroup::reset() { 252 if (fOriginal) // has been copied 253 return; 254 int index = 0; 255 int max = fCopies.count() << 5; 256 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 257 if (index >= max || copySet(index) == false) 258 continue; 259 SkApply* apply = (SkApply*) *ptr; 260 SkASSERT(apply->isApply()); 261 SkASSERT(apply->getScope()); 262 *ptr = apply->getScope(); 263 markCopyClear(index); 264 index++; 265 } 266} 267 268bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) { 269 SkGroup* original = (SkGroup*) orig; 270 SkTDDrawableArray& originalChildren = original->fChildren; 271 SkADrawable** originalPtr = originalChildren.begin(); 272 SkADrawable** ptr = fChildren.begin(); 273 SkADrawable** end = fChildren.end(); 274 SkADrawable** origChild = ((SkGroup*) orig)->fChildren.begin(); 275 while (ptr < end) { 276 SkADrawable* drawable = *ptr++; 277 maker.resolveID(drawable, *origChild++); 278 if (drawable->resolveIDs(maker, *originalPtr++, apply) == true) 279 return true; // failed 280 } 281 return false; 282} 283 284void SkGroup::setSteps(int steps) { 285 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 286 SkADrawable* drawable = *ptr; 287 if (drawable->isDrawable() == false) 288 continue; 289 drawable->setSteps(steps); 290 } 291} 292 293#ifdef SK_DEBUG 294void SkGroup::validate() { 295 for (SkADrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { 296 SkADrawable* drawable = *ptr; 297 drawable->validate(); 298 } 299} 300#endif 301 302#if SK_USE_CONDENSED_INFO == 0 303 304const SkMemberInfo SkSave::fInfo[] = { 305 SK_MEMBER_INHERITED 306}; 307 308#endif 309 310DEFINE_GET_MEMBER(SkSave); 311 312bool SkSave::draw(SkAnimateMaker& maker) { 313 maker.fCanvas->save(); 314 SkPaint* save = maker.fPaint; 315 SkPaint local = SkPaint(*maker.fPaint); 316 maker.fPaint = &local; 317 bool result = INHERITED::draw(maker); 318 maker.fPaint = save; 319 maker.fCanvas->restore(); 320 return result; 321} 322