Home | History | Annotate | Download | only in animator
      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 children
    181 }
    182 
    183 int SkGroup::findGroup(SkDrawable* match,  SkTDDrawableArray** list,
    184                  SkGroup** parent, SkGroup** found, SkTDDrawableArray** grandList) {
    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* apply) {
    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 
    332