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
19namespace {
20
21class CowboyView : public SampleView {
22public:
23    CowboyView()
24        : fLabel("SampleCowboy")
25        , fState(kZoomIn)
26        , fAnimationLoop(kAnimationIterations)
27        , fDelta(1) {}
28    ~CowboyView() override = default;
29
30protected:
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
131private:
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
144DEF_SAMPLE( return new CowboyView(); )
145
146