A toolkit for working with phylogenetic data.
v0.19.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
attributes.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
36 
37 #include <ostream>
38 
39 namespace genesis {
40 namespace utils {
41 
42 // =================================================================================================
43 // Svg Stroke
44 // =================================================================================================
45 
46 // -------------------------------------------------------------
47 // Constructors and Rule of Five
48 // -------------------------------------------------------------
49 
51  : type( type )
52  , color()
53  , width( 1.0 )
54  , width_unit()
55  , line_cap( LineCap::kOmit )
56  , line_join( LineJoin::kOmit )
57  , miterlimit( 1.0 )
58  , dash_array()
59  , dash_offset( 0.0 )
60 {}
61 
62 SvgStroke::SvgStroke( Color color_value, double width_value )
63  : SvgStroke( Type::kColor )
64 {
65  color = color_value;
66  width = width_value;
67 }
68 
69 SvgStroke::SvgStroke( std::string gradient_id_value )
70  : SvgStroke( Type::kGradient )
71 {
72  gradient_id = gradient_id_value;
73 }
74 
75 // -------------------------------------------------------------
76 // Drawing Function
77 // -------------------------------------------------------------
78 
79 void SvgStroke::write( std::ostream& out ) const
80 {
81  // Treat special cases.
82  if( type == Type::kOmit ) {
83  return;
84  }
85  if( type == Type::kNone ) {
86  out << svg_attribute( "stroke", "none" );
87  return;
88  }
89  if( type == Type::kGradient ) {
90  out << svg_attribute( "stroke", "url(#" + gradient_id + ")" );
91  return;
92  }
93 
94  out << svg_attribute( "stroke", color_to_hex( color ) );
95  out << svg_attribute( "stroke-opacity", color.a() );
96  out << svg_attribute( "stroke-width", width, width_unit );
97 
98  switch( line_cap ) {
99  case LineCap::kOmit:
100  break;
101  case LineCap::kButt:
102  out << svg_attribute( "stroke-linecap", "butt" );
103  break;
104  case LineCap::kSquare:
105  out << svg_attribute( "stroke-linecap", "square" );
106  break;
107  case LineCap::kRound:
108  out << svg_attribute( "stroke-linecap", "round" );
109  break;
110  }
111 
112  switch( line_join ) {
113  case LineJoin::kOmit:
114  break;
115  case LineJoin::kMiter:
116  out << svg_attribute( "stroke-linejoin", "miter" );
117  out << svg_attribute( "stroke-miterlimit", miterlimit );
118  break;
119  case LineJoin::kRound:
120  out << svg_attribute( "stroke-linejoin", "round" );
121  break;
122  case LineJoin::kBevel:
123  out << svg_attribute( "stroke-linejoin", "bevel" );
124  break;
125  }
126 
127  if( dash_array.size() > 0 ) {
128  out << svg_attribute( "stroke-dasharray", join( dash_array, " " ));
129  out << svg_attribute( "stroke-dashoffset", dash_offset );
130  }
131 }
132 
133 // =================================================================================================
134 // Svg Fill
135 // =================================================================================================
136 
137 // -------------------------------------------------------------
138 // Constructors and Rule of Five
139 // -------------------------------------------------------------
140 
142  : type( type )
143  , color()
144  , rule( Rule::kNone )
145 {}
146 
148  : type( SvgFill::Type::kColor )
149  , color( color )
150  , rule( Rule::kNone )
151 {}
152 
153 SvgFill::SvgFill( std::string gradient_id_value )
154  : SvgFill( Type::kGradient )
155 {
156  gradient_id = gradient_id_value;
157 }
158 
159 // -------------------------------------------------------------
160 // Drawing Function
161 // -------------------------------------------------------------
162 
163 void SvgFill::write( std::ostream& out ) const
164 {
165  // Treat special cases.
166  if( type == Type::kOmit ) {
167  return;
168  }
169  if( type == Type::kNone ) {
170  out << svg_attribute( "fill", "none" );
171  return;
172  }
173  if( type == Type::kGradient ) {
174  out << svg_attribute( "fill", "url(#" + gradient_id + ")" );
175  return;
176  }
177 
178  out << svg_attribute( "fill", color_to_hex( color ) );
179  out << svg_attribute( "fill-opacity", color.a() );
180 
181  switch( rule ) {
182  case Rule::kNone:
183  break;
184  case Rule::kNonZero:
185  out << svg_attribute( "fill-rule", "nonzero" );
186  break;
187  case Rule::kEvenOdd:
188  out << svg_attribute( "fill-rule", "evenodd" );
189  break;
190  }
191 }
192 
193 // =================================================================================================
194 // Svg Font
195 // =================================================================================================
196 
197 // -------------------------------------------------------------
198 // Constructors and Rule of Five
199 // -------------------------------------------------------------
200 
201 SvgFont::SvgFont( double size_value, std::string const& family_value )
202  : size( size_value )
203  , family( family_value )
204 {}
205 
206 // -------------------------------------------------------------
207 // Drawing Function
208 // -------------------------------------------------------------
209 
210 void SvgFont::write( std::ostream& out ) const
211 {
212  out << svg_attribute( "font-size", size );
213  out << svg_attribute( "font-family", family );
214 }
215 
216 // =================================================================================================
217 // Svg Transformation
218 // =================================================================================================
219 
220 // -------------------------------------------------------------------------
221 // Subclass Translate
222 // -------------------------------------------------------------------------
223 
224 void SvgTransform::Translate::write( std::ostream &out ) const
225 {
226  if( tx != 0.0 || ty != 0.0 ) {
227  out << "translate( " << tx << ", " << ty << " )";
228  }
229 }
230 
231 // -------------------------------------------------------------------------
232 // Subclass Rotate
233 // -------------------------------------------------------------------------
234 
235 void SvgTransform::Rotate::write( std::ostream &out ) const
236 {
237  if( a != 0.0 ) {
238  if( cx != 0.0 || cy != 0.0 ) {
239  out << "rotate( " << a << ", " << cx << ", " << cy << " )";
240  } else {
241  out << "rotate( " << a << " )";
242  }
243  }
244 }
245 
246 // -------------------------------------------------------------------------
247 // Subclass Scale
248 // -------------------------------------------------------------------------
249 
250 void SvgTransform::Scale::write( std::ostream &out ) const
251 {
252  if( sx != 1.0 || sy != 1.0 ) {
253  if( sx == sy ) {
254  out << "scale( " << sx << " )";
255  } else {
256  out << "scale( " << sx << ", " << sy << " )";
257  }
258  }
259 }
260 
261 // -------------------------------------------------------------------------
262 // Subclass Skew
263 // -------------------------------------------------------------------------
264 
265 void SvgTransform::Skew::write( std::ostream &out ) const
266 {
267  if( ax != 0.0 ) {
268  out << "skewX( " << ax << " )";
269  }
270  if( ax != 0.0 && ay != 0.0 ) {
271  out << " ";
272  }
273  if( ay != 0.0 ) {
274  out << "skewY( " << ay << " )";
275  }
276 }
277 
278 // -------------------------------------------------------------------------
279 // Subclass Matrix
280 // -------------------------------------------------------------------------
281 
282 void SvgTransform::Matrix::write( std::ostream &out ) const
283 {
284  if( a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0 || e != 0.0 || f != 0.0 ) {
285  out << "matrix( " << a << ", " << b << ", " << c << ", ";
286  out << d << ", " << e << ", " << f << " )";
287  }
288 }
289 
290 // -------------------------------------------------------------------------
291 // SvgTransform Main Class
292 // -------------------------------------------------------------------------
293 
295 {
296  transformations.push_back( std::move( t ));
297 }
298 
300 {
301  transformations.push_back( t );
302 }
303 
304 void SvgTransform::write( std::ostream& out ) const
305 {
306  if( ! transformations.empty() ) {
307  out << " transform=\"";
308  for( auto const& t : transformations ) {
309  if( &t != &transformations[0] ) {
310  out << " ";
311  }
312  t.write( out );
313  }
314  out << "\"";
315  }
316 }
317 
318 } // namespace utils
319 } // namespace genesis
Skip no whitespace. Thus, immediately treat the current input char.
void append(Transformation &&t)
Definition: attributes.cpp:294
void write(std::ostream &out) const
Definition: attributes.cpp:235
void write(std::ostream &out) const
Definition: attributes.cpp:163
void write(std::ostream &out) const
Definition: attributes.cpp:282
void write(std::ostream &out) const
Definition: attributes.cpp:250
std::string join(T const &v, std::string const &delimiter)
Return a string where the elements of a container v are joined using the string delimiter in between ...
Definition: string.hpp:391
std::string svg_attribute(std::string const &name, T const &value, std::string const &unit="")
SvgFill(Type type=Type::kColor)
Definition: attributes.cpp:141
Provides some commonly used string utility functions.
void write(std::ostream &out) const
Definition: attributes.cpp:79
std::vector< Transformation > transformations
Definition: attributes.hpp:609
Internal helper class used as an abstraction to be able to store Transformations without need for inh...
Definition: attributes.hpp:493
void write(std::ostream &out) const
Definition: attributes.cpp:304
SvgFont(double size=10, std::string const &family="Verdana")
Definition: attributes.cpp:201
void write(std::ostream &out) const
Definition: attributes.cpp:265
void write(std::ostream &out) const
Definition: attributes.cpp:224
Color operators and functions.
std::vector< double > dash_array
Definition: attributes.hpp:122
double a() const
Definition: color.hpp:118
std::string color_to_hex(Color const &c, std::string const &prefix, bool uppercase, bool with_alpha)
Return a hex string representation of a Color in the format "#003366[ff]".
SvgStroke(Type type=Type::kColor)
Definition: attributes.cpp:50
void write(std::ostream &out) const
Definition: attributes.cpp:210