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