]>
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 void wxColour::InitFromName(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 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
)
101 // Allocate a colour, or nearest colour, using the given display.
102 // If realloc is TRUE, ignore the existing pixel, otherwise just return
104 // Returns the old or allocated pixel.
106 // TODO: can this handle mono displays? If not, we should have an extra
107 // flag to specify whether this should be black or white by default.
109 int wxColour::AllocColour(WXDisplay
* display
, bool realloc
)
111 if ((m_pixel
!= -1) && !realloc
)
115 color
.red
= (unsigned short) Red ();
116 color
.red
|= color
.red
<< 8;
117 color
.green
= (unsigned short) Green ();
118 color
.green
|= color
.green
<< 8;
119 color
.blue
= (unsigned short) Blue ();
120 color
.blue
|= color
.blue
<< 8;
122 color
.flags
= DoRed
| DoGreen
| DoBlue
;
124 WXColormap cmap
= wxTheApp
->GetMainColormap(display
);
126 if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
))
128 m_pixel
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
);
133 m_pixel
= (int) color
.pixel
;
138 /*-------------------------------------------
139 Markus Emmenegger <mege@iqe.ethz.ch>
140 Find the pixel value with an assigned color closest to the desired color
141 Used if color cell allocation fails
142 As the returned pixel value may be in use by another application,
143 the color might change anytime.
144 But in many cases, that is still better than always using black.
146 Chris Breeze <chris@hel.co.uk>
148 1) More efficient calculation of RGB distance of colour cell from
149 the desired colour. There is no need to take the sqrt of 'dist', and
150 since we are only interested in the top 8-bits of R, G and B we
151 can perform integer arithmetic.
152 2) Attempt to allocate a read-only colour when a close match is found.
153 A read-only colour will not change.
154 3) Fall back to the closest match if no read-only colours are available.
156 Possible further improvements:
157 1) Scan the lookup table and sort the colour cells in order of
159 distance from the desired colour. Then attempt to allocate a
161 colour starting from the nearest match.
162 2) Linear RGB distance is not a particularly good method of colour
164 (though it is quick). Converting the colour to HLS and then comparing
165 may give better matching.
166 -------------------------------------------*/
168 int wxGetBestMatchingPixel(Display
*display
, XColor
*desiredColor
, Colormap cmap
)
170 if (cmap
== (Colormap
) NULL
)
171 cmap
= (Colormap
) wxTheApp
->GetMainColormap(display
);
173 int numPixVals
= XDisplayCells(display
, DefaultScreen (display
));
174 int mindist
= 256 * 256 * 3;
175 int bestpixel
= (int) BlackPixel (display
, DefaultScreen (display
));
176 int red
= desiredColor
->red
>> 8;
177 int green
= desiredColor
->green
>> 8;
178 int blue
= desiredColor
->blue
>> 8;
179 const int threshold
= 2 * 2 * 3; // allow an error of up to 2 in R,G & B
181 for (int pixelcount
= 0; pixelcount
< numPixVals
; pixelcount
++)
183 XColor matching_color
;
184 matching_color
.pixel
= pixelcount
;
185 XQueryColor(display
,cmap
,&matching_color
);
187 int delta_red
= red
- (matching_color
.red
>> 8);
188 int delta_green
= green
- (matching_color
.green
>> 8);
189 int delta_blue
= blue
- (matching_color
.blue
>> 8);
191 int dist
= delta_red
* delta_red
+
192 delta_green
* delta_green
+
193 delta_blue
* delta_blue
;
195 if (dist
<= threshold
)
197 // try to allocate a read-only colour...
198 if (XAllocColor (display
, cmap
, &matching_color
))
200 return matching_color
.pixel
;
205 bestpixel
= pixelcount
;