1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13     #pragma implementation "bitmap.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  25     #include "wx/palette.h" 
  26     #include "wx/dcmemory.h" 
  27     #include "wx/bitmap.h" 
  31 #include "wx/os2/private.h" 
  34 //#include "wx/msw/dib.h" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  41 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  42 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  44 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
  46 // ============================================================================ 
  48 // ============================================================================ 
  50 // ---------------------------------------------------------------------------- 
  52 // ---------------------------------------------------------------------------- 
  54 wxBitmapRefData::wxBitmapRefData() 
  57     m_pSelectedInto 
= NULL
; 
  60     m_hBitmap 
= (WXHBITMAP
) NULL
; 
  61 } // end of wxBitmapRefData::wxBitmapRefData 
  63 void wxBitmapRefData::Free() 
  65     wxASSERT_MSG( !m_pSelectedInto
, 
  66                   wxT("deleting bitmap still selected into wxMemoryDC") ); 
  70         if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) ) 
  72             wxLogLastError("GpiDeleteBitmap(hbitmap)"); 
  78 } // end of wxBitmapRefData::Free 
  80 // ---------------------------------------------------------------------------- 
  82 // ---------------------------------------------------------------------------- 
  84 // this function should be called from all wxBitmap ctors 
  87     // m_refData = NULL; done in the base class ctor 
  90         wxTheBitmapList
->AddBitmap(this); 
  91 } // end of wxBitmap::Init 
  93 bool wxBitmap::CopyFromIconOrCursor( 
  94   const wxGDIImage
&                 rIcon
 
  97     HPOINTER                        hIcon 
= (HPOINTER
)rIcon
.GetHandle(); 
  98     POINTERINFO                     SIconInfo
; 
 100     if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
)) 
 102         wxLogLastError(wxT("WinQueryPointerInfo")); 
 105     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 107     m_refData 
= pRefData
; 
 109     int                             nWidth 
= rIcon
.GetWidth(); 
 110     int                             nHeight 
= rIcon
.GetHeight(); 
 112     pRefData
->m_nWidth  
= nWidth
; 
 113     pRefData
->m_nHeight 
= nHeight
; 
 114     pRefData
->m_nDepth  
= wxDisplayDepth(); 
 116     pRefData
->m_hBitmap 
= (WXHBITMAP
)SIconInfo
.hbmColor
; 
 119     // No mask in the Info struct in OS/2 
 122 } // end of wxBitmap::CopyFromIconOrCursor 
 124 bool wxBitmap::CopyFromCursor( 
 125   const wxCursor
&                   rCursor
 
 132     return(CopyFromIconOrCursor(rCursor
)); 
 133 } // end of wxBitmap::CopyFromCursor 
 135 bool wxBitmap::CopyFromIcon( 
 144     return CopyFromIconOrCursor(rIcon
); 
 145 } // end of wxBitmap::CopyFromIcon 
 147 wxBitmap::~wxBitmap() 
 150         wxTheBitmapList
->DeleteObject(this); 
 151 } // end of wxBitmap::~wxBitmap 
 162     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 163     BITMAPINFOHEADER2               vHeader
; 
 167     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 168     SIZEL                           vSize 
= {0, 0}; 
 170     wxASSERT(vHabmain 
!= NULL
); 
 172     hDc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L); 
 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
; 
 189     vHeader
.ulColorEncoding 
= 0; 
 190     vHeader
.ulIdentifier    
= 0; 
 192     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 195         wxLogLastError("GpiCreatePS Failure"); 
 198     m_refData 
= pRefData
; 
 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
; 
 206     HBITMAP hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
); 
 209         wxLogLastError("CreateBitmap"); 
 211     SetHBITMAP((WXHBITMAP
)hBmp
); 
 212 } // end of wxBitmap::wxBitmap 
 215 // Create from XPM data 
 223     (void)Create( (void *)ppData
 
 224                  ,wxBITMAP_TYPE_XPM_DATA
 
 229 } // end of wxBitmap::wxBitmap 
 237     (void)Create( (void *)ppData
 
 238                  ,wxBITMAP_TYPE_XPM_DATA
 
 243 } // end of wxBitmap::wxBitmap 
 257 } // end of wxBitmap::wxBitmap 
 275 } // end of wxBitmap::wxBitmap 
 278   const wxString
