]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/colour.cpp
ee95c0a045c0b012c5bc3da3b87ce107f7064494
   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. 
  15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  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
) 
  46 wxColour::wxColour (const wxColour
& col
) 
  51 wxColour
& wxColour::operator =(const wxColour
& col
) 
  54     m_green 
= col
.m_green
; 
  56     m_isInit 
= col
.m_isInit
; 
  57     m_pixel 
= col
.m_pixel
; 
  61 void wxColour::InitFromName(const wxString
& name
) 
  63     *this = wxTheColourDatabase
->Find(name
); 
  66 wxColour::~wxColour () 
  70 void wxColour::Set (unsigned char r
, unsigned char g
, unsigned char b
) 
  79 // Allocate a colour, or nearest colour, using the given display. 
  80 // If realloc is TRUE, ignore the existing pixel, otherwise just return 
  82 // Returns the old or allocated pixel. 
  84 // TODO: can this handle mono displays? If not, we should have an extra 
  85 // flag to specify whether this should be black or white by default. 
  87 int wxColour::AllocColour(WXDisplay
* display
, bool realloc
) 
  89     if ((m_pixel 
!= -1) && !realloc
) 
  93     color
.red 
= (unsigned short) Red (); 
  94     color
.red 
|= color
.red 
<< 8; 
  95     color
.green 
= (unsigned short) Green (); 
  96     color
.green 
|= color
.green 
<< 8; 
  97     color
.blue 
= (unsigned short) Blue (); 
  98     color
.blue 
|= color
.blue 
<< 8; 
 100     color
.flags 
= DoRed 
| DoGreen 
| DoBlue
; 
 102     WXColormap cmap 
= wxTheApp
->GetMainColormap(display
); 
 104     if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
)) 
 106         m_pixel 
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
); 
 111         m_pixel 
= (int) color
.pixel
; 
 116 /*------------------------------------------- 
 117 Markus Emmenegger <mege@iqe.ethz.ch> 
 118 Find the pixel value with an assigned color closest to the desired color 
 119 Used if color cell allocation fails 
 120 As the returned pixel value may be in use by another application, 
 121 the color might change anytime. 
 122 But in many cases, that is still better than always using black. 
 124 Chris Breeze <chris@hel.co.uk> 
 126 1) More efficient calculation of RGB distance of colour cell from 
 127 the desired colour. There is no need to take the sqrt of 'dist', and 
 128 since we are only interested in the top 8-bits of R, G and B we 
 129 can perform integer arithmetic. 
 130 2) Attempt to allocate a read-only colour when a close match is found. 
 131 A read-only colour will not change. 
 132 3) Fall back to the closest match if no read-only colours are available. 
 134   Possible further improvements: 
 135   1) Scan the lookup table and sort the colour cells in order of 
 137   distance from the desired colour. Then attempt to allocate a 
 139   colour starting from the nearest match. 
 140   2) Linear RGB distance is not a particularly good method of colour 
 142   (though it is quick). Converting the colour to HLS and then comparing 
 143   may give better matching. 
 144 -------------------------------------------*/ 
 146 int wxGetBestMatchingPixel(Display 
*display
, XColor 
*desiredColor
, Colormap cmap
) 
 148     if (cmap 
== (Colormap
) NULL
) 
 149         cmap 
= (Colormap
) wxTheApp
->GetMainColormap(display
); 
 151     int numPixVals 
= XDisplayCells(display
, DefaultScreen (display
)); 
 152     int mindist 
= 256 * 256 * 3; 
 153     int bestpixel 
= (int) BlackPixel (display
, DefaultScreen (display
)); 
 154     int red 
= desiredColor
->red 
>> 8; 
 155     int green 
= desiredColor
->green 
>> 8; 
 156     int blue 
= desiredColor
->blue 
>> 8; 
 157     const int threshold 
= 2 * 2 * 3;    // allow an error of up to 2 in R,G & B 
 159     for (int pixelcount 
= 0; pixelcount 
< numPixVals
; pixelcount
++) 
 161         XColor matching_color
; 
 162         matching_color
.pixel 
= pixelcount
; 
 163         XQueryColor(display
,cmap
,&matching_color
); 
 165         int delta_red 
= red 
- (matching_color
.red 
>> 8); 
 166         int delta_green 
= green 
- (matching_color
.green 
>> 8); 
 167         int delta_blue 
= blue 
- (matching_color
.blue 
>> 8); 
 169         int dist 
= delta_red 
* delta_red 
+ 
 170             delta_green 
* delta_green 
+ 
 171             delta_blue 
* delta_blue
; 
 173         if (dist 
<= threshold
) 
 175             // try to allocate a read-only colour... 
 176             if (XAllocColor (display
, cmap
, &matching_color
)) 
 178                 return matching_color
.pixel
; 
 183             bestpixel 
= pixelcount
;