Loading...
Searching...
No Matches
TreeSVG.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: Jun 24, 2012
35 * Author: mpeura
36 */
37
38#ifndef DRAIN_TREE_SVG
39#define DRAIN_TREE_SVG
40
41#include <drain/Enum.h>
42#include <drain/image/AlignAnchorSVG.h>
43#include "drain/util/FileInfo.h"
44#include "drain/util/Frame.h"
45#include "drain/util/SelectorXML.h"
46#include "drain/util/TreeXML.h"
47#include "drain/util/UtilsXML.h"
48
49#include "SVG.h"
50#include "TransformSVG.h"
51
52namespace drain {
53
54namespace image {
55
56/*
57class NodeSVG;
58
59typedef drain::UnorderedMultiTree<NodeSVG,false, NodeXML<>::path_t> TreeSVG;
60//typedef NodeXML<NodeSVG>::xml_tree_t TreeSVG;
61*/
62
64class FileSVG {
65
66public:
67
68 static
69 const drain::FileInfo fileInfo;
70
71 enum PathPolicy {
72 ABSOLUTE = 1, // Else is relative, stripped away using inputPrefix?
73 PREFIXED = 2, // file:// is appended, sometimes required?
74 RELATIVE = 2, // Duplicate, for now.
75 };
76
77 // Rename IncludePolicy ?
78 enum IncludePolicy {
79 NONE = 0,
80 PNG = 1, // Main title in SVG image
81 SVG = 2,
82 TXT = 4,
83 SKIP = 16,
84 NEXT = 32,
85 ON = 64,
86 OFF = 128,
87 ALL = ON|(PNG|SVG|TXT),
88 UNKNOWN = 255,
89 // --- unused ? ---
90 // TITLE, // Default title
91 };
92
93 static
94 int radialBezierResolution;
95
96 static
97 int visualDebugLevel;
98
99 static
100 std::string DEBUG;
101
102 static
103 std::string DEBUG_ALIGN;
104
105};
106
107}
108
109DRAIN_ENUM_DICT(image::FileSVG::IncludePolicy);
110DRAIN_ENUM_DICT(image::FileSVG::PathPolicy);
111
112
113namespace image {
114
115DRAIN_ENUM_OSTREAM(image::FileSVG::IncludePolicy)
116DRAIN_ENUM_OSTREAM(image::FileSVG::PathPolicy)
117
118
119class NodeSVG;
120
121// typedef drain::UnorderedMultiTree<NodeSVG,false, NodeXML<>::path_t> TreeSVG;
122typedef DRAIN_XML_TREE(NodeSVG) TreeSVG;
123
125
126
128
134// class NodeSVG: public svg, public NodeXML<svg::tag_t>, public AlignAnchorSVG {
135class NodeSVG: public NodeXML<svg::tag_t>, public AlignSVG, public AlignAnchorSVG {
136public:
137
138 typedef svg::tag_t tag_t; // DRAIN_XML_... macros expect (NodeXML)::tag_t
139
141 static
142 std::string xlink;
143
145 static
146 std::string svg_decl;
147
148
150 NodeSVG(svg::tag_t t = svg::UNDEFINED);
151
153 NodeSVG(const NodeSVG & node);
154
155 inline virtual
156 ~NodeSVG(){};
157
158 inline
159 bool isAbstract() const {
160 return typeIs(
161 svg::tag_t::UNDEFINED,
162 svg::tag_t::COMMENT,
163 svg::tag_t::STYLE,
164 svg::tag_t::CLIP_PATH, // Semi-abstract..
165 svg::tag_t::DESC,
166 svg::tag_t::DEFS,
167 svg::tag_t::METADATA,
168 svg::tag_t::SCRIPT,
169 svg::tag_t::TITLE,
170 svg::tag_t::TSPAN
171 );
172 }
173
175 virtual inline
176 bool isSingular() const override final {
177 return false;
178 }
179
180
182 inline
183 NodeSVG & operator=(const NodeSVG & node){
184 if (!typeIsSet()){
185 setType(node.getType());
186 handleType();
187 //handleType(node.getNativeType());
188 }
189 XML::xmlAssignNode(*this, node);
190 return *this;
191 }
192
194 inline
195 NodeSVG & operator=(const std::initializer_list<Variable::init_pair_t > &l){
196 set(l);
197 return *this;
198 }
199
200 template <class T>
201 inline
202 NodeSVG & operator=(const T & arg){
203 set(arg);
204 //assign(arg);
205 return *this;
206 }
207
208 inline
209 NodeSVG & operator=(xml_tag_t type){
210 setType(type);
211 return *this;
212 }
213
214
216 /*
217 virtual
218 void setAttribute(const std::string & key, const std::string &value) override;
219
221 virtual
222 void setAttribute(const std::string & key, const char *value) override;
223 */
224
225
227 inline
228 const BBoxSVG & getBoundingBox() const {
229 return box;
230 }
231 // Consider also with conversion: getBoundingBox(Box<T> &b)
232
234 inline
235 BBoxSVG & getBoundingBox(){ // needed? (by AlignSVG, perhaps?)
236 return box;
237 }
238
240 template <typename T>
241 inline
243 setLocation(b);
244 setGeometry(b);
245 // setAttribute("data:bbox", StringBuilder<' '>(b.x, b.y, b.getWidth(), b.getHeight()));
246 }
247
249 inline
251 return box.getFrame();
252 }
253
255 inline
257 return box.getFrame();
258 }
259
260 inline
261 const Point2D<svg::coord_t> & getLocation() const {
262 return box.getLocation();
263 }
264
265 inline
266 Point2D<svg::coord_t> & getLocation() {
267 return box.getLocation();
268 }
269
270 template <typename T>
271 inline
272 void setViewBox(const drain::Box<T> & bb){
273 setViewBox(bb.x, bb.y, bb.width, bb.height);
274 }
275
276 template <typename T>
277 inline
278 void setViewBox(T & x, T & y, T & width, T & height){
279 set("viewBox", drain::StringBuilder<' '>(x, y, width, height).str());
280 }
281
283 template <typename T>
284 inline
285 void setLocation(const drain::Point2D<T> & point){
286 box.x = point.x;
287 box.y = point.y;
288 }
289
294 template <typename T>
295 inline
296 void setLocation(const T & x, const T & y){
297 box.setLocation(x, y);
298 }
299
300 template <typename T>
301 inline
302 void setGeometry(const drain::Frame2D<T> & frame){
303 box.width = frame.width;
304 box.height = frame.height;
305 }
306
311 template <typename T>
312 inline
313 void setGeometry(const T & w, const T & h){
314 box.setArea(w, h);
315 }
316
317
322 template <typename T>
323 inline
324 void setWidth(T w){
325 box.width = w;
326 }
327
328 inline
329 svg::coord_t getWidth() const {
330 return box.width;
331 }
332
334
337 template <typename T>
338 inline
339 void setMargin(T w){
340 // getMap()["data-margin"].link(box.width = w);
341 //getMap()["data-margin"].link(margin = w);
342 setUserAttribute("margin", w);
343 }
344
346
349 inline
350 svg::coord_t getMargin() const {
351 //return box.width;
352 // return margin;
353 return getUserAttribute("margin");
354 }
355
356
361 template <typename T>
362 inline
363 void setHeight(T h){
364 if (typeIs(svg::TEXT)){
365 getMap()["data-height"].link(box.height);
366 }
367 box.height = h;
368 }
369
370 inline
371 svg::coord_t getHeight() const {
372 return box.height;
373 }
374
376 void setFontSize(svg::coord_t size, svg::coord_t elemHeight = 0.0);
377
378 TransformSVG transform;
379
381
387 virtual
388 void specificAttributesToStream(std::ostream & ostr) const override;
389
391 void swapDataSVG(NodeSVG & node);
392
393protected:
394
395 virtual
396 void handleType() override final;
397
398
399 virtual
400 void updateAlign() override;
401
402 // TODO: allowedUnits drain::Units
403 BBoxSVG box;
404
405 virtual inline
406 void setAlignClass(AlignClass cls) override final {
407 addClass(cls);
408 };
409
410 // For TEXT elems only...
411 // svg::coord_t margin = 0;
412
413};
414
415
416/*
417template <typename P, typename A,typename V>
418void NodeSVG::setAlign(const P & pos, const A & axis, const V &value){
419 alignments[p][a] = v;
420}
421*/
422
423
424// Utility (move to utils?)
427
428public:
429
430 inline
431 NodePrinter(const NodeSVG & node){
432 std::stringstream sstr;
433 sstr << "<" << node.getTag();
434 if (::atoi(node.getId().c_str())==0){
435 sstr << " id=" << node.getId();
436 }
437 if (node.getName().isValid()){
438 sstr << " name=" << node.getName();
439 }
440 if (!node.getClasses().empty()){
441 sstr << " class=[" << node.getClasses() << ']';
442 }
443 sstr << '>';
444 id = sstr.str();
445 }
446
447 const std::string & str() const {
448 return id;
449 }
450
451
452protected:
453
454 std::string id;
455
456};
457
458
459//typedef NodeSVG::xml_tree_t TreeSVG;
460
461
462} // image::
463
464
465/*
466inline
467std::ostream & operator<<(std::ostream &ostr, const image::NodeSVG & node){
468 return node.nodeToStream(ostr);
469}
470*/
471
472
473
474} // drain::
475
476
477inline
478std::ostream & operator<<(std::ostream &ostr, const drain::image::NodeSVG & node){
479 return node.nodeToStream(ostr);
480}
481
482
483
484inline
485std::ostream & operator<<(std::ostream &ostr, const drain::image::TreeSVG & tree){
486 return drain::image::NodeSVG::docToStream(ostr, tree);
487}
488
489
490
491namespace drain {
492
493DRAIN_TYPENAME(image::NodeSVG);
494DRAIN_TYPENAME(image::svg::tag_t);
495
496
497
498/*
499template <>
500template <typename K, typename V>
501image::TreeSVG & image::TreeSVG::operator=(std::initializer_list<std::pair<K,V> > args){
502 drain::Logger mout(__FILE__, __FUNCTION__);
503 mout.attention("initlist pair<K,V>: ", args);
504 data.set(args); // what about TreeSVG & arg
505 return *this;
506}
507*/
508
509
510template <> // referring to Tree<NodeSVG>
511template <> // referring to tparam T
512inline
513image::TreeSVG & image::TreeSVG::operator=(const std::string & arg){
514 UtilsXML::assignString(*this, arg);
515 return *this;
516}
517
518
519template <> // referring to Tree<NodeSVG>
520inline
521image::TreeSVG & image::TreeSVG::operator=(std::initializer_list<std::pair<const char *,const Variable> > l){
522 return UtilsXML::assign(*this, l);
523}
524
525
526template <>
527template <class T>
528image::TreeSVG & image::TreeSVG::operator=(const T & arg){
529 return UtilsXML::assign(*this, arg);
530}
531
533
544DRAIN_XML_EASY_TYPE(image::TreeSVG)
545
546DRAIN_GETKEY_ENUM(image::TreeSVG, image::svg::tag_t)
547
548
549template <> // for T (Tree class)
550template <> // for K (path elem arg)
551inline
552const image::TreeSVG::key_t & image::TreeSVG::getKey(const ClassXML & cls){
553 //return image::TreeSVG::getKey(cls.strPrefixed()); // const !
554 //return image::TreeSVG::getKey((const std::string &)cls); // const !
555 return (const std::string &)cls;
556}
557
558template <> // for T (Tree class)
559template <> // for K (path elem arg)
560inline
561const image::TreeSVG::key_t & image::TreeSVG::getKey(const drain::SelectXML<image::svg::tag_t> & sel){
562 // return image::TreeSVG::getKey(sel.str()); // const !
563 return (const std::string &)sel;
564}
565
566
567
568DRAIN_XML_DEFAULT_ELEMS(image::TreeSVG);
569
571
574DRAIN_XML_DEFAULT_INIT(image::TreeSVG)
575
576// const drain::Enum<image::svg::tag_t>::dict_t & getDict();
577template <>
578void image::TreeSVG::swapData(image::NodeSVG & node);
579
580
582
587template <> // for T - Tree class
588template <> // for K - argument
589image::TreeSVG & image::TreeSVG::addChild(const image::svg::tag_t & type);
590
591} // drain::
592
593#endif // DRAIN_TREE_SVG
594
Definition FileInfo.h:47
Something that has width and height.
Definition Frame.h:53
Definition TreeXML.h:55
virtual std::ostream & nodeToStream(std::ostream &ostr, tag_display_mode mode=EMPTY_TAG) const override
Dumps info. Future option: outputs leading and ending tag.
Definition TreeXML.h:412
virtual const std::string & getTag() const override
Default implementation of tag name retrieval based on drain::Enum<t>.
Definition TreeXML.h:140
Definition SelectorXML.h:75
Definition StringBuilder.h:58
static T & assign(T &dst, const T &src)
Assign another tree structure to another.
Definition UtilsXML.h:108
static TX & assignString(TX &tree, const std::string &s)
When assigning a string, create new element unless the element itself is of type CTEXT.
Definition UtilsXML.h:183
bool typeIs(const T2 &arg, const T3... args) const
Return true, if type is any of the arguments.
Definition XML.h:230
bool typeIsSet() const
Return true, if type is any of the arguments.
Definition XML.h:220
const std::string & getId() const
Returns ID of this element. Hopefully a unique ID...
Definition XML.h:286
void setType(const T &t)
Definition XML.h:200
static N & xmlAssignNode(N &dst, const N &src)
Assign tree node (data) to another.
Definition XML.h:887
Definition SVG.h:91
DOC: Add class description.
Definition TreeSVG.h:64
DOC: Add class description.
Definition TreeSVG.h:426
Definition TreeSVG.h:135
void setBoundingBox(const drain::Box< T > &b)
Set position (x,y), width and height of an object.
Definition TreeSVG.h:242
void setLocation(const T &x, const T &y)
Definition TreeSVG.h:296
const BBoxSVG & getBoundingBox() const
Set attribute value, handling units in string arguments, like in "50%" or "640px".
Definition TreeSVG.h:228
NodeSVG & operator=(const NodeSVG &node)
Copy data from a node. (Does not copy subtree.)
Definition TreeSVG.h:183
static std::string xlink
In opening SVG tag, referred to by attribute "xmlns:xlink".
Definition TreeSVG.h:142
void setMargin(T w)
Set margin of a TEXT element (non-standard).
Definition TreeSVG.h:339
svg::coord_t getMargin() const
Get margin of a TEXT element (non-standard).
Definition TreeSVG.h:350
void setWidth(T w)
Definition TreeSVG.h:324
NodeSVG & operator=(const std::initializer_list< Variable::init_pair_t > &l)
Copy data from a node. (Does not copy subtree.)
Definition TreeSVG.h:195
virtual void specificAttributesToStream(std::ostream &ostr) const override
Write transform, in addition to XML::ClassList.
Definition TreeSVG.cpp:315
Frame2D< svg::coord_t > & getGeometry()
Get location (x,y) and geometry (width,height) of an object.
Definition TreeSVG.h:256
void swapDataSVG(NodeSVG &node)
Swaps XML properties and also alignment, anchors etc.
Definition TreeSVG.cpp:250
void setFontSize(svg::coord_t size, svg::coord_t elemHeight=0.0)
Sets font size and also text elem "height".
Definition TreeSVG.cpp:217
const Frame2D< svg::coord_t > & getGeometry() const
Get location (x,y) and geometry (width,height) of an object.
Definition TreeSVG.h:250
void setHeight(T h)
Definition TreeSVG.h:363
virtual bool isSingular() const override final
If true, render always as single elem (without child elems)
Definition TreeSVG.h:176
void setLocation(const drain::Point2D< T > &point)
Set position (x,y) of an object.
Definition TreeSVG.h:285
BBoxSVG & getBoundingBox()
Get location (x,y) and geometry (width,height) of an object.
Definition TreeSVG.h:235
static std::string svg_decl
In opening SVG tag, referred to by attributes "xmlns" and "xmlns:svg".
Definition TreeSVG.h:146
void setGeometry(const T &w, const T &h)
Definition TreeSVG.h:313
Definition TransformSVG.h:103
Definition Data.h:1473
std::ostream & operator<<(std::ostream &ostr, const PlainData< DT > &d)
Definition Data.h:631
Something that has coordinates (x,y) and dimensions (width, height).
Definition Frame.h:225
Definition Point.h:48
Adapter designed for NodeSVG.
Definition AlignAnchorSVG.h:159
User-friendly programming interface for alignment considering two elements.
Definition AlignSVG.h:59
AlignClass
Moved from Layput.
Definition AlignSVG.h:117