&                   rFilename
 
 287 } // end of wxBitmap::wxBitmap 
 289 bool wxBitmap::Create( 
 296     BITMAPINFOHEADER2               vHeader
; 
 298     wxASSERT(vHabmain 
!= NULL
); 
 300     m_refData 
= new wxBitmapRefData
; 
 301     GetBitmapData()->m_nWidth 
= nW
; 
 302     GetBitmapData()->m_nHeight 
= nH
; 
 303     GetBitmapData()->m_nDepth 
= nD
; 
 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
); 
 312         memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
)); 
 313         vHeader
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
 317         vHeader
.cBitCount 
= nD
; 
 319         hBmp 
= ::GpiCreateBitmap( hPS
 
 334         hPSScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 335         hDCScreen 
= ::GpiQueryDevice(hPSScreen
); 
 336         ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 338         memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
)); 
 339         vHeader
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
 343         vHeader
.cBitCount 
= lBitCount
; 
 345         hBmp 
= ::GpiCreateBitmap( hPSScreen
 
 352         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 353         ::WinReleasePS(hPSScreen
); 
 355     SetHBITMAP((WXHBITMAP
)hBmp
); 
 357 #if WXWIN_COMPATIBILITY_2 
 358     GetBitmapData()->m_bOk 
= hBmp 
!= 0; 
 359 #endif // WXWIN_COMPATIBILITY_2 
 362 } // end of wxBitmap::Create 
 364 bool wxBitmap::LoadFile( 
 365   const wxString
&                   rFilename
 
 369     HPS                             hPs 
= NULLHANDLE
; 
 373     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 379         m_refData 
= new wxBitmapRefData
; 
 381         return(pHandler
->LoadFile( this 
 393         if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() ) 
 396         *this = vImage
.ConvertToBitmap(); 
 400 } // end of wxBitmap::LoadFile 
 402 bool wxBitmap::Create( 
 412     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 418         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for " 
 419                        "type %d defined."), lType
); 
 424     m_refData 
