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