]>
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 IMPLEMENT_DYNAMIC_CLASS(wxColour
, wxObject
) 
  40     m_red 
= m_blue 
= m_green 
= 0; 
  44 wxColour::wxColour (unsigned char r
, unsigned char g
, unsigned char b
) 
  53 wxColour::wxColour (const wxColour
& col
) 
  56     m_green 
= col
.m_green
; 
  58     m_isInit 
= col
.m_isInit
; 
  59     m_pixel 
= col
.m_pixel
; 
  62 wxColour
& wxColour::operator =(const wxColour
& col
) 
  65     m_green 
= col
.m_green
; 
  67     m_isInit 
= col
.m_isInit
; 
  68     m_pixel 
= col
.m_pixel
; 
  72 void wxColour::InitFromName(const wxString
& col
) 
  74     wxColour 
*the_colour 
= wxTheColourDatabase
->FindColour (col
); 
  77         m_red 
= the_colour
->Red (); 
  78         m_green 
= the_colour
->Green (); 
  79         m_blue 
= the_colour
->Blue (); 
  80         m_pixel 
= the_colour
->m_pixel
; 
  92 wxColour::~wxColour () 
  96 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
) 
 105 // Allocate a colour, or nearest colour, using the given display. 
 106 // If realloc is TRUE, ignore the existing pixel, otherwise just return 
 108 // Returns the old or allocated pixel. 
 110 // TODO: can this handle mono displays? If not, we should have an extra 
 111 // flag to specify whether this should be black or white by default. 
 113 int wxColour::AllocColour(WXDisplay
* display
, bool realloc
) 
 115     if ((m_pixel 
!= -1) && !realloc
) 
 119     color
.red 
= (unsigned short) Red (); 
 120     color
.red 
|= color
.red 
<< 8; 
 121     color
.green 
= (unsigned short) Green (); 
 122     color
.green 
|= color
.green 
<< 8; 
 123     color
.blue 
= (unsigned short) Blue (); 
 124     color
.blue 
|= color
.blue 
<< 8; 
 126     color
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 128     WXColormap cmap 
= wxTheApp
->GetMainColormap(display
); 
 130     if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
)) 
 132         m_pixel 
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
); 
 137         m_pixel 
= (int) color
.pixel
; 
 142 /*------------------------------------------- 
 143 Markus Emmenegger <mege@iqe.ethz.ch> 
 144 Find the pixel value with an assigned color closest to the desired color 
 145 Used if color cell allocation fails 
 146 As the returned pixel value may be in use by another application, 
 147 the color might change anytime. 
 148 But in many cases, that is still better than always using black. 
 150 Chris Breeze <chris@hel.co.uk> 
 152 1) More efficient calculation of RGB distance of colour cell from 
 153 the desired colour. There is no need to take the sqrt of 'dist', and 
 154 since we are only interested in the top 8-bits of R, G and B we 
 155 can perform integer arithmetic. 
 156 2) Attempt to allocate a read-only colour when a close match is found. 
 157 A read-only colour will not change. 
 158 3) Fall back to the closest match if no read-only colours are available. 
 160   Possible further improvements: 
 161   1) Scan the lookup table and sort the colour cells in order of 
 163   distance from the desired colour. Then attempt to allocate a 
 165   colour starting from the nearest match. 
 166   2) Linear RGB distance is not a particularly good method of colour 
 168   (though it is quick). Converting the colour to HLS and then comparing 
 169   may give better matching. 
 170 -------------------------------------------*/ 
 172 int wxGetBestMatchingPixel(Display 
*display
, XColor 
*desiredColor
, Colormap cmap
) 
 174     if (cmap 
== (Colormap
) NULL
) 
 175         cmap 
= (Colormap
) wxTheApp
->GetMainColormap(display
); 
 177     int numPixVals 
= XDisplayCells(display
, DefaultScreen (display
)); 
 178     int mindist 
= 256 * 256 * 3; 
 179     int bestpixel 
= (int) BlackPixel (display
, DefaultScreen (display
)); 
 180     int red 
= desiredColor
->red 
>> 8; 
 181     int green 
= desiredColor
->green 
>> 8; 
 182     int blue 
= desiredColor
->blue 
>> 8; 
 183     const int threshold 
= 2 * 2 * 3;    // allow an error of up to 2 in R,G & B 
 185     for (int pixelcount 
= 0; pixelcount 
< numPixVals
; pixelcount
++) 
 187         XColor matching_color
; 
 188         matching_color
.pixel 
= pixelcount
; 
 189         XQueryColor(display
,cmap
,&matching_color
); 
 191         int delta_red 
= red 
- (matching_color
.red 
>> 8); 
 192         int delta_green 
= green 
- (matching_color
.green 
>> 8); 
 193         int delta_blue 
= blue 
- (matching_color
.blue 
>> 8); 
 195         int dist 
= delta_red 
* delta_red 
+ 
 196             delta_green 
* delta_green 
+ 
 197             delta_blue 
* delta_blue
; 
 199         if (dist 
<= threshold
) 
 201             // try to allocate a read-only colour... 
 202             if (XAllocColor (display
, cmap
, &matching_color
)) 
 204                 return matching_color
.pixel
; 
 209             bestpixel 
= pixelcount
;