= new wxBitmapRefData
; 
 426     return(pHandler
->Create( this 
 433 } // end of wxBitmap::Create 
 435 bool wxBitmap::SaveFile( 
 436   const wxString
&                   rFilename
 
 438 , const wxPalette
*                  pPalette
 
 441     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 447         return pHandler
->SaveFile( this 
 455         // FIXME what about palette? shouldn't we use it? 
 456         wxImage                     
vImage(*this); 
 461         return(vImage
.SaveFile( rFilename
 
 465 } // end of wxBitmap::SaveFile 
 468 // ---------------------------------------------------------------------------- 
 469 // wxImage-wxBitmap convertion 
 470 // ---------------------------------------------------------------------------- 
 472 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth 
) 
 474     wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") ) 
 478     int sizeLimit = 1024*768*3; 
 480     // width and height of the device-dependent bitmap 
 481     int width = GetWidth(); 
 482     int bmpHeight = GetHeight(); 
 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; 
 489     if( lineBoundary > 0 ) 
 491         padding = sizeDWORD - lineBoundary; 
 492         bytePerLine += padding; 
 494     // calc the number of DIBs and heights of DIBs 
 497     int height = sizeLimit/bytePerLine; 
 498     if( height >= bmpHeight ) 
 502         numDIB =  bmpHeight / height; 
 503         hRemain = bmpHeight % height; 
 504         if( hRemain >0 )  numDIB++; 
 507     // set bitmap parameters 
 509     wxCHECK_MSG( Ok(), bitmap, wxT("invalid image") ); 
 510     bitmap.SetWidth( width ); 
 511     bitmap.SetHeight( bmpHeight ); 
 512     bitmap.SetDepth( wxDisplayDepth() ); 
 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 ); 
 538         wxFAIL_MSG( wxT("could not allocate memory for DIB") ); 
 543     // create and set the device-dependent bitmap 
 544     HDC hdc = ::GetDC(NULL); 
 545     HDC memdc = ::CreateCompatibleDC( hdc ); 
 547     hbitmap = ::CreateCompatibleBitmap( hdc, width, bmpHeight ); 
 548     ::SelectObject( memdc, hbitmap); 
 550     // copy image data into DIB data and then into DDB (in a loop) 
 551     unsigned char *data = GetData(); 
 554     unsigned char *ptdata = data; 
 555     unsigned char *ptbits; 
 557     for( n=0; n<numDIB; n++ ) 
 559         if( numDIB > 1 && n == numDIB-1 && hRemain > 0 ) 
 561             // redefine height and size of the (possibly) last smaller DIB 
 562             // memory is not reallocated 
 564             lpDIBh->bmiHeader.biHeight = (DWORD)(-height); 
 565             lpDIBh->bmiHeader.biSizeImage = bytePerLine*height; 
 569         for( j=0; j<height; j++ ) 
 571             for( i=0; i<width; i++ ) 
 573                 *(ptbits++) = *(ptdata+2); 
 574                 *(ptbits++) = *(ptdata+1); 
 575                 *(ptbits++) = *(ptdata  ); 
 578             for( i=0; i< padding; i++ )   *(ptbits++) = 0; 
 580         ::StretchDIBits( memdc, 0, origin, width, height,\ 
 581             0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY); 
 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 ); 
 597     bitmap.SetHBITMAP( (WXHBITMAP) hbitmap ); 
 599     // similarly, created an mono-bitmap for the possible mask 
 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; 
 609         unsigned char r = GetMaskRed(); 
 610         unsigned char g = GetMaskGreen(); 
 611         unsigned char b = GetMaskBlue(); 
 612         unsigned char zero = 0, one = 255; 
 614         for( n=0; n<numDIB; n++ ) 
 616             if( numDIB > 1 && n == numDIB - 1 && hRemain > 0 ) 
 618                 // redefine height and size of the (possibly) last smaller DIB 
 619                 // memory is not reallocated 
 621                 lpDIBh->bmiHeader.biHeight = (DWORD)(-height); 
 622                 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height; 
 625             for( int j=0; j<height; j++ ) 
 627                 for(i=0; i<width; i++ ) 
 629                     if( (*(ptdata++)!=r) | (*(ptdata++)!=g) | (*(ptdata++)!=b) ) 
 642                 for( i=0; i< padding; i++ )   *(ptbits++) = zero; 
 644             ::StretchDIBits( memdc, 0, origin, width, height,\ 
 645                 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY); 
 648         // create a wxMask object 
 649         wxMask *mask = new wxMask(); 
 650         mask->SetMaskBitmap( (WXHBITMAP) hbitmap ); 
 651         bitmap.SetMask( mask ); 
 654     // free allocated resources 
 655     ::SelectObject( memdc, 0 ); 
 657     ::ReleaseDC(NULL, hdc); 
 661     // check the wxBitmap object 
 662     if( bitmap.GetHBITMAP() ) 
 663         bitmap.SetOk( TRUE ); 
 665         bitmap.SetOk( FALSE ); 
 671 wxImage 
wxBitmap::ConvertToImage() const 
 675     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 677     // create an wxImage object 
 678     int width 
= GetWidth(); 
 679     int height 
= GetHeight(); 
 680     image
.Create( width
, height 
); 
 681     unsigned char *data 
= image
.GetData(); 
 684         wxFAIL_MSG( wxT("could not allocate data for image") ); 
 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
; 
 693     if( lineBoundary 
> 0 ) 
 695         padding 
= sizeDWORD 
- lineBoundary
; 
 696         bytePerLine 
+= padding
; 
 700     // create a DIB header 
 701     int headersize = sizeof(BITMAPINFOHEADER); 
 702     LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize ); 
 705         wxFAIL_MSG( wxT("could not allocate data for DIB header") ); 
 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 ); 
 727         wxFAIL_MSG( wxT("could not allocate data for DIB") ); 
 733     // copy data from the device-dependent bitmap to the DIB 
 734     HDC hdc = ::GetDC(NULL); 
 736     hbitmap = (HBITMAP) bitmap.GetHBITMAP(); 
 737     ::GetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS ); 
 739     // copy DIB data into the wxImage object 
 741     unsigned char *ptdata = data; 
 742     unsigned char *ptbits = lpBits; 
 743     for( i=0; i<height; i++ ) 
 745         for( j=0; j<width; j++ ) 
 747             *(ptdata++) = *(ptbits+2); 
 748             *(ptdata++) = *(ptbits+1); 
 749             *(ptdata++) = *(ptbits  ); 
 755     // similarly, set data according to the possible mask bitmap 
 756     if( bitmap.GetMask() && bitmap.GetMask()->GetMaskBitmap() ) 
 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 ); 
 765         // background color set to RGB(16,16,16) in consistent with wxGTK 
 766         unsigned char r=16, g=16, b=16; 
 769         for( i=0; i<height; i++ ) 
 771             for( j=0; j<width; j++ ) 
 785         SetMaskColour( r, g, b ); 
 792     // free allocated resources 
 793     ::ReleaseDC(NULL, hdc); 
 802 // ---------------------------------------------------------------------------- 
 803 // sub bitmap extraction 
 804 // ---------------------------------------------------------------------------- 
 806 wxBitmap 
