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