1/*
2 * Copyright 2019 Google LLC.
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#ifndef SkShape_DEFINED
9#define SkShape_DEFINED
10
11#include "experimental/xform/SkXform.h"
12#include "include/core/SkPaint.h"
13
14class SkCanvas;
15
16class XContext {
17public:
18    virtual ~XContext() {}
19
20    void push(Xform* parentXform) { this->onPush(parentXform); }
21    void pop() { this->onPop(); }
22
23    void drawRect(const SkRect&, const SkPaint&, Xform* localXform);
24
25    static std::unique_ptr<XContext> Make(SkCanvas*);
26
27protected:
28    virtual void onPush(Xform*) = 0;
29    virtual void onPop() = 0;
30
31    virtual void onDrawRect(const SkRect&, const SkPaint&, Xform*) = 0;
32};
33
34class Shape : public SkRefCnt {
35    sk_sp<Xform>    fXform;
36
37public:
38    Shape(sk_sp<Xform> x = nullptr) : fXform(std::move(x)) {}
39
40    Xform* xform() const { return fXform.get(); }
41    void setXform(sk_sp<Xform> x) {
42        fXform = std::move(x);
43    }
44
45    virtual void draw(XContext*) {}
46};
47
48class GeoShape : public Shape {
49    SkRect  fRect;
50    SkPaint fPaint;
51
52    GeoShape(sk_sp<Xform> x, const SkRect& r, SkColor c) : Shape(std::move(x)), fRect(r) {
53        fPaint.setColor(c);
54    }
55
56public:
57    static sk_sp<Shape> Make(sk_sp<Xform> x, const SkRect& r, SkColor c) {
58        return sk_sp<Shape>(new GeoShape(std::move(x), r, c));
59    }
60
61    void draw(XContext*) override;
62};
63
64class GroupShape : public Shape {
65    SkTDArray<Shape*> fArray;
66
67    GroupShape(sk_sp<Xform> x) : Shape(std::move(x)) {}
68
69public:
70    static sk_sp<GroupShape> Make(sk_sp<Xform> x = nullptr) {
71        return sk_sp<GroupShape>(new GroupShape(std::move(x)));
72    }
73
74    static sk_sp<GroupShape> Make(sk_sp<Xform> x, sk_sp<Shape> s) {
75        auto g = sk_sp<GroupShape>(new GroupShape(std::move(x)));
76        g->append(std::move(s));
77        return g;
78    }
79
80    ~GroupShape() override {
81        fArray.unrefAll();
82    }
83
84    int count() const { return fArray.count(); }
85    Shape* get(int index) const { return fArray[index]; }
86    void set(int index, sk_sp<Shape> s) {
87        fArray[index] = s.release();
88    }
89
90    void append(sk_sp<Shape> s) {
91        *fArray.append() = s.release();
92    }
93    void insert(int index, sk_sp<Shape> s) {
94        *fArray.insert(index) = s.release();
95    }
96    void remove(int index) {
97        SkSafeUnref(fArray[index]);
98        fArray.remove(index);
99    }
100
101    void draw(XContext*) override ;
102};
103
104#endif
105