wxBitmap::GetSubBitmap( 
 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") ); 
 816     wxBitmap                        
vRet( rRect
.width
 
 820     wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") ); 
 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() 
 837     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
 838     ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
 848     // Copy mask if there is one 
 852         BITMAPINFOHEADER2           vBmih
; 
 854         memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
 855         vBmih
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
 856         vBmih
.cx        
= rRect
.width
; 
 857         vBmih
.cy        
= rRect
.height
; 
 861         HBITMAP                     hBmpMask 
= ::GpiCreateBitmap( hPSDst
 
 868         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
 869         ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
 871         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap()); 
 872         ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
); 
 881         wxMask
*                     pMask 
= new wxMask((WXHBITMAP
)hBmpMask
); 
 885     ::GpiSetBitmap(hPSSrc
, NULL
); 
 886     ::GpiSetBitmap(hPSDst
, NULL
); 
 887     ::GpiDestroyPS(hPSSrc
); 
 888     ::GpiDestroyPS(hPSDst
); 
 889     ::DevCloseDC(hDCSrc
); 
 890     ::DevCloseDC(hDCDst
); 
 892 } // end of wxBitmap::GetSubBitmap 
 894 // ---------------------------------------------------------------------------- 
 895 // wxBitmap accessors 
 896 // ---------------------------------------------------------------------------- 
 898 void wxBitmap::SetQuality( 
 904     GetBitmapData()->m_nQuality 
= nQ
; 
 905 } // end of wxBitmap::SetQuality 
 907 #if WXWIN_COMPATIBILITY_2 
 908 void wxBitmap::SetOk( 
 914     GetBitmapData()->m_bOk 
= bOk
; 
 915 } // end of wxBitmap::SetOk 
 916 #endif // WXWIN_COMPATIBILITY_2 
 918 void wxBitmap::SetPalette( 
 919   const wxPalette
&                  rPalette
 
 924     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
 925 } // end of wxBitmap::SetPalette 
 927 void wxBitmap::SetMask( 
 933     GetBitmapData()->m_pBitmapMask 
= pMask
; 
 934 } // end of wxBitmap::SetMask 
 937 // Will try something for OS/2 but not really sure how close 
 938 // to the msw intent this is. 
 940 wxBitmap 
wxBitmap::GetBitmapForDC( 
 945     wxBitmap                        
vTmpBitmap( this->GetWidth() 
 949     WXHBITMAP                       vOldBitmap
; 
 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
); 
 958     // TODO: Set the points 
 960     vOldBitmap 
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP()); 
 961     ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
); 
 964 } // end of wxBitmap::GetBitmapForDC 
 966 // ---------------------------------------------------------------------------- 
 968 // ---------------------------------------------------------------------------- 
 973 } // end of wxMask::wxMask 
 975 // Construct a mask from a bitmap and a colour indicating 
 976 // the transparent area 
 978   const wxBitmap
&                   rBitmap
 
 979 , const wxColour
&                   rColour
 
 986 } // end of wxMask::wxMask 
 988 // Construct a mask from a bitmap and a palette index indicating 
 989 // the transparent area 
 991   const wxBitmap
&                   rBitmap
 
 999 } // end of wxMask::wxMask 
1001 // Construct a mask from a mono bitmap (copies the bitmap). 
1003   const wxBitmap
&                   rBitmap
 
