]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/colour.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/colour.cpp
3 // Purpose: wxColour class
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 //// TODO: make wxColour a ref-counted object,
12 //// so pixel values get shared.
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
17 #include "wx/colour.h"
21 #include "wx/gdicmn.h"
25 #pragma message disable nosimpint
29 #pragma message enable nosimpint
32 #include "wx/motif/private.h"
34 wxCOMPILE_TIME_ASSERT( sizeof(WXPixel
) == sizeof(Pixel
), PixelSizeIsOk
);
41 m_red
= m_blue
= m_green
= 0;
45 wxColour::wxColour(const wxColour
& col
)
50 wxColour
& wxColour::operator =(const wxColour
& col
)
53 m_green
= col
.m_green
;
55 m_isInit
= col
.m_isInit
;
56 m_pixel
= col
.m_pixel
;
64 void wxColour::InitRGBA(unsigned char r
, unsigned char g
, unsigned char b
,
65 unsigned char WXUNUSED(a
))
74 // Allocate a colour, or nearest colour, using the given display.
75 // If realloc is true, ignore the existing pixel, otherwise just return
77 // Returns the old or allocated pixel.
79 // TODO: can this handle mono displays? If not, we should have an extra
80 // flag to specify whether this should be black or white by default.
82 WXPixel
wxColour::AllocColour(WXDisplay
* display
, bool realloc
)
84 if ((m_pixel
!= -1) && !realloc
)
88 color
.red
= (unsigned short) Red ();
89 color
.red
|= (unsigned short)(color
.red
<< 8);
90 color
.green
= (unsigned short) Green ();
91 color
.green
|= (unsigned short)(color
.green
<< 8);
92 color
.blue
= (unsigned short) Blue ();
93 color
.blue
|= (unsigned short)(color
.blue
<< 8);
95 color
.flags
= DoRed
| DoGreen
| DoBlue
;
97 WXColormap cmap
= wxTheApp
->GetMainColormap(display
);
99 if (!XAllocColor ((Display
*) display
, (Colormap
) cmap
, &color
))
101 m_pixel
= wxGetBestMatchingPixel((Display
*) display
, &color
,(Colormap
) cmap
);
106 m_pixel
= (WXPixel
) color
.pixel
;
111 /*-------------------------------------------
112 Markus Emmenegger <mege@iqe.ethz.ch>
113 Find the pixel value with an assigned color closest to the desired color
114 Used if color cell allocation fails
115 As the returned pixel value may be in use by another application,
116 the color might change anytime.
117 But in many cases, that is still better than always using black.
119 Chris Breeze <chris@hel.co.uk>
121 1) More efficient calculation of RGB distance of colour cell from
122 the desired colour. There is no need to take the sqrt of 'dist', and
123 since we are only interested in the top 8-bits of R, G and B we
124 can perform integer arithmetic.
125 2) Attempt to allocate a read-only colour when a close match is found.
126 A read-only colour will not change.
127 3) Fall back to the closest match if no read-only colours are available.
129 Possible further improvements:
130 1) Scan the lookup table and sort the colour cells in order of
132 distance from the desired colour. Then attempt to allocate a
134 colour starting from the nearest match.
135 2) Linear RGB distance is not a particularly good method of colour
137 (though it is quick). Converting the colour to HLS and then comparing
138 may give better matching.
139 -------------------------------------------*/
141 WXPixel
wxGetBestMatchingPixel(Display
*display
, XColor
*desiredColor
, Colormap cmap
)
143 if (cmap
== (Colormap
) NULL
)
144 cmap
= (Colormap
) wxTheApp
->GetMainColormap(display
);
146 int numPixVals
= XDisplayCells(display
, DefaultScreen (display
));
147 int mindist
= 256 * 256 * 3;
148 Pixel bestpixel
= BlackPixel (display
, DefaultScreen (display
));
149 int red
= desiredColor
->red
>> 8;
150 int green
= desiredColor
->green
>> 8;
151 int blue
= desiredColor
->blue
>> 8;
152 const int threshold
= 2 * 2 * 3; // allow an error of up to 2 in R,G & B
154 for (int pixelcount
= 0; pixelcount
< numPixVals
; pixelcount
++)
156 XColor matching_color
;
157 matching_color
.pixel
= pixelcount
;
158 XQueryColor(display
,cmap
,&matching_color
);
160 int delta_red
= red
- (matching_color
.red
>> 8);
161 int delta_green
= green
- (matching_color
.green
>> 8);
162 int delta_blue
= blue
- (matching_color
.blue
>> 8);
164 int dist
= delta_red
* delta_red
+
165 delta_green
* delta_green
+
166 delta_blue
* delta_blue
;
168 if (dist
<= threshold
)
170 // try to allocate a read-only colour...
171 if (XAllocColor (display
, cmap
, &matching_color
))
173 return matching_color
.pixel
;
178 bestpixel
= pixelcount
;