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){
60// class NodeXML<image::svg::tag_t>::Elem<image::svg::tag_t::RECT>{
61public:
62
63 inline
64 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::RECT), x(node["x"]), y(node["y"]), width(node["width"]), height(node["height"]){
65 };
66
67 NodeXML<image::svg::tag_t> & node;
68
71 FlexibleVariable & width;
72 FlexibleVariable & height;
73};
74DRAIN_SVG_ELEM(RECT)
75
76
77
78template <>
79template <>
80class DRAIN_SVG_ELEM_CLS(CIRCLE){
81
82public:
83
84 NodeXML<image::svg::tag_t> & node;
85
86 inline
87 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::CIRCLE), cx(node["cx"]), cy(node["cy"]), r(node["r"] = 0.0){
88 };
89
90 // Center point, x coord
92 // Center point, y coord
94 // Radius
96
97 // NodeXML<T> class could not access NodeSVG.box
98 // Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::CIRCLE), cx(node.box.x), cy(node.box.y), r(node["r"]){
99
100};
101DRAIN_SVG_ELEM(CIRCLE)
102
103
104
105template <>
106template <>
107class DRAIN_SVG_ELEM_CLS(POLYGON){
108
109public:
110
111 inline
112 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::POLYGON), points(node["points"]), writablePoints(node["points"]){
113 };
114
115 NodeXML<image::svg::tag_t> & node;
116
117 const FlexibleVariable & points;
118
119protected:
120
121 FlexibleVariable & writablePoints;
122
123public:
124
125 void clear(){
126 writablePoints.clear();
127 }
128
129 template <typename T>
130 inline
131 void append(const T &x, const T &y){
132 writablePoints << x << ',' << y << ' ';
133 }
134
135 template <typename T>
136 inline
137 void append(drain::Point2D<T> &p){
138 writablePoints << p.x << ',' << p.y << ' ';
139 }
140
141};
142DRAIN_SVG_ELEM(POLYGON)
143
144
145
146template <>
147template <>
148class DRAIN_SVG_ELEM_CLS(PATH){
149//class svgPATH {
150public:
151
152 inline
153 Elem(image::NodeSVG & node) : node(node = image::svg::tag_t::PATH), d(node["d"]) {
154 //node[d].setType<std::string>();
155 //node["d"].setSeparator(' ');
156 };
157
158 ~Elem(){
159 flush();
160 }
161
162 bool noReset = true;
163
164 NodeXML<image::svg::tag_t> & node;
165
166 // Path description, "d" attribute.
167 const FlexibleVariable & d;
168
169 enum Command {
170 MOVE = 'M',
171 LINE = 'L',
172 // Cubic Bezier curves
173 CURVE_C = 'C',
174 CURVE_C_SHORT = 'S',
175 // Quadratic Bezier curves
176 CURVE_Q = 'Q',
177 CURVE_Q_SHORT = 'T',
178 CLOSE = 'Z',
179 };
180
181 enum Coord {
182 ABSOLUTE = 0,
183 RELATIVE = 32, // upper case 'm' -> 'M'
184 };
185
186public:
187
188 template <Command C, typename ...T>
189 void relative(const T... args){
190 appendCmd<C,RELATIVE>();
191 appendArgs<C>(args...);
192 }
193
194 template <Command C, typename ...T>
195 void absolute(const T... args){
196 appendCmd<C,ABSOLUTE>();
197 appendArgs<C>(args...);
198 }
199
200
201 void clear(){
202 sstr.str("");
203 node["d"].clear();
204 }
205
206protected:
207
208 mutable
209 std::stringstream sstr;
210
211 // Could be protected
212 void flush(){
213 // Logger mout(__FILE__, __FUNCTION__);
214 // mout.warn("contents1: ", d);
215 if (noReset){
216 node["d"].append(sstr.str());
217 // mout.warn("appended contents_: ", d);
218 }
219 else {
220 node["d"] = sstr.str();
221 // mout.warn("NEW contents_: ", d);
222 }
223 sstr.str(""); // Destructor would do this anyway
224 }
225
226 template <Command C, Coord R=RELATIVE>
227 inline
228 void appendCmd(){
229 sstr << char(int(C) + int(R)) << ' ';
230 }
231
232 template <Command C>
233 void appendArgs();
234
235 template <Command C>
236 void appendArgs(double x, double y);
237
238 template <Command C>
239 void appendArgs(double x, double y, double x2, double y2);
240
241 template <Command C>
242 void appendArgs(double x, double y, double x2, double y2, double x3, double y3);
243
244
245 template <Command C, typename T>
246 inline
247 void appendArgs(const drain::Point2D<T> & p){
248 appendArgs<C>(p.x, p.y);
249 }
250
251 template <Command C, typename T>
252 inline
253 void appendArgs(const drain::Point2D<T> & p, const drain::Point2D<T> & p2){
254 appendArgs<C>(p.x, p.y, p2.x, p2.y);
255 }
256
257 template <Command C, typename T>
258 inline
259 void appendArgs(const drain::Point2D<T> & p, const drain::Point2D<T> & p2, const drain::Point2D<T> & p3){
260 appendArgs<C>(p.x, p.y, p2.x, p2.y, p3.x, p3.y);
261 }
262
263
264
265 inline
266 void appendPoint(double x){
267 sstr << x << ' ';
268 }
269
270 template <typename T>
271 inline
272 void appendPoint(const drain::Point2D<T> & p){
273 sstr << p.x << ' ' << p.y << ' ';
274 }
275
276
277
278 template <typename ...TT>
279 inline
280 void appendPoints(double x, double y, const TT... args){
281 //appendPoint(p);
282 sstr << x << ' ' << y;
283 appendMorePoints(args...);
284 //sstr << ' ';
285 }
286
287 template <typename T, typename ...TT>
288 inline
289 void appendPoints(const drain::Point2D<double> & p, const TT... args){
290 sstr << p.x << ' ' << p.y;
291 //appendPoint(p);
292 appendMorePoints(args...);
293 }
294
295 template <typename ...TT>
296 inline
297 void appendMorePoints(const TT... args){
298 sstr << ',';
299 appendPoints(args...);
300 }
301
302 // Terminal function
303 inline
304 void appendMorePoints(){
305 sstr << ' ';
306 }
307
308
309
310
311};
312DRAIN_SVG_ELEM(PATH)
313
314
315template <>
316inline
317void svgPATH::appendArgs<svgPATH::CLOSE>(){
318};
319
320
321template <>
322inline
323void svgPATH::appendArgs<svgPATH::MOVE>(double x, double y){
324 appendPoints(x, y);
325};
326
327template <>
328inline
329void svgPATH::appendArgs<svgPATH::LINE>(double x, double y){
330 appendPoints(x, y);
331};
332
333template <>
334inline
335void svgPATH::appendArgs<svgPATH::CURVE_C>(double x1, double y1, double x2, double y2, double x3, double y3){
336 appendPoints(x1,y1, x2,y2, x3,y3);
337};
338
339template <>
340inline
341void svgPATH::appendArgs<svgPATH::CURVE_C_SHORT>(double x2, double y2, double x, double y){
342 appendPoints(x2,y2, x,y);
343};
344
345
346
347namespace image {
348
349} // image::
350
351} // drain::
352
353
393#endif // TREESVG_H_
394
Definition DataSelector.cpp:1277
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