1008 } // end of wxMask::wxMask 
1013         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
1014 } // end of wxMask::~wxMask 
1016 // Create a mask from a mono bitmap (copies the bitmap). 
1017 bool wxMask::Create( 
1018   const wxBitmap
&                   rBitmap
 
1021     BITMAPINFOHEADER2               vBmih
; 
1022     SIZEL                           vSize 
= {0, 0}; 
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() 
1034         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1037     if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1) 
1042     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1043     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1044     vBmih
.cx        
= rBitmap
.GetWidth(); 
1045     vBmih
.cy        
= rBitmap
.GetHeight(); 
1047     vBmih
.cBitCount 
= 1; 
1049     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1056     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1057     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1066     ::GpiDestroyPS(hPSSrc
); 
1067     ::GpiDestroyPS(hPSDst
); 
1068     ::DevCloseDC(hDCSrc
); 
1069     ::DevCloseDC(hDCDst
); 
1071 } // end of wxMask::Create 
1073 // Create a mask from a bitmap and a palette index indicating 
1074 // the transparent area 
1075 bool wxMask::Create( 
1076   const wxBitmap
&                   rBitmap
 
1082         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1085     if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok()) 
1088         unsigned char               cGreen
; 
1089         unsigned char               cBlue
; 
1091         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
1097             wxColour                
vTransparentColour( cRed
 
1102             return (Create( rBitmap
 
1108 } // end of wxMask::Create 
1110 // Create a mask from a bitmap and a colour indicating 
1111 // the transparent area 
1112 bool wxMask::Create( 
1113   const wxBitmap
&                   rBitmap
 
1114 , const wxColour
&                   rColour
 
1118     COLORREF                        vMaskColour 
= OS2RGB( rColour
.Red() 
1122     BITMAPINFOHEADER2               vBmih
; 
1123     SIZEL                           vSize 
= {0, 0}; 
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() 
1135         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1144     // Scan the bitmap for the transparent colour and set 
1145     // the corresponding pixels in the mask to BLACK and 
1146     // the rest to WHITE 
1149     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1150     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1151     vBmih
.cx        
= rBitmap
.GetWidth(); 
1152     vBmih
.cy        
= rBitmap
.GetHeight(); 
1154     vBmih
.cBitCount 
= 1; 
1156     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1163     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1164     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1167     // This is not very efficient, but I can't think 
1168     // of a better way of doing it 
1170     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
1172         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
1174             POINTL                  vPt 
= {w
, h
}; 
1175             COLORREF                vCol 
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
); 
1176             if (vCol 
== (COLORREF
)CLR_NOINDEX
) 
1179                 // Doesn't make sense to continue 
1185             if (vCol 
== vMaskColour
) 
1187                 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0)); 
1188                 ::GpiSetPel(hPSDst
, &vPt
); 
1192                 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255)); 
1193                 ::GpiSetPel(hPSDst
, &vPt
); 
1197     ::GpiSetBitmap(hPSSrc
, NULL
); 
1198     ::GpiSetBitmap(hPSDst
, NULL
); 
1199     ::GpiDestroyPS(hPSSrc
); 
1200     ::GpiDestroyPS(hPSDst
); 
1201     ::DevCloseDC(hDCSrc
); 
1202     ::DevCloseDC(hDCDst
); 
1204 } // end of wxMask::Create 
1206 // ---------------------------------------------------------------------------- 
1208 // ---------------------------------------------------------------------------- 
1210 bool wxBitmapHandler::Create( 
1219     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1223     return(pBitmap 
? Create( pBitmap
 
1231 bool wxBitmapHandler::Load( 
1233 , const wxString
&                   rName
 
1240     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1244     return(pBitmap 
? LoadFile( pBitmap
 
1253 bool wxBitmapHandler::Save( 
1255 , const wxString
&                   rName
 
1259     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1263     return(pBitmap 
? SaveFile( pBitmap
 
1269 bool 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
) 
1281 bool wxBitmapHandler::LoadFile( 
1282   wxBitmap
*                         WXUNUSED(pBitmap
) 
1283 , const wxString
&                   WXUNUSED(rName
) 
1285 , long                              WXUNUSED(lType
) 
1286 , int                               WXUNUSED(nDesiredWidth
) 
1287 , int                               WXUNUSED(nDesiredHeight
) 
1293 bool wxBitmapHandler::SaveFile( 
1294   wxBitmap
*                         WXUNUSED(pBitmap
) 
1295 , const wxString
&                   WXUNUSED(rName
) 
1296 , int                               WXUNUSED(nType
) 
1297 , const wxPalette
*                  WXUNUSED(pPalette
) 
1303 // ---------------------------------------------------------------------------- 
1304 // Utility functions 
1305 // ---------------------------------------------------------------------------- 
1306 HBITMAP 
wxInvertMask( 
1312     HBITMAP                         hBmpInvMask 
= 0; 
1314     wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") ); 
1317     // Get width/height from the bitmap if not given 
1319     if (!nWidth 
|| !nHeight
) 
1321         BITMAPINFOHEADER2           vBmhdr
; 
1323         ::GpiQueryBitmapInfoHeader( hBmpMask
 
1326         nWidth  
= (int)vBmhdr
.cx
; 
1327         nHeight 
= (int)vBmhdr
.cy
; 
1330     BITMAPINFOHEADER2               vBmih
; 
1331     SIZEL                           vSize 
= {0, 0}; 
1332     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
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
 
1341     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1342     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1346     vBmih
.cBitCount 
= 1; 
1348     hBmpInvMask 
= ::GpiCreateBitmap( hPSDst
 
1355     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
); 
1356     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
); 
1366     ::GpiDestroyPS(hPSSrc
); 
1367     ::GpiDestroyPS(hPSDst
); 
1368     ::DevCloseDC(hDCSrc
); 
1369     ::DevCloseDC(hDCDst
); 
1372 } // end of WxWinGdi_InvertMask