• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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