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