A toolkit for working with phylogenetic data.
v0.20.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gradient.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 
37 
38 #include <algorithm>
39 
40 namespace genesis {
41 namespace utils {
42 
43 // =================================================================================================
44 // Svg Gradient Stop
45 // =================================================================================================
46 
48 {
49  // Boundary checks.
50  if( offset < 0.0 || offset > 1.0 ) {
51  throw std::invalid_argument(
52  "Invalid Svg Gradient Stop offset. Has to be in range [ 0.0, 1.0 ], but is " +
53  std::to_string( offset ) + "."
54  );
55  }
56 }
57 
58 void SvgGradientStop::write( std::ostream& out ) const
59 {
60  validate();
61  out << "<stop";
62  out << svg_attribute( "offset", 100 * offset, "%" );
63  out << svg_attribute( "stop-color", color_to_hex( stop_color ) );
64  out << svg_attribute( "stop-opacity", stop_color.a() );
65  out << " />\n";
66 }
67 
68 bool SvgGradientStop::operator< ( self_type const& rhs ) const
69 {
70  return offset < rhs.offset;
71 }
72 
73 // =================================================================================================
74 // Svg Gradient Linear
75 // =================================================================================================
76 
78 {
79  // Check fixpoints.
80  if(
81  point_1.x < 0.0 || point_1.x > 1.0 || point_1.y < 0.0 || point_1.y > 1.0 ||
82  point_2.x < 0.0 || point_2.x > 1.0 || point_2.y < 0.0 || point_2.y > 1.0
83  ) {
84  throw std::invalid_argument(
85  "Invalid Svg Linar Gradient point. All coordinates of the points need to be in "
86  "range [ 0.0, 1.0 ]."
87  );
88  }
89 
90  // Check range sanity.
91  if( stops.size() < 2 ) {
92  throw std::invalid_argument(
93  "Svg Linar Gradient range needs to contain at least two colors."
94  );
95  }
96  if( stops.begin()->offset != 0.0 ) {
97  throw std::invalid_argument(
98  "Svg Linar Gradient range needs to start with key value 0.0."
99  );
100  }
101  if( stops.rbegin()->offset != 1.0 ) {
102  throw std::invalid_argument(
103  "Svg Linar Gradient range needs to end with key value 1.0."
104  );
105  }
106 
107  // Sort order.
108  auto const sorted = std::is_sorted(
109  stops.begin(), stops.end(),
110  []( SvgGradientStop const& lhs, SvgGradientStop const& rhs ){
111  return lhs.offset < rhs.offset;
112  }
113  );
114  if( ! sorted ) {
115  throw std::invalid_argument(
116  "Svg Linar Gradient range needs to be sorted by offset."
117  );
118  }
119 }
120 
121 void SvgGradientLinear::write( std::ostream& out, size_t indent ) const
122 {
123  // Do not write anything if emtpy
124  if( stops.empty() ) {
125  return;
126  }
127 
128  validate();
129 
130  out << repeat( SvgDocument::indentation_string, indent );
131  out << "<linearGradient";
132  out << svg_attribute( "id", id );
133 
134  out << svg_attribute( "x1", 100 * point_1.x, "%" );
135  out << svg_attribute( "y1", 100 * point_1.y, "%" );
136  out << svg_attribute( "x2", 100 * point_2.x, "%" );
137  out << svg_attribute( "y2", 100 * point_2.y, "%" );
138 
139  switch( spread_method ) {
140  case SpreadMethod::kPad: {
141  out << svg_attribute( "spreadMethod", "pad" );
142  break;
143  }
144  case SpreadMethod::kRepeat: {
145  out << svg_attribute( "spreadMethod", "repeat" );
146  break;
147  }
148  case SpreadMethod::kReflect: {
149  out << svg_attribute( "spreadMethod", "reflect" );
150  break;
151  }
152  default: {
153  assert( false );
154  }
155  }
156  transform.write( out );
157 
158  out << " >\n";
159 
160  for( auto const& stop : stops ) {
161  out << repeat( SvgDocument::indentation_string, indent + 1 );
162  stop.write( out );
163  }
164 
165  out << repeat( SvgDocument::indentation_string, indent );
166  out << "</linearGradient>\n";
167 }
168 
169 SvgGradientLinear& SvgGradientLinear::set_stops( std::map<double, Color> const& ranges )
170 {
171  // Set new stops.
172  stops.clear();
173  for( auto const& stop : ranges ) {
174  stops.emplace_back( stop.first, stop.second );
175  }
176 
177  return *this;
178 }
179 
181 {
182  insert_sorted( stops, stop );
183  return *this;
184 }
185 
187 {
188  return stops.empty();
189 }
190 
191 } // namespace utils
192 } // namespace genesis
Provides some valuable algorithms that are not part of the C++ 11 STL.
std::vector< SvgGradientStop > stops
Definition: gradient.hpp:175
std::string svg_attribute(std::string const &name, T const &value, std::string const &unit="")
std::string repeat(std::string const &word, size_t times)
Take a string and repeat it a given number of times.
Definition: string.cpp:418
std::string to_string(T const &v)
Return a string representation of a given value.
Definition: string.hpp:381
SvgGradientLinear & add_stop(SvgGradientStop const &stop)
Definition: gradient.cpp:180
bool operator<(self_type const &rhs) const
Definition: gradient.cpp:68
std::string indent(std::string const &text, std::string const &indentation)
Indent each line of text with indentation and return the result.
Definition: string.cpp:272
void write(std::ostream &out, size_t indent=0) const
Definition: gradient.cpp:121
Provides some commonly used string utility functions.
void write(std::ostream &out) const
Definition: attributes.cpp:304
SvgGradientLinear & set_stops(std::map< double, Color > const &ranges)
Definition: gradient.cpp:169
Color operators and functions.
static std::string indentation_string
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]".
void write(std::ostream &out) const
Definition: gradient.cpp:58
std::vector< T >::iterator insert_sorted(std::vector< T > &vec, T const &item)
Insert into a vector vec, sorted by the value of the item. The vector must already be sorted...
Definition: algorithm.hpp:94