Home | History | Annotate | Download | only in animator
      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 
     22 const SkMemberInfo SkGroup::fInfo[] = {
     23     SK_MEMBER(condition, String),
     24     SK_MEMBER(enableCondition, String)
     25 };
     26 
     27 #endif
     28 
     29 DEFINE_GET_MEMBER(SkGroup);
     30 
     31 SkGroup::SkGroup() : fParentList(NULL), fOriginal(NULL) {
     32 }
     33 
     34 SkGroup::~SkGroup() {
     35     if (fOriginal)  // has been copied
     36         return;
     37     int index = 0;
     38     int max = fCopies.count() << 5;
     39     for (SkDrawable** 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 
     52 bool SkGroup::add(SkAnimateMaker& , SkDisplayable* child) {
     53     SkASSERT(child);
     54 //  SkASSERT(child->isDrawable());
     55     *fChildren.append() = (SkDrawable*) child;
     56     if (child->isGroup()) {
     57         SkGroup* groupie = (SkGroup*) child;
     58         SkASSERT(groupie->fParentList == NULL);
     59         groupie->fParentList = &fChildren;
     60     }
     61     return true;
     62 }
     63 
     64 bool SkGroup::contains(SkDisplayable* match) {
     65     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
     66         SkDrawable* drawable = *ptr;
     67         if (drawable == match || drawable->contains(match))
     68             return true;
     69     }
     70     return false;
     71 }
     72 
     73 SkGroup* SkGroup::copy() {
     74     SkGroup* result = new SkGroup();
     75     result->fOriginal = this;
     76     result->fChildren = fChildren;
     77     return result;
     78 }
     79 
     80 SkBool SkGroup::copySet(int index) {
     81     return (fCopies[index >> 5] & 1 << (index & 0x1f)) != 0;
     82 }
     83 
     84 SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) {
     85     SkDisplayable* copy = INHERITED::deepCopy(maker);
     86     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
     87         SkDisplayable* displayable = (SkDisplayable*)*ptr;
     88         SkDisplayable* deeperCopy = displayable->deepCopy(maker);
     89         ((SkGroup*)copy)->add(*maker, deeperCopy);
     90     }
     91     return copy;
     92 }
     93 
     94 bool SkGroup::doEvent(SkDisplayEvent::Kind kind, SkEventState* state) {
     95     bool handled = false;
     96     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
     97         SkDrawable* drawable = *ptr;
     98         if (drawable->isDrawable() == false)
     99             continue;
    100         handled |= drawable->doEvent(kind, state);
    101     }
    102     return handled;
    103 }
    104 
    105 bool SkGroup::draw(SkAnimateMaker& maker) {
    106     bool conditionTrue = ifCondition(maker, this, condition);
    107     bool result = false;
    108     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    109         SkDrawable* 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
    125 void 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 
    134 void SkGroup::dumpDrawables(SkAnimateMaker* maker) {
    135     SkDisplayList::fIndent += 4;
    136     int save = SkDisplayList::fDumpIndex;
    137     SkDisplayList::fDumpIndex = 0;
    138     bool closedYet = false;
    139     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    140         if (closedYet == false) {
    141             closedYet = true;
    142             SkDebugf(">\n");
    143         }
    144         SkDrawable* 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 
    156 void SkGroup::dumpEvents() {
    157     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    158         SkDrawable* drawable = *ptr;
    159         drawable->dumpEvents();
    160     }
    161 }
    162 #endif
    163 
    164 bool SkGroup::enable(SkAnimateMaker& maker ) {
    165     reset();
    166     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    167         SkDrawable* 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 
    175 int SkGroup::findGroup(SkDrawable* match,  SkTDDrawableArray** list,
    176                  SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
    177     *list = &fChildren;
    178     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    179         SkDrawable* drawable = *ptr;
    180         if (drawable->isGroup()) {
    181             SkGroup* childGroup = (SkGroup*) drawable;
    182             if (childGroup->fOriginal == match)
    183                 goto foundMatch;
    184         }
    185         if (drawable == match) {
    186 foundMatch:
    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 
    195 bool SkGroup::hasEnable() const {
    196     return true;
    197 }
    198 
    199 bool SkGroup::ifCondition(SkAnimateMaker& maker, SkDrawable* drawable,
    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 
    219 void SkGroup::initialize() {
    220     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    221         SkDrawable* drawable = *ptr;
    222         if (drawable->isDrawable() == false)
    223             continue;
    224         drawable->initialize();
    225     }
    226 }
    227 
    228 void SkGroup::markCopyClear(int index) {
    229     if (index < 0)
    230         index = fChildren.count();
    231     fCopies[index >> 5] &= ~(1 << (index & 0x1f));
    232 }
    233 
    234 void SkGroup::markCopySet(int index) {
    235     if (index < 0)
    236         index = fChildren.count();
    237     fCopies[index >> 5] |= 1 << (index & 0x1f);
    238 }
    239 
    240 void 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 
    251 void SkGroup::reset() {
    252     if (fOriginal)  // has been copied
    253         return;
    254     int index = 0;
    255     int max = fCopies.count() << 5;
    256     for (SkDrawable** 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 
    268 bool SkGroup::resolveIDs(SkAnimateMaker& maker, SkDisplayable* orig, SkApply* apply) {
    269     SkGroup* original = (SkGroup*) orig;
    270     SkTDDrawableArray& originalChildren = original->fChildren;
    271     SkDrawable** originalPtr = originalChildren.begin();
    272     SkDrawable** ptr = fChildren.begin();
    273     SkDrawable** end = fChildren.end();
    274     SkDrawable** origChild = ((SkGroup*) orig)->fChildren.begin();
    275     while (ptr < end) {
    276         SkDrawable* 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 
    284 void SkGroup::setSteps(int steps) {
    285     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    286         SkDrawable* drawable = *ptr;
    287         if (drawable->isDrawable() == false)
    288             continue;
    289         drawable->setSteps(steps);
    290     }
    291 }
    292 
    293 #ifdef SK_DEBUG
    294 void SkGroup::validate() {
    295     for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
    296         SkDrawable* drawable = *ptr;
    297         drawable->validate();
    298     }
    299 }
    300 #endif
    301 
    302 #if SK_USE_CONDENSED_INFO == 0
    303 
    304 const SkMemberInfo SkSave::fInfo[] = {
    305     SK_MEMBER_INHERITED
    306 };
    307 
    308 #endif
    309 
    310 DEFINE_GET_MEMBER(SkSave);
    311 
    312 bool 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 
    323 
    324