1 #ifndef oxygenrgba_h
2 #define oxygenrgba_h
3 /*
4 * this file is part of the oxygen gtk engine
5 * Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
6 *
7 * inspired notably from kdelibs/kdeui/color/kcolorutils.h
8 * Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
9 * Copyright (C) 2007 Thomas Zander <zander@kde.org>
10 * Copyright (C) 2007 Zack Rusin <zack@kde.org>
11 *
12 * This  library is free  software; you can  redistribute it and/or
13 * modify it  under  the terms  of the  GNU Lesser  General  Public
14 * License  as published  by the Free  Software  Foundation; either
15 * version 2 of the License, or( at your option ) any later version.
16 *
17 * This library is distributed  in the hope that it will be useful,
18 * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License  along  with  this library;  if not,  write to  the Free
24 * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
25 * MA 02110-1301, USA.
26 */
27 
28 #include <climits>
29 #include <iostream>
30 #include <iomanip>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34 #include <gdk/gdk.h>
35 
36 namespace Oxygen
37 {
38 
39     namespace ColorUtils
40     {
41 
42         //! stores rgba representation of a color
43         /*! all values must be between 0 and 1 */
44         class Rgba
45         {
46 
47             private:
48             typedef unsigned short color_t;
49 
50             public:
51 
52             //! constructor
Rgba(void)53             Rgba( void ):
54                 _red(0),
55                 _green(0),
56                 _blue(0),
57                 _alpha(USHRT_MAX),
58                 _mask(0)
59             {}
60 
61             //! constructor
62             Rgba( double r, double g, double b, double a = 1 ):
63                 _red( (color_t) (r*USHRT_MAX) ),
64                 _green( (color_t) (g*USHRT_MAX) ),
65                 _blue( (color_t) (b*USHRT_MAX) ),
66                 _alpha( (color_t) (a*USHRT_MAX) ),
67                 _mask( RGBA )
68             {}
69 
70             //! equal to operator
71             /*! TODO: check why alpha channel is not used in the comparison */
72             bool operator == (const Rgba& other ) const
73             {
74                 return
75                     _mask == other._mask &&
76                     _red == other._red &&
77                     _green == other._green &&
78                     _blue == other._blue;
79             }
80 
81             //! different operator
82             bool operator != (const Rgba& other ) const
83             {
84                 return
85                     _mask != other._mask ||
86                     _red != other._red ||
87                     _green != other._green ||
88                     _blue != other._blue;
89             }
90 
91             // convert to integer
toInt(void)92             guint32 toInt( void ) const
93             {
94                 return
95                     (guint32( _red >> 8 ) << 24) |
96                     (guint32( _green >> 8 ) << 16) |
97                     (guint32( _green >> 8 ) << 8) |
98                     guint32( _alpha >> 8 );
99             }
100 
101             // convert to string
string(void)102             operator std::string ( void ) const
103             {
104                 std::ostringstream out;
105                 out
106                     << "#"
107                     << std::hex
108                     << std::setw( 2 ) << std::setfill( '0' ) << guint32( _red >> 8 )
109                     << std::setw( 2 ) << std::setfill( '0' ) << guint32( _green >> 8 )
110                     << std::setw( 2 ) << std::setfill( '0' ) << guint32( _blue >> 8 );
111                 return out.str();
112             }
113 
114             //! make color lighter
115             /*! Copied from QColor. Amount must be > 100. */
116             Rgba light( int amount ) const;
117 
118             //! make color darker
119             /*! Copied from QColor. Amount must be > 100. */
120             Rgba dark( int amount ) const;
121 
122             //!@name access colors
123             //@{
124 
red(void)125             double red( void ) const
126             { return double(_red)/USHRT_MAX; }
127 
green(void)128             double green( void ) const
129             { return double(_green)/USHRT_MAX; }
130 
blue(void)131             double blue( void ) const
132             { return double(_blue)/USHRT_MAX; }
133 
alpha(void)134             double alpha( void ) const
135             { return double(_alpha)/USHRT_MAX; }
136 
137             //! value (in HSV colorspace)
value(void)138             double value( void ) const
139             { return std::max( red(), std::max( green(), blue() ) ); }
140 
141             //@}
142 
143             //!@name set colors
144             //@{
145 
setRed(double value)146             Rgba& setRed( double value )
147             {
148                 _red = (color_t)(value*USHRT_MAX);
149                 _mask |= R;
150                 return *this;
151             }
152 
setGreen(double value)153             Rgba& setGreen( double value )
154             {
155                 _green = (color_t)(value*USHRT_MAX);
156                 _mask |= G;
157                 return *this;
158             }
159 
setBlue(double value)160             Rgba& setBlue( double value )
161             {
162                 _blue = (color_t)(value*USHRT_MAX);
163                 _mask |= B;
164                 return *this;
165             }
166 
setAlpha(double value)167             Rgba& setAlpha( double value )
168             {
169                 _alpha = (color_t)(value*USHRT_MAX);
170                 _mask |= A;
171                 return *this;
172             }
173 
174             //@}
175 
176             //! convert to hsv
177             void toHsv( double&, double&, double& ) const;
178 
179             //! convert from hsv
180             Rgba& fromHsv( double, double, double );
181 
182             //! validity
isValid(void)183             bool isValid( void ) const
184             { return (_mask & RGB ) == RGB; }
185 
186             //! utilities
187             static Rgba fromKdeOption( std::string );
188 
189             //!@name predefined colors
190             //@{
black(void)191             static Rgba black( void ) { return Rgba( 0, 0, 0, 1 ); }
white(void)192             static Rgba white( void ) { return Rgba( 1, 1, 1, 1 ); }
193             static Rgba transparent( const ColorUtils::Rgba& base = black()  )
194             { return Rgba( base ).setAlpha(0); }
195 
196             //@}
197 
198             private:
199 
200             enum ColorBit
201             {
202                 R = 1<<0,
203                 G = 1<<1,
204                 B = 1<<2,
205                 A = 1<<3,
206                 RGB = R|G|B,
207                 RGBA = RGB|A
208             };
209 
210             color_t _red;
211             color_t _green;
212             color_t _blue;
213             color_t _alpha;
214 
215             unsigned int _mask;
216 
217             friend std::ostream& operator << ( std::ostream& out, const Rgba& rgba )
218             { return out << ( rgba._red >> 8 ) << "," << ( rgba._green >> 8 ) << "," << ( rgba._blue >> 8 ) << "," << (rgba._alpha >> 8); }
219 
220         };
221 
222     }
223 }
224 
225 #endif
226