Loading...
Searching...
No Matches
AlignAnchorSVG.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: Nov, 2024
35 * Author: mpeura
36 */
37
38#ifndef DRAIN_ALIGN_ADAPTER_SVG
39#define DRAIN_ALIGN_ADAPTER_SVG
40
41//#include "drain/util/FileInfo.h"
42// #include "drain/util/Frame.h"
43//
44#include <string>
45//#include "drain/util/EnumFlags.h"
46
47#include "AlignSVG.h"
48
49namespace drain {
50
51namespace image {
52
53/* Semantics:
54 *
55 * if myAnchor is set, use it.
56 * if myAnchor is unset, use group anchor; it servers as a default anchor
57 * if groupAnchor is unset -> use previous object as anchor.
58 *
59 * GroupAnchor (default anchor):
60 DEFAULT(=UNSET): use previous object
61 NONE: use nothing, don't align
62 PREVIOUS: use previous (unneeded, this is the default for group)
63 COLLECTIVE: use compound bounding bbox
64
65 MyAnchor (specific anchor, always overrides)
66 DEFAULT(=UNSET) -> use GroupAnchor
67 NONE: don't align me! (raise error if Align set?)
68 PREVIOUS:
69 COLLECTIVE: use compound bounding box
70
71 SPECIAL: both DEFAULT: use PREVIOUS
72 *
73 */
74
75// Could be internal class in Adapter?
76struct AnchorElem : public std::string {
77
78 // More like a symbol.
79 enum Anchor {
80 DEFAULT = 0, // use group's default anchor, or if that is not set, use previous
81 NONE = 1, // don't align at alla
82 PREVIOUS, // use previous object
83 NEXT, // use next object - applied typically by background map adapting to actual overlay image (requires revisiting loop)
84 COLLECTIVE_CURRENT, // use dynamically growing bounding box or the compound
85 COLLECTIVE_FINAL, // use dynamically growing bounding box or the compound - in the end.
86 };
87
88
89 inline
90 AnchorElem(const std::string & s="") : std::string(s){
91 };
92
93 inline
94 AnchorElem(const AnchorElem & a) : std::string(a){
95 };
96
97 inline
98 const std::string & str() const {
99 return *this;
100 }
101
102 inline
103 std::string & str() {
104 return *this;
105 }
106
107 void set(const std::string & s);
108
109 void set(const AnchorElem::Anchor & anchor);
110
112 inline
113 bool isSet() const {
114 return !empty();
115 }
116
117 // Use the bounding box of the compound, "accumulated" object as anchor.
118 inline
119 bool isCollective() const {
120 return (drain::EnumDict<AnchorElem::Anchor>::getValue(*this) == Anchor::COLLECTIVE_CURRENT);
121 }
122
123 // Use the bounding box of the latest object as anchor.
124 bool isPrevious() const {
125 return (drain::EnumDict<AnchorElem::Anchor>::getValue(*this) == Anchor::PREVIOUS);
126 }
127
128 // Explicitly states that an object uses no anchor, hence the position is absolute (not aligned)
129 bool isNone() const {
130 return (drain::EnumDict<AnchorElem::Anchor>::getValue(*this) == Anchor::NONE);
131 }
132
133 // Use the bounding box of a named object as anchor.
134 inline
135 bool isSpecific() const {
136 return isSet() && (!isCollective()) && (!isPrevious()) && (!isNone());
137 }
138
139
140};
141
142} // drain::
143
144// }
145//
146// namespace drain {
147
148DRAIN_ENUM_DICT(image::AnchorElem::Anchor);
149DRAIN_ENUM_OSTREAM(image::AnchorElem::Anchor);
150
151namespace image {
152
154struct AlignAnchorSVG { // : public AlignSVG {
155
156
157public:
158
159 typedef AnchorElem anchor_t; // needed?
160
161 template <class T>
162 inline
163 void setMyAlignAnchor(const T & value){
164 adjustAnchor(myAnchorHorz, value);
165 myAnchorVert = myAnchorHorz;
166 updateAlign();
167 }
168
169 template <AlignBase::Axis AX, class T>
170 inline
171 void setMyAlignAnchor(const T & value){
172 adjustAnchor(getMyAlignAnchor<AX>(), value);
173 updateAlign();
174 }
175
176 template <class T>
177 inline
178 void setDefaultAlignAnchor(const T & value){
179 adjustAnchor(defaultAnchorHorz, value);
180 defaultAnchorVert = defaultAnchorHorz;
181 updateAlign();
182 }
183
184 template <AlignBase::Axis AX, class T>
185 inline
186 void setDefaultAlignAnchor(const T & value){
187 AnchorElem & defaultAnchor = getDefaultAlignAnchor<AX>();
188 adjustAnchor(defaultAnchor, value);
189 if (defaultAnchor.isPrevious()){
190 Logger(__FILE__, __FUNCTION__, __LINE__).suspicious("Removing explicit ", AnchorElem::Anchor::PREVIOUS, " as non-informative for group default");
191 // getDefaultAlignAnchor<AX>() = AnchorElem::Anchor::DEFAULT;
192 adjustAnchor(defaultAnchor, AnchorElem::Anchor::DEFAULT);
193 }
194 updateAlign();
195 }
196
197
199 template <AlignBase::Axis AX>
200 const anchor_t & getMyAlignAnchor() const;
201
203 template <AlignBase::Axis AX>
204 const anchor_t & getDefaultAlignAnchor() const;
205
207 template <AlignBase::Axis AX>
209
211 template <AlignBase::Axis AX>
212 anchor_t & getDefaultAlignAnchor();
213
214
215
216 inline virtual
217 ~AlignAnchorSVG(){};
218
219 void swapAnchors(AlignAnchorSVG & anchors);
220
221protected:
222
223 // "string detectors"
224
225 static inline
226 void adjustAnchor(AnchorElem & anchor, const std::string & value){
227 anchor.assign(value);
228 }
229
230 static inline
231 void adjustAnchor(AnchorElem & anchor, const char * value){
232 anchor.assign(value);
233 }
234
235 static inline
236 void adjustAnchor(AnchorElem & anchor, const AnchorElem & elem){
237 anchor.assign(elem);
238 }
239
240 template <class T>
241 static inline
242 void adjustAnchor(AnchorElem & anchor, const T & value){
243 anchor.assign(EnumDict<T>::getKey(value));
244 }
245
247 virtual
248 void updateAlign() = 0;
249
250 // essentially std::string's
251 anchor_t myAnchorHorz;
252 anchor_t myAnchorVert;
253
254 anchor_t defaultAnchorHorz;
255 anchor_t defaultAnchorVert;
256
257
258};
259
260
261template <>
262inline
263const AlignAnchorSVG::anchor_t & AlignAnchorSVG::getMyAlignAnchor<AlignBase::Axis::HORZ>() const {
264 return myAnchorHorz;
265};
266
267template <>
268inline
269const AlignAnchorSVG::anchor_t & AlignAnchorSVG::getMyAlignAnchor<AlignBase::Axis::VERT>() const {
270 return myAnchorVert;
271};
272
274template <>
275inline
276const AlignAnchorSVG::anchor_t & AlignAnchorSVG::getDefaultAlignAnchor<AlignBase::Axis::HORZ>() const {
277 return defaultAnchorHorz;
278};
279
280template <>
281inline
282const AlignAnchorSVG::anchor_t & AlignAnchorSVG::getDefaultAlignAnchor<AlignBase::Axis::VERT>() const {
283 return defaultAnchorVert;
284};
285
286template <>
287inline
288AlignAnchorSVG::anchor_t & AlignAnchorSVG::getMyAlignAnchor<AlignBase::Axis::HORZ>() {
289 return myAnchorHorz;
290};
291
292template <>
293inline
294AlignAnchorSVG::anchor_t & AlignAnchorSVG::getMyAlignAnchor<AlignBase::Axis::VERT>() {
295 return myAnchorVert;
296};
297
299template <>
300inline
301AlignAnchorSVG::anchor_t & AlignAnchorSVG::getDefaultAlignAnchor<AlignBase::Axis::HORZ>() {
302 return defaultAnchorHorz;
303};
304
305template <>
306inline
307AlignAnchorSVG::anchor_t & AlignAnchorSVG::getDefaultAlignAnchor<AlignBase::Axis::VERT>() {
308 return defaultAnchorVert;
309};
310
311
312
313} // image::
314
315
316
317} // drain::
318
319//DRAIN_ENUM_DICT(drain::image::AnchorElem::Anchor);
320//DRAIN_ENUM_OSTREAM(drain::image::AnchorElem::Anchor);
321
322#endif // DRAIN_ALIGN_SVG_H_
323
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & suspicious(const TT &... args)
A weak warning about something going possibly wrong.
Definition Log.h:501
Definition DataSelector.cpp:1277
A container for a static dictionary of enumeration values.
Definition EnumFlags.h:69
static const std::string & getKey(const std::string &s, bool lenient=true)
Convenience for object.set(...) like commands.
Definition EnumFlags.h:162
Adapter designed for NodeSVG.
Definition AlignAnchorSVG.h:154
const anchor_t & getMyAlignAnchor() const
Store anchor object/symbol for aligning this object.
virtual void updateAlign()=0
Redefined in NodeSVG.
Definition AlignAnchorSVG.h:76
bool isSet() const
If not set, use default.
Definition AlignAnchorSVG.h:113