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