]> git.lyx.org Git - features.git/blob - src/frontends/xforms/Color.C
use size_t instead of int to avoid a singed/unsigned warning
[features.git] / src / frontends / xforms / Color.C
1 /**
2  * \file Color.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "Color.h"
14
15 #include "lyx_forms.h"
16
17 #include "LColor.h"
18
19 #include "support/std_sstream.h"
20
21 #include <cmath>
22 #include <iomanip>
23
24 #ifndef CXX_GLOBAL_CSTD
25 using std::floor;
26 #endif
27
28 using std::max;
29 using std::min;
30 using std::setw;
31
32 using std::istringstream;
33 using std::ostringstream;
34 using std::string;
35
36 namespace lyx {
37 namespace frontend {
38
39 namespace {
40
41 int const nohue = -1;
42
43 int hexstrToInt(string const & str)
44 {
45         int val = 0;
46         istringstream is(str);
47         is >> std::setbase(16) >> val;
48         return val;
49 }
50
51 } // namespace anon
52
53
54
55 bool getRGBColor(LColor_color col,
56                  unsigned int & r, unsigned int & g, unsigned int & b)
57 {
58         string const name = lcolor.getX11Name(col);
59         Display * const display = fl_get_display();
60         Colormap const cmap = fl_state[fl_get_vclass()].colormap;
61         XColor xcol, ccol;
62
63         if (XLookupColor(display, cmap, name.c_str(), &xcol, &ccol) == 0) {
64                 r = 0;
65                 g = 0;
66                 b = 0;
67                 return false;
68         }
69
70         r = xcol.red   / 256;
71         g = xcol.green / 256;
72         b = xcol.blue  / 256;
73         return true;
74 }
75
76
77 string const X11hexname(RGBColor const & col)
78 {
79         ostringstream ostr;
80
81         ostr << '#' << std::setbase(16) << std::setfill('0')
82              << setw(2) << col.r
83              << setw(2) << col.g
84              << setw(2) << col.b;
85
86         return ostr.str();
87 }
88
89
90 RGBColor::RGBColor(string const & x11hexname)
91         : r(0), g(0), b(0)
92 {
93         BOOST_ASSERT(x11hexname.size() == 7 && x11hexname[0] == '#');
94         r = hexstrToInt(x11hexname.substr(1,2));
95         g = hexstrToInt(x11hexname.substr(3,2));
96         b = hexstrToInt(x11hexname.substr(5,2));
97 }
98
99
100 RGBColor::RGBColor(HSVColor const & hsv)
101 {
102         double h = hsv.h;
103         double const s = hsv.s;
104         double const v = hsv.v;
105
106         double rd, gd, bd;
107
108         if (h == nohue || s == 0.0) {
109                 rd = gd = bd = v;
110         } else {
111                 if (h == 360.0) h = 0.0;
112                 h /= 60.0;
113
114                 int const j = max(0, static_cast<int>(::floor(h)));
115                 //if (j < 0) j = 0;
116
117                 double const f = h - j;
118                 double const p = v * (1.0 - s);
119                 double const q = v * (1.0 - (s * f));
120                 double const t = v * (1.0 - (s * (1.0 - f)));
121
122                 switch (j) {
123                 case 0:
124                         rd = v;
125                         gd = t;
126                         bd = p;
127                         break;
128                 case 1:
129                         rd = q;
130                         gd = v;
131                         bd = p;
132                         break;
133                 case 2:
134                         rd = p;
135                         gd = v;
136                         bd = t;
137                         break;
138                 case 3:
139                         rd = p;
140                         gd = q;
141                         bd = v;
142                         break;
143                 case 4:
144                         rd = t;
145                         gd = p;
146                         bd = v;
147                         break;
148                 case 5:
149                         rd = v;
150                         gd = p;
151                         bd = q;
152                         break;
153                 default:
154                         rd = v;
155                         gd = t;
156                         bd = p;
157                         break;  // should never happen.
158                 }
159         }
160
161         r = static_cast<int>(::floor((rd * 255.0) + 0.5));
162         g = static_cast<int>(::floor((gd * 255.0) + 0.5));
163         b = static_cast<int>(::floor((bd * 255.0) + 0.5));
164 }
165
166
167 HSVColor::HSVColor(RGBColor const & rgb)
168 {
169         double const r = rgb.r / 255.0;
170         double const g = rgb.g / 255.0;
171         double const b = rgb.b / 255.0;
172
173         double const maxval = max(max(r, g), b);
174         double const minval = min(min(r, g), b);
175
176         v = maxval;
177
178         double const diff = maxval - minval;
179         if (maxval != 0.0)
180                 s = diff / maxval;
181         else
182                 s = 0.0;
183
184         h = nohue;
185         if (s != 0.0) {
186                 double const rc = (maxval - r) / diff;
187                 double const gc = (maxval - g) / diff;
188                 double const bc = (maxval - b) / diff;
189
190                 if (r == maxval)
191                         h = bc - gc;
192                 else if (g == maxval)
193                         h = 2.0 + rc - bc;
194                 else if (b == maxval)
195                         h = 4.0 + gc - rc;
196
197                 h *= 60.0;
198                 if (h < 0)
199                         h += 360;
200         }
201 }
202
203 } // namespace frontend
204 } // namespace lyx