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