The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
color_range.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
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 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Generate ranges of colors, and color palettes.
18  * Used e.g. to color HP, XP.
19  */
20 
21 #include "color_range.hpp"
22 
23 #include "game_config.hpp"
24 #include "map/map.hpp"
26 #include "util.hpp"
27 
28 #include <iomanip>
29 
30 std::map<Uint32, Uint32> recolor_range(const color_range& new_range, const std::vector<Uint32>& old_rgb){
31  std::map<Uint32, Uint32> map_rgb;
32 
33  Uint16 new_red = (new_range.mid() & 0x00FF0000)>>16;
34  Uint16 new_green= (new_range.mid() & 0x0000FF00)>>8;
35  Uint16 new_blue = (new_range.mid() & 0x000000FF);
36  Uint16 max_red = (new_range.max() & 0x00FF0000)>>16;
37  Uint16 max_green= (new_range.max() & 0x0000FF00)>>8 ;
38  Uint16 max_blue = (new_range.max() & 0x000000FF) ;
39  Uint16 min_red = (new_range.min() & 0x00FF0000)>>16;
40  Uint16 min_green= (new_range.min() & 0x0000FF00)>>8 ;
41  Uint16 min_blue = (new_range.min() & 0x000000FF) ;
42 
43  // Map first color in vector to exact new color
44  Uint32 temp_rgb= old_rgb.empty() ? 0 : old_rgb[0];
45  Uint16 old_r=(temp_rgb & 0X00FF0000)>>16;
46  Uint16 old_g=(temp_rgb & 0X0000FF00)>>8;
47  Uint16 old_b=(temp_rgb & 0X000000FF);
48  Uint16 reference_avg = (( old_r + old_g + old_b) / 3);
49 
50  for(std::vector< Uint32 >::const_iterator temp_rgb2 = old_rgb.begin();
51  temp_rgb2 != old_rgb.end(); ++temp_rgb2)
52  {
53  Uint16 old_r=((*temp_rgb2) & 0X00FF0000)>>16;
54  Uint16 old_g=((*temp_rgb2) & 0X0000FF00)>>8;
55  Uint16 old_b=((*temp_rgb2) & 0X000000FF);
56 
57  const Uint16 old_avg = (( old_r + old_g + old_b) / 3);
58  // Calculate new color
59  Uint32 new_r, new_g, new_b;
60 
61  if(reference_avg && old_avg <= reference_avg){
62  float old_rat = static_cast<float>(old_avg)/reference_avg;
63  new_r=Uint32( old_rat * new_red + (1 - old_rat) * min_red);
64  new_g=Uint32( old_rat * new_green + (1 - old_rat) * min_green);
65  new_b=Uint32( old_rat * new_blue + (1 - old_rat) * min_blue);
66  }else if(255 - reference_avg){
67  float old_rat = (255.0f - static_cast<float>(old_avg)) /
68  (255.0f - reference_avg);
69 
70  new_r=static_cast<Uint32>( old_rat * new_red + (1 - old_rat) * max_red);
71  new_g=static_cast<Uint32>( old_rat * new_green + (1 - old_rat) * max_green);
72  new_b=static_cast<Uint32>( old_rat * new_blue + (1 - old_rat) * max_blue);
73  }else{
74  new_r=0; new_g=0; new_b=0; // Suppress warning
75  assert(false);
76  // Should never get here.
77  // Would imply old_avg > reference_avg = 255
78  }
79 
80  if(new_r>255) new_r=255;
81  if(new_g>255) new_g=255;
82  if(new_b>255) new_b=255;
83 
84  Uint32 newrgb = (new_r << 16) + (new_g << 8) + (new_b );
85  map_rgb[*temp_rgb2]=newrgb;
86  }
87 
88  return map_rgb;
89 }
90 
91 bool string2rgb(const std::string& s, std::vector<Uint32>& result) {
92  result = std::vector<Uint32>();
93  std::vector<Uint32> out;
94  std::vector<std::string> rgb_vec = utils::split(s);
95  std::vector<std::string>::iterator c=rgb_vec.begin();
96  while(c!=rgb_vec.end())
97  {
98  Uint32 rgb_hex;
99  if(c->length() != 6)
100  {
101  try {
102  // integer triplets, e.g. white="255,255,255"
103  rgb_hex = (0x00FF0000 & ((lexical_cast<int>(*c++))<<16)); //red
104  if(c!=rgb_vec.end())
105  {
106  rgb_hex += (0x0000FF00 & ((lexical_cast<int>(*c++))<<8)); //green
107  if(c!=rgb_vec.end())
108  {
109  rgb_hex += (0x000000FF & ((lexical_cast<int>(*c++))<<0)); //blue
110  }
111  }
112  } catch (bad_lexical_cast&) {
113  return false;
114  }
115  } else {
116  // hexadecimal format, e.g. white="FFFFFF"
117  char* endptr;
118  rgb_hex = (0x00FFFFFF & strtol(c->c_str(), &endptr, 16));
119  if (*endptr != '\0') {
120  return false;
121  }
122  ++c;
123  }
124  out.push_back(rgb_hex);
125  }
126  result = out;
127  return true;
128 }
129 
130 std::vector<Uint32> palette(color_range cr){
131 // generate a color palette from a color range
132  std::vector<Uint32> temp,res;
133  std::set<Uint32> clist;
134  // use blue to make master set of possible colors
135  for(int i=255;i!=0;i--){
136  int j=255-i;
137  Uint32 rgb = i;
138  temp.push_back(rgb);
139  rgb = (j << 16) + (j << 8) + 255;
140  temp.push_back(rgb);
141  }
142 
143  // Use recolor function to generate list of possible colors.
144  // Could use a special function, would be more efficient,
145  // but harder to maintain.
146  std::map<Uint32,Uint32> cmap = recolor_range(cr,temp);
147  for(std::map<Uint32,Uint32>::const_iterator k=cmap.begin(); k!=cmap.end();++k){
148  clist.insert(k->second);
149  }
150  res.push_back(cmap[255]);
151  for(std::set<Uint32>::const_iterator c=clist.begin();c!=clist.end();++c){
152  if(*c != res[0] && *c!=0 && *c != 0x00FFFFFF){
153  res.push_back(*c);}
154  }
155  return(res);
156 }
157 
159 {
160  std::ostringstream h;
161  // Must match what the escape interpreter for marked-up-text expects
162  h << "<" << ((rgb & 0xFF0000) >> 16)
163  << "," << ((rgb & 0x00FF00) >> 8)
164  << "," << (rgb & 0x0000FF) << ">";
165  return h.str();
166 }
167 
169 {
170  std::ostringstream h;
171  // Must match what the pango expects
172  h << "#" << std::hex << std::setfill('0') << std::setw(2) << ((rgb & 0xFF0000) >> 16)
173  << std::hex << std::setfill('0') << std::setw(2) <<((rgb & 0x00FF00) >> 8)
174  << std::hex << std::setfill('0') << std::setw(2) <<(rgb & 0x0000FF);
175  return h.str();
176 }
177 
179 {
180  for(int i = 1; i <= gamemap::MAX_PLAYERS; ++i) {
181  if(*this==(game_config::color_info(std::to_string(i)))) {
182  return i;
183  }
184  }
185  return 0;
186 }
187 
189 {
190  std::ostringstream o;
191 
192  static const Uint32 mask = 0x00FFFFFF;
193 
194  o << std::hex << std::setfill('0')
195  << '{' << std::setw(6) << (mid_ & mask)
196  << ',' << std::setw(6) << (max_ & mask)
197  << ',' << std::setw(6) << (min_ & mask)
198  << ',' << std::setw(6) << (rep_ & mask)
199  << '}';
200 
201  return o.str();
202 }
std::string debug() const
Return a string describing the color range for debug output.
const GLfloat * c
Definition: glew.h:12741
Uint32 mid() const
Average color shade.
Definition: color_range.hpp:82
bool string2rgb(const std::string &s, std::vector< Uint32 > &result)
Definition: color_range.cpp:91
#define h
To lexical_cast(From value)
Lexical cast converts one type to another.
GLuint64EXT * result
Definition: glew.h:10727
GLenum GLint GLuint mask
Definition: glew.h:1813
Templates and utility-routines for strings and numbers.
GLuint res
Definition: glew.h:9258
A color range definition is made of four reference RGB colors, used for calculating conversions from ...
Definition: color_range.hpp:54
size_t i
Definition: function.cpp:1057
int index() const
const color_range & color_info(const std::string &name)
Uint32 min() const
Minimum color shade.
Definition: color_range.hpp:86
#define c
Definition: glew.h:12743
std::map< Uint32, Uint32 > recolor_range(const color_range &new_range, const std::vector< Uint32 > &old_rgb)
Converts a source palette using the specified color_range object.
Definition: color_range.cpp:30
std::string rgb2highlight(Uint32 rgb)
Converts a color value to WML text markup syntax for highlighting.
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
std::string rgb2highlight_pango(Uint32 rgb)
Converts a color value to WML text markup syntax for highlighting.
#define mask(n)
Definition: lbitlib.cpp:28
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
GLdouble s
Definition: glew.h:1358
Thrown when a lexical_cast fails.
std::vector< Uint32 > palette(color_range cr)
Creates a reference color palette from a color range.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Uint32 max() const
Maximum color shade.
Definition: color_range.hpp:84