]> git.saurik.com Git - wxWidgets.git/blame - src/motif/colour.cpp
Add virtual ~wxAnyScrollHelperBase() to fix compiler warning.
[wxWidgets.git] / src / motif / colour.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
55034339 2// Name: src/motif/colour.cpp
4bb6408c
JS
3// Purpose: wxColour class
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
4bb6408c 7// Copyright: (c) Julian Smart
55034339 8// Licence: wxWindows licence
4bb6408c
JS
9/////////////////////////////////////////////////////////////////////////////
10
dfc54541
JS
11//// TODO: make wxColour a ref-counted object,
12//// so pixel values get shared.
13
1248b41f
MB
14// For compilers that support precompilation, includes "wx.h".
15#include "wx/wxprec.h"
16
4bb6408c 17#include "wx/colour.h"
40989e46 18
670f9935
WS
19#ifndef WX_PRECOMP
20 #include "wx/app.h"
dd05139a 21 #include "wx/gdicmn.h"
670f9935
WS
22#endif
23
338dd992
JJ
24#ifdef __VMS__
25#pragma message disable nosimpint
26#endif
dfc54541 27#include <Xm/Xm.h>
338dd992
JJ
28#ifdef __VMS__
29#pragma message enable nosimpint
30#endif
dfc54541
JS
31
32#include "wx/motif/private.h"
4bb6408c 33
3e0071d9
MB
34wxCOMPILE_TIME_ASSERT( sizeof(WXPixel) == sizeof(Pixel), PixelSizeIsOk );
35
4bb6408c
JS
36// Colour
37
aad6765c 38void wxColour::Init()
4bb6408c 39{
aad6765c 40 m_isInit = false;
3e0071d9 41 m_red = m_blue = m_green = 0;
dfc54541 42 m_pixel = -1;
4bb6408c
JS
43}
44
aad6765c 45wxColour::wxColour(const wxColour& col)
4bb6408c 46{
564a150b 47 *this = col;
4bb6408c
JS
48}
49
50wxColour& wxColour::operator =(const wxColour& col)
51{
2d120f83
JS
52 m_red = col.m_red;
53 m_green = col.m_green;
54 m_blue = col.m_blue;
55 m_isInit = col.m_isInit;
56 m_pixel = col.m_pixel;
57 return *this;
4bb6408c
JS
58}
59
aad6765c 60wxColour::~wxColour()
4bb6408c
JS
61{
62}
63
aea95b1c
VZ
64void wxColour::InitRGBA(unsigned char r, unsigned char g, unsigned char b,
65 unsigned char WXUNUSED(a))
4bb6408c
JS
66{
67 m_red = r;
68 m_green = g;
69 m_blue = b;
aad6765c 70 m_isInit = true;
e97f20a0 71 m_pixel = -1;
4bb6408c 72}
dfc54541
JS
73
74// Allocate a colour, or nearest colour, using the given display.
aad6765c 75// If realloc is true, ignore the existing pixel, otherwise just return
dfc54541 76// the existing one.
16c1f7f3 77// Returns the old or allocated pixel.
dfc54541
JS
78
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.
81
3e0071d9 82WXPixel wxColour::AllocColour(WXDisplay* display, bool realloc)
dfc54541
JS
83{
84 if ((m_pixel != -1) && !realloc)
2d120f83 85 return m_pixel;
aad6765c 86
dfc54541
JS
87 XColor color;
88 color.red = (unsigned short) Red ();
55034339 89 color.red |= (unsigned short)(color.red << 8);
dfc54541 90 color.green = (unsigned short) Green ();
55034339 91 color.green |= (unsigned short)(color.green << 8);
dfc54541 92 color.blue = (unsigned short) Blue ();
55034339 93 color.blue |= (unsigned short)(color.blue << 8);
aad6765c 94
dfc54541 95 color.flags = DoRed | DoGreen | DoBlue;
aad6765c 96
dfc54541 97 WXColormap cmap = wxTheApp->GetMainColormap(display);
aad6765c 98
dfc54541
JS
99 if (!XAllocColor ((Display*) display, (Colormap) cmap, &color))
100 {
2d120f83
JS
101 m_pixel = wxGetBestMatchingPixel((Display*) display, &color,(Colormap) cmap);
102 return m_pixel;
dfc54541
JS
103 }
104 else
105 {
3e0071d9 106 m_pixel = (WXPixel) color.pixel;
2d120f83 107 return m_pixel;
dfc54541
JS
108 }
109}
110
111/*-------------------------------------------
112Markus Emmenegger <mege@iqe.ethz.ch>
113Find the pixel value with an assigned color closest to the desired color
114Used if color cell allocation fails
115As the returned pixel value may be in use by another application,
116the color might change anytime.
117But in many cases, that is still better than always using black.
118--
119Chris Breeze <chris@hel.co.uk>
120Improvements:
1211) More efficient calculation of RGB distance of colour cell from
2d120f83
JS
122the desired colour. There is no need to take the sqrt of 'dist', and
123since we are only interested in the top 8-bits of R, G and B we
124can perform integer arithmetic.
dfc54541 1252) Attempt to allocate a read-only colour when a close match is found.
2d120f83 126A read-only colour will not change.
dfc54541
JS
1273) Fall back to the closest match if no read-only colours are available.
128
2d120f83
JS
129 Possible further improvements:
130 1) Scan the lookup table and sort the colour cells in order of
131 increasing
132 distance from the desired colour. Then attempt to allocate a
133 read-only
134 colour starting from the nearest match.
135 2) Linear RGB distance is not a particularly good method of colour
136 matching
137 (though it is quick). Converting the colour to HLS and then comparing
138 may give better matching.
dfc54541
JS
139-------------------------------------------*/
140
3e0071d9 141WXPixel wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap)
dfc54541
JS
142{
143 if (cmap == (Colormap) NULL)
2d120f83 144 cmap = (Colormap) wxTheApp->GetMainColormap(display);
aad6765c 145
dfc54541
JS
146 int numPixVals = XDisplayCells(display, DefaultScreen (display));
147 int mindist = 256 * 256 * 3;
3e0071d9 148 Pixel bestpixel = BlackPixel (display, DefaultScreen (display));
dfc54541
JS
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
aad6765c 153
dfc54541
JS
154 for (int pixelcount = 0; pixelcount < numPixVals; pixelcount++)
155 {
156 XColor matching_color;
157 matching_color.pixel = pixelcount;
158 XQueryColor(display,cmap,&matching_color);
aad6765c 159
dfc54541
JS
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);
aad6765c 163
dfc54541 164 int dist = delta_red * delta_red +
2d120f83
JS
165 delta_green * delta_green +
166 delta_blue * delta_blue;
aad6765c 167
dfc54541
JS
168 if (dist <= threshold)
169 {
170 // try to allocate a read-only colour...
171 if (XAllocColor (display, cmap, &matching_color))
172 {
173 return matching_color.pixel;
174 }
175 }
176 if (dist < mindist)
177 {
178 bestpixel = pixelcount;
179 mindist = dist;
180 }
181 }
182 return bestpixel;
183}