1 /* 2 * Copyright 2016 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 #ifndef SkSVGRenderContext_DEFINED 9 #define SkSVGRenderContext_DEFINED 10 11 #include "include/core/SkFontMgr.h" 12 #include "include/core/SkM44.h" 13 #include "include/core/SkPaint.h" 14 #include "include/core/SkPath.h" 15 #include "include/core/SkRect.h" 16 #include "include/core/SkSize.h" 17 #include "include/core/SkTypes.h" 18 #include "modules/skresources/include/SkResources.h" 19 #include "modules/svg/include/SkSVGAttribute.h" 20 #include "modules/svg/include/SkSVGIDMapper.h" 21 #include "src/core/SkTLazy.h" 22 23 static constexpr uint32_t DEFAULT_RESIZE_PERCENTAGE = 100; 24 class SkCanvas; 25 class SkSVGLength; 26 27 class SkSVGLengthContext { 28 public: 29 SkSVGLengthContext(const SkSize& viewport, uint32_t resizePercentage = DEFAULT_RESIZE_PERCENTAGE, SkScalar dpi = 90) fViewport(viewport)30 : fViewport(viewport), fResizePercentage(resizePercentage), fDPI(dpi) {} 31 32 enum class LengthType { 33 kHorizontal, 34 kVertical, 35 kOther, 36 }; 37 viewPort()38 const SkSize& viewPort() const { return fViewport; } setViewPort(const SkSize & viewport)39 void setViewPort(const SkSize& viewport) { fViewport = viewport; } 40 41 SkScalar resolve(const SkSVGLength&, LengthType) const; 42 SkRect resolveRect(const SkSVGLength& x, const SkSVGLength& y, 43 const SkSVGLength& w, const SkSVGLength& h) const; 44 45 private: 46 SkSize fViewport; 47 uint32_t fResizePercentage; 48 SkScalar fDPI; 49 }; 50 51 struct SkSVGPresentationContext { 52 SkSVGPresentationContext(); 53 SkSVGPresentationContext(const SkSVGPresentationContext&) = default; 54 SkSVGPresentationContext& operator=(const SkSVGPresentationContext&) = default; 55 56 // Inherited presentation attributes, computed for the current node. 57 SkSVGPresentationAttributes fInherited; 58 }; 59 60 class SkSVGRenderContext { 61 public: 62 // Captures data required for object bounding box resolution. 63 struct OBBScope { 64 const SkSVGNode* fNode; 65 const SkSVGRenderContext* fCtx; 66 }; 67 68 SkSVGRenderContext(SkCanvas*, const sk_sp<SkFontMgr>&, 69 const sk_sp<skresources::ResourceProvider>&, const SkSVGIDMapper&, 70 const SkSVGLengthContext&, const SkSVGPresentationContext&, 71 const OBBScope&); 72 SkSVGRenderContext(const SkSVGRenderContext&); 73 SkSVGRenderContext(const SkSVGRenderContext&, SkCanvas*); 74 // Establish a new OBB scope. Normally used when entering a node's render scope. 75 SkSVGRenderContext(const SkSVGRenderContext&, const SkSVGNode*); 76 ~SkSVGRenderContext(); 77 lengthContext()78 const SkSVGLengthContext& lengthContext() const { return *fLengthContext; } writableLengthContext()79 SkSVGLengthContext* writableLengthContext() { return fLengthContext.writable(); } 80 presentationContext()81 const SkSVGPresentationContext& presentationContext() const { return *fPresentationContext; } 82 canvas()83 SkCanvas* canvas() const { return fCanvas; } 84 void saveOnce(); 85 86 enum ApplyFlags { 87 kLeaf = 1 << 0, // the target node doesn't have descendants 88 }; 89 void applyPresentationAttributes(const SkSVGPresentationAttributes&, uint32_t flags); 90 91 // Scoped wrapper that temporarily clears the original node reference. 92 class BorrowedNode { 93 public: BorrowedNode(sk_sp<SkSVGNode> * node)94 explicit BorrowedNode(sk_sp<SkSVGNode>* node) 95 : fOwner(node) { 96 if (fOwner) { 97 fBorrowed = std::move(*fOwner); 98 *fOwner = nullptr; 99 } 100 } 101 102 // Required until C++17 copy elision 103 BorrowedNode(BorrowedNode&&) = default; 104 ~BorrowedNode()105 ~BorrowedNode() { 106 if (fOwner) { 107 *fOwner = std::move(fBorrowed); 108 } 109 } 110 get()111 const SkSVGNode* get() const { return fBorrowed.get(); } 112 const SkSVGNode* operator->() const { return fBorrowed.get(); } 113 const SkSVGNode& operator*() const { return *fBorrowed; } 114 115 operator bool() const { return !!fBorrowed; } 116 117 private: 118 // noncopyable 119 BorrowedNode(const BorrowedNode&) = delete; 120 BorrowedNode& operator=(BorrowedNode&) = delete; 121 122 sk_sp<SkSVGNode>* fOwner; 123 sk_sp<SkSVGNode> fBorrowed; 124 }; 125 126 // Note: the id->node association is cleared for the lifetime of the returned value 127 // (effectively breaks reference cycles, assuming appropriate return value scoping). 128 BorrowedNode findNodeById(const SkSVGIRI&) const; 129 130 SkTLazy<SkPaint> fillPaint() const; 131 SkTLazy<SkPaint> strokePaint() const; 132 133 SkSVGColorType resolveSvgColor(const SkSVGColor&) const; 134 135 // The local computed clip path (not inherited). clipPath()136 const SkPath* clipPath() const { return fClipPath.getMaybeNull(); } 137 resourceProvider()138 const sk_sp<skresources::ResourceProvider>& resourceProvider() const { 139 return fResourceProvider; 140 } 141 fontMgr()142 sk_sp<SkFontMgr> fontMgr() const { 143 return fFontMgr ? fFontMgr : SkFontMgr::RefDefault(); 144 } 145 146 // Returns the translate/scale transformation required to map into the current OBB scope, 147 // with the specified units. 148 struct OBBTransform { 149 SkV2 offset, scale; 150 }; 151 OBBTransform transformForCurrentOBB(SkSVGObjectBoundingBoxUnits) const; 152 153 SkRect resolveOBBRect(const SkSVGLength& x, const SkSVGLength& y, 154 const SkSVGLength& w, const SkSVGLength& h, 155 SkSVGObjectBoundingBoxUnits) const; 156 157 private: 158 // Stack-only 159 void* operator new(size_t) = delete; 160 void* operator new(size_t, void*) = delete; 161 SkSVGRenderContext& operator=(const SkSVGRenderContext&) = delete; 162 163 void applyOpacity(SkScalar opacity, uint32_t flags, bool hasFilter); 164 void applyFilter(const SkSVGFuncIRI&); 165 void applyClip(const SkSVGFuncIRI&); 166 void applyMask(const SkSVGFuncIRI&); 167 168 SkTLazy<SkPaint> commonPaint(const SkSVGPaint&, float opacity) const; 169 170 const sk_sp<SkFontMgr>& fFontMgr; 171 const sk_sp<skresources::ResourceProvider>& fResourceProvider; 172 const SkSVGIDMapper& fIDMapper; 173 SkTCopyOnFirstWrite<SkSVGLengthContext> fLengthContext; 174 SkTCopyOnFirstWrite<SkSVGPresentationContext> fPresentationContext; 175 SkCanvas* fCanvas; 176 // The save count on 'fCanvas' at construction time. 177 // A restoreToCount() will be issued on destruction. 178 int fCanvasSaveCount; 179 180 // clipPath, if present for the current context (not inherited). 181 SkTLazy<SkPath> fClipPath; 182 183 // Deferred opacity optimization for leaf nodes. 184 float fDeferredPaintOpacity = 1; 185 186 // Current object bounding box scope. 187 const OBBScope fOBBScope; 188 }; 189 190 #endif // SkSVGRenderContext_DEFINED 191