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