1 /* 2 * Copyright 2017 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 8 #include "include/core/SkTypes.h" 9 10 #ifdef SK_XML 11 12 #include "experimental/svg/model/SkSVGDOM.h" 13 #include "include/core/SkCanvas.h" 14 #include "include/core/SkRect.h" 15 #include "include/core/SkStream.h" 16 #include "samplecode/Sample.h" 17 #include "src/core/SkOSFile.h" 18 #include "src/utils/SkOSPath.h" 19 #include "src/xml/SkDOM.h" 20 #include "tools/Resources.h" 21 22 namespace { 23 class AnimatedSVGSample : public Sample { 24 static constexpr auto kAnimationIterations = 5; 25 enum State { 26 kZoomIn, 27 kScroll, 28 kZoomOut 29 }; 30 sk_sp<SkSVGDOM> fDom; 31 const char* fResource = nullptr; 32 const char* fName = nullptr; 33 State fState = kZoomIn; 34 int fAnimationLoop = kAnimationIterations; 35 SkScalar fDelta = 1; 36 37 public: AnimatedSVGSample(const char * r,const char * n)38 AnimatedSVGSample(const char* r, const char* n) : fResource(r), fName(n) {} 39 40 private: onOnceBeforeDraw()41 void onOnceBeforeDraw() override { 42 SkASSERT(fResource); 43 auto data = GetResourceAsData(fResource); 44 if (!data) { 45 SkDebugf("Resource not found: \"%s\"\n", fResource); 46 return; 47 } 48 SkMemoryStream svgStream(std::move(data)); 49 50 SkDOM xmlDom; 51 if (!xmlDom.build(svgStream)) { 52 SkDebugf("XML parsing failed: \"%s\"\n", fResource); 53 return; 54 } 55 56 fDom = SkSVGDOM::MakeFromDOM(xmlDom); 57 if (fDom) { 58 fDom->setContainerSize(SkSize::Make(this->width(), this->height())); 59 } 60 } 61 onDrawContent(SkCanvas * canvas)62 void onDrawContent(SkCanvas* canvas) override { 63 if (fDom) { 64 canvas->setMatrix(SkMatrix::MakeScale(3)); 65 canvas->clipRect(SkRect::MakeLTRB(0, 0, 400, 400)); 66 switch (fState) { 67 case kZoomIn: 68 fDelta += 0.2f; 69 canvas->concat(SkMatrix::MakeScale(fDelta)); 70 break; 71 case kScroll: 72 if (fAnimationLoop > kAnimationIterations/2) { 73 fDelta += 80.f; 74 } else { 75 fDelta -= 80.f; 76 } 77 canvas->concat(SkMatrix::MakeScale(fDelta)); 78 canvas->translate(fDelta, 0); 79 break; 80 case kZoomOut: 81 fDelta += 0.2f; 82 canvas->concat(SkMatrix::MakeScale(fDelta)); 83 break; 84 } 85 86 fDom->render(canvas); 87 } 88 } 89 onSizeChange()90 void onSizeChange() override { 91 if (fDom) { 92 fDom->setContainerSize(SkSize::Make(this->width(), this->height())); 93 } 94 } 95 name()96 SkString name() override { return SkASSERT(fName), SkString(fName); } 97 onAnimate(double nanos)98 bool onAnimate(double nanos) override { 99 if (!fDom) { 100 return false; 101 } 102 103 --fAnimationLoop; 104 if (fAnimationLoop == 0) { 105 fAnimationLoop = kAnimationIterations; 106 switch (fState) { 107 case kZoomIn: 108 fState = kScroll; 109 fDelta = 0; 110 break; 111 case kScroll: 112 fState = kZoomOut; 113 fDelta = 2; 114 break; 115 case kZoomOut: 116 fState = kZoomIn; 117 fDelta = 1; 118 break; 119 } 120 } 121 return true; 122 } 123 }; 124 } // namespace 125 126 DEF_SAMPLE( return new AnimatedSVGSample("Cowboy.svg", "SampleCowboy"); ) 127 128 #endif // SK_XML 129