A toolkit for working with phylogenetic data.
v0.18.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-2017 Lucas Czech
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 
147 SvgFill::SvgFill( Color color, double opacity )
148  : type( SvgFill::Type::kColor )
149  , color( color )
150  , rule( Rule::kNone )
151 {
152  color.a( opacity );
153 }
154 
155 SvgFill::SvgFill( std::string gradient_id_value )
156  : SvgFill( Type::kGradient )
157 {
158  gradient_id = gradient_id_value;
159 }
160 
161 // -------------------------------------------------------------
162 // Drawing Function
163 // -------------------------------------------------------------
164 
165 void SvgFill::write( std::ostream& out ) const
166 {
167  // Treat special cases.
168  if( type == Type::kOmit ) {
169  return;
170  }
171  if( type == Type::kNone ) {
172  out << svg_attribute( "fill", "none" );
173  return;
174  }
175  if( type == Type::kGradient ) {
176  out << svg_attribute( "fill", "url(#" + gradient_id + ");" );
177  return;
178  }
179 
180  out << svg_attribute( "fill", color_to_hex( color ) );
181  out << svg_attribute( "fill-opacity", color.a() );
182 
183  switch( rule ) {
184  case Rule::kNone:
185  break;
186  case Rule::kNonZero:
187  out << svg_attribute( "fill-rule", "nonzero" );
188  break;
189  case Rule::kEvenOdd:
190  out << svg_attribute( "fill-rule", "evenodd" );
191  break;
192  }
193 }
194 
195 // =================================================================================================
196 // Svg Font
197 // =================================================================================================
198 
199 // -------------------------------------------------------------
200 // Constructors and Rule of Five
201 // -------------------------------------------------------------
202 
203 SvgFont::SvgFont( double size_value, std::string const& family_value )
204  : size( size_value )
205  , family( family_value )
206 {}
207 
208 // -------------------------------------------------------------
209 // Drawing Function
210 // -------------------------------------------------------------
211 
212 void SvgFont::write( std::ostream& out ) const
213 {
214  out << svg_attribute( "font-size", size );
215  out << svg_attribute( "font-family", family );
216 }
217 
218 // =================================================================================================
219 // Svg Transformation
220 // =================================================================================================
221 
222 // -------------------------------------------------------------------------
223 // Subclass Translate
224 // -------------------------------------------------------------------------
225 
226 void SvgTransform::Translate::write( std::ostream &out ) const
227 {
228  if( tx != 0.0 || ty != 0.0 ) {
229  out << "translate( " << tx << ", " << ty << " )";
230  }
231 }
232 
233 // -------------------------------------------------------------------------
234 // Subclass Rotate
235 // -------------------------------------------------------------------------
236 
237 void SvgTransform::Rotate::write( std::ostream &out ) const
238 {
239  if( a != 0.0 ) {
240  if( cx != 0.0 || cy != 0.0 ) {
241  out << "rotate( " << a << ", " << cx << ", " << cy << " )";
242  } else {
243  out << "rotate( " << a << " )";
244  }
245  }
246 }
247 
248 // -------------------------------------------------------------------------
249 // Subclass Scale
250 // -------------------------------------------------------------------------
251 
252 void SvgTransform::Scale::write( std::ostream &out ) const
253 {
254  if( sx != 1.0 || sy != 1.0 ) {
255  if( sx == sy ) {
256  out << "scale( " << sx << " )";
257  } else {
258  out << "scale( " << sx << ", " << sy << " )";
259  }
260  }
261 }
262 
263 // -------------------------------------------------------------------------
264 // Subclass Skew
265 // -------------------------------------------------------------------------
266 
267 void SvgTransform::Skew::write( std::ostream &out ) const
268 {
269  if( ax != 0.0 ) {
270  out << "skewX( " << ax << " )";
271  }
272  if( ax != 0.0 && ay != 0.0 ) {
273  out << " ";
274  }
275  if( ay != 0.0 ) {
276  out << "skewY( " << ay << " )";
277  }
278 }
279 
280 // -------------------------------------------------------------------------
281 // Subclass Matrix
282 // -------------------------------------------------------------------------
283 
284 void SvgTransform::Matrix::write( std::ostream &out ) const
285 {
286  if( a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0 || e != 0.0 || f != 0.0 ) {
287  out << "matrix( " << a << ", " << b << ", " << c << ", ";
288  out << d << ", " << e << ", " << f << " )";
289  }
290 }
291 
292 // -------------------------------------------------------------------------
293 // SvgTransform Main Class
294 // -------------------------------------------------------------------------
295 
297 {
298  transformations.push_back( std::move( t ));
299 }
300 
302 {
303  transformations.push_back( t );
304 }
305 
306 void SvgTransform::write( std::ostream& out ) const
307 {
308  if( ! transformations.empty() ) {
309  out << " transform=\"";
310  for( auto const& t : transformations ) {
311  if( &t != &transformations[0] ) {
312  out << " ";
313  }
314  t.write( out );
315  }
316  out << "\"";
317  }
318 }
319 
320 } // namespace utils
321 } // namespace genesis
Skip no whitespace. Thus, immediately treat the current input char.
void append(Transformation &&t)
Definition: attributes.cpp:296
void write(std::ostream &out) const
Definition: attributes.cpp:237
void write(std::ostream &out) const
Definition: attributes.cpp:165
void write(std::ostream &out) const
Definition: attributes.cpp:284
void write(std::ostream &out) const
Definition: attributes.cpp:252
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:318
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:604
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:306
SvgFont(double size=10, std::string const &family="Verdana")
Definition: attributes.cpp:203
void write(std::ostream &out) const
Definition: attributes.cpp:267
void write(std::ostream &out) const
Definition: attributes.cpp:226
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:212