]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/Color.C
Refactor xforms' colour handling code.
[lyx.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 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "Color.h"
18 #include <algorithm> // max
19 #include <cmath> // floor
20 #include FORMS_H_LOCATION
21
22 #ifndef CXX_GLOBAL_CSTD
23 using std::floor;
24 #endif
25
26 using std::max;
27 using std::min;
28
29 namespace {
30
31 int const nohue = -1;
32
33 } // namespace anon
34
35
36 bool getRGBColor(LColor::color col,
37                  unsigned int & r, unsigned int & g, unsigned int & b)
38 {
39         string const name = lcolor.getX11Name(col);
40         Display * const display = fl_get_display();
41         Colormap const cmap = fl_state[fl_get_vclass()].colormap;
42         XColor xcol, ccol;
43
44         if (XLookupColor(display, cmap, name.c_str(), &xcol, &ccol) == 0) {
45                 r = 0;
46                 g = 0;
47                 b = 0;
48                 return false;
49         }
50
51         r = xcol.red   / 256;
52         g = xcol.green / 256;
53         b = xcol.blue  / 256;
54         return true;
55 }
56
57
58 RGBColor::RGBColor(HSVColor const & hsv)
59 {
60         double h = hsv.h;
61         double const s = hsv.s;
62         double const v = hsv.v;
63
64         double rd, gd, bd;
65
66         if (h == nohue || s == 0.0) {
67                 rd = gd = bd = v;
68         } else {
69                 if (h == 360.0) h = 0.0;
70                 h /= 60.0;
71
72                 int const j = max(0, static_cast<int>(::floor(h)));
73                 //if (j < 0) j = 0;
74
75                 double const f = h - j;
76                 double const p = v * (1.0 - s);
77                 double const q = v * (1.0 - (s * f));
78                 double const t = v * (1.0 - (s * (1.0 - f)));
79
80                 switch (j) {
81                 case 0:
82                         rd = v;
83                         gd = t;
84                         bd = p;
85                         break;
86                 case 1:
87                         rd = q;
88                         gd = v;
89                         bd = p;
90                         break;
91                 case 2:
92                         rd = p;
93                         gd = v;
94                         bd = t;
95                         break;
96                 case 3:
97                         rd = p;
98                         gd = q;
99                         bd = v;
100                         break;
101                 case 4:
102                         rd = t;
103                         gd = p;
104                         bd = v;
105                         break;
106                 case 5:
107                         rd = v;
108                         gd = p;
109                         bd = q;
110                         break;
111                 default:
112                         rd = v;
113                         gd = t;
114                         bd = p;
115                         break;  // should never happen.
116                 }
117         }
118
119         r = static_cast<int>(::floor((rd * 255.0) + 0.5));
120         g = static_cast<int>(::floor((gd * 255.0) + 0.5));
121         b = static_cast<int>(::floor((bd * 255.0) + 0.5));
122 }
123
124
125 HSVColor::HSVColor(RGBColor const & rgb)
126 {
127         double const r = rgb.r / 255.0;
128         double const g = rgb.g / 255.0;
129         double const b = rgb.b / 255.0;
130
131         double const maxval = max(max(r, g), b);
132         double const minval = min(min(r, g), b);
133
134         v = maxval;
135
136         double const diff = maxval - minval;
137         if (maxval != 0.0)
138                 s = diff / maxval;
139         else
140                 s = 0.0;
141
142         h = nohue;
143         if (s != 0.0) {
144                 double const rc = (maxval - r) / diff;
145                 double const gc = (maxval - g) / diff;
146                 double const bc = (maxval - b) / diff;
147
148                 if (r == maxval)
149                         h = bc - gc;
150                 else if (g == maxval)
151                         h = 2.0 + rc - bc;
152                 else if (b == maxval)
153                         h = 4.0 + gc - rc;
154
155                 h *= 60.0;
156                 if (h < 0)
157                         h += 360;
158         }
159 }