/* * Copyright 2019 Google LLC. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkXform_DEFINED #define SkXform_DEFINED #include "include/core/SkClipOp.h" #include "include/core/SkMatrix.h" #include "include/core/SkPath.h" #include "include/core/SkRRect.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/private/SkTDArray.h" class XformResolver { public: virtual ~XformResolver() {} virtual void concat(const SkMatrix&) = 0; virtual void clipRect(const SkRect&, SkClipOp) = 0; virtual void clipRRect(const SkRRect&, SkClipOp) = 0; virtual void clipPath(const SkPath&, SkClipOp) = 0; }; class ClipCache : public SkRefCnt { public: ClipCache() {} }; class Xform : public SkRefCnt { public: typedef uint32_t GenID; Xform* parent() const { return fParent.get(); } void setParent(sk_sp p); void visit(XformResolver* resolver); GenID genID() const { return fGenID; } bool isCached() const { return !!fClip; } void invalidateCaches(); const SkMatrix& ctm() const { return fCTM; } ClipCache* clip() const { return fClip.get(); } void setCache(const SkMatrix&, sk_sp); protected: Xform(sk_sp parent = nullptr) { if (parent) { this->setParent(std::move(parent)); } } virtual void onVisit(XformResolver*) {} private: sk_sp fParent; // unowned bare pointers SkTDArray fChildren; // cache SkMatrix fCTM; sk_sp fClip; uint32_t fGenID = 0; static GenID NextGenID(); void internalInvalidateCaches() { fClip = nullptr; } void internalAddChild(Xform*); void internalRemoveChild(Xform*); #ifdef SK_DEBUG void debugValidate() const; #else void debugValidate() const {} #endif }; /////////////////////////////////////////////////////////////////////////////////////////////// class MatrixXF : public Xform { public: static sk_sp Make(sk_sp parent = nullptr) { return sk_sp(new MatrixXF(std::move(parent))); } MatrixXF(sk_sp parent) : Xform(std::move(parent)) { fLocalMatrix.reset(); } void setLocalMatrix(const SkMatrix& m) { fLocalMatrix = m; } void setTranslate(SkScalar sx, SkScalar sy) { fLocalMatrix.setTranslate(sx, sy); } void setScale(SkScalar sx, SkScalar sy) { fLocalMatrix.setScale(sx, sy); } void setRotate(SkScalar degrees) { fLocalMatrix.setRotate(degrees); } protected: void onVisit(XformResolver* resolver) override; private: SkMatrix fLocalMatrix; }; class ClipXF : public Xform { public: ClipXF(sk_sp parent = nullptr) : Xform(std::move(parent)) {} ClipXF(sk_sp parent, const SkRect& r, SkClipOp op = SkClipOp::kIntersect) : Xform(std::move(parent)) , fRect(r) , fOp(op) {} void setRect(const SkRect& r, SkClipOp op = SkClipOp::kIntersect) { fRect = r; fOp = op; } protected: void onVisit(XformResolver* resolver) override; private: SkRect fRect; SkClipOp fOp; }; #endif