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