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