xref: /haiku/src/servers/app/RGBColor.cpp (revision 93aeb8c3bc3f13cb1f282e3e749258a23790d947)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, Haiku, Inc.
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		RGBColor.cpp
23 //	Author:			DarkWyrm <bpmagic@columbus.rr.com>
24 //	Description:	Color encapsulation class for the app_server
25 //
26 //------------------------------------------------------------------------------
27 
28 // Standard Includes -----------------------------------------------------------
29 #include <stdio.h>
30 
31 // Local Includes --------------------------------------------------------------
32 #include "RGBColor.h"
33 #include "SystemPalette.h"
34 #include <ColorUtils.h>
35 
36 /*!
37 	\brief Create an RGBColor from specified values
38 	\param red red
39 	\param green green
40 	\param blue blue
41 	\param alpha alpha, defaults to 255
42 */
43 RGBColor::RGBColor(uint8 r, uint8 g, uint8 b, uint8 a)
44 {
45 	SetColor(r,g,b,a);
46 }
47 
48 /*!
49 	\brief Create an RGBColor from specified values
50 	\param red red
51 	\param green green
52 	\param blue blue
53 	\param alpha alpha, defaults to 255
54 */
55 RGBColor::RGBColor(int r, int g, int b, int a)
56 {
57 	SetColor(r,g,b,a);
58 }
59 
60 /*!
61 	\brief Create an RGBColor from an rgb_color
62 	\param col color to initialize from
63 */
64 RGBColor::RGBColor(const rgb_color &col)
65 {
66 	SetColor(col);
67 }
68 
69 /*!
70 	\brief Create an RGBColor from a 16-bit RGBA color
71 	\param col color to initialize from
72 */
73 RGBColor::RGBColor(uint16 col)
74 {
75 	SetColor(col);
76 }
77 
78 /*!
79 	\brief Create an RGBColor from an index color
80 	\param col color to initialize from
81 */
82 RGBColor::RGBColor(uint8 col)
83 {
84 	SetColor(col);
85 }
86 
87 /*!
88 	\brief Copy Contructor
89 	\param col color to initialize from
90 */
91 RGBColor::RGBColor(const RGBColor &col)
92 {
93 	color32=col.color32;
94 	color16=col.color16;
95 	color8=col.color8;
96 	update8=col.update8;
97 	update16=col.update16;
98 }
99 
100 /*!
101 	\brief Create an RGBColor with the values(0,0,0,0)
102 */
103 RGBColor::RGBColor()
104 {
105 	SetColor(0,0,0,0);
106 	update8=update16=false;
107 }
108 
109 /*!
110 	\brief Returns the color as the closest 8-bit color in the palette
111 	\return The palette index for the current color
112 */
113 uint8 RGBColor::GetColor8() const
114 {
115 	if(update8)
116 	{
117 		color8=FindClosestColor(SystemPalette(), color32);
118 		update8=false;
119 	}
120 
121 	return color8;
122 }
123 
124 /*!
125 	\brief Returns the color as the closest 15-bit color
126 	\return 15-bit value of the current color plus 1-bit alpha
127 */
128 uint16 RGBColor::GetColor15() const
129 {
130 	if(update15)
131 	{
132 		color15=FindClosestColor15(color32);
133 		update15=false;
134 	}
135 
136 	return color15;
137 }
138 
139 /*!
140 	\brief Returns the color as the closest 16-bit color
141 	\return 16-bit value of the current color
142 */
143 uint16 RGBColor::GetColor16() const
144 {
145 	if(update16)
146 	{
147 		color16=FindClosestColor16(color32);
148 		update16=false;
149 	}
150 
151 	return color16;
152 }
153 
154 /*!
155 	\brief Returns the color as a 32-bit color
156 	\return current color, including alpha
157 */
158 rgb_color RGBColor::GetColor32() const
159 {
160 	return color32;
161 }
162 
163 /*!
164 	\brief Set the object to specified values
165 	\param red red
166 	\param green green
167 	\param blue blue
168 	\param alpha alpha, defaults to 255
169 */
170 void RGBColor::SetColor(uint8 r, uint8 g, uint8 b, uint8 a)
171 {
172 	color32.red=r;
173 	color32.green=g;
174 	color32.blue=b;
175 	color32.alpha=a;
176 
177 	update8=update16=true;
178 }
179 
180 /*!
181 	\brief Set the object to specified values
182 	\param red red
183 	\param green green
184 	\param blue blue
185 	\param alpha alpha, defaults to 255
186 */
187 void RGBColor::SetColor(int r, int g, int b, int a)
188 {
189 	color32.red=(uint8)r;
190 	color32.green=(uint8)g;
191 	color32.blue=(uint8)b;
192 	color32.alpha=(uint8)a;
193 
194 	update8=update16=true;
195 }
196 
197 /*!
198 	\brief Set the object to specified value
199 	\param col16 color to copy
200 */
201 void RGBColor::SetColor(uint16 col16)
202 {
203 	color16=col16;
204 	SetRGBColor(&color32,col16);
205 
206 	update8=true;
207 	update16=false;
208 }
209 
210 /*!
211 	\brief Set the object to specified index in the palette
212 	\param col8 color to copy
213 */
214 void RGBColor::SetColor(uint8 col8)
215 {
216 	color8=col8;
217 	color32=SystemPalette()[col8];
218 
219 	update8=false;
220 	update16=true;
221 }
222 
223 /*!
224 	\brief Set the object to specified color
225 	\param color color to copy
226 */
227 void RGBColor::SetColor(const rgb_color &color)
228 {
229 	color32=color;
230 	update8=update16=true;
231 }
232 
233 /*!
234 	\brief Set the object to specified color
235 	\param col color to copy
236 */
237 void RGBColor::SetColor(const RGBColor &col)
238 {
239 	color32=col.color32;
240 	color16=col.color16;
241 	color8=col.color8;
242 	update8=col.update8;
243 	update16=col.update16;
244 }
245 
246 /*!
247 	\brief Set the object to specified color
248 	\param col color to copy
249 */
250 const RGBColor & RGBColor::operator=(const RGBColor &col)
251 {
252 	color32=col.color32;
253 	color16=col.color16;
254 	color8=col.color8;
255 	update8=col.update8;
256 	update16=col.update16;
257 	return *this;
258 }
259 
260 /*!
261 	\brief Set the object to specified color
262 	\param col color to copy
263 */
264 const RGBColor & RGBColor::operator=(const rgb_color &col)
265 {
266 	color32=col;
267 	update8=update16=true;
268 
269 	return *this;
270 }
271 
272 /*!
273 	\brief Returns a color blended between the object's value and
274 	another color.
275 
276 	\param color The other color to be blended with.
277 	\param position A weighted percentage of the second color to use. 0 <= value <= 1.0
278 	\return The blended color
279 
280 	If the position passed to this function is invalid, the starting
281 	color will be returned.
282 */
283 RGBColor RGBColor::MakeBlendColor(const RGBColor &color, const float &position)
284 {
285 	rgb_color col=color32;
286 	rgb_color col2=color.color32;
287 
288 	rgb_color newcol={0,0,0,0};
289 	float mod=0;
290 	int16 delta;
291 	if(position<0 || position>1)
292 		return *this;
293 
294 	delta=int16(col2.red)-int16(col.red);
295 	mod=col.red + (position * delta);
296 	newcol.red=uint8(mod);
297 	if(mod>255 )
298 		newcol.red=255;
299 	if(mod<0 )
300 		newcol.red=0;
301 
302 delta=int16(col2.green)-int16(col.green);
303 	mod=col.green + (position * delta);
304 	newcol.green=uint8(mod);
305 	if(mod>255 )
306 		newcol.green=255;
307 	if(mod<0 )
308 		newcol.green=0;
309 
310 	delta=int16(col2.blue)-int16(col.blue);
311 	mod=col.blue + (position * delta);
312 	newcol.blue=uint8(mod);
313 	if(mod>255 )
314 		newcol.blue=255;
315 	if(mod<0 )
316 		newcol.blue=0;
317 
318 	delta=int8(col2.alpha)-int8(col.alpha);
319 	mod=col.alpha + (position * delta);
320 	newcol.alpha=uint8(mod);
321 	if(mod>255 )
322 		newcol.alpha=255;
323 	if(mod<0 )
324 		newcol.alpha=0;
325 
326 	return RGBColor(newcol);
327 }
328 
329 /*!
330 	\brief Prints the 32-bit values of the color to standard out
331 */
332 void RGBColor::PrintToStream(void) const
333 {
334 	printf("RGBColor (%u,%u,%u,%u)\n", color32.red,color32.green,color32.blue,color32.alpha);
335 }
336 
337 /*!
338 	\brief Overloaded comaparison
339 	\return true if all color elements are exactly equal
340 */
341 bool RGBColor::operator==(const rgb_color &col) const
342 {
343 	return color32.red == col.red &&
344 		   color32.green == col.green &&
345 		   color32.blue == col.blue &&
346 		   color32.alpha == col.alpha;
347 }
348 
349 /*!
350 	\brief Overloaded comaparison
351 	\return true if all color elements are exactly equal
352 */
353 bool RGBColor::operator==(const RGBColor &col) const
354 {
355 	return color32.red == col.color32.red &&
356 		   color32.green == col.color32.green &&
357 		   color32.blue == col.color32.blue &&
358 		   color32.alpha == col.color32.alpha;
359 }
360 
361 // IsTransparentMagic
362 bool
363 RGBColor::IsTransparentMagic() const
364 {
365 	// TODO: validate this for B_CMAP8 for example
366 	return *this == B_TRANSPARENT_COLOR;
367 }
368