1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/bitmap.cpp 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #include "wx/bitmap.h" 
  23     #include "wx/palette.h" 
  24     #include "wx/dcmemory.h" 
  30 #include "wx/os2/dc.h" 
  31 #include "wx/os2/private.h" 
  33 #include "wx/xpmdecod.h" 
  35 // ---------------------------------------------------------------------------- 
  37 // ---------------------------------------------------------------------------- 
  39 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  42 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
  44 // ============================================================================ 
  46 // ============================================================================ 
  48 // ---------------------------------------------------------------------------- 
  50 // ---------------------------------------------------------------------------- 
  52 wxBitmapRefData::wxBitmapRefData() 
  55     m_pSelectedInto 
= NULL
; 
  58     m_hBitmap       
= (WXHBITMAP
) NULL
; 
  59 } // end of wxBitmapRefData::wxBitmapRefData 
  61 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData 
&tocopy
) 
  63     m_nQuality 
= tocopy
.m_nQuality
; 
  64     m_pSelectedInto 
= NULL
;     // don't copy this 
  65     m_nNumColors    
= tocopy
.m_nNumColors
; 
  68     if (tocopy
.m_pBitmapMask
) 
  69         m_pBitmapMask 
= new wxMask(*tocopy
.m_pBitmapMask
); 
  71     m_hBitmap 
= wxCopyBmp(tocopy
.m_hBitmap
); 
  74 void wxBitmapRefData::Free() 
  76     if ( m_pSelectedInto 
) 
  78         wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  82         if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
)) 
  84             wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  87     wxDELETE(m_pBitmapMask
); 
  88 } // end of wxBitmapRefData::Free 
  90 // ---------------------------------------------------------------------------- 
  92 // ---------------------------------------------------------------------------- 
  94 wxGDIRefData
* wxBitmap::CloneGDIRefData(const wxGDIRefData
* data
) const 
  96     return new wxBitmapRefData(*static_cast<const wxBitmapRefData 
*>(data
)); 
  99 // this function should be called from all wxBitmap ctors 
 100 void wxBitmap::Init() 
 104     // True for all bitmaps created from bits, wxImages, Xpms 
 106 } // end of wxBitmap::Init 
 108 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
) 
 110     HPOINTER                        hIcon 
= (HPOINTER
)rIcon
.GetHandle(); 
 111     POINTERINFO                     SIconInfo
; 
 113     if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
)) 
 115         wxLogLastError(wxT("WinQueryPointerInfo")); 
 118     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 120     m_refData 
= pRefData
; 
 122     int                             nWidth 
= rIcon
.GetWidth(); 
 123     int                             nHeight 
= rIcon
.GetHeight(); 
 125     pRefData
->m_nWidth  
= nWidth
; 
 126     pRefData
->m_nHeight 
= nHeight
; 
 127     pRefData
->m_nDepth  
= wxDisplayDepth(); 
 129     pRefData
->m_hBitmap 
= (WXHBITMAP
)SIconInfo
.hbmColor
; 
 131     wxMask
*                         pMask 
= new wxMask(SIconInfo
.hbmPointer
); 
 133     pMask
->SetMaskBitmap(GetHBITMAP()); 
 137 } // end of wxBitmap::CopyFromIconOrCursor 
 139 bool wxBitmap::CopyFromCursor( 
 140   const wxCursor
&                   rCursor
 
 147     return(CopyFromIconOrCursor(rCursor
)); 
 148 } // end of wxBitmap::CopyFromCursor 
 150 bool wxBitmap::CopyFromIcon( 
 159     return CopyFromIconOrCursor(rIcon
); 
 160 } // end of wxBitmap::CopyFromIcon 
 162 wxBitmap::~wxBitmap() 
 164 } // end of wxBitmap::~wxBitmap 
 175     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 176     BITMAPINFOHEADER2               vHeader
; 
 180     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 181     SIZEL                           vSize 
= {0, 0}; 
 184     wxASSERT(vHabmain 
!= NULL
); 
 186     m_refData 
= pRefData
; 
 188     pRefData
->m_nWidth        
= nWidth
; 
 189     pRefData
->m_nHeight       
= nHeight
; 
 190     pRefData
->m_nDepth        
= nDepth
; 
 191     pRefData
->m_nNumColors    
= 0; 
 192     pRefData
->m_pSelectedInto 
= NULL
; 
 194     hDc   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 195     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 198         wxLogLastError(wxT("GpiCreatePS Failure")); 
 204         // We assume that it is in XBM format which is not quite the same as 
 205         // the format CreateBitmap() wants because the order of bytes in the 
 208         const size_t                nBytesPerLine 
