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