]> git.saurik.com Git - wxWidgets.git/blame - src/os2/bitmap.cpp
Added some notes on the Nano-X port.
[wxWidgets.git] / src / os2 / bitmap.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: bitmap.cpp
3// Purpose: wxBitmap
f0a56ab0 4// Author: David Webster
0e320a79 5// Modified by:
f0a56ab0 6// Created: 08/08/99
0e320a79 7// RCS-ID: $Id$
f0a56ab0 8// Copyright: (c) David Webster
0e320a79
DW
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
aa213887
SN
12#ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14#endif
15
d88de032
DW
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifndef WX_PRECOMP
20 #include <stdio.h>
21
22 #include "wx/list.h"
23 #include "wx/utils.h"
24 #include "wx/app.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
28 #include "wx/icon.h"
0e320a79
DW
29#endif
30
d88de032 31#include "wx/os2/private.h"
0e320a79
DW
32#include "wx/log.h"
33
3b9e3455
DW
34//#include "wx/msw/dib.h"
35#include "wx/image.h"
1c344e89 36#include "wx/xpmdecod.h"
3b9e3455 37
d88de032
DW
38// ----------------------------------------------------------------------------
39// macros
40// ----------------------------------------------------------------------------
41
0e320a79
DW
42IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
43IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
3b9e3455
DW
44
45IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
0e320a79 46
3b9e3455
DW
47// ============================================================================
48// implementation
49// ============================================================================
50
51// ----------------------------------------------------------------------------
52// wxBitmapRefData
53// ----------------------------------------------------------------------------
54
0e320a79
DW
55wxBitmapRefData::wxBitmapRefData()
56{
3b9e3455
DW
57 m_nQuality = 0;
58 m_pSelectedInto = NULL;
59 m_nNumColors = 0;
60 m_pBitmapMask = NULL;
341366c6
DW
61 m_hBitmap = (WXHBITMAP) NULL;
62} // end of wxBitmapRefData::wxBitmapRefData
0e320a79 63
3b9e3455 64void wxBitmapRefData::Free()
0e320a79 65{
3b9e3455
DW
66 wxASSERT_MSG( !m_pSelectedInto,
67 wxT("deleting bitmap still selected into wxMemoryDC") );
0e320a79 68
3b9e3455
DW
69 if (m_hBitmap)
70 {
71 if ( !::GpiDeleteBitmap((HBITMAP)m_hBitmap) )
72 {
73 wxLogLastError("GpiDeleteBitmap(hbitmap)");
74 }
75 }
76
77 delete m_pBitmapMask;
78 m_pBitmapMask = NULL;
341366c6 79} // end of wxBitmapRefData::Free
0e320a79 80
3b9e3455
DW
81// ----------------------------------------------------------------------------
82// wxBitmap creation
83// ----------------------------------------------------------------------------
0e320a79 84
3b9e3455
DW
85// this function should be called from all wxBitmap ctors
86void wxBitmap::Init()
0e320a79 87{
3b9e3455 88 // m_refData = NULL; done in the base class ctor
0e320a79 89
3b9e3455 90 if (wxTheBitmapList)
0e320a79 91 wxTheBitmapList->AddBitmap(this);
6f38c86f 92} // end of wxBitmap::Init
0e320a79 93
3b9e3455
DW
94bool wxBitmap::CopyFromIconOrCursor(
95 const wxGDIImage& rIcon
96)
d88de032 97{
6f38c86f
DW
98 HPOINTER hIcon = (HPOINTER)rIcon.GetHandle();
99 POINTERINFO SIconInfo;
100
101 if (!::WinQueryPointerInfo(hIcon, &SIconInfo))
102 {
103 wxLogLastError(wxT("WinQueryPointerInfo"));
104 return FALSE;
105 }
3b9e3455 106 wxBitmapRefData* pRefData = new wxBitmapRefData;
d88de032 107
3b9e3455 108 m_refData = pRefData;
d88de032 109
6f38c86f
DW
110 int nWidth = rIcon.GetWidth();
111 int nHeight = rIcon.GetHeight();
d88de032 112
6f38c86f
DW
113 pRefData->m_nWidth = nWidth;
114 pRefData->m_nHeight = nHeight;
115 pRefData->m_nDepth = wxDisplayDepth();
d88de032 116
6f38c86f
DW
117 pRefData->m_hBitmap = (WXHBITMAP)SIconInfo.hbmColor;
118
119 //
120 // No mask in the Info struct in OS/2
121 //
3b9e3455 122 return(TRUE);
6f38c86f 123} // end of wxBitmap::CopyFromIconOrCursor
0e320a79 124
3b9e3455
DW
125bool wxBitmap::CopyFromCursor(
126 const wxCursor& rCursor
127)
d88de032 128{
3b9e3455 129 UnRef();
d88de032 130
3b9e3455
DW
131 if (!rCursor.Ok())
132 return(FALSE);
43543d98 133 return(CopyFromIconOrCursor(rCursor));
6f38c86f 134} // end of wxBitmap::CopyFromCursor
d88de032 135
3b9e3455
DW
136bool wxBitmap::CopyFromIcon(
137 const wxIcon& rIcon
138)
0e320a79 139{
3b9e3455 140 UnRef();
0e320a79 141
3b9e3455
DW
142 if (!rIcon.Ok())
143 return(FALSE);
0e320a79 144
43543d98 145 return CopyFromIconOrCursor(rIcon);
6f38c86f 146} // end of wxBitmap::CopyFromIcon
0e320a79 147
3b9e3455 148wxBitmap::~wxBitmap()
d88de032 149{
3b9e3455
DW
150 if (wxTheBitmapList)
151 wxTheBitmapList->DeleteObject(this);
6f38c86f 152} // end of wxBitmap::~wxBitmap
d88de032 153
3b9e3455
DW
154wxBitmap::wxBitmap(
155 const char zBits[]
156, int nTheWidth
157, int nTheHeight
158, int nNoBits
159)
160{
161 Init();
162
163 wxBitmapRefData* pRefData = new wxBitmapRefData;
164 BITMAPINFOHEADER2 vHeader;
165 BITMAPINFO2 vInfo;
166 HDC hDc;
167 HPS hPs;
43543d98 168 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3b9e3455
DW
169 SIZEL vSize = {0, 0};
170
43543d98 171 wxASSERT(vHabmain != NULL);
3b9e3455
DW
172
173 hDc = ::DevOpenDC(vHabmain, OD_MEMORY, (PSZ)"*", 1L, (PDEVOPENDATA)&vDop, 0L);
174
175 vHeader.cbFix = sizeof(vHeader);
176 vHeader.cx = (USHORT)nTheWidth;
177 vHeader.cy = (USHORT)nTheHeight;
178 vHeader.cPlanes = 1L;
179 vHeader.cBitCount = nNoBits;
180 vHeader.ulCompression = BCA_UNCOMP;
181 vHeader.cxResolution = 0;
182 vHeader.cyResolution = 0;
183 vHeader.cclrUsed = 0;
184 vHeader.cclrImportant = 0;
185 vHeader.usUnits = BRU_METRIC;
186 vHeader.usRecording = BRA_BOTTOMUP;
187 vHeader.usRendering = BRH_NOTHALFTONED;
188 vHeader.cSize1 = 0;
189 vHeader.cSize2 = 0;
190 vHeader.ulColorEncoding = 0;
191 vHeader.ulIdentifier = 0;
192
43543d98 193 hPs = ::GpiCreatePS(vHabmain, hDc, &vSize, GPIA_ASSOC | PU_PELS);
4f72fe4f 194 if (hPs == 0)
3b9e3455
DW
195 {
196 wxLogLastError("GpiCreatePS Failure");
197 }
0e320a79 198
3b9e3455 199 m_refData = pRefData;
0e320a79 200
43543d98
DW
201 pRefData->m_nWidth = nTheWidth;
202 pRefData->m_nHeight = nTheHeight;
203 pRefData->m_nDepth = nNoBits;
204 pRefData->m_nNumColors = 0;
205 pRefData->m_pSelectedInto = NULL;
0e320a79 206
3b9e3455 207 HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, 0L, NULL, &vInfo);
43543d98 208 if (!hBmp)
3b9e3455
DW
209 {
210 wxLogLastError("CreateBitmap");
211 }
43543d98 212 SetHBITMAP((WXHBITMAP)hBmp);
6f38c86f 213} // end of wxBitmap::wxBitmap
0e320a79 214
3b9e3455
DW
215wxBitmap::wxBitmap(
216 int nW
217, int nH
218, int nD
219)
220{
221 Init();
222
223 (void)Create( nW
224 ,nH
225 ,nD
226 );
6f38c86f 227} // end of wxBitmap::wxBitmap
3b9e3455
DW
228
229wxBitmap::wxBitmap(
230 void* pData
231, long lType
232, int nWidth
233, int nHeight
234, int nDepth
235)
236{
237 Init();
238
239 (void)Create( pData
240 ,lType
241 ,nWidth
242 ,nHeight
243 ,nDepth
244 );
6f38c86f 245} // end of wxBitmap::wxBitmap
3b9e3455
DW
246
247wxBitmap::wxBitmap(
248 const wxString& rFilename
249, long lType
250)
251{
252 Init();
253
254 LoadFile( rFilename
255 ,(int)lType
256 );
6f38c86f 257} // end of wxBitmap::wxBitmap
3b9e3455
DW
258
259bool wxBitmap::Create(
260 int nW
261, int nH
262, int nD
263)
264{
265 HBITMAP hBmp;
266 BITMAPINFOHEADER2 vHeader;
3b9e3455 267
43543d98 268 wxASSERT(vHabmain != NULL);
0e320a79 269 UnRef();
0e320a79 270 m_refData = new wxBitmapRefData;
43543d98
DW
271 GetBitmapData()->m_nWidth = nW;
272 GetBitmapData()->m_nHeight = nH;
273 GetBitmapData()->m_nDepth = nD;
0e320a79 274
3b9e3455
DW
275 if (nD > 0)
276 {
6f38c86f
DW
277 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
278 SIZEL vSize = {0, 0};
279 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
280 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
281
282 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
283 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
284 vHeader.cx = nW;
285 vHeader.cy = nH;
286 vHeader.cPlanes = 1;
287 vHeader.cBitCount = nD;
288
289 hBmp = ::GpiCreateBitmap( hPS
290 ,&vHeader
291 ,0L
292 ,NULL
293 ,NULL
294 );
295 ::GpiDestroyPS(hPS);
296 ::DevCloseDC(hDC);
3b9e3455
DW
297 }
298 else
299 {
6f38c86f
DW
300 HPS hPSScreen;
301 HDC hDCScreen;
302 LONG lBitCount;
303
304 hPSScreen = ::WinGetScreenPS(HWND_DESKTOP);
305 hDCScreen = ::GpiQueryDevice(hPSScreen);
306 ::DevQueryCaps(hDCScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
307
308 memset(&vHeader, '\0', sizeof(BITMAPINFOHEADER2));
309 vHeader.cbFix = sizeof(BITMAPINFOHEADER2);
310 vHeader.cx = nW;
311 vHeader.cy = nH;
312 vHeader.cPlanes = 1;
313 vHeader.cBitCount = lBitCount;
314
315 hBmp = ::GpiCreateBitmap( hPSScreen
316 ,&vHeader
317 ,0L
318 ,NULL
319 ,NULL
320 );
4f72fe4f 321
43543d98 322 GetBitmapData()->m_nDepth = wxDisplayDepth();
6f38c86f 323 ::WinReleasePS(hPSScreen);
3b9e3455 324 }
4f72fe4f 325 SetHBITMAP((WXHBITMAP)hBmp);
0e320a79 326
3b9e3455 327#if WXWIN_COMPATIBILITY_2
4f72fe4f 328 GetBitmapData()->m_bOk = hBmp != 0;
3b9e3455
DW
329#endif // WXWIN_COMPATIBILITY_2
330
331 return Ok();
6f38c86f 332} // end of wxBitmap::Create
0e320a79 333
1c344e89
DW
334bool wxBitmap::CreateFromXpm(
335 const char** ppData
336)
337{
338#if wxUSE_IMAGE && wxUSE_XPM
339 Init();
340
341 wxCHECK_MSG(ppData != NULL, FALSE, wxT("invalid bitmap data"))
342
343 wxXPMDecoder vDecoder;
344 wxImage vImg = vDecoder.ReadData(ppData);
345
346 wxCHECK_MSG(vImg.Ok(), FALSE, wxT("invalid bitmap data"))
347
348 *this = wxBitmap(vImg);
349 return TRUE;
350#else
351 return FALSE;
352#endif
353} // end of wxBitmap::CreateFromXpm
354
4f72fe4f
DW
355bool wxBitmap::LoadFile(
356 const wxString& rFilename
357, long lType
358)
0e320a79 359{
4e0f4f97 360 HPS hPs = NULLHANDLE;
8ea3f821 361
0e320a79
DW
362 UnRef();
363
4f72fe4f
DW
364 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
365 ,wxBitmapHandler
366 );
0e320a79 367
4f72fe4f 368 if (pHandler)
3b9e3455
DW
369 {
370 m_refData = new wxBitmapRefData;
0e320a79 371
4f72fe4f
DW
372 return(pHandler->LoadFile( this
373 ,rFilename
8ea3f821 374 ,hPs
4f72fe4f
DW
375 ,lType
376 , -1
377 , -1
43543d98 378 ));
0e320a79 379 }
3b9e3455
DW
380 else
381 {
4f72fe4f 382 wxImage vImage;
0e320a79 383
43543d98 384 if (!vImage.LoadFile(rFilename, lType) || !vImage.Ok() )
4f72fe4f 385 return(FALSE);
3b9e3455 386
4f72fe4f
DW
387 *this = vImage.ConvertToBitmap();
388
389 return(TRUE);
3b9e3455 390 }
6f38c86f 391} // end of wxBitmap::LoadFile
0e320a79 392
4f72fe4f
DW
393bool wxBitmap::Create(
394 void* pData
395, long lType
396, int nWidth
397, int nHeight
398, int nDepth
399)
0e320a79
DW
400{
401 UnRef();
402
4f72fe4f
DW
403 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
404 ,wxBitmapHandler
405 );
0e320a79 406
4f72fe4f 407 if (!pHandler)
3b9e3455
DW
408 {
409 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
43543d98 410 "type %d defined."), lType);
0e320a79 411
4f72fe4f 412 return(FALSE);
0e320a79
DW
413 }
414
3b9e3455
DW
415 m_refData = new wxBitmapRefData;
416
43543d98
DW
417 return(pHandler->Create( this
418 ,pData
419 ,lType
420 ,nWidth
421 ,nHeight
422 ,nDepth
423 ));
6f38c86f 424} // end of wxBitmap::Create
0e320a79 425
58b16424 426bool wxBitmap::SaveFile(
4f72fe4f
DW
427 const wxString& rFilename
428, int lType
429, const wxPalette* pPalette
430)
0e320a79 431{
4f72fe4f
DW
432 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
433 ,wxBitmapHandler
434 );
0e320a79 435
4f72fe4f 436 if (pHandler)
3b9e3455 437 {
4f72fe4f
DW
438 return pHandler->SaveFile( this
439 ,rFilename
440 ,lType
441 ,pPalette
442 );
3b9e3455
DW
443 }
444 else
445 {
446 // FIXME what about palette? shouldn't we use it?
4f72fe4f
DW
447 wxImage vImage(*this);
448
449 if (!vImage.Ok())
450 return(FALSE);
0e320a79 451
4f72fe4f
DW
452 return(vImage.SaveFile( rFilename
453 ,lType
454 ));
3b9e3455 455 }
6f38c86f
DW
456} // end of wxBitmap::SaveFile
457
fec19ea9
VS
458
459// ----------------------------------------------------------------------------
460// wxImage-wxBitmap convertion
461// ----------------------------------------------------------------------------
462
463bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
464{
465 wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
466
467// TODO:
468/*
469 int sizeLimit = 1024*768*3;
470
471 // width and height of the device-dependent bitmap
472 int width = GetWidth();
473 int bmpHeight = GetHeight();
474
475 // calc the number of bytes per scanline and padding
476 int bytePerLine = width*3;
477 int sizeDWORD = sizeof( DWORD );
478 int lineBoundary = bytePerLine % sizeDWORD;
479 int padding = 0;
480 if( lineBoundary > 0 )
481 {
482 padding = sizeDWORD - lineBoundary;
483 bytePerLine += padding;
484 }
485 // calc the number of DIBs and heights of DIBs
486 int numDIB = 1;
487 int hRemain = 0;
488 int height = sizeLimit/bytePerLine;
489 if( height >= bmpHeight )
490 height = bmpHeight;
491 else
492 {
493 numDIB = bmpHeight / height;
494 hRemain = bmpHeight % height;
495 if( hRemain >0 ) numDIB++;
496 }
497
498 // set bitmap parameters
499 wxBitmap bitmap;
500 wxCHECK_MSG( Ok(), bitmap, wxT("invalid image") );
501 bitmap.SetWidth( width );
502 bitmap.SetHeight( bmpHeight );
503 bitmap.SetDepth( wxDisplayDepth() );
504
505 // create a DIB header
506 int headersize = sizeof(BITMAPINFOHEADER);
507 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
508 wxCHECK_MSG( lpDIBh, bitmap, wxT("could not allocate memory for DIB header") );
509 // Fill in the DIB header
510 lpDIBh->bmiHeader.biSize = headersize;
511 lpDIBh->bmiHeader.biWidth = (DWORD)width;
512 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
513 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
514 // the general formula for biSizeImage:
515 // ( ( ( ((DWORD)width*24) +31 ) & ~31 ) >> 3 ) * height;
516 lpDIBh->bmiHeader.biPlanes = 1;
517 lpDIBh->bmiHeader.biBitCount = 24;
518 lpDIBh->bmiHeader.biCompression = BI_RGB;
519 lpDIBh->bmiHeader.biClrUsed = 0;
520 // These seem not really needed for our purpose here.
521 lpDIBh->bmiHeader.biClrImportant = 0;
522 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
523 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
524 // memory for DIB data
525 unsigned char *lpBits;
526 lpBits = (unsigned char *)malloc( lpDIBh->bmiHeader.biSizeImage );
527 if( !lpBits )
528 {
529 wxFAIL_MSG( wxT("could not allocate memory for DIB") );
530 free( lpDIBh );
531 return bitmap;
532 }
533
534 // create and set the device-dependent bitmap
535 HDC hdc = ::GetDC(NULL);
536 HDC memdc = ::CreateCompatibleDC( hdc );
537 HBITMAP hbitmap;
538 hbitmap = ::CreateCompatibleBitmap( hdc, width, bmpHeight );
539 ::SelectObject( memdc, hbitmap);
540
541 // copy image data into DIB data and then into DDB (in a loop)
542 unsigned char *data = GetData();
543 int i, j, n;
544 int origin = 0;
545 unsigned char *ptdata = data;
546 unsigned char *ptbits;
547
548 for( n=0; n<numDIB; n++ )
549 {
550 if( numDIB > 1 && n == numDIB-1 && hRemain > 0 )
551 {
552 // redefine height and size of the (possibly) last smaller DIB
553 // memory is not reallocated
554 height = hRemain;
555 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
556 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
557 }
558 ptbits = lpBits;
559
560 for( j=0; j<height; j++ )
561 {
562 for( i=0; i<width; i++ )
563 {
564 *(ptbits++) = *(ptdata+2);
565 *(ptbits++) = *(ptdata+1);
566 *(ptbits++) = *(ptdata );
567 ptdata += 3;
568 }
569 for( i=0; i< padding; i++ ) *(ptbits++) = 0;
570 }
571 ::StretchDIBits( memdc, 0, origin, width, height,\
572 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
573 origin += height;
574 // if numDIB = 1, lines below can also be used
575 // hbitmap = CreateDIBitmap( hdc, &(lpDIBh->bmiHeader), CBM_INIT, lpBits, lpDIBh, DIB_RGB_COLORS );
576 // The above line is equivalent to the following two lines.
577 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
578 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
579 // or the following lines
580 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
581 // HDC memdc = ::CreateCompatibleDC( hdc );
582 // ::SelectObject( memdc, hbitmap);
583 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
584 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
585 // ::SelectObject( memdc, 0 );
586 // ::DeleteDC( memdc );
587 }
588 bitmap.SetHBITMAP( (WXHBITMAP) hbitmap );
589
590 // similarly, created an mono-bitmap for the possible mask
591 if( HasMask() )
592 {
593 hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
594 ::SelectObject( memdc, hbitmap);
595 if( numDIB == 1 ) height = bmpHeight;
596 else height = sizeLimit/bytePerLine;
597 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
598 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
599 origin = 0;
600 unsigned char r = GetMaskRed();
601 unsigned char g = GetMaskGreen();
602 unsigned char b = GetMaskBlue();
603 unsigned char zero = 0, one = 255;
604 ptdata = data;
605 for( n=0; n<numDIB; n++ )
606 {
607 if( numDIB > 1 && n == numDIB - 1 && hRemain > 0 )
608 {
609 // redefine height and size of the (possibly) last smaller DIB
610 // memory is not reallocated
611 height = hRemain;
612 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
613 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
614 }
615 ptbits = lpBits;
616 for( int j=0; j<height; j++ )
617 {
618 for(i=0; i<width; i++ )
619 {
620 if( (*(ptdata++)!=r) | (*(ptdata++)!=g) | (*(ptdata++)!=b) )
621 {
622 *(ptbits++) = one;
623 *(ptbits++) = one;
624 *(ptbits++) = one;
625 }
626 else
627 {
628 *(ptbits++) = zero;
629 *(ptbits++) = zero;
630 *(ptbits++) = zero;
631 }
632 }
633 for( i=0; i< padding; i++ ) *(ptbits++) = zero;
634 }
635 ::StretchDIBits( memdc, 0, origin, width, height,\
636 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
637 origin += height;
638 }
639 // create a wxMask object
640 wxMask *mask = new wxMask();
641 mask->SetMaskBitmap( (WXHBITMAP) hbitmap );
642 bitmap.SetMask( mask );
643 }
644
645 // free allocated resources
646 ::SelectObject( memdc, 0 );
647 ::DeleteDC( memdc );
648 ::ReleaseDC(NULL, hdc);
649 free(lpDIBh);
650 free(lpBits);
651
652 // check the wxBitmap object
653 if( bitmap.GetHBITMAP() )
654 bitmap.SetOk( TRUE );
655 else
656 bitmap.SetOk( FALSE );
657*/
658
659 return TRUE;
660}
661
662wxImage wxBitmap::ConvertToImage() const
663{
664 wxImage image;
1c344e89 665
fec19ea9
VS
666 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
667
668 // create an wxImage object
669 int width = GetWidth();
670 int height = GetHeight();
671 image.Create( width, height );
672 unsigned char *data = image.GetData();
673 if( !data )
674 {
675 wxFAIL_MSG( wxT("could not allocate data for image") );
676 return wxNullImage;
677 }
678
679 // calc the number of bytes per scanline and padding in the DIB
680 int bytePerLine = width*3;
681 int sizeDWORD = sizeof( DWORD );
682 int lineBoundary = bytePerLine % sizeDWORD;
683 int padding = 0;
684 if( lineBoundary > 0 )
685 {
686 padding = sizeDWORD - lineBoundary;
687 bytePerLine += padding;
688 }
689// TODO:
690/*
691 // create a DIB header
692 int headersize = sizeof(BITMAPINFOHEADER);
693 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
694 if( !lpDIBh )
695 {
696 wxFAIL_MSG( wxT("could not allocate data for DIB header") );
697 free( data );
698 return;
699 }
700 // Fill in the DIB header
701 lpDIBh->bmiHeader.biSize = headersize;
702 lpDIBh->bmiHeader.biWidth = width;
703 lpDIBh->bmiHeader.biHeight = -height;
704 lpDIBh->bmiHeader.biSizeImage = bytePerLine * height;
705 lpDIBh->bmiHeader.biPlanes = 1;
706 lpDIBh->bmiHeader.biBitCount = 24;
707 lpDIBh->bmiHeader.biCompression = BI_RGB;
708 lpDIBh->bmiHeader.biClrUsed = 0;
709 // These seem not really needed for our purpose here.
710 lpDIBh->bmiHeader.biClrImportant = 0;
711 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
712 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
713 // memory for DIB data
714 unsigned char *lpBits;
715 lpBits = (unsigned char *) malloc( lpDIBh->bmiHeader.biSizeImage );
716 if( !lpBits )
717 {
718 wxFAIL_MSG( wxT("could not allocate data for DIB") );
719 free( data );
720 free( lpDIBh );
721 return;
722 }
723
724 // copy data from the device-dependent bitmap to the DIB
725 HDC hdc = ::GetDC(NULL);
726 HBITMAP hbitmap;
727 hbitmap = (HBITMAP) bitmap.GetHBITMAP();
728 ::GetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
729
730 // copy DIB data into the wxImage object
731 int i, j;
732 unsigned char *ptdata = data;
733 unsigned char *ptbits = lpBits;
734 for( i=0; i<height; i++ )
735 {
736 for( j=0; j<width; j++ )
737 {
738 *(ptdata++) = *(ptbits+2);
739 *(ptdata++) = *(ptbits+1);
740 *(ptdata++) = *(ptbits );
741 ptbits += 3;
742 }
743 ptbits += padding;
744 }
745
746 // similarly, set data according to the possible mask bitmap
747 if( bitmap.GetMask() && bitmap.GetMask()->GetMaskBitmap() )
748 {
749 hbitmap = (HBITMAP) bitmap.GetMask()->GetMaskBitmap();
750 // memory DC created, color set, data copied, and memory DC deleted
751 HDC memdc = ::CreateCompatibleDC( hdc );
752 ::SetTextColor( memdc, RGB( 0, 0, 0 ) );
753 ::SetBkColor( memdc, RGB( 255, 255, 255 ) );
754 ::GetDIBits( memdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
755 ::DeleteDC( memdc );
756 // background color set to RGB(16,16,16) in consistent with wxGTK
757 unsigned char r=16, g=16, b=16;
758 ptdata = data;
759 ptbits = lpBits;
760 for( i=0; i<height; i++ )
761 {
762 for( j=0; j<width; j++ )
763 {
764 if( *ptbits != 0 )
765 ptdata += 3;
766 else
767 {
768 *(ptdata++) = r;
769 *(ptdata++) = g;
770 *(ptdata++) = b;
771 }
772 ptbits += 3;
773 }
774 ptbits += padding;
775 }
776 SetMaskColour( r, g, b );
777 SetMask( TRUE );
778 }
779 else
780 {
781 SetMask( FALSE );
782 }
783 // free allocated resources
784 ::ReleaseDC(NULL, hdc);
785 free(lpDIBh);
786 free(lpBits);
787*/
788
789 return image;
790}
791
792
6f38c86f
DW
793// ----------------------------------------------------------------------------
794// sub bitmap extraction
795// ----------------------------------------------------------------------------
796
797wxBitmap wxBitmap::GetSubBitmap(
798 const wxRect& rRect
799) const
800{
801 wxCHECK_MSG( Ok() &&
802 (rRect.x >= 0) && (rRect.y >= 0) &&
803 (rRect.x + rRect.width <= GetWidth()) &&
804 (rRect.y + rRect.height <= GetHeight()),
805 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
806
807 wxBitmap vRet( rRect.width
808 ,rRect.height
809 ,GetDepth()
810 );
811 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
812
813
814 //
815 // Copy bitmap data
816 //
817 SIZEL vSize = {0, 0};
818 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
819 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
820 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
821 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
822 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
823 POINTL vPoint[4] = { rRect.x, rRect.y,
824 rRect.x + rRect.width, rRect.y + rRect.height,
825 0, 0, GetWidth(), GetHeight()
826 };
827
828 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
829 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
830 ::GpiBitBlt( hPSDst
831 ,hPSSrc
832 ,4L
833 ,vPoint
834 ,ROP_SRCCOPY
835 ,BBO_IGNORE
836 );
837
838 //
839 // Copy mask if there is one
840 //
841 if (GetMask())
842 {
843 BITMAPINFOHEADER2 vBmih;
844
845 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
846 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
847 vBmih.cx = rRect.width;
848 vBmih.cy = rRect.height;
849 vBmih.cPlanes = 1;
850 vBmih.cBitCount = 1;
851
852 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
853 ,&vBmih
854 ,0L
855 ,NULL
856 ,NULL
857 );
858
859 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
860 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
861
862 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
863 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
864 ::GpiBitBlt( hPSDst
865 ,hPSSrc
866 ,4L
867 ,vPoint
868 ,ROP_SRCCOPY
869 ,BBO_IGNORE
870 );
871
872 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
873 vRet.SetMask(pMask);
874 }
875
876 ::GpiSetBitmap(hPSSrc, NULL);
877 ::GpiSetBitmap(hPSDst, NULL);
878 ::GpiDestroyPS(hPSSrc);
879 ::GpiDestroyPS(hPSDst);
880 ::DevCloseDC(hDCSrc);
881 ::DevCloseDC(hDCDst);
882 return vRet;
883} // end of wxBitmap::GetSubBitmap
0e320a79 884
3b9e3455
DW
885// ----------------------------------------------------------------------------
886// wxBitmap accessors
887// ----------------------------------------------------------------------------
0e320a79 888
4f72fe4f
DW
889void wxBitmap::SetQuality(
890 int nQ
891)
0e320a79 892{
3b9e3455 893 EnsureHasData();
0e320a79 894
4f72fe4f 895 GetBitmapData()->m_nQuality = nQ;
6f38c86f 896} // end of wxBitmap::SetQuality
0e320a79 897
3b9e3455 898#if WXWIN_COMPATIBILITY_2
4f72fe4f
DW
899void wxBitmap::SetOk(
900 bool bOk
901)
0e320a79 902{
3b9e3455 903 EnsureHasData();
0e320a79 904
4f72fe4f 905 GetBitmapData()->m_bOk = bOk;
6f38c86f 906} // end of wxBitmap::SetOk
3b9e3455 907#endif // WXWIN_COMPATIBILITY_2
0e320a79 908
4f72fe4f
DW
909void wxBitmap::SetPalette(
910 const wxPalette& rPalette
911)
0e320a79 912{
3b9e3455 913 EnsureHasData();
0e320a79 914
4f72fe4f 915 GetBitmapData()->m_vBitmapPalette = rPalette;
6f38c86f 916} // end of wxBitmap::SetPalette
0e320a79 917
4f72fe4f
DW
918void wxBitmap::SetMask(
919 wxMask* pMask
920)
0e320a79 921{
3b9e3455 922 EnsureHasData();
0e320a79 923
4f72fe4f 924 GetBitmapData()->m_pBitmapMask = pMask;
6f38c86f 925} // end of wxBitmap::SetMask
0e320a79 926
6f38c86f 927//
4f72fe4f 928// Will try something for OS/2 but not really sure how close
58b16424 929// to the msw intent this is.
6f38c86f 930//
4f72fe4f
DW
931wxBitmap wxBitmap::GetBitmapForDC(
932 wxDC& rDc
933) const
d88de032 934{
4f72fe4f
DW
935 wxMemoryDC vMemDC;
936 wxBitmap vTmpBitmap( this->GetWidth()
937 ,this->GetHeight()
938 ,rDc.GetDepth()
939 );
43543d98 940 WXHBITMAP vOldBitmap;
4f72fe4f
DW
941 HPS hMemoryPS;
942 HPS hPs;
943 POINTL vPoint[4];
43543d98 944 SIZEL vSize = {0,0};
d88de032 945
43543d98
DW
946 hMemoryPS = ::GpiCreatePS(vHabmain, (HDC)vMemDC.GetHDC(), &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
947 hPs = ::GpiCreatePS(vHabmain, (HDC)rDc.GetHDC(), &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC);
d88de032 948
4f72fe4f 949 // TODO: Set the points
3b9e3455 950
43543d98
DW
951 vOldBitmap = (WXHBITMAP)::GpiSetBitmap(hPs, (HBITMAP)vTmpBitmap.GetHBITMAP());
952 ::GpiBitBlt(hPs, hMemoryPS, 4L, vPoint, ROP_SRCCOPY, BBO_IGNORE);
58b16424
DW
953
954 return(vTmpBitmap);
6f38c86f 955} // end of wxBitmap::GetBitmapForDC
d88de032 956
3b9e3455
DW
957// ----------------------------------------------------------------------------
958// wxMask
959// ----------------------------------------------------------------------------
0e320a79
DW
960
961wxMask::wxMask()
962{
4f72fe4f 963 m_hMaskBitmap = 0;
6f38c86f 964} // end of wxMask::wxMask
0e320a79
DW
965
966// Construct a mask from a bitmap and a colour indicating
967// the transparent area
4f72fe4f
DW
968wxMask::wxMask(
969 const wxBitmap& rBitmap
970, const wxColour& rColour
971)
0e320a79 972{
4f72fe4f
DW
973 m_hMaskBitmap = 0;
974 Create( rBitmap
975 ,rColour
976 );
6f38c86f 977} // end of wxMask::wxMask
0e320a79
DW
978
979// Construct a mask from a bitmap and a palette index indicating
980// the transparent area
4f72fe4f
DW
981wxMask::wxMask(
982 const wxBitmap& rBitmap
983, int nPaletteIndex
984)
0e320a79 985{
4f72fe4f
DW
986 m_hMaskBitmap = 0;
987 Create( rBitmap
988 ,nPaletteIndex
989 );
6f38c86f 990} // end of wxMask::wxMask
0e320a79
DW
991
992// Construct a mask from a mono bitmap (copies the bitmap).
4f72fe4f
DW
993wxMask::wxMask(
994 const wxBitmap& rBitmap
995)
0e320a79 996{
4f72fe4f
DW
997 m_hMaskBitmap = 0;
998 Create(rBitmap);
6f38c86f 999} // end of wxMask::wxMask
0e320a79
DW
1000
1001wxMask::~wxMask()
1002{
4f72fe4f
DW
1003 if (m_hMaskBitmap)
1004 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
6f38c86f 1005} // end of wxMask::~wxMask
0e320a79
DW
1006
1007// Create a mask from a mono bitmap (copies the bitmap).
58b16424
DW
1008bool wxMask::Create(
1009 const wxBitmap& rBitmap
1010)
0e320a79 1011{
6f38c86f 1012 BITMAPINFOHEADER2 vBmih;
58b16424 1013 SIZEL vSize = {0, 0};
6f38c86f
DW
1014 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1015 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1016 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1017 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1018 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1019 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1020 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1021 };
58b16424
DW
1022
1023 if (m_hMaskBitmap)
3b9e3455 1024 {
58b16424
DW
1025 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1026 m_hMaskBitmap = 0;
3b9e3455 1027 }
58b16424 1028 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
3b9e3455 1029 {
58b16424 1030 return(FALSE);
3b9e3455 1031 }
6f38c86f
DW
1032
1033 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1034 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1035 vBmih.cx = rBitmap.GetWidth();
1036 vBmih.cy = rBitmap.GetHeight();
1037 vBmih.cPlanes = 1;
1038 vBmih.cBitCount = 1;
1039
1040 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1041 ,&vBmih
1042 ,0L
1043 ,NULL
1044 ,NULL
1045 );
1046
1047 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1048 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1049 ::GpiBitBlt( hPSDst
1050 ,hPSSrc
1051 ,4L
1052 ,vPoint
1053 ,ROP_SRCCOPY
1054 ,BBO_IGNORE
1055 );
1056
1057 ::GpiDestroyPS(hPSSrc);
1058 ::GpiDestroyPS(hPSDst);
1059 ::DevCloseDC(hDCSrc);
1060 ::DevCloseDC(hDCDst);
58b16424 1061 return(TRUE);
6f38c86f 1062} // end of wxMask::Create
0e320a79
DW
1063
1064// Create a mask from a bitmap and a palette index indicating
1065// the transparent area
58b16424
DW
1066bool wxMask::Create(
1067 const wxBitmap& rBitmap
1068, int nPaletteIndex
1069)
0e320a79 1070{
58b16424 1071 if (m_hMaskBitmap)
3b9e3455 1072 {
58b16424
DW
1073 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1074 m_hMaskBitmap = 0;
3b9e3455 1075 }
58b16424 1076 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
3b9e3455 1077 {
43543d98
DW
1078 unsigned char cRed;
1079 unsigned char cGreen;
1080 unsigned char cBlue;
1081
58b16424 1082 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
43543d98
DW
1083 ,&cRed
1084 ,&cGreen
1085 ,&cBlue
58b16424 1086 ))
3b9e3455 1087 {
43543d98
DW
1088 wxColour vTransparentColour( cRed
1089 ,cGreen
1090 ,cBlue
58b16424
DW
1091 );
1092
1093 return (Create( rBitmap
1094 ,vTransparentColour
1095 ));
3b9e3455
DW
1096 }
1097 }
58b16424 1098 return(FALSE);
6f38c86f 1099} // end of wxMask::Create
0e320a79
DW
1100
1101// Create a mask from a bitmap and a colour indicating
1102// the transparent area
58b16424
DW
1103bool wxMask::Create(
1104 const wxBitmap& rBitmap
1105, const wxColour& rColour
1106)
0e320a79 1107{
6f38c86f
DW
1108 bool bOk = TRUE;
1109 COLORREF vMaskColour = OS2RGB( rColour.Red()
1110 ,rColour.Green()
1111 ,rColour.Blue()
1112 );
1113 BITMAPINFOHEADER2 vBmih;
58b16424 1114 SIZEL vSize = {0, 0};
6f38c86f
DW
1115 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1116 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1117 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1118 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1119 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1120 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1121 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1122 };
58b16424
DW
1123
1124 if (m_hMaskBitmap)
3b9e3455 1125 {
58b16424
DW
1126 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1127 m_hMaskBitmap = 0;
3b9e3455 1128 }
58b16424 1129 if (!rBitmap.Ok())
3b9e3455 1130 {
58b16424 1131 return(FALSE);
3b9e3455
DW
1132 }
1133
6f38c86f
DW
1134 //
1135 // Scan the bitmap for the transparent colour and set
3b9e3455
DW
1136 // the corresponding pixels in the mask to BLACK and
1137 // the rest to WHITE
6f38c86f
DW
1138 //
1139
1140 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1141 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1142 vBmih.cx = rBitmap.GetWidth();
1143 vBmih.cy = rBitmap.GetHeight();
1144 vBmih.cPlanes = 1;
1145 vBmih.cBitCount = 1;
1146
1147 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1148 ,&vBmih
1149 ,0L
1150 ,NULL
1151 ,NULL
1152 );
1153
1154 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1155 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1156
1157 //
1158 // This is not very efficient, but I can't think
3b9e3455 1159 // of a better way of doing it
6f38c86f 1160 //
58b16424 1161 for (int w = 0; w < rBitmap.GetWidth(); w++)
3b9e3455 1162 {
58b16424 1163 for (int h = 0; h < rBitmap.GetHeight(); h++)
3b9e3455 1164 {
6f38c86f
DW
1165 POINTL vPt = {w, h};
1166 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1167 if (vCol == (COLORREF)CLR_NOINDEX)
1168 {
1169 //
1170 // Doesn't make sense to continue
1171 //
1172 bOk = FALSE;
1173 break;
1174 }
58b16424 1175
6f38c86f 1176 if (vCol == vMaskColour)
3b9e3455 1177 {
6f38c86f
DW
1178 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1179 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1180 }
1181 else
1182 {
6f38c86f
DW
1183 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1184 ::GpiSetPel(hPSDst, &vPt);
3b9e3455
DW
1185 }
1186 }
1187 }
6f38c86f
DW
1188 ::GpiSetBitmap(hPSSrc, NULL);
1189 ::GpiSetBitmap(hPSDst, NULL);
1190 ::GpiDestroyPS(hPSSrc);
1191 ::GpiDestroyPS(hPSDst);
1192 ::DevCloseDC(hDCSrc);
1193 ::DevCloseDC(hDCDst);
58b16424 1194 return(TRUE);
6f38c86f 1195} // end of wxMask::Create
0e320a79 1196
3b9e3455
DW
1197// ----------------------------------------------------------------------------
1198// wxBitmapHandler
1199// ----------------------------------------------------------------------------
0e320a79 1200
58b16424
DW
1201bool wxBitmapHandler::Create(
1202 wxGDIImage* pImage
1203, void* pData
1204, long lFlags
1205, int nWidth
1206, int nHeight
1207, int nDepth
1208)
3b9e3455 1209{
58b16424
DW
1210 wxBitmap* pBitmap = wxDynamicCast( pImage
1211 ,wxBitmap
1212 );
3b9e3455 1213
58b16424
DW
1214 return(pBitmap ? Create( pBitmap
1215 ,pData
1216 ,nWidth
1217 ,nHeight
1218 ,nDepth
1219 ) : FALSE);
3b9e3455
DW
1220}
1221
58b16424
DW
1222bool wxBitmapHandler::Load(
1223 wxGDIImage* pImage
1224, const wxString& rName
8ea3f821 1225, HPS hPs
58b16424
DW
1226, long lFlags
1227, int nWidth
1228, int nHeight
1229)
3b9e3455 1230{
43543d98
DW
1231 wxBitmap* pBitmap = wxDynamicCast( pImage
1232 ,wxBitmap
1233 );
3b9e3455 1234
58b16424
DW
1235 return(pBitmap ? LoadFile( pBitmap
1236 ,rName
8ea3f821 1237 ,hPs
58b16424
DW
1238 ,lFlags
1239 ,nWidth
1240 ,nHeight
1241 ) : FALSE);
3b9e3455
DW
1242}
1243
58b16424
DW
1244bool wxBitmapHandler::Save(
1245 wxGDIImage* pImage
1246, const wxString& rName
1247, int lType
1248)
0e320a79 1249{
58b16424
DW
1250 wxBitmap* pBitmap = wxDynamicCast( pImage
1251 ,wxBitmap
1252 );
0e320a79 1253
58b16424
DW
1254 return(pBitmap ? SaveFile( pBitmap
1255 ,rName
1256 ,lType
1257 ) : FALSE);
0e320a79
DW
1258}
1259
58b16424
DW
1260bool wxBitmapHandler::Create(
1261 wxBitmap* WXUNUSED(pBitmap)
1262, void* WXUNUSED(pData)
1263, long WXUNUSED(lType)
1264, int WXUNUSED(nWidth)
1265, int WXUNUSED(nHeight)
1266, int WXUNUSED(nDepth)
1267)
0e320a79 1268{
58b16424 1269 return(FALSE);
0e320a79
DW
1270}
1271
58b16424
DW
1272bool wxBitmapHandler::LoadFile(
1273 wxBitmap* WXUNUSED(pBitmap)
1274, const wxString& WXUNUSED(rName)
8ea3f821 1275, HPS WXUNUSED(hPs)
58b16424
DW
1276, long WXUNUSED(lType)
1277, int WXUNUSED(nDesiredWidth)
1278, int WXUNUSED(nDesiredHeight)
1279)
0e320a79 1280{
43543d98 1281 return(FALSE);
0e320a79
DW
1282}
1283
58b16424
DW
1284bool wxBitmapHandler::SaveFile(
1285 wxBitmap* WXUNUSED(pBitmap)
1286, const wxString& WXUNUSED(rName)
1287, int WXUNUSED(nType)
1288, const wxPalette* WXUNUSED(pPalette)
1289)
0e320a79 1290{
58b16424 1291 return(FALSE);
0e320a79 1292}
ce44c50e 1293
020a1653
DW
1294// ----------------------------------------------------------------------------
1295// Utility functions
1296// ----------------------------------------------------------------------------
1297HBITMAP wxInvertMask(
1298 HBITMAP hBmpMask
1299, int nWidth
1300, int nHeight
1301)
1302{
1303 HBITMAP hBmpInvMask = 0;
1304
1305 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1306
1307 //
1308 // Get width/height from the bitmap if not given
1309 //
1310 if (!nWidth || !nHeight)
1311 {
1312 BITMAPINFOHEADER2 vBmhdr;
1313
1314 ::GpiQueryBitmapInfoHeader( hBmpMask
1315 ,&vBmhdr
1316 );
1317 nWidth = (int)vBmhdr.cx;
e464c180 1318 nHeight = (int)vBmhdr.cy;
020a1653
DW
1319 }
1320
1321 BITMAPINFOHEADER2 vBmih;
1322 SIZEL vSize = {0, 0};
1323 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
e464c180
DW
1324 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1325 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1326 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1327 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1328 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1329 0, 0, nWidth, nHeight
020a1653
DW
1330 };
1331
e464c180 1332 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
020a1653 1333 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
e464c180
DW
1334 vBmih.cx = nWidth;
1335 vBmih.cy = nHeight;
020a1653
DW
1336 vBmih.cPlanes = 1;
1337 vBmih.cBitCount = 1;
1338
1339 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1340 ,&vBmih
1341 ,0L
1342 ,NULL
1343 ,NULL
1344 );
1345
1346 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1347 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1348
1349 ::GpiBitBlt( hPSDst
1350 ,hPSSrc
1351 ,4L
e464c180 1352 ,vPoint
8e8d8eef 1353 ,ROP_SRCINVERT
020a1653
DW
1354 ,BBO_IGNORE
1355 );
1356
1357 ::GpiDestroyPS(hPSSrc);
1358 ::GpiDestroyPS(hPSDst);
1359 ::DevCloseDC(hDCSrc);
e464c180 1360 ::DevCloseDC(hDCDst);
020a1653
DW
1361
1362 return hBmpInvMask;
1363} // end of WxWinGdi_InvertMask