]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/colour.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / colour.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
edc536d3 2// Name: src/gtk/colour.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
dbf858b5
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
ed39ff57 13#include "wx/colour.h"
40989e46 14
071a2d78 15#include <gdk/gdk.h>
9dc44eff 16#include "wx/gtk/private.h"
c801d85f
KB
17
18//-----------------------------------------------------------------------------
19// wxColour
20//-----------------------------------------------------------------------------
21
8f884a0d 22class wxColourRefData : public wxGDIRefData
c801d85f 23{
47c93b63 24public:
9dc44eff
PC
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
3bbc1d95 57 wxColourRefData(guint16 red, guint16 green, guint16 blue, wxByte alpha = 0xff)
c89f5c02 58 {
fa21f438 59 m_color.red =
c6685317 60 m_red = red;
fa21f438 61 m_color.green =
c6685317 62 m_green = green;
fa21f438 63 m_color.blue =
c6685317 64 m_blue = blue;
dc888336 65 m_alpha = alpha;
c89f5c02 66 m_color.pixel = 0;
c4fa282c 67 m_colormap = NULL;
dbb846c6
VZ
68 }
69
d3c7fc99 70 virtual ~wxColourRefData()
c89f5c02
RR
71 {
72 FreeColour();
73 }
15248e43 74
68dda785 75 void FreeColour();
d13fd3e4 76 void AllocColour( GdkColormap* cmap );
8bbe427f 77
c801d85f
KB
78 GdkColor m_color;
79 GdkColormap *m_colormap;
c6685317
PC
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;
9dc44eff 84#endif
3bbc1d95 85 wxByte m_alpha;
c6685317 86
c0c133e1 87 wxDECLARE_NO_COPY_CLASS(wxColourRefData);
c801d85f
KB
88};
89
9dc44eff 90#ifndef __WXGTK3__
68dda785 91void wxColourRefData::FreeColour()
c801d85f 92{
c6685317 93 if (m_colormap)
47c93b63 94 {
c4fa282c 95 gdk_colormap_free_colors(m_colormap, &m_color, 1);
c6685317
PC
96 m_colormap = NULL;
97 m_color.pixel = 0;
47c93b63 98 }
ff7b1510 99}
c801d85f 100
d13fd3e4
VZ
101void wxColourRefData::AllocColour( GdkColormap *cmap )
102{
c6685317
PC
103 if (m_colormap != cmap)
104 {
105 FreeColour();
4e6b8309 106
c6685317
PC
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 }
d13fd3e4 115}
9dc44eff 116#endif
d13fd3e4 117
c801d85f
KB
118//-----------------------------------------------------------------------------
119
5c33522f 120#define M_COLDATA static_cast<wxColourRefData*>(m_refData)
c801d85f 121
c6685317 122// GDK's values are in 0..65535 range, ours are in 0..255
3b9faf4c 123#define SHIFT 8
c801d85f 124
9dc44eff
PC
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
c6685317
PC
136wxColour::wxColour(const GdkColor& gdkColor)
137{
3bbc1d95 138 m_refData = new wxColourRefData(gdkColor.red, gdkColor.green, gdkColor.blue);
c6685317 139}
9dc44eff 140#endif
c6685317 141
68dda785 142wxColour::~wxColour()
c801d85f 143{
ff7b1510 144}
c801d85f 145
33b64e6f 146bool wxColour::operator == ( const wxColour& col ) const
8bbe427f 147{
4e6b8309 148 if (m_refData == col.m_refData)
aad6765c 149 return true;
15248e43 150
4e6b8309 151 if (!m_refData || !col.m_refData)
aad6765c 152 return false;
15248e43 153
c6685317 154 wxColourRefData* refData = M_COLDATA;
5c33522f 155 wxColourRefData* that_refData = static_cast<wxColourRefData*>(col.m_refData);
9dc44eff
PC
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
c6685317
PC
161 return refData->m_red == that_refData->m_red &&
162 refData->m_green == that_refData->m_green &&
dc888336 163 refData->m_blue == that_refData->m_blue &&
9dc44eff 164#endif
dc888336 165 refData->m_alpha == that_refData->m_alpha;
ff7b1510 166}
c801d85f 167
aea95b1c 168void wxColour::InitRGBA(unsigned char red, unsigned char green, unsigned char blue,
dc888336 169 unsigned char alpha)
c801d85f 170{
c6685317 171 UnRef();
4e6b8309 172
9dc44eff
PC
173#ifdef __WXGTK3__
174 m_refData = new wxColourRefData(red, green, blue, alpha);
175#else
c6685317
PC
176 m_refData = new wxColourRefData(
177 (guint16(red) << SHIFT) + red,
178 (guint16(green) << SHIFT) + green,
dc888336 179 (guint16(blue) << SHIFT) + blue,
3bbc1d95 180 alpha);
9dc44eff 181#endif
ff7b1510 182}
c801d85f 183
68dda785 184unsigned char wxColour::Red() const
c801d85f 185{
a1b806b9 186 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
8bbe427f 187
9dc44eff
PC
188#ifdef __WXGTK3__
189 return wxByte(M_COLDATA->m_gdkColor.red >> 8);
190#else
c6685317 191 return wxByte(M_COLDATA->m_red >> SHIFT);
9dc44eff 192#endif
ff7b1510 193}
c801d85f 194
68dda785 195unsigned char wxColour::Green() const
c801d85f 196{
a1b806b9 197 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
8bbe427f 198
9dc44eff
PC
199#ifdef __WXGTK3__
200 return wxByte(M_COLDATA->m_gdkColor.green >> 8);
201#else
c6685317 202 return wxByte(M_COLDATA->m_green >> SHIFT);
9dc44eff 203#endif
ff7b1510 204}
c801d85f 205
68dda785 206unsigned char wxColour::Blue() const
c801d85f 207{
a1b806b9 208 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
8bbe427f 209
9dc44eff
PC
210#ifdef __WXGTK3__
211 return wxByte(M_COLDATA->m_gdkColor.blue >> 8);
212#else
c6685317 213 return wxByte(M_COLDATA->m_blue >> SHIFT);
9dc44eff 214#endif
ff7b1510 215}
c801d85f 216
dc888336
SC
217unsigned char wxColour::Alpha() const
218{
a1b806b9 219 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
dc888336 220
3bbc1d95 221 return M_COLDATA->m_alpha;
dc888336
SC
222}
223
9dc44eff 224#ifndef __WXGTK3__
c801d85f
KB
225void wxColour::CalcPixel( GdkColormap *cmap )
226{
a1b806b9 227 if (!IsOk()) return;
8bbe427f 228
d13fd3e4 229 M_COLDATA->AllocColour( cmap );
ff7b1510 230}
c801d85f 231
68dda785 232int wxColour::GetPixel() const
c801d85f 233{
a1b806b9 234 wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") );
8bbe427f 235
1ecc4d80 236 return M_COLDATA->m_color.pixel;
ff7b1510 237}
9dc44eff 238#endif
c801d85f 239
c6685317 240const GdkColor *wxColour::GetColor() const
c801d85f 241{
a1b806b9 242 wxCHECK_MSG( IsOk(), NULL, wxT("invalid colour") );
8bbe427f 243
9dc44eff
PC
244#ifdef __WXGTK3__
245 return &M_COLDATA->m_gdkColor;
246#else
1ecc4d80 247 return &M_COLDATA->m_color;
9dc44eff 248#endif
ff7b1510 249}
40989e46 250
9dc44eff
PC
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
e86d4e59 261bool wxColour::FromString(const wxString& str)
40989e46 262{
9dc44eff
PC
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
40989e46
WS
271 GdkColor colGDK;
272 if ( gdk_color_parse( wxGTK_CONV_SYS( str ), &colGDK ) )
273 {
c6685317 274 *this = wxColour(colGDK);
40989e46
WS
275 return true;
276 }
9dc44eff 277#endif
40989e46
WS
278
279 return wxColourBase::FromString(str);
280}