]> Pileus Git - ~andy/gtk/blob - gtk/gtkcolorutils.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkcolorutils.c
1 /* Color utilities
2  *
3  * Copyright (C) 1999 The Free Software Foundation
4  *
5  * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
6  *          Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
7  *          Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 /*
24  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
25  * file for a list of people on the GTK+ Team.  See the ChangeLog
26  * files for a list of changes.  These files are distributed with
27  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28  */
29
30 #include "config.h"
31
32 #include <math.h>
33 #include <string.h>
34
35 #include "gtkcolorutils.h"
36
37
38 #define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
39
40 /* Converts from HSV to RGB */
41 static void
42 hsv_to_rgb (gdouble *h,
43             gdouble *s,
44             gdouble *v)
45 {
46   gdouble hue, saturation, value;
47   gdouble f, p, q, t;
48
49   if (*s == 0.0)
50     {
51       *h = *v;
52       *s = *v;
53       *v = *v; /* heh */
54     }
55   else
56     {
57       hue = *h * 6.0;
58       saturation = *s;
59       value = *v;
60
61       if (hue == 6.0)
62         hue = 0.0;
63
64       f = hue - (int) hue;
65       p = value * (1.0 - saturation);
66       q = value * (1.0 - saturation * f);
67       t = value * (1.0 - saturation * (1.0 - f));
68
69       switch ((int) hue)
70         {
71         case 0:
72           *h = value;
73           *s = t;
74           *v = p;
75           break;
76
77         case 1:
78           *h = q;
79           *s = value;
80           *v = p;
81           break;
82
83         case 2:
84           *h = p;
85           *s = value;
86           *v = t;
87           break;
88
89         case 3:
90           *h = p;
91           *s = q;
92           *v = value;
93           break;
94
95         case 4:
96           *h = t;
97           *s = p;
98           *v = value;
99           break;
100
101         case 5:
102           *h = value;
103           *s = p;
104           *v = q;
105           break;
106
107         default:
108           g_assert_not_reached ();
109         }
110     }
111 }
112
113 /* Converts from RGB to HSV */
114 static void
115 rgb_to_hsv (gdouble *r,
116             gdouble *g,
117             gdouble *b)
118 {
119   gdouble red, green, blue;
120   gdouble h, s, v;
121   gdouble min, max;
122   gdouble delta;
123
124   red = *r;
125   green = *g;
126   blue = *b;
127
128   h = 0.0;
129
130   if (red > green)
131     {
132       if (red > blue)
133         max = red;
134       else
135         max = blue;
136
137       if (green < blue)
138         min = green;
139       else
140         min = blue;
141     }
142   else
143     {
144       if (green > blue)
145         max = green;
146       else
147         max = blue;
148
149       if (red < blue)
150         min = red;
151       else
152         min = blue;
153     }
154
155   v = max;
156
157   if (max != 0.0)
158     s = (max - min) / max;
159   else
160     s = 0.0;
161
162   if (s == 0.0)
163     h = 0.0;
164   else
165     {
166       delta = max - min;
167
168       if (red == max)
169         h = (green - blue) / delta;
170       else if (green == max)
171         h = 2 + (blue - red) / delta;
172       else if (blue == max)
173         h = 4 + (red - green) / delta;
174
175       h /= 6.0;
176
177       if (h < 0.0)
178         h += 1.0;
179       else if (h > 1.0)
180         h -= 1.0;
181     }
182
183   *r = h;
184   *g = s;
185   *b = v;
186 }
187
188 /**
189  * gtk_hsv_to_rgb:
190  * @h: Hue
191  * @s: Saturation
192  * @v: Value
193  * @r: (out): Return value for the red component
194  * @g: (out): Return value for the green component
195  * @b: (out): Return value for the blue component
196  *
197  * Converts a color from HSV space to RGB.
198  *
199  * Input values must be in the [0.0, 1.0] range;
200  * output values will be in the same range.
201  *
202  * Since: 2.14
203  */
204 void
205 gtk_hsv_to_rgb (gdouble  h, gdouble  s, gdouble  v,
206                 gdouble *r, gdouble *g, gdouble *b)
207 {
208   g_return_if_fail (h >= 0.0 && h <= 1.0);
209   g_return_if_fail (s >= 0.0 && s <= 1.0);
210   g_return_if_fail (v >= 0.0 && v <= 1.0);
211
212   hsv_to_rgb (&h, &s, &v);
213
214   if (r)
215     *r = h;
216
217   if (g)
218     *g = s;
219
220   if (b)
221     *b = v;
222 }
223
224 /**
225  * gtk_rgb_to_hsv:
226  * @r: Red
227  * @g: Green
228  * @b: Blue
229  * @h: (out): Return value for the hue component
230  * @s: (out): Return value for the saturation component
231  * @v: (out): Return value for the value component
232  *
233  * Converts a color from RGB space to HSV.
234  *
235  * Input values must be in the [0.0, 1.0] range;
236  * output values will be in the same range.
237  *
238  * Since: 2.14
239  */
240 void
241 gtk_rgb_to_hsv (gdouble  r, gdouble  g, gdouble  b,
242                 gdouble *h, gdouble *s, gdouble *v)
243 {
244   g_return_if_fail (r >= 0.0 && r <= 1.0);
245   g_return_if_fail (g >= 0.0 && g <= 1.0);
246   g_return_if_fail (b >= 0.0 && b <= 1.0);
247
248   rgb_to_hsv (&r, &g, &b);
249
250   if (h)
251     *h = r;
252
253   if (s)
254     *s = g;
255
256   if (v)
257     *v = b;
258 }