Loading...
Searching...
No Matches
TreeElemUtilsSVG.h
1/*
2
3MIT License
4
5Copyright (c) 2023 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31/*
32 * TreeSVG.h
33 *
34 * Created on: 2025
35 * Author: mpeura
36 */
37
38#ifndef DRAIN_TREE_ELEM_UTILS_SVG
39#define DRAIN_TREE_ELEM_UTILS_SVG
40
41
42#include <drain/util/TreeXML.h>
43
44#include "TreeSVG.h"
45
46//namespace drain {
47
48#define DRAIN_SVG_ELEM_CLS(E) drain::NodeXML<drain::image::svg::tag_t>::Elem<drain::image::svg::tag_t::E>
49#define DRAIN_SVG_ELEM(E) typedef drain::NodeXML<drain::image::svg::tag_t>::Elem<drain::image::svg::tag_t::E> svg##E;
50
51//#define DRAIN_SVG_SUPER(E) class drain::NodeXML<drain::image::svg::tag_t>::Elem<drain::image::svg::tag_t::E>; typedef drain::NodeXML<drain::image::svg::tag_t>::Elem<drain::image::svg::tag_t::E> svg##E;
52
53
54namespace drain {
55
56
57
58template <> template <>
59class DRAIN_SVG_ELEM_CLS(RECT){
60public:
61
62 inline
63 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::RECT), x(node["x"]), y(node["y"]), width(node["width"]), height(node["height"]){
64 };
65
66 NodeXML<image::svg::tag_t> & node;
67
70 FlexibleVariable & width;
71 FlexibleVariable & height;
72};
73DRAIN_SVG_ELEM(RECT)
74
75
76
77template <>
78template <>
79class DRAIN_SVG_ELEM_CLS(CIRCLE){
80
81public:
82
83 NodeXML<image::svg::tag_t> & node;
84
85 inline
86 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::CIRCLE), cx(node["cx"]), cy(node["cy"]), r(node["r"] = 0.0){
87 };
88
89 // Center point, x coord
91 // Center point, y coord
93 // Radius
95
96 // NodeXML<T> class could not access NodeSVG.box
97 // Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::CIRCLE), cx(node.box.x), cy(node.box.y), r(node["r"]){
98
99};
100DRAIN_SVG_ELEM(CIRCLE)
101
102
103
104template <>
105template <>
106class DRAIN_SVG_ELEM_CLS(POLYGON){
107
108public:
109
110 inline
111 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::POLYGON), points(node["points"]), writablePoints(node["points"]){
112 };
113
114 NodeXML<image::svg::tag_t> & node;
115
116 const FlexibleVariable & points;
117
118protected:
119
120 FlexibleVariable & writablePoints;
121
122public:
123
124 void clear(){
125 writablePoints.clear();
126 }
127
128 template <typename T>
129 inline
130 void append(const T &x, const T &y){
131 writablePoints << x << ',' << y << ' ';
132 }
133
134 template <typename T>
135 inline
136 void append(drain::Point2D<T> &p){
137 writablePoints << p.x << ',' << p.y << ' ';
138 }
139
140};
141DRAIN_SVG_ELEM(POLYGON)
142
143
144
145template <>
146template <>
147class DRAIN_SVG_ELEM_CLS(PATH){
148public:
149
150 inline
151 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::PATH), d(node["d"]) {
152 };
153
154 inline
155 ~Elem(){
156 flush();
157 }
158
159 bool noReset = true;
160
161 NodeXML<image::svg::tag_t> & node;
162
163 // Path description, "d" attribute.
164 const FlexibleVariable & d;
165
166 enum Command {
167 MOVE = 'M',
168 LINE = 'L',
169 // Cubic Bezier curves
170 CURVE_C = 'C',
171 CURVE_C_SHORT = 'S',
172 // Quadratic Bezier curves
173 CURVE_Q = 'Q',
174 CURVE_Q_SHORT = 'T',
175 CLOSE = 'Z',
176 };
177
178 enum Coord {
179 ABSOLUTE = 0,
180 RELATIVE = 32, // upper case 'm' -> 'M'
181 };
182
183public:
184
185 template <Command C, typename ...T>
186 void relative(const T... args){
187 appendCmd<C,RELATIVE>();
188 appendArgs<C>(args...);
189 }
190
191 template <Command C, typename ...T>
192 void absolute(const T... args){
193 appendCmd<C,ABSOLUTE>();
194 appendArgs<C>(args...);
195 }
196
197
198 void clear(){
199 sstr.str("");
200 node["d"].clear();
201 }
202
203protected:
204
205 mutable
206 std::stringstream sstr;
207
208 // Could be protected
209 void flush(){
210 // Logger mout(__FILE__, __FUNCTION__);
211 if (noReset){
212 node["d"].append(sstr.str());
213 // mout.warn("appended contents_: ", d);
214 }
215 else {
216 node["d"] = sstr.str();
217 // mout.warn("NEW contents_: ", d);
218 }
219 sstr.str(""); // Destructor would do this anyway
220 }
221
222 template <Command C, Coord R=RELATIVE>
223 inline
224 void appendCmd(){
225 sstr << char(int(C) + int(R)) << ' ';
226 }
227
228 template <Command C>
229 void appendArgs();
230
231 template <Command C>
232 void appendArgs(double x, double y);
233
234 template <Command C>
235 void appendArgs(double x, double y, double x2, double y2);
236
237 template <Command C>
238 void appendArgs(double x, double y, double x2, double y2, double x3, double y3);
239
240
241 template <Command C, typename T>
242 inline
243 void appendArgs(const drain::Point2D<T> & p){
244 appendArgs<C>(p.x, p.y);
245 }
246
247 template <Command C, typename T>
248 inline
249 void appendArgs(const drain::Point2D<T> & p, const drain::Point2D<T> & p2){
250 appendArgs<C>(p.x, p.y, p2.x, p2.y);
251 }
252
253 template <Command C, typename T>
254 inline
255 void appendArgs(const drain::Point2D<T> & p, const drain::Point2D<T> & p2, const drain::Point2D<T> & p3){
256 appendArgs<C>(p.x, p.y, p2.x, p2.y, p3.x, p3.y);
257 }
258
259
260
261 inline
262 void appendPoint(double x){
263 sstr << x << ' ';
264 }
265
266 template <typename T>
267 inline
268 void appendPoint(const drain::Point2D<T> & p){
269 sstr << p.x << ' ' << p.y << ' ';
270 }
271
272
273
274 template <typename ...TT>
275 inline
276 void appendPoints(double x, double y, const TT... args){
277 //appendPoint(p);
278 sstr << x << ' ' << y;
279 appendMorePoints(args...);
280 //sstr << ' ';
281 }
282
283 template <typename T, typename ...TT>
284 inline
285 void appendPoints(const drain::Point2D<double> & p, const TT... args){
286 sstr << p.x << ' ' << p.y;
287 //appendPoint(p);
288 appendMorePoints(args...);
289 }
290
291 template <typename ...TT>
292 inline
293 void appendMorePoints(const TT... args){
294 sstr << ',';
295 appendPoints(args...);
296 }
297
298 // Terminal function
299 inline
300 void appendMorePoints(){
301 sstr << ' ';
302 }
303
304
305
306
307};
308DRAIN_SVG_ELEM(PATH)
309
310
311template <>
312inline
313void svgPATH::appendArgs<svgPATH::CLOSE>(){
314}
315
316
317template <>
318inline
319void svgPATH::appendArgs<svgPATH::MOVE>(double x, double y){
320 appendPoints(x, y);
321}
322
323template <>
324inline
325void svgPATH::appendArgs<svgPATH::LINE>(double x, double y){
326 appendPoints(x, y);
327}
328
329template <>
330inline
331void svgPATH::appendArgs<svgPATH::CURVE_C>(double x1, double y1, double x2, double y2, double x3, double y3){
332 appendPoints(x1,y1, x2,y2, x3,y3);
333}
334
335template <>
336inline
337void svgPATH::appendArgs<svgPATH::CURVE_C_SHORT>(double x2, double y2, double x, double y){
338 appendPoints(x2,y2, x,y);
339}
340
341
342
343namespace image {
344
345} // image::
346
347} // drain::
348
349
389#endif // TREESVG_H_
390
Definition Data.h:1473
VariableT< VariableInitializer< ReferenceT< VariableBase > > > FlexibleVariable
Value container supporting dynamic type with own memory and optional linking (referencing) of externa...
Definition FlexibleVariable.h:66
Definition Point.h:48