]>
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
;