]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/colour.cpp
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 ();
76 m_pixel
= the_colour
->m_pixel
;
88 wxColour::~wxColour ()
92 wxColour
& wxColour::operator = (const wxString
& col
)
94 wxColour
*the_colour
= wxTheColourDatabase
->FindColour (col
);
97 m_red
= the_colour
->Red ();
98 m_green
= the_colour
->Green ();
99 m_blue
= the_colour
->Blue ();
100 m_pixel
= the_colour
->m_pixel
;
114 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
)
123 // Allocate a colour, or nearest colour, using the given display.
124 // If realloc is TRUE, ignore the existing pixel, otherwise just return
126 // Returns the old or allocated pixel.
128 // TODO: can this handle mono displays? If not, we should have an extra
129 // flag to specify whether this should be black or white by default.
131 int wxColour::AllocColour(WXDisplay
* display
, bool realloc
)
133 if ((m_pixel
!= -1) && !realloc
)
137 color
.red
= (unsigned short) Red ();
138 color
.red
|= color
.red
<< 8;
139 color
.green
= (unsigned short) Green ();
140 color
.green
|= color
.green
<< 8;
141 color
.blue
= (unsigned short) Blue ();
142 color
.blue
|= color
.blue
<< 8;
144 color
.flags
= DoRed
| DoGreen
| DoBlue
;
146 WXColormap cmap
= wxTheApp
->GetMainColormap(display
);
148 if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
))
150 m_pixel
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
);
155 m_pixel
= (int) color
.pixel
;
160 /*-------------------------------------------
161 Markus Emmenegger <mege@iqe.ethz.ch>
162 Find the pixel value with an assigned color closest to the desired color
163 Used if color cell allocation fails
164 As the returned pixel value may be in use by another application,
165 the color might change anytime.
166 But in many cases, that is still better than always using black.
168 Chris Breeze <chris@hel.co.uk>
170 1) More efficient calculation of RGB distance of colour cell from
171 the desired colour. There is no need to take the sqrt of 'dist', and
172 since we are only interested in the top 8-bits of R, G and B we
173 can perform integer arithmetic.
174 2) Attempt to allocate a read-only colour when a close match is found.
175 A read-only colour will not change.
176 3) Fall back to the closest match if no read-only colours are available.
178 Possible further improvements:
179 1) Scan the lookup table and sort the colour cells in order of
181 distance from the desired colour. Then attempt to allocate a
183 colour starting from the nearest match.
184 2) Linear RGB distance is not a particularly good method of colour
186 (though it is quick). Converting the colour to HLS and then comparing
187 may give better matching.
188 -------------------------------------------*/
190 int wxGetBestMatchingPixel(Display
*display
, XColor
*desiredColor
, Colormap cmap
)
192 if (cmap
== (Colormap
) NULL
)
193 cmap
= (Colormap
) wxTheApp
->GetMainColormap(display
);
195 int numPixVals
= XDisplayCells(display
, DefaultScreen (display
));
196 int mindist
= 256 * 256 * 3;
197 int bestpixel
= (int) BlackPixel (display
, DefaultScreen (display
));
198 int red
= desiredColor
->red
>> 8;
199 int green
= desiredColor
->green
>> 8;
200 int blue
= desiredColor
->blue
>> 8;
201 const int threshold
= 2 * 2 * 3; // allow an error of up to 2 in R,G & B
203 for (int pixelcount
= 0; pixelcount
< numPixVals
; pixelcount
++)
205 XColor matching_color
;
206 matching_color
.pixel
= pixelcount
;
207 XQueryColor(display
,cmap
,&matching_color
);
209 int delta_red
= red
- (matching_color
.red
>> 8);
210 int delta_green
= green
- (matching_color
.green
>> 8);
211 int delta_blue
= blue
- (matching_color
.blue
>> 8);
213 int dist
= delta_red
* delta_red
+
214 delta_green
* delta_green
+
215 delta_blue
* delta_blue
;
217 if (dist
<= threshold
)
219 // try to allocate a read-only colour...
220 if (XAllocColor (display
, cmap
, &matching_color
))
222 return matching_color
.pixel
;
227 bestpixel
= pixelcount
;