= (nWidth 
+ 7) / 8; 
 209         const size_t                nPadding 
= nBytesPerLine 
% 2; 
 210         const size_t                nLen 
= nHeight 
* (nPadding 
+ nBytesPerLine
); 
 211         const char*                 pzSrc 
= zBits
; 
 215         pzData 
= (char *)malloc(nLen
); 
 217         char*                       pzDst 
= pzData
; 
 219         for (nRows 
= 0; nRows 
< nHeight
; nRows
++) 
 221             for (nCols 
= 0; nCols 
< nBytesPerLine
; nCols
++) 
 223                 unsigned char ucVal 
= *pzSrc
++; 
 224                 unsigned char ucReversed 
= 0; 
 227                 for (nBits 
= 0; nBits 
< 8; nBits
++) 
 230                     ucReversed 
= (unsigned char)(ucReversed 
| (ucVal 
& 0x01)); 
 233                 *pzDst
++ = ucReversed
; 
 242         // Bits should already be in Windows standard format 
 244         pzData 
= (char *)zBits
;    // const_cast is harmless 
 248         nDepth 
= 24; // MAX supported in PM 
 249     memset(&vHeader
, '\0', 16); 
 251     vHeader
.cx              
= (USHORT
)nWidth
; 
 252     vHeader
.cy              
= (USHORT
)nHeight
; 
 253     vHeader
.cPlanes         
= 1L; 
 254     vHeader
.cBitCount       
= (USHORT
)nDepth
; 
 255     vHeader
.usReserved      
= 0; 
 257     memset(&vInfo
, '\0', 16); 
 259     vInfo
.cx              
= (USHORT
)nWidth
; 
 260     vInfo
.cy              
= (USHORT
)nHeight
; 
 262     vInfo
