]>
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"
24 #pragma message disable nosimpint
28 #pragma message enable nosimpint
31 #include "wx/motif/private.h"
33 #if !USE_SHARED_LIBRARY
34 IMPLEMENT_DYNAMIC_CLASS(wxColour
, wxObject
)
42 m_red
= m_blue
= m_green
= 0;
46 wxColour::wxColour (unsigned char r
, unsigned char g
, unsigned char b
)
55 wxColour::wxColour (const wxColour
& col
)
58 m_green
= col
.m_green
;
60 m_isInit
= col
.m_isInit
;
61 m_pixel
= col
.m_pixel
;
64 wxColour
& wxColour::operator =(const wxColour
& col
)
67 m_green
= col
.m_green
;
69 m_isInit
= col
.m_isInit
;
70 m_pixel
= col
.m_pixel
;
74 void wxColour::InitFromName(const wxString
& col
)
76 wxColour
*the_colour
= wxTheColourDatabase
->FindColour (col
);
79 m_red
= the_colour
->Red ();
80 m_green
= the_colour
->Green ();
81 m_blue
= the_colour
->Blue ();
82 m_pixel
= the_colour
->m_pixel
;
94 wxColour::~wxColour ()
98 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
)
107 // Allocate a colour, or nearest colour, using the given display.
108 // If realloc is TRUE, ignore the existing pixel, otherwise just return
110 // Returns the old or allocated pixel.
112 // TODO: can this handle mono displays? If not, we should have an extra
113 // flag to specify whether this should be black or white by default.
115 int wxColour::AllocColour(WXDisplay
* display
, bool realloc
)
117 if ((m_pixel
!= -1) && !realloc
)
121 color
.red
= (unsigned short) Red ();
122 color
.red
|= color
.red
<< 8;
123 color
.green
= (unsigned short) Green ();
124 color
.green
|= color
.green
<< 8;
125 color
.blue
= (unsigned short) Blue ();
126 color
.blue
|= color
.blue
<< 8;
128 color
.flags
= DoRed
| DoGreen
| DoBlue
;
130 WXColormap cmap
= wxTheApp
->GetMainColormap(display
);
132 if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
))
134 m_pixel
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
);
139 m_pixel
= (int) color
.pixel
;
144 /*-------------------------------------------
145 Markus Emmenegger <mege@iqe.ethz.ch>
146 Find the pixel value with an assigned color closest to the desired color
147 Used if color cell allocation fails
148 As the returned pixel value may be in use by another application,
149 the color might change anytime.
150 But in many cases, that is still better than always using black.
152 Chris Breeze <chris@hel.co.uk>
154 1) More efficient calculation of RGB distance of colour cell from
155 the desired colour. There is no need to take the sqrt of 'dist', and
156 since we are only interested in the top 8-bits of R, G and B we
157 can perform integer arithmetic.
158 2) Attempt to allocate a read-only colour when a close match is found.
159 A read-only colour will not change.
160 3) Fall back to the closest match if no read-only colours are available.
162 Possible further improvements:
163 1) Scan the lookup table and sort the colour cells in order of
165 distance from the desired colour. Then attempt to allocate a
167 colour starting from the nearest match.
168 2) Linear RGB distance is not a particularly good method of colour
170 (though it is quick). Converting the colour to HLS and then comparing
171 may give better matching.
172 -------------------------------------------*/
174 int wxGetBestMatchingPixel(Display
*display
, XColor
*desiredColor
, Colormap cmap
)
176 if (cmap
== (Colormap
) NULL
)
177 cmap
= (Colormap
) wxTheApp
->GetMainColormap(display
);
179 int numPixVals
= XDisplayCells(display
, DefaultScreen (display
));
180 int mindist
= 256 * 256 * 3;
181 int bestpixel
= (int) BlackPixel (display
, DefaultScreen (display
));
182 int red
= desiredColor
->red
>> 8;
183 int green
= desiredColor
->green
>> 8;
184 int blue
= desiredColor
->blue
>> 8;
185 const int threshold
= 2 * 2 * 3; // allow an error of up to 2 in R,G & B
187 for (int pixelcount
= 0; pixelcount
< numPixVals
; pixelcount
++)
189 XColor matching_color
;
190 matching_color
.pixel
= pixelcount
;
191 XQueryColor(display
,cmap
,&matching_color
);
193 int delta_red
= red
- (matching_color
.red
>> 8);
194 int delta_green
= green
- (matching_color
.green
>> 8);
195 int delta_blue
= blue
- (matching_color
.blue
>> 8);
197 int dist
= delta_red
* delta_red
+
198 delta_green
* delta_green
+
199 delta_blue
* delta_blue
;
201 if (dist
<= threshold
)
203 // try to allocate a read-only colour...
204 if (XAllocColor (display
, cmap
, &matching_color
))
206 return matching_color
.pixel
;
211 bestpixel
= pixelcount
;