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 SkXform_DEFINED
9 #define SkXform_DEFINED
10 
11 #include "include/core/SkClipOp.h"
12 #include "include/core/SkMatrix.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkRRect.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 
18 #include "include/private/SkTDArray.h"
19 
20 class XformResolver {
21 public:
~XformResolver()22     virtual ~XformResolver() {}
23 
24     virtual void concat(const SkMatrix&) = 0;
25     virtual void clipRect(const SkRect&, SkClipOp) = 0;
26     virtual void clipRRect(const SkRRect&, SkClipOp) = 0;
27     virtual void clipPath(const SkPath&, SkClipOp) = 0;
28 };
29 
30 class ClipCache : public SkRefCnt {
31 public:
ClipCache()32     ClipCache() {}
33 };
34 
35 class Xform : public SkRefCnt {
36 public:
37     typedef uint32_t GenID;
38 
parent()39     Xform* parent() const { return fParent.get(); }
40     void setParent(sk_sp<Xform> p);
41 
42     void visit(XformResolver* resolver);
43 
genID()44     GenID genID() const { return fGenID; }
45 
isCached()46     bool isCached() const { return !!fClip; }
47     void invalidateCaches();
48 
ctm()49     const SkMatrix& ctm() const { return fCTM; }
clip()50     ClipCache* clip() const { return fClip.get(); }
51 
52     void setCache(const SkMatrix&, sk_sp<ClipCache>);
53 
54 protected:
55     Xform(sk_sp<Xform> parent = nullptr) {
56         if (parent) {
57             this->setParent(std::move(parent));
58         }
59     }
60 
onVisit(XformResolver *)61     virtual void onVisit(XformResolver*) {}
62 
63 private:
64     sk_sp<Xform> fParent;
65 
66     // unowned bare pointers
67     SkTDArray<Xform*> fChildren;
68 
69     // cache
70     SkMatrix         fCTM;
71     sk_sp<ClipCache> fClip;
72 
73     uint32_t fGenID = 0;
74 
75     static GenID NextGenID();
76 
internalInvalidateCaches()77     void internalInvalidateCaches() { fClip = nullptr; }
78     void internalAddChild(Xform*);
79     void internalRemoveChild(Xform*);
80 
81 #ifdef SK_DEBUG
82     void debugValidate() const;
83 #else
debugValidate()84     void debugValidate() const {}
85 #endif
86 };
87 
88 ///////////////////////////////////////////////////////////////////////////////////////////////
89 
90 class MatrixXF : public Xform {
91 public:
92     static sk_sp<MatrixXF> Make(sk_sp<Xform> parent = nullptr) {
93         return sk_sp<MatrixXF>(new MatrixXF(std::move(parent)));
94     }
95 
MatrixXF(sk_sp<Xform> parent)96     MatrixXF(sk_sp<Xform> parent) : Xform(std::move(parent)) {
97         fLocalMatrix.reset();
98     }
99 
setLocalMatrix(const SkMatrix & m)100     void setLocalMatrix(const SkMatrix& m) {
101         fLocalMatrix = m;
102     }
setTranslate(SkScalar sx,SkScalar sy)103     void setTranslate(SkScalar sx, SkScalar sy) {
104         fLocalMatrix.setTranslate(sx, sy);
105     }
setScale(SkScalar sx,SkScalar sy)106     void setScale(SkScalar sx, SkScalar sy) {
107         fLocalMatrix.setScale(sx, sy);
108     }
setRotate(SkScalar degrees)109     void setRotate(SkScalar degrees) {
110         fLocalMatrix.setRotate(degrees);
111     }
112 
113 protected:
114     void onVisit(XformResolver* resolver) override;
115 
116 private:
117     SkMatrix fLocalMatrix;
118 };
119 
120 class ClipXF : public Xform {
121 public:
Xform(std::move (parent))122     ClipXF(sk_sp<Xform> parent = nullptr) : Xform(std::move(parent)) {}
123     ClipXF(sk_sp<Xform> parent, const SkRect& r, SkClipOp op = SkClipOp::kIntersect)
Xform(std::move (parent))124         : Xform(std::move(parent))
125         , fRect(r)
126         , fOp(op)
127     {}
128 
129     void setRect(const SkRect& r, SkClipOp op = SkClipOp::kIntersect) {
130         fRect = r;
131         fOp = op;
132     }
133 
134 protected:
135     void onVisit(XformResolver* resolver) override;
136 
137 private:
138     SkRect      fRect;
139     SkClipOp    fOp;
140 };
141 
142 #endif
143