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