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 "SkTypes.h" 9 10 #ifdef SK_XML 11 12 #include "Sample.h" 13 #include "Resources.h" 14 #include "SkCanvas.h" 15 #include "SkDOM.h" 16 #include "SkOSFile.h" 17 #include "SkOSPath.h" 18 #include "SkRect.h" 19 #include "SkStream.h" 20 #include "SkSVGDOM.h" 21 22 namespace { 23 24 class CowboyView : public Sample { 25 public: CowboyView()26 CowboyView() 27 : fLabel("SampleCowboy") 28 , fState(kZoomIn) 29 , fAnimationLoop(kAnimationIterations) 30 , fDelta(1) {} 31 ~CowboyView() override = default; 32 33 protected: 34 static constexpr auto kAnimationIterations = 5; 35 36 enum State { 37 kZoomIn, 38 kScroll, 39 kZoomOut 40 }; 41 onOnceBeforeDraw()42 void onOnceBeforeDraw() override { 43 constexpr char path[] = "Cowboy.svg"; 44 auto data = GetResourceAsData(path); 45 if (!data) { 46 SkDebugf("file not found: \"%s\"\n", path); 47 return; 48 } 49 SkMemoryStream svgStream(std::move(data)); 50 51 SkDOM xmlDom; 52 if (!xmlDom.build(svgStream)) { 53 SkDebugf("XML parsing failed: \"path\"\n", fPath.c_str()); 54 return; 55 } 56 57 fDom = SkSVGDOM::MakeFromDOM(xmlDom); 58 if (fDom) { 59 fDom->setContainerSize(SkSize::Make(this->width(), this->height())); 60 } 61 } 62 onDrawContent(SkCanvas * canvas)63 void onDrawContent(SkCanvas* canvas) override { 64 if (fDom) { 65 canvas->setMatrix(SkMatrix::MakeScale(3)); 66 canvas->clipRect(SkRect::MakeLTRB(0, 0, 400, 400)); 67 switch (fState) { 68 case kZoomIn: 69 fDelta += 0.2f; 70 canvas->concat(SkMatrix::MakeScale(fDelta)); 71 break; 72 case kScroll: 73 if (fAnimationLoop > kAnimationIterations/2) { 74 fDelta += 80.f; 75 } else { 76 fDelta -= 80.f; 77 } 78 canvas->concat(SkMatrix::MakeScale(fDelta)); 79 canvas->translate(fDelta, 0); 80 break; 81 case kZoomOut: 82 fDelta += 0.2f; 83 canvas->concat(SkMatrix::MakeScale(fDelta)); 84 break; 85 } 86 87 fDom->render(canvas); 88 } 89 } 90 onSizeChange()91 void onSizeChange() override { 92 if (fDom) { 93 fDom->setContainerSize(SkSize::Make(this->width(), this->height())); 94 } 95 96 this->INHERITED::onSizeChange(); 97 } 98 onQuery(Sample::Event * evt)99 bool onQuery(Sample::Event* evt) override { 100 if (Sample::TitleQ(*evt)) { 101 Sample::TitleR(evt, fLabel.c_str()); 102 return true; 103 } 104 105 return this->INHERITED::onQuery(evt); 106 } 107 onAnimate(const SkAnimTimer & timer)108 bool onAnimate(const SkAnimTimer& timer) override { 109 if (!fDom) { 110 return false; 111 } 112 113 --fAnimationLoop; 114 if (fAnimationLoop == 0) { 115 fAnimationLoop = kAnimationIterations; 116 switch (fState) { 117 case kZoomIn: 118 fState = kScroll; 119 fDelta = 0; 120 break; 121 case kScroll: 122 fState = kZoomOut; 123 fDelta = 2; 124 break; 125 case kZoomOut: 126 fState = kZoomIn; 127 fDelta = 1; 128 break; 129 } 130 } 131 return true; 132 } 133 134 private: 135 sk_sp<SkSVGDOM> fDom; 136 SkString fPath; 137 SkString fLabel; 138 State fState; 139 int fAnimationLoop; 140 SkScalar fDelta; 141 142 typedef Sample INHERITED; 143 }; 144 145 } // anonymous namespace 146 147 DEF_SAMPLE( return new CowboyView(); ) 148 149 #endif // SK_XML 150