]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/bitmap.mm
In destructor: DestroyChildren() and make sure m_cocoaNSView is NULL so that
[wxWidgets.git] / src / cocoa / bitmap.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: David Elliott
5 // Modified by:
6 // Created: 2003/07/19
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 David Elliott
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/setup.h"
13 #include "wx/utils.h"
14 #include "wx/palette.h"
15 #include "wx/bitmap.h"
16 #include "wx/icon.h"
17 #include "wx/log.h"
18 #include "wx/image.h"
19 #include "wx/xpmdecod.h"
20
21 #include "wx/cocoa/autorelease.h"
22 #include "wx/cocoa/string.h"
23
24 #import <AppKit/NSBitmapImageRep.h>
25 #import <AppKit/NSGraphics.h>
26
27 // ========================================================================
28 // wxBitmapRefData
29 // ========================================================================
30 class wxBitmapRefData: public wxGDIRefData
31 {
32 friend class wxBitmap;
33 public:
34 wxBitmapRefData();
35 wxBitmapRefData( const wxBitmapRefData& data );
36 virtual ~wxBitmapRefData();
37
38 protected:
39 int m_width;
40 int m_height;
41 int m_depth;
42 bool m_ok;
43 int m_numColors;
44 wxPalette m_bitmapPalette;
45 int m_quality;
46 WX_NSBitmapImageRep m_cocoaNSBitmapImageRep;
47 wxMask *m_bitmapMask; // Optional mask
48 };
49
50 #define M_BITMAPDATA ((wxBitmapRefData *)m_refData)
51
52 wxBitmapRefData::wxBitmapRefData()
53 {
54 m_ok = FALSE;
55 m_width = 0;
56 m_height = 0;
57 m_depth = 0;
58 m_quality = 0;
59 m_numColors = 0;
60 m_cocoaNSBitmapImageRep = nil;
61 m_bitmapMask = NULL;
62 }
63
64 wxBitmapRefData::wxBitmapRefData( const wxBitmapRefData& data)
65 {
66 m_width = data.m_width;
67 m_height = data.m_height;
68 m_depth = data.m_depth;
69 m_ok = data.m_ok;
70 m_numColors = data.m_numColors;
71 m_bitmapPalette = data.m_bitmapPalette;
72 m_quality = data.m_quality;
73 m_cocoaNSBitmapImageRep = data.m_cocoaNSBitmapImageRep;
74 [m_cocoaNSBitmapImageRep retain];
75 m_bitmapMask = data.m_bitmapMask?new wxMask(*data.m_bitmapMask):NULL;
76 }
77
78 wxBitmapRefData::~wxBitmapRefData()
79 {
80 [m_cocoaNSBitmapImageRep release];
81 m_cocoaNSBitmapImageRep = NULL;
82
83 delete m_bitmapMask;
84 m_bitmapMask = NULL;
85 }
86
87 // ========================================================================
88 // wxBitmap
89 // ========================================================================
90 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
91
92 wxBitmap::wxBitmap()
93 {
94 m_refData = NULL;
95 }
96
97 wxBitmap::~wxBitmap()
98 {
99 }
100
101 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
102 {
103 m_refData = new wxBitmapRefData;
104
105 M_BITMAPDATA->m_width = the_width ;
106 M_BITMAPDATA->m_height = the_height ;
107 M_BITMAPDATA->m_depth = no_bits ;
108 M_BITMAPDATA->m_numColors = 0;
109
110 /* TODO: create the bitmap from data */
111 }
112
113 wxBitmap::wxBitmap(int w, int h, int d)
114 {
115 (void)Create(w, h, d);
116 }
117
118 wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
119 {
120 (void) Create(data, type, width, height, depth);
121 }
122
123 wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
124 {
125 LoadFile(filename, type);
126 }
127
128 wxObjectRefData *wxBitmap::CreateRefData() const
129 {
130 return new wxBitmapRefData;
131 }
132
133 wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *data) const
134 {
135 return new wxBitmapRefData(*(wxBitmapRefData*)data);
136 }
137
138 WX_NSBitmapImageRep wxBitmap::GetNSBitmapImageRep()
139 {
140 if(!M_BITMAPDATA)
141 return NULL;
142 return M_BITMAPDATA->m_cocoaNSBitmapImageRep;
143 }
144
145 void wxBitmap::SetWidth(int w)
146 {
147 if (!M_BITMAPDATA)
148 m_refData = new wxBitmapRefData;
149
150 M_BITMAPDATA->m_width = w;
151 }
152
153 void wxBitmap::SetHeight(int h)
154 {
155 if (!M_BITMAPDATA)
156 m_refData = new wxBitmapRefData;
157
158 M_BITMAPDATA->m_height = h;
159 }
160
161 void wxBitmap::SetDepth(int d)
162 {
163 if (!M_BITMAPDATA)
164 m_refData = new wxBitmapRefData;
165
166 M_BITMAPDATA->m_depth = d;
167 }
168
169 void wxBitmap::SetQuality(int q)
170 {
171 if (!M_BITMAPDATA)
172 m_refData = new wxBitmapRefData;
173
174 M_BITMAPDATA->m_quality = q;
175 }
176
177 void wxBitmap::SetOk(bool isOk)
178 {
179 if (!M_BITMAPDATA)
180 m_refData = new wxBitmapRefData;
181
182 M_BITMAPDATA->m_ok = isOk;
183 }
184
185 void wxBitmap::SetPalette(const wxPalette& palette)
186 {
187 if (!M_BITMAPDATA)
188 m_refData = new wxBitmapRefData;
189
190 M_BITMAPDATA->m_bitmapPalette = palette ;
191 }
192
193 void wxBitmap::SetMask(wxMask *mask)
194 {
195 if (!M_BITMAPDATA)
196 m_refData = new wxBitmapRefData;
197
198 M_BITMAPDATA->m_bitmapMask = mask ;
199 }
200
201 bool wxBitmap::Ok() const
202 {
203 return m_refData && M_BITMAPDATA->m_ok;
204 }
205
206 wxPalette* wxBitmap::GetPalette() const
207 {
208 if(!m_refData)
209 return NULL;
210 return &M_BITMAPDATA->m_bitmapPalette;
211 }
212
213 wxMask* wxBitmap::GetMask() const
214 {
215 if(!m_refData)
216 return NULL;
217 return M_BITMAPDATA->m_bitmapMask;
218 }
219
220 int wxBitmap::GetDepth() const
221 {
222 if(!m_refData)
223 return 0;
224 return M_BITMAPDATA->m_depth;
225 }
226
227 int wxBitmap::GetWidth() const
228 {
229 if(!m_refData)
230 return 0;
231 return M_BITMAPDATA->m_width;
232 }
233
234 int wxBitmap::GetHeight() const
235 {
236 if(!m_refData)
237 return 0;
238 return M_BITMAPDATA->m_height;
239 }
240
241 bool wxBitmap::Create(int w, int h, int d)
242 {
243 UnRef();
244
245 m_refData = new wxBitmapRefData;
246
247 M_BITMAPDATA->m_width = w;
248 M_BITMAPDATA->m_height = h;
249 M_BITMAPDATA->m_depth = d;
250
251 /* TODO: create new bitmap */
252
253 return M_BITMAPDATA->m_ok;
254 }
255
256 bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
257 {
258 wxAutoNSAutoreleasePool pool;
259 UnRef();
260
261 m_refData = new wxBitmapRefData;
262
263 NSBitmapImageRep *imageRep = [NSBitmapImageRep
264 imageRepWithContentsOfFile:wxNSStringWithWxString(filename)];
265
266 if(imageRep)
267 {
268 M_BITMAPDATA->m_width = [imageRep pixelsWide];
269 M_BITMAPDATA->m_height = [imageRep pixelsHigh];
270 M_BITMAPDATA->m_depth = 24; // FIXME
271 M_BITMAPDATA->m_ok = true;
272 M_BITMAPDATA->m_numColors = 0;
273 M_BITMAPDATA->m_quality = 0;
274 M_BITMAPDATA->m_cocoaNSBitmapImageRep = [imageRep retain];
275 M_BITMAPDATA->m_bitmapMask = NULL;
276 return true;
277 }
278 wxImage image;
279 if(!image.LoadFile(filename,type))
280 return false;
281 if(!image.Ok())
282 return false;
283 *this = wxBitmap(image);
284 return true;
285 }
286
287 bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth)
288 {
289 UnRef();
290
291 m_refData = new wxBitmapRefData;
292
293 return false;
294 }
295
296 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
297 {
298 return false;
299 }
300
301 bool wxBitmap::CopyFromIcon(const wxIcon& icno)
302 {
303 return false;
304 }
305
306 wxBitmap wxBitmap::GetSubBitmap(wxRect const&) const
307 {
308 return wxNullBitmap;
309 }
310
311 wxImage wxBitmap::ConvertToImage() const
312 {
313 if(!M_BITMAPDATA->m_ok)
314 return wxImage(5,5)/*wxNullImage*/;
315 return wxImage(M_BITMAPDATA->m_width,M_BITMAPDATA->m_height);
316 }
317
318 bool wxBitmap::CreateFromXpm(const char **xpm)
319 {
320 #if wxUSE_IMAGE && wxUSE_XPM
321 UnRef();
322
323 wxCHECK_MSG( xpm, false, wxT("invalid XPM data") )
324
325 wxXPMDecoder decoder;
326 wxImage img = decoder.ReadData(xpm);
327 wxCHECK_MSG( img.Ok(), false, wxT("invalid XPM data") )
328
329 *this = wxBitmap(img);
330 return true;
331 #else
332 return false;
333 #endif
334 }
335
336 bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
337 {
338 UnRef();
339
340 wxCHECK_MSG(image.Ok(), false, wxT("invalid image"));
341 wxCHECK_MSG(depth == -1 || depth == 1, false, wxT("invalid bitmap depth"));
342
343 m_refData = new wxBitmapRefData();
344
345 M_BITMAPDATA->m_width = image.GetWidth();
346 M_BITMAPDATA->m_height = image.GetHeight();
347 NSBitmapImageRep *bitmapImage = [[NSBitmapImageRep alloc]
348 initWithBitmapDataPlanes: NULL
349 pixelsWide: image.GetWidth()
350 pixelsHigh: image.GetHeight()
351 bitsPerSample: 8
352 samplesPerPixel: 3
353 hasAlpha: NO
354 isPlanar: NO
355 colorSpaceName: NSCalibratedRGBColorSpace
356 bytesPerRow: 0
357 bitsPerPixel: 0];
358
359 const int numBytes = image.GetWidth()*image.GetHeight()*3;
360 memcpy([bitmapImage bitmapData], image.GetData(), numBytes);
361 // TODO: Alpha and convert to desired depth
362 M_BITMAPDATA->m_depth = 24;
363 M_BITMAPDATA->m_ok = true;
364 M_BITMAPDATA->m_numColors = 0;
365 M_BITMAPDATA->m_quality = 0;
366 M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImage;
367 M_BITMAPDATA->m_bitmapMask = NULL;
368 return true;
369 }
370
371 // ========================================================================
372 // wxMask
373 // ========================================================================
374
375 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
376
377 wxMask::wxMask()
378 {
379 /* TODO
380 m_maskBitmap = 0;
381 */
382 }
383
384 // Construct a mask from a bitmap and a colour indicating
385 // the transparent area
386 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
387 {
388 /* TODO
389 m_maskBitmap = 0;
390 */
391 Create(bitmap, colour);
392 }
393
394 // Construct a mask from a bitmap and a palette index indicating
395 // the transparent area
396 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
397 {
398 /* TODO
399 m_maskBitmap = 0;
400 */
401
402 Create(bitmap, paletteIndex);
403 }
404
405 // Construct a mask from a mono bitmap (copies the bitmap).
406 wxMask::wxMask(const wxBitmap& bitmap)
407 {
408 /* TODO
409 m_maskBitmap = 0;
410 */
411
412 Create(bitmap);
413 }
414
415 wxMask::~wxMask()
416 {
417 // TODO: delete mask bitmap
418 }
419
420 // Create a mask from a mono bitmap (copies the bitmap).
421 bool wxMask::Create(const wxBitmap& bitmap)
422 {
423 // TODO
424 return FALSE;
425 }
426
427 // Create a mask from a bitmap and a palette index indicating
428 // the transparent area
429 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
430 {
431 // TODO
432 return FALSE;
433 }
434
435 // Create a mask from a bitmap and a colour indicating
436 // the transparent area
437 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
438 {
439 // TODO
440 return FALSE;
441 }
442