Skia
2D Graphics Library
SkSVGRenderContext.h
Go to the documentation of this file.
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"
21 #include "src/base/SkTLazy.h"
22 #include "src/core/SkTHash.h"
23 
24 class SkCanvas;
25 class SkSVGLength;
26 
27 class SK_API SkSVGLengthContext {
28 public:
29  SkSVGLengthContext(const SkSize& viewport, SkScalar dpi = 90)
30  : fViewport(viewport), fDPI(dpi) {}
31 
32  enum class LengthType {
33  kHorizontal,
34  kVertical,
35  kOther,
36  };
37 
38  const SkSize& viewPort() const { return fViewport; }
39  void setViewPort(const SkSize& viewport) { fViewport = viewport; }
40 
43  const SkSVGLength& w, const SkSVGLength& h) const;
44 
45 private:
46  SkSize fViewport;
47  SkScalar fDPI;
48 };
49 
50 struct SK_API SkSVGPresentationContext {
54 
55  const skia_private::THashMap<SkString, SkSVGColorType>* fNamedColors = nullptr;
56 
57  // Inherited presentation attributes, computed for the current node.
59 };
60 
61 class SK_API SkSVGRenderContext {
62 public:
63  // Captures data required for object bounding box resolution.
64  struct OBBScope {
65  const SkSVGNode* fNode;
67  };
68 
72  const OBBScope&);
75  // Establish a new OBB scope. Normally used when entering a node's render scope.
78 
79  const SkSVGLengthContext& lengthContext() const { return *fLengthContext; }
80  SkSVGLengthContext* writableLengthContext() { return fLengthContext.writable(); }
81 
82  const SkSVGPresentationContext& presentationContext() const { return *fPresentationContext; }
83 
84  SkCanvas* canvas() const { return fCanvas; }
85  void saveOnce();
86 
87  enum ApplyFlags {
88  kLeaf = 1 << 0, // the target node doesn't have descendants
89  };
91 
92  // Scoped wrapper that temporarily clears the original node reference.
93  class BorrowedNode {
94  public:
96  : fOwner(node) {
97  if (fOwner) {
98  fBorrowed = std::move(*fOwner);
99  *fOwner = nullptr;
100  }
101  }
102 
104  if (fOwner) {
105  *fOwner = std::move(fBorrowed);
106  }
107  }
108 
109  const SkSVGNode* get() const { return fBorrowed.get(); }
110  const SkSVGNode* operator->() const { return fBorrowed.get(); }
111  const SkSVGNode& operator*() const { return *fBorrowed; }
112 
113  explicit operator bool() const { return !!fBorrowed; }
114 
115  private:
116  // noncopyable
117  BorrowedNode(const BorrowedNode&) = delete;
118  BorrowedNode& operator=(BorrowedNode&) = delete;
119 
120  sk_sp<SkSVGNode>* fOwner;
121  sk_sp<SkSVGNode> fBorrowed;
122  };
123 
124  // Note: the id->node association is cleared for the lifetime of the returned value
125  // (effectively breaks reference cycles, assuming appropriate return value scoping).
127 
128  SkTLazy<SkPaint> fillPaint() const;
129  SkTLazy<SkPaint> strokePaint() const;
130 
132 
133  // The local computed clip path (not inherited).
134  const SkPath* clipPath() const { return fClipPath.getMaybeNull(); }
135 
137  return fResourceProvider;
138  }
139 
141  // It is probably an oversight to try to render <text> without having set the SkFontMgr.
142  // We will assert this in debug mode, but fallback to an empty fontmgr in release builds.
143  SkASSERT(fFontMgr);
144  return fFontMgr ? fFontMgr : SkFontMgr::RefEmpty();
145  }
146 
147  // Returns the translate/scale transformation required to map into the current OBB scope,
148  // with the specified units.
149  struct OBBTransform {
150  SkV2 offset, scale;
151  };
153 
155  const SkSVGLength& w, const SkSVGLength& h,
157 
158 private:
159  // Stack-only
160  void* operator new(size_t) = delete;
161  void* operator new(size_t, void*) = delete;
162  SkSVGRenderContext& operator=(const SkSVGRenderContext&) = delete;
163 
164  void applyOpacity(SkScalar opacity, uint32_t flags, bool hasFilter);
165  void applyFilter(const SkSVGFuncIRI&);
166  void applyClip(const SkSVGFuncIRI&);
167  void applyMask(const SkSVGFuncIRI&);
168 
169  SkTLazy<SkPaint> commonPaint(const SkSVGPaint&, float opacity) const;
170 
171  const sk_sp<SkFontMgr>& fFontMgr;
172  const sk_sp<skresources::ResourceProvider>& fResourceProvider;
173  const SkSVGIDMapper& fIDMapper;
174  SkTCopyOnFirstWrite<SkSVGLengthContext> fLengthContext;
175  SkTCopyOnFirstWrite<SkSVGPresentationContext> fPresentationContext;
176  SkCanvas* fCanvas;
177  // The save count on 'fCanvas' at construction time.
178  // A restoreToCount() will be issued on destruction.
179  int fCanvasSaveCount;
180 
181  // clipPath, if present for the current context (not inherited).
182  SkTLazy<SkPath> fClipPath;
183 
184  // Deferred opacity optimization for leaf nodes.
185  float fDeferredPaintOpacity = 1;
186 
187  // Current object bounding box scope.
188  const OBBScope fOBBScope;
189 };
190 
191 #endif // SkSVGRenderContext_DEFINED
skia_private::THashMap< SkString, sk_sp< SkSVGNode > > SkSVGIDMapper
Definition: SkSVGIDMapper.h:17
SkColor SkSVGColorType
Definition: SkSVGTypes.h:25
float SkScalar
Definition: SkScalar.h:14
SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
Definition: SkCanvas.h:99
static sk_sp< SkFontMgr > RefEmpty()
SkPath contain geometry.
Definition: SkPath.h:58
Definition: SkSVGTypes.h:177
Definition: SkSVGTypes.h:264
Definition: SkSVGTypes.h:152
Definition: SkSVGRenderContext.h:27
const SkSize & viewPort() const
Definition: SkSVGRenderContext.h:38
LengthType
Definition: SkSVGRenderContext.h:32
void setViewPort(const SkSize &viewport)
Definition: SkSVGRenderContext.h:39
SkRect resolveRect(const SkSVGLength &x, const SkSVGLength &y, const SkSVGLength &w, const SkSVGLength &h) const
SkScalar resolve(const SkSVGLength &, LengthType) const
SkSVGLengthContext(const SkSize &viewport, SkScalar dpi=90)
Definition: SkSVGRenderContext.h:29
Definition: SkSVGTypes.h:116
Definition: SkSVGNode.h:95
Definition: SkSVGTypes.h:454
Definition: SkSVGTypes.h:224
Definition: SkSVGRenderContext.h:93
~BorrowedNode()
Definition: SkSVGRenderContext.h:103
BorrowedNode(sk_sp< SkSVGNode > *node)
Definition: SkSVGRenderContext.h:95
const SkSVGNode * get() const
Definition: SkSVGRenderContext.h:109
const SkSVGNode & operator*() const
Definition: SkSVGRenderContext.h:111
const SkSVGNode * operator->() const
Definition: SkSVGRenderContext.h:110
Definition: SkSVGRenderContext.h:61
SkSVGColorType resolveSvgColor(const SkSVGColor &) const
const sk_sp< skresources::ResourceProvider > & resourceProvider() const
Definition: SkSVGRenderContext.h:136
SkRect resolveOBBRect(const SkSVGLength &x, const SkSVGLength &y, const SkSVGLength &w, const SkSVGLength &h, SkSVGObjectBoundingBoxUnits) const
sk_sp< SkFontMgr > fontMgr() const
Definition: SkSVGRenderContext.h:140
ApplyFlags
Definition: SkSVGRenderContext.h:87
SkSVGRenderContext(SkCanvas *, const sk_sp< SkFontMgr > &, const sk_sp< skresources::ResourceProvider > &, const SkSVGIDMapper &, const SkSVGLengthContext &, const SkSVGPresentationContext &, const OBBScope &)
const SkPath * clipPath() const
Definition: SkSVGRenderContext.h:134
const SkSVGPresentationContext & presentationContext() const
Definition: SkSVGRenderContext.h:82
SkSVGRenderContext(const SkSVGRenderContext &, SkCanvas *)
SkTLazy< SkPaint > strokePaint() const
BorrowedNode findNodeById(const SkSVGIRI &) const
void applyPresentationAttributes(const SkSVGPresentationAttributes &, uint32_t flags)
SkTLazy< SkPaint > fillPaint() const
SkSVGRenderContext(const SkSVGRenderContext &, const SkSVGNode *)
SkCanvas * canvas() const
Definition: SkSVGRenderContext.h:84
SkSVGRenderContext(const SkSVGRenderContext &)
const SkSVGLengthContext & lengthContext() const
Definition: SkSVGRenderContext.h:79
OBBTransform transformForCurrentOBB(SkSVGObjectBoundingBoxUnits) const
SkSVGLengthContext * writableLengthContext()
Definition: SkSVGRenderContext.h:80
SkRect holds four float coordinates describing the upper and lower bounds of a rectangle.
Definition: SkRect.h:582
Definition: SkSVGAttribute.h:69
Definition: SkSVGRenderContext.h:50
SkSVGPresentationAttributes fInherited
Definition: SkSVGRenderContext.h:58
SkSVGPresentationContext & operator=(const SkSVGPresentationContext &)=default
SkSVGPresentationContext(const SkSVGPresentationContext &)=default
Definition: SkSVGRenderContext.h:64
const SkSVGRenderContext * fCtx
Definition: SkSVGRenderContext.h:66
const SkSVGNode * fNode
Definition: SkSVGRenderContext.h:65
Definition: SkSVGRenderContext.h:149
SkV2 offset
Definition: SkSVGRenderContext.h:150
Definition: SkSize.h:51
Definition: SkM44.h:19