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