Coverage Report

Created: 2021-08-22 09:07

/src/skia/modules/svg/include/SkSVGRenderContext.h
Line
Count
Source (jump to first uncovered line)
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)
29
20.4k
        : fViewport(viewport), fDPI(dpi) {}
30
31
    enum class LengthType {
32
        kHorizontal,
33
        kVertical,
34
        kOther,
35
    };
36
37
25.7k
    const SkSize& viewPort() const { return fViewport; }
38
1.71k
    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
45.2k
    SkSVGPresentationContext(const SkSVGPresentationContext&)            = default;
52
0
    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
76
180k
    const SkSVGLengthContext& lengthContext() const { return *fLengthContext; }
77
1.71k
    SkSVGLengthContext* writableLengthContext() { return fLengthContext.writable(); }
78
79
925k
    const SkSVGPresentationContext& presentationContext() const { return *fPresentationContext; }
80
81
462k
    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:
92
        explicit BorrowedNode(sk_sp<SkSVGNode>* node)
93
11.3k
            : fOwner(node) {
94
11.3k
            if (fOwner) {
95
10.0k
                fBorrowed = std::move(*fOwner);
96
10.0k
                *fOwner = nullptr;
97
10.0k
            }
98
11.3k
        }
99
100
11.3k
        ~BorrowedNode() {
101
11.3k
            if (fOwner) {
102
10.0k
                *fOwner = std::move(fBorrowed);
103
10.0k
            }
104
11.3k
        }
105
106
9.96k
        const SkSVGNode* get() const { return fBorrowed.get(); }
107
10.0k
        const SkSVGNode* operator->() const { return fBorrowed.get(); }
108
0
        const SkSVGNode& operator*() const { return *fBorrowed; }
109
110
11.3k
        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).
131
256k
    const SkPath* clipPath() const { return fClipPath.getMaybeNull(); }
132
133
0
    const sk_sp<skresources::ResourceProvider>& resourceProvider() const {
134
0
        return fResourceProvider;
135
0
    }
136
137
37.1k
    sk_sp<SkFontMgr> fontMgr() const {
138
37.1k
        return fFontMgr ? fFontMgr : SkFontMgr::RefDefault();
139
37.1k
    }
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