A library for working with phylogenetic and population genetic data.
v0.32.0
gradient.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2023 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 <lczech@carnegiescience.edu>
20  Department of Plant Biology, Carnegie Institution For Science
21  260 Panama Street, Stanford, CA 94305, USA
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 
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 ) {
162  stop.write( out );
163  }
164 
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
algorithm.hpp
Provides some valuable algorithms that are not part of the C++ 11 STL.
genesis::utils::SvgPoint::x
double x
Definition: utils/formats/svg/helper.hpp:69
genesis::utils::indent
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:719
genesis::utils::SvgPoint::y
double y
Definition: utils/formats/svg/helper.hpp:70
genesis::utils::SvgGradientLinear::stops
std::vector< SvgGradientStop > stops
Definition: gradient.hpp:175
genesis::utils::SvgTransform::write
void write(std::ostream &out) const
Definition: attributes.cpp:394
genesis::utils::SvgGradientLinear::point_2
SvgPoint point_2
Definition: gradient.hpp:171
genesis::population::to_string
std::string to_string(GenomeLocus const &locus)
Definition: function/genome_locus.hpp:52
genesis::utils::SvgDocument::indentation_string
static std::string indentation_string
Definition: svg/document.hpp:60
genesis::utils::SvgGradientLinear::add_stop
SvgGradientLinear & add_stop(SvgGradientStop const &stop)
Definition: gradient.cpp:180
string.hpp
Provides some commonly used string utility functions.
genesis::utils::SvgGradientLinear::spread_method
SpreadMethod spread_method
Definition: gradient.hpp:173
document.hpp
genesis::utils::SvgGradientStop::operator<
bool operator<(self_type const &rhs) const
Definition: gradient.cpp:68
genesis::utils::Color::a
double a() const
Definition: color.hpp:124
genesis::utils::SvgGradientLinear::write
void write(std::ostream &out, size_t indent=0) const
Definition: gradient.cpp:121
gradient.hpp
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
functions.hpp
Color operators and functions.
genesis::utils::svg_attribute
std::string svg_attribute(std::string const &name, T const &value, std::string const &unit="")
Definition: utils/formats/svg/helper.hpp:229
genesis::utils::SvgGradientLinear
Definition: gradient.hpp:102
genesis::utils::SvgGradientLinear::SpreadMethod::kReflect
@ kReflect
genesis::utils::repeat
std::string repeat(std::string const &word, size_t times)
Take a string and repeat it a given number of times.
Definition: string.cpp:1001
genesis::utils::SvgGradientLinear::set_stops
SvgGradientLinear & set_stops(std::map< double, Color > const &ranges)
Definition: gradient.cpp:169
genesis::utils::SvgGradientLinear::SpreadMethod::kPad
@ kPad
genesis::utils::SvgGradientLinear::transform
SvgTransform transform
Definition: gradient.hpp:176
genesis::utils::SvgGradientLinear::SpreadMethod::kRepeat
@ kRepeat
genesis::utils::SvgGradientStop::write
void write(std::ostream &out) const
Definition: gradient.cpp:58
genesis::utils::SvgGradientStop::offset
double offset
Definition: gradient.hpp:97
genesis::utils::SvgGradientStop
Definition: gradient.hpp:52
genesis::utils::color_to_hex
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]".
Definition: utils/color/functions.cpp:100
genesis::utils::SvgGradientLinear::validate
void validate() const
Definition: gradient.cpp:77
genesis::utils::insert_sorted
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:152
genesis::utils::SvgGradientLinear::point_1
SvgPoint point_1
Definition: gradient.hpp:170
genesis::utils::SvgGradientStop::validate
void validate() const
Definition: gradient.cpp:47
genesis::utils::SvgGradientLinear::empty
bool empty() const
Definition: gradient.cpp:186
genesis::utils::SvgGradientStop::stop_color
Color stop_color
Definition: gradient.hpp:98