Line data Source code
1 : /**
2 : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_VG_SPVECTORIMAGE_H_
25 : #define STAPPLER_VG_SPVECTORIMAGE_H_
26 :
27 : #include "SPVectorPath.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::vg {
30 :
31 : class VectorImage;
32 :
33 : class VectorPathRef : public RefBase<Interface> {
34 : public:
35 : using String = Interface::StringType;
36 :
37 1093406 : virtual ~VectorPathRef() { }
38 :
39 : bool init(VectorImage *, const String &, const Rc<VectorPath> &);
40 : bool init(VectorImage *, const String &, Rc<VectorPath> &&);
41 :
42 : size_t count() const;
43 :
44 : VectorPathRef & setPath(BytesView);
45 : VectorPathRef & setPath(StringView);
46 :
47 : VectorPathRef & openForWriting(const Callback<void(PathWriter &)> &);
48 :
49 : VectorPathRef & setFillColor(const Color4B &color);
50 : const Color4B &getFillColor() const;
51 :
52 : VectorPathRef & setStrokeColor(const Color4B &color);
53 : const Color4B &getStrokeColor() const;
54 :
55 : VectorPathRef & setFillOpacity(uint8_t value);
56 : uint8_t getFillOpacity() const;
57 :
58 : VectorPathRef & setStrokeOpacity(uint8_t value);
59 : uint8_t getStrokeOpacity() const;
60 :
61 : VectorPathRef & setStrokeWidth(float width);
62 : float getStrokeWidth() const;
63 :
64 : VectorPathRef &setWindingRule(vg::Winding);
65 : vg::Winding getWindingRule() const;
66 :
67 : VectorPathRef & setStyle(vg::DrawStyle s);
68 : vg::DrawStyle getStyle() const;
69 :
70 : VectorPathRef & setTransform(const Mat4 &);
71 : VectorPathRef & applyTransform(const Mat4 &);
72 : const Mat4 &getTransform() const;
73 :
74 : VectorPathRef & setAntialiased(bool value);
75 : bool isAntialiased() const;
76 :
77 : VectorPathRef & clear();
78 :
79 : StringView getId() const;
80 :
81 : bool empty() const;
82 : bool valid() const;
83 :
84 : explicit operator bool() const;
85 :
86 : void setPath(Rc<VectorPath> &&);
87 : VectorPath *getPath() const;
88 :
89 : void markCopyOnWrite();
90 : void setImage(VectorImage *);
91 :
92 : protected:
93 : void copy();
94 :
95 : bool _copyOnWrite = false;
96 : String _id;
97 : Rc<VectorPath> _path;
98 : VectorImage *_image;
99 : };
100 :
101 : class VectorImageData : public RefBase<Interface> {
102 : public:
103 : using String = Interface::StringType;
104 :
105 1097512 : virtual ~VectorImageData() { }
106 :
107 : bool init(VectorImage *, Size2 size, Rect viewBox, Interface::VectorType<PathXRef> &&,
108 : Interface::MapType<String, VectorPath> &&, uint16_t ids);
109 : bool init(VectorImage *, Size2 size, Rect viewBox);
110 : bool init(VectorImageData &);
111 :
112 : void setImageSize(const Size2 &);
113 611723 : Size2 getImageSize() const { return _imageSize; }
114 :
115 25 : Rect getViewBox() const { return _viewBox; }
116 : const Interface::MapType<String, Rc<VectorPath>> &getPaths() const;
117 :
118 : Rc<VectorPath> copyPath(StringView);
119 :
120 : uint16_t getNextId();
121 :
122 : Rc<VectorPath> addPath(StringView id, StringView cacheId, VectorPath &&, Mat4 mat = Mat4::IDENTITY);
123 : void removePath(StringView);
124 :
125 : void clear();
126 :
127 25 : const Interface::VectorType<PathXRef> &getDrawOrder() const { return _order; }
128 50 : void setDrawOrder(Interface::VectorType<PathXRef> &&order) { _order = move(order); }
129 : void resetDrawOrder();
130 :
131 100 : void setViewBoxTransform(const Mat4 &m) { _viewBoxTransform = m; }
132 482993 : const Mat4 &getViewBoxTransform() const { return _viewBoxTransform; }
133 :
134 25 : void setBatchDrawing(bool value) { _allowBatchDrawing = value; }
135 75 : bool isBatchDrawing() const { return _allowBatchDrawing; }
136 :
137 : template <typename Callback>
138 : void draw(const Callback &) const;
139 :
140 : protected:
141 : bool _allowBatchDrawing = true;
142 : Size2 _imageSize;
143 : Rect _viewBox;
144 : Mat4 _viewBoxTransform = Mat4::IDENTITY;
145 : Interface::VectorType<PathXRef> _order;
146 : Interface::MapType<String, Rc<VectorPath>> _paths;
147 : uint16_t _nextId = 0;
148 : VectorImage *_image = nullptr;
149 : };
150 :
151 : class VectorImage : public RefBase<Interface> {
152 : public:
153 : using String = Interface::StringType;
154 :
155 : #if MODULE_STAPPLER_BITMAP
156 : static bool isSvg(StringView);
157 : static bool isSvg(BytesView);
158 :
159 : #if MODULE_STAPPLER_FILESYSTEM
160 : static bool isSvg(FilePath);
161 : #endif
162 : #endif // MODULE_STAPPLER_BITMAP
163 :
164 : virtual ~VectorImage();
165 :
166 : bool init(Size2, StringView);
167 : bool init(Size2, VectorPath &&);
168 : bool init(Size2);
169 : bool init(StringView);
170 : bool init(BytesView);
171 :
172 : #if MODULE_STAPPLER_FILESYSTEM
173 : bool init(FilePath);
174 : #endif
175 :
176 : void setImageSize(const Size2 &);
177 : Size2 getImageSize() const;
178 :
179 : Rect getViewBox() const;
180 :
181 : Rc<VectorPathRef> addPath(const VectorPath &, StringView id = StringView(), StringView cache = StringView(), Mat4 = Mat4::IDENTITY);
182 : Rc<VectorPathRef> addPath(VectorPath &&, StringView id = StringView(), StringView cache = StringView(), Mat4 = Mat4::IDENTITY);
183 : Rc<VectorPathRef> addPath(StringView id = StringView(), StringView cache = StringView(), Mat4 = Mat4::IDENTITY);
184 :
185 : Rc<VectorPathRef> getPath(StringView) const;
186 556448 : const Interface::MapType<String, Rc<VectorPathRef>> &getPaths() const { return _paths; }
187 :
188 : void removePath(const Rc<VectorPathRef> &);
189 : void removePath(StringView);
190 :
191 : void clear();
192 :
193 : const Interface::VectorType<PathXRef> &getDrawOrder() const;
194 : void setDrawOrder(const Interface::VectorType<PathXRef> &);
195 : void setDrawOrder(Interface::VectorType<PathXRef> &&);
196 :
197 : void resetDrawOrder();
198 :
199 : void setViewBoxTransform(const Mat4 &);
200 : const Mat4 &getViewBoxTransform() const;
201 :
202 : void setBatchDrawing(bool value);
203 : bool isBatchDrawing() const;
204 :
205 : Rc<VectorImageData> popData();
206 :
207 : bool isDirty() const;
208 : void setDirty();
209 : void clearDirty();
210 :
211 : protected:
212 : friend class VectorPathRef;
213 :
214 : void copy();
215 : void markCopyOnWrite();
216 :
217 : Rc<VectorPath> copyPath(StringView);
218 :
219 : bool _dirty = false;
220 : bool _copyOnWrite = false;
221 : Rc<VectorImageData> _data;
222 : Interface::MapType<String, Rc<VectorPathRef>> _paths;
223 : };
224 :
225 : template <typename Callback>
226 192029 : void VectorImageData::draw(const Callback &cb) const {
227 192029 : if (!_order.empty()) {
228 384000 : for (auto &it : _order) {
229 192115 : auto pathIt = _paths.find(it.id);
230 192073 : if (pathIt != _paths.end()) {
231 192079 : cb(*pathIt->second, it.cacheId, it.mat);
232 : }
233 : }
234 : } else {
235 96 : for (auto &it : _paths) {
236 0 : cb(*it.second, StringView(), Mat4());
237 : }
238 : }
239 191996 : }
240 :
241 : }
242 :
243 : #endif /* STAPPLER_VG_SPVECTORIMAGE_H_ */
|