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