Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 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 | |
Florin Malita | 7006e15 | 2020-11-10 15:24:59 -0500 | [diff] [blame] | 11 | #include "include/core/SkFontMgr.h" |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 12 | #include "include/core/SkPaint.h" |
| 13 | #include "include/core/SkPath.h" |
| 14 | #include "include/core/SkRect.h" |
| 15 | #include "include/core/SkSize.h" |
| 16 | #include "include/core/SkTypes.h" |
| 17 | #include "modules/svg/include/SkSVGAttribute.h" |
| 18 | #include "modules/svg/include/SkSVGIDMapper.h" |
| 19 | #include "src/core/SkTLazy.h" |
| 20 | |
| 21 | class SkCanvas; |
| 22 | class SkSVGLength; |
| 23 | |
| 24 | class SkSVGLengthContext { |
| 25 | public: |
| 26 | SkSVGLengthContext(const SkSize& viewport, SkScalar dpi = 90) |
| 27 | : fViewport(viewport), fDPI(dpi) {} |
| 28 | |
| 29 | enum class LengthType { |
| 30 | kHorizontal, |
| 31 | kVertical, |
| 32 | kOther, |
| 33 | }; |
| 34 | |
| 35 | const SkSize& viewPort() const { return fViewport; } |
| 36 | void setViewPort(const SkSize& viewport) { fViewport = viewport; } |
| 37 | |
| 38 | SkScalar resolve(const SkSVGLength&, LengthType) const; |
| 39 | SkRect resolveRect(const SkSVGLength& x, const SkSVGLength& y, |
| 40 | const SkSVGLength& w, const SkSVGLength& h) const; |
| 41 | |
| 42 | private: |
| 43 | SkSize fViewport; |
| 44 | SkScalar fDPI; |
| 45 | }; |
| 46 | |
| 47 | struct SkSVGPresentationContext { |
| 48 | SkSVGPresentationContext(); |
| 49 | SkSVGPresentationContext(const SkSVGPresentationContext&) = default; |
| 50 | SkSVGPresentationContext& operator=(const SkSVGPresentationContext&) = default; |
| 51 | |
| 52 | // Inherited presentation attributes, computed for the current node. |
| 53 | SkSVGPresentationAttributes fInherited; |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 54 | }; |
| 55 | |
| 56 | class SkSVGRenderContext { |
| 57 | public: |
Florin Malita | 7006e15 | 2020-11-10 15:24:59 -0500 | [diff] [blame] | 58 | SkSVGRenderContext(SkCanvas*, const sk_sp<SkFontMgr>&, const SkSVGIDMapper&, |
| 59 | const SkSVGLengthContext&, const SkSVGPresentationContext&, |
Florin Malita | adc6889 | 2020-12-15 10:52:26 -0500 | [diff] [blame] | 60 | const SkSVGNode*); |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 61 | SkSVGRenderContext(const SkSVGRenderContext&); |
| 62 | SkSVGRenderContext(const SkSVGRenderContext&, SkCanvas*); |
Tyler Denniston | 53281c7 | 2020-10-22 15:54:24 -0400 | [diff] [blame] | 63 | SkSVGRenderContext(const SkSVGRenderContext&, const SkSVGNode*); |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 64 | ~SkSVGRenderContext(); |
| 65 | |
| 66 | const SkSVGLengthContext& lengthContext() const { return *fLengthContext; } |
| 67 | SkSVGLengthContext* writableLengthContext() { return fLengthContext.writable(); } |
| 68 | |
| 69 | const SkSVGPresentationContext& presentationContext() const { return *fPresentationContext; } |
| 70 | |
| 71 | SkCanvas* canvas() const { return fCanvas; } |
| 72 | void saveOnce(); |
| 73 | |
| 74 | enum ApplyFlags { |
| 75 | kLeaf = 1 << 0, // the target node doesn't have descendants |
| 76 | }; |
| 77 | void applyPresentationAttributes(const SkSVGPresentationAttributes&, uint32_t flags); |
| 78 | |
| 79 | // Scoped wrapper that temporarily clears the original node reference. |
| 80 | class BorrowedNode { |
| 81 | public: |
| 82 | explicit BorrowedNode(sk_sp<SkSVGNode>* node) |
| 83 | : fOwner(node) { |
| 84 | if (fOwner) { |
| 85 | fBorrowed = std::move(*fOwner); |
| 86 | *fOwner = nullptr; |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | ~BorrowedNode() { |
| 91 | if (fOwner) { |
| 92 | *fOwner = std::move(fBorrowed); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | const SkSVGNode* get() const { return fBorrowed.get(); } |
| 97 | const SkSVGNode* operator->() const { return fBorrowed.get(); } |
| 98 | const SkSVGNode& operator*() const { return *fBorrowed; } |
| 99 | |
| 100 | operator bool() const { return !!fBorrowed; } |
| 101 | |
| 102 | private: |
| 103 | // noncopyable |
| 104 | BorrowedNode(const BorrowedNode&) = delete; |
| 105 | BorrowedNode& operator=(BorrowedNode&) = delete; |
| 106 | |
| 107 | sk_sp<SkSVGNode>* fOwner; |
| 108 | sk_sp<SkSVGNode> fBorrowed; |
| 109 | }; |
| 110 | |
| 111 | // Note: the id->node association is cleared for the lifetime of the returned value |
| 112 | // (effectively breaks reference cycles, assuming appropriate return value scoping). |
| 113 | BorrowedNode findNodeById(const SkString&) const; |
| 114 | |
Florin Malita | bde06cc | 2021-01-19 10:12:37 -0500 | [diff] [blame^] | 115 | SkTLazy<SkPaint> fillPaint() const; |
| 116 | SkTLazy<SkPaint> strokePaint() const; |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 117 | |
Tyler Denniston | b2d1a3b | 2020-12-11 10:31:07 -0500 | [diff] [blame] | 118 | SkSVGColorType resolveSvgColor(const SkSVGColor&) const; |
| 119 | |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 120 | // The local computed clip path (not inherited). |
| 121 | const SkPath* clipPath() const { return fClipPath.getMaybeNull(); } |
| 122 | |
Tyler Denniston | 53281c7 | 2020-10-22 15:54:24 -0400 | [diff] [blame] | 123 | // The node being rendered (may be null). |
| 124 | const SkSVGNode* node() const { return fNode; } |
| 125 | |
Florin Malita | 7006e15 | 2020-11-10 15:24:59 -0500 | [diff] [blame] | 126 | sk_sp<SkFontMgr> fontMgr() const { |
| 127 | return fFontMgr ? fFontMgr : SkFontMgr::RefDefault(); |
| 128 | } |
| 129 | |
Florin Malita | 4919110 | 2021-01-14 11:58:09 -0500 | [diff] [blame] | 130 | SkRect resolveOBBRect(const SkSVGLength& x, const SkSVGLength& y, |
| 131 | const SkSVGLength& w, const SkSVGLength& h, |
| 132 | SkSVGObjectBoundingBoxUnits) const; |
| 133 | |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 134 | private: |
| 135 | // Stack-only |
| 136 | void* operator new(size_t) = delete; |
| 137 | void* operator new(size_t, void*) = delete; |
| 138 | SkSVGRenderContext& operator=(const SkSVGRenderContext&) = delete; |
| 139 | |
Tyler Denniston | a22d21e | 2021-01-15 12:12:35 -0500 | [diff] [blame] | 140 | void applyOpacity(SkScalar opacity, uint32_t flags, bool hasFilter); |
Florin Malita | 836c2ca | 2021-01-13 11:48:02 -0500 | [diff] [blame] | 141 | void applyFilter(const SkSVGFuncIRI&); |
| 142 | void applyClip(const SkSVGFuncIRI&); |
Florin Malita | 4919110 | 2021-01-14 11:58:09 -0500 | [diff] [blame] | 143 | void applyMask(const SkSVGFuncIRI&); |
Florin Malita | bde06cc | 2021-01-19 10:12:37 -0500 | [diff] [blame^] | 144 | |
| 145 | SkTLazy<SkPaint> commonPaint(const SkSVGPaint&, float opacity) const; |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 146 | |
Florin Malita | 7006e15 | 2020-11-10 15:24:59 -0500 | [diff] [blame] | 147 | const sk_sp<SkFontMgr>& fFontMgr; |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 148 | const SkSVGIDMapper& fIDMapper; |
| 149 | SkTCopyOnFirstWrite<SkSVGLengthContext> fLengthContext; |
| 150 | SkTCopyOnFirstWrite<SkSVGPresentationContext> fPresentationContext; |
| 151 | SkCanvas* fCanvas; |
| 152 | // The save count on 'fCanvas' at construction time. |
| 153 | // A restoreToCount() will be issued on destruction. |
| 154 | int fCanvasSaveCount; |
| 155 | |
| 156 | // clipPath, if present for the current context (not inherited). |
| 157 | SkTLazy<SkPath> fClipPath; |
Tyler Denniston | 53281c7 | 2020-10-22 15:54:24 -0400 | [diff] [blame] | 158 | |
Florin Malita | bde06cc | 2021-01-19 10:12:37 -0500 | [diff] [blame^] | 159 | // Deferred opacity optimization for leaf nodes. |
| 160 | float fDeferredPaintOpacity = 1; |
| 161 | |
Tyler Denniston | 53281c7 | 2020-10-22 15:54:24 -0400 | [diff] [blame] | 162 | const SkSVGNode* fNode; |
Florin Malita | b341810 | 2020-10-15 18:10:29 -0400 | [diff] [blame] | 163 | }; |
| 164 | |
| 165 | #endif // SkSVGRenderContext_DEFINED |