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