1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 2012 Benjamin Otte <otte@gnome.org> |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | |
20 | #include "gdkhslaprivate.h" |
21 | |
22 | #include <math.h> |
23 | |
24 | void |
25 | _gdk_hsla_init_from_rgba (GdkHSLA *hsla, |
26 | const GdkRGBA *rgba) |
27 | { |
28 | float min; |
29 | float max; |
30 | float red; |
31 | float green; |
32 | float blue; |
33 | float delta; |
34 | |
35 | g_return_if_fail (hsla != NULL); |
36 | g_return_if_fail (rgba != NULL); |
37 | |
38 | red = rgba->red; |
39 | green = rgba->green; |
40 | blue = rgba->blue; |
41 | |
42 | if (red > green) |
43 | { |
44 | if (red > blue) |
45 | max = red; |
46 | else |
47 | max = blue; |
48 | |
49 | if (green < blue) |
50 | min = green; |
51 | else |
52 | min = blue; |
53 | } |
54 | else |
55 | { |
56 | if (green > blue) |
57 | max = green; |
58 | else |
59 | max = blue; |
60 | |
61 | if (red < blue) |
62 | min = red; |
63 | else |
64 | min = blue; |
65 | } |
66 | |
67 | hsla->lightness = (max + min) / 2; |
68 | hsla->saturation = 0; |
69 | hsla->hue = 0; |
70 | hsla->alpha = rgba->alpha; |
71 | |
72 | if (max != min) |
73 | { |
74 | if (hsla->lightness <= 0.5) |
75 | hsla->saturation = (max - min) / (max + min); |
76 | else |
77 | hsla->saturation = (max - min) / (2 - max - min); |
78 | |
79 | delta = max -min; |
80 | if (red == max) |
81 | hsla->hue = (green - blue) / delta; |
82 | else if (green == max) |
83 | hsla->hue = 2 + (blue - red) / delta; |
84 | else if (blue == max) |
85 | hsla->hue = 4 + (red - green) / delta; |
86 | |
87 | hsla->hue *= 60; |
88 | if (hsla->hue < 0.0) |
89 | hsla->hue += 360; |
90 | } |
91 | } |
92 | |
93 | void |
94 | _gdk_rgba_init_from_hsla (GdkRGBA *rgba, |
95 | const GdkHSLA *hsla) |
96 | { |
97 | float hue; |
98 | float lightness; |
99 | float saturation; |
100 | float m1, m2; |
101 | |
102 | lightness = hsla->lightness; |
103 | saturation = hsla->saturation; |
104 | |
105 | if (lightness <= 0.5) |
106 | m2 = lightness * (1 + saturation); |
107 | else |
108 | m2 = lightness + saturation - lightness * saturation; |
109 | m1 = 2 * lightness - m2; |
110 | |
111 | rgba->alpha = hsla->alpha; |
112 | |
113 | if (saturation == 0) |
114 | { |
115 | rgba->red = lightness; |
116 | rgba->green = lightness; |
117 | rgba->blue = lightness; |
118 | } |
119 | else |
120 | { |
121 | hue = hsla->hue + 120; |
122 | while (hue > 360) |
123 | hue -= 360; |
124 | while (hue < 0) |
125 | hue += 360; |
126 | |
127 | if (hue < 60) |
128 | rgba->red = m1 + (m2 - m1) * hue / 60; |
129 | else if (hue < 180) |
130 | rgba->red = m2; |
131 | else if (hue < 240) |
132 | rgba->red = m1 + (m2 - m1) * (240 - hue) / 60; |
133 | else |
134 | rgba->red = m1; |
135 | |
136 | hue = hsla->hue; |
137 | while (hue > 360) |
138 | hue -= 360; |
139 | while (hue < 0) |
140 | hue += 360; |
141 | |
142 | if (hue < 60) |
143 | rgba->green = m1 + (m2 - m1) * hue / 60; |
144 | else if (hue < 180) |
145 | rgba->green = m2; |
146 | else if (hue < 240) |
147 | rgba->green = m1 + (m2 - m1) * (240 - hue) / 60; |
148 | else |
149 | rgba->green = m1; |
150 | |
151 | hue = hsla->hue - 120; |
152 | while (hue > 360) |
153 | hue -= 360; |
154 | while (hue < 0) |
155 | hue += 360; |
156 | |
157 | if (hue < 60) |
158 | rgba->blue = m1 + (m2 - m1) * hue / 60; |
159 | else if (hue < 180) |
160 | rgba->blue = m2; |
161 | else if (hue < 240) |
162 | rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60; |
163 | else |
164 | rgba->blue = m1; |
165 | } |
166 | } |
167 | |
168 | void |
169 | _gdk_hsla_shade (GdkHSLA *dest, |
170 | const GdkHSLA *src, |
171 | float factor) |
172 | { |
173 | g_return_if_fail (dest != NULL); |
174 | g_return_if_fail (src != NULL); |
175 | |
176 | dest->hue = src->hue; |
177 | |
178 | dest->lightness = src->lightness * factor; |
179 | dest->lightness = CLAMP (dest->lightness, 0.0, 1.0); |
180 | |
181 | dest->saturation = src->saturation * factor; |
182 | dest->saturation = CLAMP (dest->saturation, 0.0, 1.0); |
183 | |
184 | dest->alpha = src->alpha; |
185 | } |
186 | |