Home | History | Annotate | Download | only in samplecode
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      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 #include "SampleCode.h"
      9 #include "SkView.h"
     10 #include "SkCanvas.h"
     11 
     12 #include "SkAnimator.h"
     13 #include "SkStream.h"
     14 #include "SkDOM.h"
     15 
     16 ///////////////////////////////////////////////////////////////////////////////
     17 
     18 class SkAnimatorView : public SkView {
     19 public:
     20     SkAnimatorView();
     21     virtual ~SkAnimatorView();
     22 
     23     void setURIBase(const char dir[]);
     24 
     25     SkAnimator* getAnimator() const { return fAnimator; }
     26 
     27     bool    decodeFile(const char path[]);
     28     bool    decodeMemory(const void* buffer, size_t size);
     29     bool    decodeStream(SkStream* stream);
     30 
     31 protected:
     32     // overrides
     33     virtual void onDraw(SkCanvas*);
     34     virtual bool onQuery(SkEvent* evt);
     35 
     36 private:
     37     SkString fBaseURI;
     38     SkAnimator* fAnimator;
     39 
     40     typedef SkView INHERITED;
     41 };
     42 
     43 SkAnimatorView::SkAnimatorView() : fAnimator(nullptr) {}
     44 
     45 SkAnimatorView::~SkAnimatorView() {
     46     delete fAnimator;
     47 }
     48 
     49 void SkAnimatorView::setURIBase(const char dir[]) {
     50     fBaseURI.set(dir);
     51 }
     52 
     53 bool SkAnimatorView::decodeFile(const char path[]) {
     54     SkAutoTDelete<SkStream> is(SkStream::NewFromFile(path));
     55     return is.get() != nullptr && this->decodeStream(is);
     56 }
     57 
     58 bool SkAnimatorView::decodeMemory(const void* buffer, size_t size) {
     59     SkMemoryStream is(buffer, size);
     60     return this->decodeStream(&is);
     61 }
     62 
     63 static const SkDOMNode* find_nodeID(const SkDOM& dom,
     64                         const SkDOMNode* node, const char name[]) {
     65     if (nullptr == node) {
     66         node = dom.getRootNode();
     67     }
     68     do {
     69         const char* idval = dom.findAttr(node, "id");
     70         if (idval && !strcmp(idval, name)) {
     71             return node;
     72         }
     73         const SkDOMNode* child = dom.getFirstChild(node);
     74         if (child) {
     75             const SkDOMNode* found = find_nodeID(dom, child, name);
     76             if (found) {
     77                 return found;
     78             }
     79         }
     80     } while ((node = dom.getNextSibling(node)) != nullptr);
     81     return nullptr;
     82 }
     83 
     84 bool SkAnimatorView::decodeStream(SkStream* stream) {
     85     delete fAnimator;
     86     fAnimator = new SkAnimator;
     87     fAnimator->setURIBase(fBaseURI.c_str());
     88 #if 0
     89     if (!fAnimator->decodeStream(stream)) {
     90         delete fAnimator;
     91         fAnimator = nullptr;
     92         return false;
     93     }
     94 #else
     95     size_t len = stream->getLength();
     96     char* text = (char*)sk_malloc_throw(len);
     97     stream->read(text, len);
     98     SkDOM dom;
     99     const SkDOM::Node* root = dom.build(text, len);
    100     if (nullptr == root) {
    101         return false;
    102     }
    103     if (!fAnimator->decodeDOM(dom, root)) {
    104         delete fAnimator;
    105         fAnimator = nullptr;
    106         return false;
    107     }
    108     for (int i = 0; i <= 10; i++) {
    109         SkString name("glyph");
    110         name.appendS32(i);
    111         const SkDOM::Node* node = find_nodeID(dom, nullptr, name.c_str());
    112         SkASSERT(node);
    113         SkRect r;
    114         dom.findScalar(node, "left", &r.fLeft);
    115         dom.findScalar(node, "top", &r.fTop);
    116         dom.findScalar(node, "width", &r.fRight); r.fRight += r.fLeft;
    117         dom.findScalar(node, "height", &r.fBottom); r.fBottom += r.fTop;
    118         SkDebugf("--- %s [%g %g %g %g]\n", name.c_str(),
    119                  r.fLeft, r.fTop, r.fRight, r.fBottom);
    120     }
    121 #endif
    122     return true;
    123 }
    124 
    125 #include "SkTime.h"
    126 
    127 void SkAnimatorView::onDraw(SkCanvas* canvas) {
    128     canvas->drawColor(SK_ColorWHITE);
    129     if (fAnimator) {
    130         fAnimator->draw(canvas, 0);
    131 #if 0
    132         canvas->save();
    133         canvas->translate(120, 30);
    134         canvas->scale(0.5, 0.5);
    135         fAnimator->draw(canvas, 0);
    136         canvas->restore();
    137 
    138         canvas->save();
    139         canvas->translate(190, 40);
    140         canvas->scale(0.25, 0.25);
    141         fAnimator->draw(canvas, 0);
    142         canvas->restore();
    143 
    144         this->inval(nullptr);
    145 #endif
    146     }
    147 }
    148 
    149 bool SkAnimatorView::onQuery(SkEvent* evt) {
    150     if (SampleCode::TitleQ(*evt)) {
    151         SampleCode::TitleR(evt, "Animator");
    152         return true;
    153     }
    154     return this->INHERITED::onQuery(evt);
    155 }
    156 
    157 //////////////////////////////////////////////////////////////////////////////
    158 
    159 static SkView* MyFactory() {
    160     SkAnimatorView* av = new SkAnimatorView;
    161 //    av->decodeFile("/skimages/test.xml");
    162 #if 0
    163     av->setURIBase("/skia/trunk/animations/");
    164     av->decodeFile("/skia/trunk/animations/checkbox.xml");
    165 #else
    166     av->setURIBase("/");
    167     av->decodeFile("/testanim.txt");
    168 #endif
    169     return av;
    170 }
    171 
    172 static SkViewRegister reg(MyFactory);
    173