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