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