]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/colour.cpp
4aa74d14c07443ced73acbde4dad3c71cc4571fd
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxColour class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 //// TODO: make wxColour a ref-counted object,
13 //// so pixel values get shared.
16 #pragma implementation "colour.h"
19 #include "wx/gdicmn.h"
20 #include "wx/colour.h"
25 #include "wx/motif/private.h"
27 #if !USE_SHARED_LIBRARY
28 IMPLEMENT_DYNAMIC_CLASS(wxColour
, wxObject
)
36 m_red
= m_blue
= m_green
= 0;
40 wxColour::wxColour (unsigned char r
, unsigned char g
, unsigned char b
)
49 wxColour::wxColour (const wxColour
& col
)
52 m_green
= col
.m_green
;
54 m_isInit
= col
.m_isInit
;
55 m_pixel
= col
.m_pixel
;
58 wxColour
& wxColour::operator =(const wxColour
& col
)
61 m_green
= col
.m_green
;
63 m_isInit
= col
.m_isInit
;
64 m_pixel
= col
.m_pixel
;
68 wxColour::wxColour (const wxString
& col
)
70 wxColour
*the_colour
= wxTheColourDatabase
->FindColour (col
);
73 m_red
= the_colour
->Red ();
74 m_green
= the_colour
->Green ();
75 m_blue
= the_colour
->Blue ();
86 m_pixel = PALETTERGB (m_red, m_green, m_blue);
90 wxColour::~wxColour ()
94 wxColour
& wxColour::operator = (const wxString
& col
)
96 wxColour
*the_colour
= wxTheColourDatabase
->FindColour (col
);
99 m_red
= the_colour
->Red ();
100 m_green
= the_colour
->Green ();
101 m_blue
= the_colour
->Blue ();
112 m_pixel = PALETTERGB (m_red, m_green, m_blue);
117 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
)
124 m_pixel = PALETTERGB (m_red, m_green, m_blue);
128 // Allocate a colour, or nearest colour, using the given display.
129 // If realloc is TRUE, ignore the existing pixel, otherwise just return
131 // Returns FALSE if an exact match was not found, TRUE otherwise.
133 // TODO: can this handle mono displays? If not, we should have an extra
134 // flag to specify whether this should be black or white by default.
136 bool wxColour::AllocColour(WXDisplay
* display
, bool realloc
)
138 if ((m_pixel
!= -1) && !realloc
)
142 color
.red
= (unsigned short) Red ();
143 color
.red
|= color
.red
<< 8;
144 color
.green
= (unsigned short) Green ();
145 color
.green
|= color
.green
<< 8;
146 color
.blue
= (unsigned short) Blue ();
147 color
.blue
|= color
.blue
<< 8;
149 color
.flags
= DoRed
| DoGreen
| DoBlue
;
151 WXColormap cmap
= wxTheApp
->GetMainColormap(display
);
153 if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
))
155 m_pixel
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
);
160 m_pixel
= (int) color
.pixel
;
165 /*-------------------------------------------
166 Markus Emmenegger <mege@iqe.ethz.ch>
167 Find the pixel value with an assigned color closest to the desired color
168 Used if color cell allocation fails
169 As the returned pixel value may be in use by another application,
170 the color might change anytime.
171 But in many cases, that is still better than always using black.
173 Chris Breeze <chris@hel.co.uk>
175 1) More efficient calculation of RGB distance of colour cell from
176 the desired colour. There is no need to take the sqrt of 'dist', and
177 since we are only interested in the top 8-bits of R, G and B we
178 can perform integer arithmetic.
179 2) Attempt to allocate a read-only colour when a close match is found.
180 A read-only colour will not change.
181 3) Fall back to the closest match if no read-only colours are available.
183 Possible further improvements:
184 1) Scan the lookup table and sort the colour cells in order of
186 distance from the desired colour. Then attempt to allocate a
188 colour starting from the nearest match.
189 2) Linear RGB distance is not a particularly good method of colour
191 (though it is quick). Converting the colour to HLS and then comparing
192 may give better matching.
193 -------------------------------------------*/
195 int wxGetBestMatchingPixel(Display
*display
, XColor
*desiredColor
, Colormap cmap
)
197 if (cmap
== (Colormap
) NULL
)
198 cmap
= (Colormap
) wxTheApp
->GetMainColormap(display
);
200 int numPixVals
= XDisplayCells(display
, DefaultScreen (display
));
201 int mindist
= 256 * 256 * 3;
202 int bestpixel
= (int) BlackPixel (display
, DefaultScreen (display
));
203 int red
= desiredColor
->red
>> 8;
204 int green
= desiredColor
->green
>> 8;
205 int blue
= desiredColor
->blue
>> 8;
206 const int threshold
= 2 * 2 * 3; // allow an error of up to 2 in R,G & B
208 for (int pixelcount
= 0; pixelcount
< numPixVals
; pixelcount
++)
210 XColor matching_color
;
211 matching_color
.pixel
= pixelcount
;
212 XQueryColor(display
,cmap
,&matching_color
);
214 int delta_red
= red
- (matching_color
.red
>> 8);
215 int delta_green
= green
- (matching_color
.green
>> 8);
216 int delta_blue
= blue
- (matching_color
.blue
>> 8);
218 int dist
= delta_red
* delta_red
+
219 delta_green
* delta_green
+
220 delta_blue
* delta_blue
;
222 if (dist
<= threshold
)
224 // try to allocate a read-only colour...
225 if (XAllocColor (display
, cmap
, &matching_color
))
227 return matching_color
.pixel
;
232 bestpixel
= pixelcount
;