]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/colour.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / colour.cpp
... / ...
CommitLineData
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
22class wxColourRefData : public wxGDIRefData
23{
24public:
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__
91void 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
101void 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__
126wxColour::wxColour(const GdkRGBA& gdkRGBA)
127{
128 m_refData = new wxColourRefData(gdkRGBA);
129}
130
131wxColour::wxColour(const GdkColor& gdkColor)
132{
133 m_refData = new wxColourRefData(gdkColor);
134}
135#else
136wxColour::wxColour(const GdkColor& gdkColor)
137{
138 m_refData = new wxColourRefData(gdkColor.red, gdkColor.green, gdkColor.blue);
139}
140#endif
141
142wxColour::~wxColour()
143{
144}
145
146bool 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
168void 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
184unsigned 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
195unsigned 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
206unsigned 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
217unsigned 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__
225void wxColour::CalcPixel( GdkColormap *cmap )
226{
227 if (!IsOk()) return;
228
229 M_COLDATA->AllocColour( cmap );
230}
231
232int wxColour::GetPixel() const
233{
234 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
235
236 return M_COLDATA->m_color.pixel;
237}
238#endif
239
240const 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__
252wxColour::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
261bool 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}