]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/colour.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / colour.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/colour.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #include "wx/colour.h"
14
15 #include <gdk/gdk.h>
16 #include "wx/gtk/private.h"
17
18 //-----------------------------------------------------------------------------
19 // wxColour
20 //-----------------------------------------------------------------------------
21
22 class wxColourRefData : public wxGDIRefData
23 {
24 public:
25 #ifdef __WXGTK3__
26 wxColourRefData(const GdkRGBA& gdkRGBA)
27 : m_gdkRGBA(gdkRGBA)
28 {
29 m_gdkColor.red = guint16(gdkRGBA.red * 65535);
30 m_gdkColor.green = guint16(gdkRGBA.green * 65535);
31 m_gdkColor.blue = guint16(gdkRGBA.blue * 65535);
32 m_alpha = wxByte(gdkRGBA.alpha * 255 + 0.5);
33 }
34 wxColourRefData(const GdkColor& gdkColor)
35 : m_gdkColor(gdkColor)
36 {
37 m_gdkRGBA.red = gdkColor.red / 65535.0;
38 m_gdkRGBA.green = gdkColor.green / 65535.0;
39 m_gdkRGBA.blue = gdkColor.blue / 65535.0;
40 m_gdkRGBA.alpha = 1;
41 m_alpha = 255;
42 }
43 wxColourRefData(guchar red, guchar green, guchar blue, guchar alpha)
44 {
45 m_gdkRGBA.red = red / 255.0;
46 m_gdkRGBA.green = green / 255.0;
47 m_gdkRGBA.blue = blue / 255.0;
48 m_gdkRGBA.alpha = alpha / 255.0;
49 m_gdkColor.red = (guint16(red) << 8) + red;
50 m_gdkColor.green = (guint16(green) << 8) + green;
51 m_gdkColor.blue = (guint16(blue) << 8) + blue;
52 m_alpha = alpha;
53 }
54 GdkRGBA m_gdkRGBA;
55 GdkColor m_gdkColor;
56 #else
57 wxColourRefData(guint16 red, guint16 green, guint16 blue, wxByte alpha = 0xff)
58 {
59 m_color.red =
60 m_red = red;
61 m_color.green =
62 m_green = green;
63 m_color.blue =
64 m_blue = blue;
65 m_alpha = alpha;
66 m_color.pixel = 0;
67 m_colormap = NULL;
68 }
69
70 virtual ~wxColourRefData()
71 {
72 FreeColour();
73 }
74
75 void FreeColour();
76 void AllocColour( GdkColormap* cmap );
77
78 GdkColor m_color;
79 GdkColormap *m_colormap;
80 // gdk_colormap_alloc_color may change the RGB values in m_color, so we need separate copies
81 guint16 m_red;
82 guint16 m_green;
83 guint16 m_blue;
84 #endif
85 wxByte m_alpha;
86
87 wxDECLARE_NO_COPY_CLASS(wxColourRefData);
88 };
89
90 #ifndef __WXGTK3__
91 void wxColourRefData::FreeColour()
92 {
93 if (m_colormap)
94 {
95 gdk_colormap_free_colors(m_colormap, &m_color, 1);
96 m_colormap = NULL;
97 m_color.pixel = 0;
98 }
99 }
100
101 void wxColourRefData::AllocColour( GdkColormap *cmap )
102 {
103 if (m_colormap != cmap)
104 {
105 FreeColour();
106
107 m_color.red = m_red;
108 m_color.green = m_green;
109 m_color.blue = m_blue;
110 if (gdk_colormap_alloc_color(cmap, &m_color, FALSE, TRUE))
111 {
112 m_colormap = cmap;
113 }
114 }
115 }
116 #endif
117
118 //-----------------------------------------------------------------------------
119
120 #define M_COLDATA static_cast<wxColourRefData*>(m_refData)
121
122 // GDK's values are in 0..65535 range, ours are in 0..255
123 #define SHIFT 8
124
125 #ifdef __WXGTK3__
126 wxColour::wxColour(const GdkRGBA& gdkRGBA)
127 {
128 m_refData = new wxColourRefData(gdkRGBA);
129 }
130
131 wxColour::wxColour(const GdkColor& gdkColor)
132 {
133 m_refData = new wxColourRefData(gdkColor);
134 }
135 #else
136 wxColour::wxColour(const GdkColor& gdkColor)
137 {
138 m_refData = new wxColourRefData(gdkColor.red, gdkColor.green, gdkColor.blue);
139 }
140 #endif
141
142 wxColour::~wxColour()
143 {
144 }
145
146 bool wxColour::operator == ( const wxColour& col ) const
147 {
148 if (m_refData == col.m_refData)
149 return true;
150
151 if (!m_refData || !col.m_refData)
152 return false;
153
154 wxColourRefData* refData = M_COLDATA;
155 wxColourRefData* that_refData = static_cast<wxColourRefData*>(col.m_refData);
156 #ifdef __WXGTK3__
157 return refData->m_gdkColor.red == that_refData->m_gdkColor.red &&
158 refData->m_gdkColor.green == that_refData->m_gdkColor.green &&
159 refData->m_gdkColor.blue == that_refData->m_gdkColor.blue &&
160 #else
161 return refData->m_red == that_refData->m_red &&
162 refData->m_green == that_refData->m_green &&
163 refData->m_blue == that_refData->m_blue &&
164 #endif
165 refData->m_alpha == that_refData->m_alpha;
166 }
167
168 void wxColour::InitRGBA(unsigned char red, unsigned char green, unsigned char blue,
169 unsigned char alpha)
170 {
171 UnRef();
172
173 #ifdef __WXGTK3__
174 m_refData = new wxColourRefData(red, green, blue, alpha);
175 #else
176 m_refData = new wxColourRefData(
177 (guint16(red) << SHIFT) + red,
178 (guint16(green) << SHIFT) + green,
179 (guint16(blue) << SHIFT) + blue,
180 alpha);
181 #endif
182 }
183
184 unsigned char wxColour::Red() const
185 {
186 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
187
188 #ifdef __WXGTK3__
189 return wxByte(M_COLDATA->m_gdkColor.red >> 8);
190 #else
191 return wxByte(M_COLDATA->m_red >> SHIFT);
192 #endif
193 }
194
195 unsigned char wxColour::Green() const
196 {
197 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
198
199 #ifdef __WXGTK3__
200 return wxByte(M_COLDATA->m_gdkColor.green >> 8);
201 #else
202 return wxByte(M_COLDATA->m_green >> SHIFT);
203 #endif
204 }
205
206 unsigned char wxColour::Blue() const
207 {
208 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
209
210 #ifdef __WXGTK3__
211 return wxByte(M_COLDATA->m_gdkColor.blue >> 8);
212 #else
213 return wxByte(M_COLDATA->m_blue >> SHIFT);
214 #endif
215 }
216
217 unsigned char wxColour::Alpha() const
218 {
219 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
220
221 return M_COLDATA->m_alpha;
222 }
223
224 #ifndef __WXGTK3__
225 void wxColour::CalcPixel( GdkColormap *cmap )
226 {
227 if (!IsOk()) return;
228
229 M_COLDATA->AllocColour( cmap );
230 }
231
232 int wxColour::GetPixel() const
233 {
234 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
235
236 return M_COLDATA->m_color.pixel;
237 }
238 #endif
239
240 const GdkColor *wxColour::GetColor() const
241 {
242 wxCHECK_MSG( IsOk(), NULL, wxT("invalid colour") );
243
244 #ifdef __WXGTK3__
245 return &M_COLDATA->m_gdkColor;
246 #else
247 return &M_COLDATA->m_color;
248 #endif
249 }
250
251 #ifdef __WXGTK3__
252 wxColour::operator const GdkRGBA*() const
253 {
254 const GdkRGBA* c = NULL;
255 if (IsOk())
256 c = &M_COLDATA->m_gdkRGBA;
257 return c;
258 }
259 #endif
260
261 bool wxColour::FromString(const wxString& str)
262 {
263 #ifdef __WXGTK3__
264 GdkRGBA gdkRGBA;
265 if (gdk_rgba_parse(&gdkRGBA, wxGTK_CONV_SYS(str)))
266 {
267 *this = wxColour(gdkRGBA);
268 return true;
269 }
270 #else
271 GdkColor colGDK;
272 if ( gdk_color_parse( wxGTK_CONV_SYS( str ), &colGDK ) )
273 {
274 *this = wxColour(colGDK);
275 return true;
276 }
277 #endif
278
279 return wxColourBase::FromString(str);
280 }