.cBitCount       
= (USHORT
)nDepth
; 
 264     HBITMAP                         hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
); 
 268         wxLogLastError(wxT("CreateBitmap")); 
 272     SetHBITMAP((WXHBITMAP
)hBmp
); 
 273 } // end of wxBitmap::wxBitmap 
 291 } // end of wxBitmap::wxBitmap 
 303 } // end of wxBitmap::wxBitmap 
 305 bool wxBitmap::Create( 
 312     BITMAPINFOHEADER2               vHeader
; 
 314     wxASSERT(vHabmain 
!= NULL
); 
 316     m_refData 
= new wxBitmapRefData
; 
 317     GetBitmapData()->m_nWidth 
= nW
; 
 318     GetBitmapData()->m_nHeight 
= nH
; 
 319     GetBitmapData()->m_nDepth 
= nD
; 
 322     // Xpms and bitmaps from other images can also be mono's, but only 
 323     // mono's need help changing their colors with MemDC changes 
 327         DEVOPENSTRUC                vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 328         SIZEL                       vSize 
= {0, 0}; 
 329         HDC                         hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 330         HPS                         hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 334         memset(&vHeader
, '\0', 16); 
 339         vHeader
.cBitCount 
= 24; //nD; 
 341         hBmp 
= ::GpiCreateBitmap( hPS
 
 356         hPSScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 357         hDCScreen 
= ::GpiQueryDevice(hPSScreen
); 
 358         ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 363         memset(&vHeader
, '\0', 16); 
 368         vHeader
.cBitCount 
= (USHORT
)lBitCount
; 
 370         hBmp 
= ::GpiCreateBitmap( hPSScreen
 
 377         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 378         ::WinReleasePS(hPSScreen
); 
 380     SetHBITMAP((WXHBITMAP
)hBmp
); 
 383 } // end of wxBitmap::Create 
 385 bool wxBitmap::LoadFile(const wxString
& filename
, wxBitmapType type
) 
 389     wxBitmapHandler 
*handler 
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
); 
 393         m_refData 
= new wxBitmapRefData
; 
 395         return handler
->LoadFile(this, filename
, type
, -1, -1); 
 398     else // no bitmap handler found 
 401         if ( image
.LoadFile( filename
, type 
) && image
.IsOk() ) 
 403             *this = wxBitmap(image
); 
 408 #endif // wxUSE_IMAGE 
 413 bool wxBitmap::LoadFile( 
 420     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 426         m_refData 
= new wxBitmapRefData
; 
 428         return(pHandler
->LoadFile( this 
 439 } // end of wxBitmap::LoadFile 
 441 bool wxBitmap::Create( 
 451     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 457         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
); 
 462     m_refData 
= new wxBitmapRefData
; 
 464     return(pHandler
->Create( this 
 471 } // end of wxBitmap::Create 
 473 bool wxBitmap::SaveFile( 
 474   const wxString
&                   rFilename
 
 476 , const wxPalette
*                  pPalette
 
 479     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 485         return pHandler
->SaveFile( this 
 493         // FIXME what about palette? shouldn't we use it? 
 494         wxImage                     vImage 
= ConvertToImage(); 
 499         return(vImage
.SaveFile( rFilename
 
 503 } // end of wxBitmap::SaveFile 
 506 // ---------------------------------------------------------------------------- 
 507 // wxImage-wxBitmap conversion 
 508 // ---------------------------------------------------------------------------- 
 510 bool wxBitmap::CreateFromImage ( 
 511   const wxImage
&                    rImage
 
 515     wxCHECK_MSG(rImage
.IsOk(), false, wxT("invalid image")); 
 516     m_refData 
= new wxBitmapRefData(); 
 518     int                             nSizeLimit 
= 1024 * 768 * 3; 
 519     int                             nWidth 
= rImage
.GetWidth(); 
 520     int                             nBmpHeight 
= rImage
.GetHeight(); 
 521     int                             nBytePerLine 
= nWidth 
* 3; 
 522     int                             nSizeDWORD 
= sizeof(DWORD
); 
 523     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 526     if (nLineBoundary 
> 0) 
 528         nPadding 
= nSizeDWORD 
- nLineBoundary
; 
 529         nBytePerLine 
+= nPadding
; 
 533     // Calc the number of DIBs and heights of DIBs 
 537     int                             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 539     if (nHeight 
>= nBmpHeight
) 
 540         nHeight 
= nBmpHeight
; 
 543         nNumDIB  
= nBmpHeight 
/ nHeight
; 
 544         nHRemain 
= nBmpHeight 
% nHeight
; 
 550     // Set bitmap parameters 
 552     wxCHECK_MSG(rImage
.IsOk(), false, wxT("invalid image")); 
 554     SetHeight(nBmpHeight
); 
 560         nDepth 
= wxDisplayDepth(); 
 565     // Copy the palette from the source image 
 567     SetPalette(rImage
.GetPalette()); 
 568 #endif // wxUSE_PALETTE 
 571     // Create a DIB header 
 573     BITMAPINFOHEADER2               vHeader
; 
 577     // Fill in the DIB header 
 579     memset(&vHeader
, '\0', 16); 
 581     vHeader
.cx              
= (ULONG
)nWidth
; 
 582     vHeader
.cy              
= (ULONG
)nHeight
; 
 583     vHeader
.cPlanes         
= 1L; 
 584     vHeader
.cBitCount       
= 24; 
 587     // Memory for DIB data 
 589     unsigned char*                  pucBits
; 
 591     pucBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 594         wxFAIL_MSG(wxT("could not allocate memory for DIB")); 
 597     memset(pucBits
, '\0', (nBytePerLine 
* nHeight
)); 
 600     // Create and set the device-dependent bitmap 
 602     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 603     SIZEL                           vSize 
= {0, 0}; 
 604     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 605     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 607     HDC                             hDCScreen 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 612     memset(&vInfo
, '\0', 16); 
 614     vInfo
.cx              
= (ULONG
)nWidth
; 
 615     vInfo
.cy              
= (ULONG
)nHeight
; 
 617     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 619     hBmp 
= ::GpiCreateBitmap( hPS
 
 626     HPAL                            hOldPalette 
= NULLHANDLE
; 
 627     if (rImage
.GetPalette().IsOk()) 
 629         hOldPalette 
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE()); 
 631 #endif // wxUSE_PALETTE 
 634     // Copy image data into DIB data and then into DDB (in a loop) 
 636     unsigned char*                  pData 
= rImage
.GetData(); 
 641     unsigned char*                  ptdata 
= pData
; 
 642     unsigned char*                  ptbits
; 
 644     if ((hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
) 
 649         vError 
= ::WinGetLastError(vHabmain
); 
 650         sError 
= wxPMErrorToStr(vError
); 
 652     for (n 
= 0; n 
< nNumDIB
; n
++) 
 654         if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 657             // Redefine height and size of the (possibly) last smaller DIB 
 658             // memory is not reallocated 
 661             vHeader
.cy      
= (DWORD
)(nHeight
); 
 662             vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 665         for (j 
= 0; j 
< nHeight
; j
++) 
 667             for (i 
= 0; i 
< nWidth
; i
++) 
 669                 *(ptbits
++) = *(ptdata 
+ 2); 
 670                 *(ptbits
++) = *(ptdata 
+ 1); 
 671                 *(ptbits
++) = *(ptdata
); 
 674             for (i 
= 0; i 
< nPadding
; i
++) 
 679         // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt 
 680         // in combination with setting the bits into the selected bitmap 
 682         if ((lScans 
= ::GpiSetBitmapBits( hPS
 
 683                                          ,0             // Start at the bottom 
 684                                          ,(LONG
)nHeight 
// One line per scan 
 692             vError 
= ::WinGetLastError(vHabmain
); 
 693             sError 
= wxPMErrorToStr(vError
); 
 695         hPSScreen 
= ::GpiCreatePS( vHabmain
 
 698                                   ,PU_PELS 
| GPIA_ASSOC
 
 701         POINTL                      vPoint
[4] = { {0, nOrigin
}, 
 703                                                   {0, 0}, {nWidth
, nHeight
} 
 707         ::GpiBitBlt( hPSScreen
 
 714         ::GpiDestroyPS(hPSScreen
); 
 717     SetHBITMAP((WXHBITMAP
)hBmp
); 
 720         ::GpiSelectPalette(hPS
, hOldPalette
); 
 721 #endif // wxUSE_PALETTE 
 724     // Similarly, created an mono-bitmap for the possible mask 
 726     if (rImage
.HasMask()) 
 730         vHeader
.cy        
= nHeight
; 
 732         vHeader
.cBitCount 
= 24; 
 733         hBmp 
= ::GpiCreateBitmap( hPS
 
 739         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
); 
 741             nHeight 
= nBmpHeight
; 
 743             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 744         vHeader
.cy 
= (DWORD
)(nHeight
); 
 747         unsigned char               cRed   
= rImage
.GetMaskRed(); 
 748         unsigned char               cGreen 
= rImage
.GetMaskGreen(); 
 749         unsigned char               cBlue  
= rImage
.GetMaskBlue(); 
 750         unsigned char               cZero 
= 0; 
 751         unsigned char               cOne 
= 255; 
 754         for (n 
= 0; n 
< nNumDIB
; n
++) 
 756             if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 759                 // Redefine height and size of the (possibly) last smaller DIB 
 760                 // memory is not reallocated 
 763                 vHeader
.cy      
= (DWORD
)(nHeight
); 
 764                 vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 767             for (int j 
= 0; j 
< nHeight
; j
++) 
 769                 for (i 
= 0; i 
< nWidth
; i
++) 
 771                     unsigned char cRedImage   
= (*(ptdata
++)) ; 
 772                     unsigned char cGreenImage 
= (*(ptdata
++)) ; 
 773                     unsigned char cBlueImage  
= (*(ptdata
++)) ; 
 775                     if ((cRedImage 
!= cRed
) || (cGreenImage 
!= cGreen
) || (cBlueImage 
!= cBlue
)) 
 788                 for (i 
= 0; i 
< nPadding
; i
++) 
 791             lScans 
= ::GpiSetBitmapBits( hPS
 
 792                                         ,0              // Start at the bottom 
 793                                         ,(LONG
)nHeight 
// One line per scan 
 797             hPSScreen 
= ::GpiCreatePS( vHabmain
 
 800                                       ,PU_PELS 
| GPIA_ASSOC
 
 802             POINTL vPoint2
[4] = { {0, nOrigin
}, 
 804                                   {0, 0}, {nWidth
, nHeight
} 
 806             ::GpiBitBlt( hPSScreen
 
 813             ::GpiDestroyPS(hPSScreen
); 
 818         // Create a wxMask object 
 820         wxMask
*                     pMask 
= new wxMask(); 
 822         pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
); 
 824         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmpOld
); 
 828     // Free allocated resources 
 830     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 832     ::DevCloseDC(hDCScreen
); 
 836 } // end of wxBitmap::CreateFromImage 
 838 wxImage 
wxBitmap::ConvertToImage() const 
 843     wxCHECK_MSG( IsOk(), wxNullImage
, wxT("invalid bitmap") ); 
 846     // Create an wxImage object 
 848     int                             nWidth        
= GetWidth(); 
 849     int                             nHeight       
= GetHeight(); 
 852     int                             nBytePerLine  
= nWidth 
* 3; 
 853     int                             nSizeDWORD    
= sizeof(DWORD
); 
 854     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 856     unsigned char*                  pData
; 
 857     unsigned char*                  lpBits
; 
 859     BITMAPINFOHEADER2               vDIBh
; 
 860     BITMAPINFO2                     vDIBInfo
; 
 864     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 865     SIZEL                           vSizlPage 
= {0,0}; 
 866     HDC                             hDCMem 
= NULLHANDLE
; 
 868     vImage
.Create( nWidth
 
 871     pData 
= vImage
.GetData(); 
 874         wxFAIL_MSG( wxT("could not allocate data for image") ); 
 877     if(nLineBoundary 
> 0) 
 879         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 880         nBytePerLine 
+= nPadding
; 
 882     wxDisplaySize( &nDevWidth
 
 886     // Create and fill a DIB header 
 888     memset(&vDIBh
, '\0', 16); 
 893     vDIBh
.cBitCount 
= 24; 
 895     memset(&vDIBInfo
, '\0', 16); 
 897     vDIBInfo
.cx              
= nWidth
; 
 898     vDIBInfo
.cy              
= nHeight
; 
 899     vDIBInfo
.cPlanes         
= 1; 
 900     vDIBInfo
.cBitCount       
= 24; 
 902     lpBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 905         wxFAIL_MSG(wxT("could not allocate data for DIB")); 
 909     memset(lpBits
, '\0', (nBytePerLine 
* nHeight
)); 
 910     hBitmap 
= (HBITMAP
)GetHBITMAP(); 
 913     // May already be selected into a PS 
 915     pDC 
= GetSelectedInto(); 
 916     const wxPMDCImpl 
*impl
; 
 918         (impl 
= wxDynamicCast( pDC
->GetImpl(), wxPMDCImpl 
)) != NULL
) 
 920         hPSMem 
= impl
->GetHPS(); 
 924         hDCMem 
= ::DevOpenDC( vHabmain
 
 931         hPSMem 
= ::GpiCreatePS( vHabmain
 
 934                                ,PU_PELS 
| GPIA_ASSOC
 
 937     if ((hOldBitmap 
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
) 
 942         vError 
= ::WinGetLastError(vHabmain
); 
 943         sError 
= wxPMErrorToStr(vError
); 
 947     // Copy data from the device-dependent bitmap to the DIB 
 949     if ((lScans 
= ::GpiQueryBitmapBits( hPSMem
 
 959         vError 
= ::WinGetLastError(vHabmain
); 
 960         sError 
= wxPMErrorToStr(vError
); 
 964     // Copy DIB data into the wxImage object 
 968     unsigned char*                  ptdata 
= pData
; 
 969     unsigned char*                  ptbits 
= lpBits
; 
 971     for (i 
= 0; i 
< nHeight
; i
++) 
 973         for (j 
= 0; j 
< nWidth
; j
++) 
 975             *(ptdata
++) = *(ptbits
+2); 
 976             *(ptdata
++) = *(ptbits
+1); 
 977             *(ptdata
++) = *(ptbits  
); 
 982     if ((pDC 
= GetSelectedInto()) == NULL
) 
 984         ::GpiSetBitmap(hPSMem
, NULLHANDLE
); 
 985         ::GpiDestroyPS(hPSMem
); 
 986         ::DevCloseDC(hDCMem
); 
 990     // Similarly, set data according to the possible mask bitmap 
 992     if (GetMask() && GetMask()->GetMaskBitmap()) 
 994         hBitmap 
= (HBITMAP
)GetMask()->GetMaskBitmap(); 
 997         // Memory DC/PS created, color set, data copied, and memory DC/PS deleted 
 999         HDC                        hMemDC 
= ::DevOpenDC( vHabmain
 
1003                                                         ,(PDEVOPENDATA
)&vDop
 
1006         HPS                         hMemPS 
= ::GpiCreatePS( vHabmain
 
1009                                                            ,PU_PELS 
| GPIA_ASSOC
 
1011         ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0)); 
1012         ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) ); 
1013         ::GpiSetBitmap(hMemPS
, hBitmap
); 
1014         ::GpiQueryBitmapBits( hPSMem
 
1020         ::GpiSetBitmap(hMemPS
, NULLHANDLE
); 
1021         ::GpiDestroyPS(hMemPS
); 
1022         ::DevCloseDC(hMemDC
); 
1025         // Background color set to RGB(16,16,16) in consistent with wxGTK 
1027         unsigned char               ucRed 
= 16; 
1028         unsigned char               ucGreen 
= 16; 
1029         unsigned char               ucBlue 
= 16; 
1033         for (i 
= 0; i 
< nHeight
; i
++) 
1035             for (j 
= 0; j 
< nWidth
; j
++) 
1041                     *(ptdata
++)  = ucRed
; 
1042                     *(ptdata
++)  = ucGreen
; 
1043                     *(ptdata
++)  = ucBlue
; 
1049         vImage
.SetMaskColour( ucRed
 
1053         vImage
.SetMask(true); 
1057         vImage
.SetMask(false); 
1061     // Free allocated resources 
1065 } // end of wxBitmap::ConvertToImage 
1067 // ---------------------------------------------------------------------------- 
1068 // sub bitmap extraction 
1069 // ---------------------------------------------------------------------------- 
1071 wxBitmap 
wxBitmap::GetSubBitmap( 
1075     wxCHECK_MSG( IsOk() && 
1076                  (rRect
.x 
>= 0) && (rRect
.y 
>= 0) && 
1077                  (rRect
.x 
+ rRect
.width 
<= GetWidth()) && 
1078                  (rRect
.y 
+ rRect
.height 
<= GetHeight()), 
1079                  wxNullBitmap
, wxT("Invalid bitmap or bitmap region") ); 
1081     wxBitmap                        
vRet( rRect
.width
 
1085     wxASSERT_MSG( vRet
.IsOk(), wxT("GetSubBitmap error") ); 
1091     SIZEL                           vSize 
= {0, 0}; 
1092     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1093     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1094     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1095     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1096     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1097     POINTL                          vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
}, 
1099                                                   {rRect
.x 
+ rRect
.width
, rRect
.y 
+ rRect
.height
} 
1102     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1103     ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1113     // Copy mask if there is one 
1117         BITMAPINFOHEADER2           vBmih
; 
1119         memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1120         vBmih
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
1121         vBmih
.cx        
= rRect
.width
; 
1122         vBmih
.cy        
= rRect
.height
; 
1124         vBmih
.cBitCount 
= 24; 
1126         HBITMAP                     hBmpMask 
= ::GpiCreateBitmap( hPSDst
 
1133         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1134         ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1136         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap()); 
1137         ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
); 
1146         wxMask
*                     pMask 
= new wxMask((WXHBITMAP
)hBmpMask
); 
1147         vRet
.SetMask(pMask
); 
1150     ::GpiSetBitmap(hPSSrc
, NULL
); 
1151     ::GpiSetBitmap(hPSDst
, NULL
); 
1152     ::GpiDestroyPS(hPSSrc
); 
1153     ::GpiDestroyPS(hPSDst
); 
1154     ::DevCloseDC(hDCSrc
); 
1155     ::DevCloseDC(hDCDst
); 
1157 } // end of wxBitmap::GetSubBitmap 
1159 // ---------------------------------------------------------------------------- 
1160 // wxBitmap accessors 
1161 // ---------------------------------------------------------------------------- 
1163 void wxBitmap::SetQuality( 
1169     GetBitmapData()->m_nQuality 
= nQ
; 
1170 } // end of wxBitmap::SetQuality 
1172 void wxBitmap::SetPalette( 
1173   const wxPalette
&                  rPalette
 
1178     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
1179 } // end of wxBitmap::SetPalette 
1181 void wxBitmap::SetMask( 
1187     GetBitmapData()->m_pBitmapMask 
= pMask
; 
1188 } // end of wxBitmap::SetMask 
1190 wxBitmap 
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const 
1193 } // end of wxBitmap::GetBitmapForDC 
1195 // ---------------------------------------------------------------------------- 
1197 // ---------------------------------------------------------------------------- 
1202 } // end of wxMask::wxMask 
1204 wxMask::wxMask(const wxMask
& tocopy
) 
1206     m_hMaskBitmap 
= wxCopyBmp(tocopy
.m_hMaskBitmap
); 
1207 } // end of wxMask::wxMask 
1209 // Construct a mask from a bitmap and a colour indicating 
1210 // the transparent area 
1212   const wxBitmap
&                   rBitmap
 
1213 , const wxColour
&                   rColour
 
1220 } // end of wxMask::wxMask 
1222 // Construct a mask from a bitmap and a palette index indicating 
1223 // the transparent area 
1225   const wxBitmap
&                   rBitmap
 
1233 } // end of wxMask::wxMask 
1235 // Construct a mask from a mono bitmap (copies the bitmap). 
1237   const wxBitmap
&                   rBitmap
 
1242 } // end of wxMask::wxMask 
1247         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
1248 } // end of wxMask::~wxMask 
1250 // Create a mask from a mono bitmap (copies the bitmap). 
1251 bool wxMask::Create( 
1252   const wxBitmap
&                   rBitmap
 
1255     BITMAPINFOHEADER2               vBmih
; 
1256     SIZEL                           vSize 
= {0, 0}; 
1257     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1258     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1259     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1260     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1261     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1262     POINTL                          vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}, 
1263                                                   {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()} 
1268         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1271     if (!rBitmap
.IsOk() || rBitmap
.GetDepth() != 1) 
1276     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1277     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1278     vBmih
.cx        
= rBitmap
.GetWidth(); 
1279     vBmih
.cy        
= rBitmap
.GetHeight(); 
1281     vBmih
.cBitCount 
= 24; 
1283     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1290     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1291     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1300     ::GpiDestroyPS(hPSSrc
); 
1301     ::GpiDestroyPS(hPSDst
); 
1302     ::DevCloseDC(hDCSrc
); 
1303     ::DevCloseDC(hDCDst
); 
1305 } // end of wxMask::Create 
1307 // Create a mask from a bitmap and a palette index indicating 
1308 // the transparent area 
1309 bool wxMask::Create( 
1310   const wxBitmap
&                   rBitmap
 
1316         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1319     if (rBitmap
.IsOk() && rBitmap
.GetPalette()->IsOk()) 
1322         unsigned char               cGreen
; 
1323         unsigned char               cBlue
; 
1325         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
1331             wxColour                
vTransparentColour( cRed
 
1336             return (Create( rBitmap
 
1342 } // end of wxMask::Create 
1344 // Create a mask from a bitmap and a colour indicating 
1345 // the transparent area 
1346 bool wxMask::Create( 
1347   const wxBitmap
&                   rBitmap
 
1348 , const wxColour
&                   rColour
 
1352     COLORREF                        vMaskColour 
= OS2RGB( rColour
.Red() 
1356     BITMAPINFOHEADER2               vBmih
; 
1357     SIZEL                           vSize 
= {0, 0}; 
1358     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
1359     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1360     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1361     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1362     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1366         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1369     if (!rBitmap
.IsOk()) 
1375     // Scan the bitmap for the transparent colour and set 
1376     // the corresponding pixels in the mask to BLACK and 
1377     // the rest to WHITE 
1380     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1381     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1382     vBmih
.cx        
= rBitmap
.GetWidth(); 
1383     vBmih
.cy        
= rBitmap
.GetHeight(); 
1385     vBmih
.cBitCount 
= 1; 
1387     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1394     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1395     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1398     // This is not very efficient, but I can't think 
1399     // of a better way of doing it 
1401     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
1403         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
1405             POINTL                  vPt 
= {w
, h
}; 
1406             COLORREF                vCol 
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
); 
1407             if (vCol 
== (COLORREF
)CLR_NOINDEX
) 
1410                 // Doesn't make sense to continue 
1416             if (vCol 
== vMaskColour
) 
1418                 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0)); 
1419                 ::GpiSetPel(hPSDst
, &vPt
); 
1423                 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255)); 
1424                 ::GpiSetPel(hPSDst
, &vPt
); 
1428     ::GpiSetBitmap(hPSSrc
, NULL
); 
1429     ::GpiSetBitmap(hPSDst
, NULL
); 
1430     ::GpiDestroyPS(hPSSrc
); 
1431     ::GpiDestroyPS(hPSDst
); 
1432     ::DevCloseDC(hDCSrc
); 
1433     ::DevCloseDC(hDCDst
); 
1435 } // end of wxMask::Create 
1437 // ---------------------------------------------------------------------------- 
1439 // ---------------------------------------------------------------------------- 
1441 bool wxBitmapHandler::Create( wxGDIImage
* pImage
, 
1448     wxBitmap
* pBitmap 
= wxDynamicCast( pImage
 
1452     return(pBitmap 
? Create( pBitmap
 
1461 bool wxBitmapHandler::Load( 
1464 , wxBitmapType                      lFlags
 
1469     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1473     return(pBitmap 
? LoadFile( pBitmap
 
1481 bool wxBitmapHandler::Save( 
1482   const wxGDIImage
*                 pImage
 
1483 , const wxString
&                   rName
 
1484 , wxBitmapType                      lType
 
1487     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1491     return(pBitmap 
? SaveFile( pBitmap
 
1497 bool wxBitmapHandler::Create( 
1498   wxBitmap
*                         WXUNUSED(pBitmap
) 
1499 , const void*                       WXUNUSED(pData
) 
1500 , wxBitmapType                      
WXUNUSED(lType
) 
1501 , int                               WXUNUSED(nWidth
) 
1502 , int                               WXUNUSED(nHeight
) 
1503 , int                               WXUNUSED(nDepth
) 
1509 bool wxBitmapHandler::LoadFile( 
1510   wxBitmap
*                         WXUNUSED(pBitmap
) 
1512 , wxBitmapType                      
WXUNUSED(lType
) 
1513 , int                               WXUNUSED(nDesiredWidth
) 
1514 , int                               WXUNUSED(nDesiredHeight
) 
1520 bool wxBitmapHandler::LoadFile( 
1521   wxBitmap
*                         WXUNUSED(pBitmap
) 
1522 , const wxString
&                   WXUNUSED(rName
) 
1523 , wxBitmapType                      
WXUNUSED(lType
) 
1524 , int                               WXUNUSED(nDesiredWidth
) 
1525 , int                               WXUNUSED(nDesiredHeight
) 
1531 bool wxBitmapHandler::SaveFile( 
1532   wxBitmap
*                         WXUNUSED(pBitmap
) 
1533 , const wxString
&                   WXUNUSED(rName
) 
1534 , wxBitmapType                      
WXUNUSED(nType
) 
1535 , const wxPalette
*                  WXUNUSED(pPalette
) 
1541 // ---------------------------------------------------------------------------- 
1542 // Utility functions 
1543 // ---------------------------------------------------------------------------- 
1544 HBITMAP 
wxInvertMask( 
1550     HBITMAP                         hBmpInvMask 
= 0; 
1552     wxCHECK_MSG( hBmpMask
, 0, wxT("invalid bitmap in wxInvertMask") ); 
1555     // Get width/height from the bitmap if not given 
1557     if (!nWidth 
|| !nHeight
) 
1559         BITMAPINFOHEADER2           vBmhdr
; 
1561         ::GpiQueryBitmapInfoHeader( hBmpMask
 
1564         nWidth  
= (int)vBmhdr
.cx
; 
1565         nHeight 
= (int)vBmhdr
.cy
; 
1568     BITMAPINFOHEADER2               vBmih
; 
1569     SIZEL                           vSize 
= {0, 0}; 
1570     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1571     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1572     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1573     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1574     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1575     POINTL                          vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
}, 
1576                                                   {0, 0}, {nWidth
, nHeight
} 
1579     memset(&vBmih
, '\0', 16); 
1584     vBmih
.cBitCount 
= 24; 
1586     hBmpInvMask 
= ::GpiCreateBitmap( hPSDst
 
1593     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
); 
1594     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
); 
1604     ::GpiDestroyPS(hPSSrc
); 
1605     ::GpiDestroyPS(hPSDst
); 
1606     ::DevCloseDC(hDCSrc
); 
1607     ::DevCloseDC(hDCDst
); 
1610 } // end of WxWinGdi_InvertMask 
1612 HBITMAP 
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight 
) 
1614     wxCHECK_MSG( hBmp
, 0, wxT("invalid bitmap in wxCopyBmp") ); 
1617     // Get width/height from the bitmap if not given 
1619     if (!nWidth 
|| !nHeight
) 
1621         BITMAPINFOHEADER2 vBmhdr
; 
1624         ::GpiQueryBitmapInfoHeader( hBmp
, 
1626         nWidth        
= (int)vBmhdr
.cx
; 
1627         nHeight       
= (int)vBmhdr
.cy
; 
1630     BITMAPINFOHEADER2 vBmih
; 
1631     SIZEL             vSize     
= {0, 0}; 
1632     DEVOPENSTRUC      vDop      
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1633     HDC               hDCSrc    
= ::DevOpenDC(  vHabmain
, 
1637                                                 (PDEVOPENDATA
)&vDop
, 
1639     HDC               hDCDst    
= ::DevOpenDC(  vHabmain
, 
1643                                                 (PDEVOPENDATA
)&vDop
, 
1645     HPS               hPSSrc    
= ::GpiCreatePS(  vHabmain
, 
1648                                                   PU_PELS 
| GPIA_ASSOC  
); 
1649     HPS               hPSDst    
= ::GpiCreatePS(  vHabmain
, 
1652                                                   PU_PELS 
| GPIA_ASSOC  
); 
1653     POINTL            vPoint
[4] = { {0,      nHeight
}, 
1656                                     {nWidth
, nHeight
} }; 
1660         vPoint
[1].y 
= nHeight
; 
1662     memset(&vBmih
, '\0', 16); 
1667     vBmih
.cBitCount 
= 24; 
1669     HBITMAP hInvBmp 
= ::GpiCreateBitmap(  hPSDst
, 
1675     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
); 
1676     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
); 
1678     ::GpiBitBlt(  hPSDst
, 
1685     ::GpiDestroyPS(hPSSrc
); 
1686     ::GpiDestroyPS(hPSDst
); 
1687     ::DevCloseDC(hDCSrc
); 
1688     ::DevCloseDC(hDCDst
); 
1691 } // end of wxFlipBmp