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 
getAnimator() const25     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 
SkAnimatorView()43 SkAnimatorView::SkAnimatorView() : fAnimator(nullptr) {}
44 
~SkAnimatorView()45 SkAnimatorView::~SkAnimatorView() {
46     delete fAnimator;
47 }
48 
setURIBase(const char dir[])49 void SkAnimatorView::setURIBase(const char dir[]) {
50     fBaseURI.set(dir);
51 }
52 
decodeFile(const char path[])53 bool SkAnimatorView::decodeFile(const char path[]) {
54     SkAutoTDelete<SkStream> is(SkStream::NewFromFile(path));
55     return is.get() != nullptr && this->decodeStream(is);
56 }
57 
decodeMemory(const void * buffer,size_t size)58 bool SkAnimatorView::decodeMemory(const void* buffer, size_t size) {
59     SkMemoryStream is(buffer, size);
60     return this->decodeStream(&is);
61 }
62 
find_nodeID(const SkDOM & dom,const SkDOMNode * node,const char name[])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 
decodeStream(SkStream * stream)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 
onDraw(SkCanvas * canvas)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 
onQuery(SkEvent * evt)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 
MyFactory()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