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" 
  36 #include "wx/xpmdecod.h" 
  38 // ---------------------------------------------------------------------------- 
  40 // ---------------------------------------------------------------------------- 
  42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
  47 // ============================================================================ 
  49 // ============================================================================ 
  51 // ---------------------------------------------------------------------------- 
  53 // ---------------------------------------------------------------------------- 
  55 wxBitmapRefData::wxBitmapRefData() 
  58     m_pSelectedInto 
= NULL
; 
  61     m_hBitmap       
= (WXHBITMAP
) NULL
; 
  62 } // end of wxBitmapRefData::wxBitmapRefData 
  64 void wxBitmapRefData::Free() 
  66     if ( m_pSelectedInto 
) 
  68         wxLogLastError("GpiDeleteBitmap(hbitmap)"); 
  72         if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
)) 
  74             wxLogLastError("GpiDeleteBitmap(hbitmap)"); 
  82 } // end of wxBitmapRefData::Free 
  84 // ---------------------------------------------------------------------------- 
  86 // ---------------------------------------------------------------------------- 
  88 // this function should be called from all wxBitmap ctors 
  93     // True for all bitmaps created from bits, wxImages, Xpms 
  95 } // end of wxBitmap::Init 
  97 bool wxBitmap::CopyFromIconOrCursor( 
  98   const wxGDIImage
&                 rIcon
 
 101     HPOINTER                        hIcon 
= (HPOINTER
)rIcon
.GetHandle(); 
 102     POINTERINFO                     SIconInfo
; 
 104     if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
)) 
 106         wxLogLastError(wxT("WinQueryPointerInfo")); 
 109     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 111     m_refData 
= pRefData
; 
 113     int                             nWidth 
= rIcon
.GetWidth(); 
 114     int                             nHeight 
= rIcon
.GetHeight(); 
 116     pRefData
->m_nWidth  
= nWidth
; 
 117     pRefData
->m_nHeight 
= nHeight
; 
 118     pRefData
->m_nDepth  
= wxDisplayDepth(); 
 120     pRefData
->m_hBitmap 
= (WXHBITMAP
)SIconInfo
.hbmColor
; 
 122     wxMask
*                         pMask 
= new wxMask(SIconInfo
.hbmPointer
); 
 124     pMask
->SetMaskBitmap(GetHBITMAP()); 
 128 } // end of wxBitmap::CopyFromIconOrCursor 
 130 bool wxBitmap::CopyFromCursor( 
 131   const wxCursor
&                   rCursor
 
 138     return(CopyFromIconOrCursor(rCursor
)); 
 139 } // end of wxBitmap::CopyFromCursor 
 141 bool wxBitmap::CopyFromIcon( 
 150     return CopyFromIconOrCursor(rIcon
); 
 151 } // end of wxBitmap::CopyFromIcon 
 153 wxBitmap::~wxBitmap() 
 155 } // end of wxBitmap::~wxBitmap 
 166     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 167     BITMAPINFOHEADER2               vHeader
; 
 171     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 172     SIZEL                           vSize 
= {0, 0}; 
 175     wxASSERT(vHabmain 
!= NULL
); 
 177     m_refData 
= pRefData
; 
 179     pRefData
->m_nWidth        
= nWidth
; 
 180     pRefData
->m_nHeight       
= nHeight
; 
 181     pRefData
->m_nDepth        
= nDepth
; 
 182     pRefData
->m_nNumColors    
= 0; 
 183     pRefData
->m_pSelectedInto 
= NULL
; 
 185     hDc   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 186     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 189         wxLogLastError("GpiCreatePS Failure"); 
 195         // We assume that it is in XBM format which is not quite the same as 
 196         // the format CreateBitmap() wants because the order of bytes in the 
 199         const size_t                nBytesPerLine 
= (nWidth 
+ 7) / 8; 
 200         const size_t                nPadding 
= nBytesPerLine 
% 2; 
 201         const size_t                nLen 
= nHeight 
* (nPadding 
+ nBytesPerLine
); 
 202         const char*                 pzSrc 
= zBits
; 
 206         pzData 
= (char *)malloc(nLen
); 
 208         char*                       pzDst 
= pzData
; 
 210         for (nRows 
= 0; nRows 
< nHeight
; nRows
++) 
 212             for (nCols 
= 0; nCols 
< nBytesPerLine
; nCols
++) 
 214                 unsigned char       ucVal 
= *pzSrc
++; 
 215                 unsigned char       ucReversed 
= 0; 
 218                 for (nBits 
= 0; nBits 
< 8; nBits
++) 
 221                     ucReversed 
|= (ucVal 
& 0x01); 
 224                 *pzDst
++ = ucReversed
; 
 233         // Bits should already be in Windows standard format 
 235         pzData 
= (char *)zBits
;    // const_cast is harmless 
 239         nDepth 
= 24; // MAX supported in PM 
 240     memset(&vHeader
, '\0', 16); 
 242     vHeader
.cx              
= (USHORT
)nWidth
; 
 243     vHeader
.cy              
= (USHORT
)nHeight
; 
 244     vHeader
.cPlanes         
= 1L; 
 245     vHeader
.cBitCount       
= nDepth
; 
 246     vHeader
.usReserved      
= 0; 
 248     memset(&vInfo
, '\0', 16); 
 250     vInfo
.cx              
= (USHORT
)nWidth
; 
 251     vInfo
.cy              
= (USHORT
)nHeight
; 
 253     vInfo
.cBitCount       
= nDepth
; 
 255     HBITMAP                         hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
); 
 259         wxLogLastError("CreateBitmap"); 
 263     SetHBITMAP((WXHBITMAP
)hBmp
); 
 264 } // end of wxBitmap::wxBitmap 
 277 } // end of wxBitmap::wxBitmap 
 295 } // end of wxBitmap::wxBitmap 
 307 } // end of wxBitmap::wxBitmap 
 309 bool wxBitmap::Create( 
 316     BITMAPINFOHEADER2               vHeader
; 
 318     wxASSERT(vHabmain 
!= NULL
); 
 320     m_refData 
= new wxBitmapRefData
; 
 321     GetBitmapData()->m_nWidth 
= nW
; 
 322     GetBitmapData()->m_nHeight 
= nH
; 
 323     GetBitmapData()->m_nDepth 
= nD
; 
 326     // Xpms and bitmaps from other images can also be mono's, but only 
 327     // mono's need help changing their colors with MemDC changes 
 331         DEVOPENSTRUC                vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 332         SIZEL                       vSize 
= {0, 0}; 
 333         HDC                         hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 334         HPS                         hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 338         memset(&vHeader
, '\0', 16); 
 343         vHeader
.cBitCount 
= 24; //nD; 
 345         hBmp 
= ::GpiCreateBitmap( hPS
 
 360         hPSScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 361         hDCScreen 
= ::GpiQueryDevice(hPSScreen
); 
 362         ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 367         memset(&vHeader
, '\0', 16); 
 372         vHeader
.cBitCount 
= lBitCount
; 
 374         hBmp 
= ::GpiCreateBitmap( hPSScreen
 
 381         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 382         ::WinReleasePS(hPSScreen
); 
 384     SetHBITMAP((WXHBITMAP
)hBmp
); 
 387 } // end of wxBitmap::Create 
 389 bool wxBitmap::CreateFromXpm( 
 393 #if wxUSE_IMAGE && wxUSE_XPM 
 396     wxCHECK_MSG(ppData 
!= NULL
, FALSE
, wxT("invalid bitmap data")) 
 398     wxXPMDecoder                    vDecoder
; 
 399     wxImage                         vImg 
= vDecoder
.ReadData(ppData
); 
 401     wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data")) 
 403     *this = wxBitmap(vImg
); 
 408 } // end of wxBitmap::CreateFromXpm 
 410 bool wxBitmap::LoadFile( 
 417     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 423         m_refData 
= new wxBitmapRefData
; 
 425         return(pHandler
->LoadFile( this 
 436 } // end of wxBitmap::LoadFile 
 438 bool wxBitmap::Create( 
 448     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 454         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
); 
 459     m_refData 
= new wxBitmapRefData
; 
 461     return(pHandler
->Create( this 
 468 } // end of wxBitmap::Create 
 470 bool wxBitmap::SaveFile( 
 471   const wxString
&                   rFilename
 
 473 , const wxPalette
*                  pPalette
 
 476     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 482         return pHandler
->SaveFile( this 
 490         // FIXME what about palette? shouldn't we use it? 
 491         wxImage                     vImage 
= ConvertToImage(); 
 496         return(vImage
.SaveFile( rFilename
 
 500 } // end of wxBitmap::SaveFile 
 503 // ---------------------------------------------------------------------------- 
 504 // wxImage-wxBitmap conversion 
 505 // ---------------------------------------------------------------------------- 
 507 bool wxBitmap::CreateFromImage ( 
 508   const wxImage
&                    rImage
 
 512     wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image")); 
 513     m_refData 
= new wxBitmapRefData(); 
 515     int                             nSizeLimit 
= 1024 * 768 * 3; 
 516     int                             nWidth 
= rImage
.GetWidth(); 
 517     int                             nBmpHeight 
= rImage
.GetHeight(); 
 518     int                             nBytePerLine 
= nWidth 
* 3; 
 519     int                             nSizeDWORD 
= sizeof(DWORD
); 
 520     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 523     if (nLineBoundary 
> 0) 
 525         nPadding 
= nSizeDWORD 
- nLineBoundary
; 
 526         nBytePerLine 
+= nPadding
; 
 530     // Calc the number of DIBs and heights of DIBs 
 534     int                             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 536     if (nHeight 
>= nBmpHeight
) 
 537         nHeight 
= nBmpHeight
; 
 540         nNumDIB  
= nBmpHeight 
/ nHeight
; 
 541         nHRemain 
= nBmpHeight 
% nHeight
; 
 547     // Set bitmap parameters 
 549     wxCHECK_MSG(rImage
.Ok(), FALSE
, wxT("invalid image")); 
 551     SetHeight(nBmpHeight
); 
 557         nDepth 
= wxDisplayDepth(); 
 562     // Copy the palette from the source image 
 564     SetPalette(rImage
.GetPalette()); 
 565 #endif // wxUSE_PALETTE 
 568     // Create a DIB header 
 570     BITMAPINFOHEADER2               vHeader
; 
 574     // Fill in the DIB header 
 576     memset(&vHeader
, '\0', 16); 
 578     vHeader
.cx              
= (ULONG
)nWidth
; 
 579     vHeader
.cy              
= (ULONG
)nHeight
; 
 580     vHeader
.cPlanes         
= 1L; 
 581     vHeader
.cBitCount       
= 24; 
 584     // Memory for DIB data 
 586     unsigned char*                  pucBits
; 
 588     pucBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 591         wxFAIL_MSG(wxT("could not allocate memory for DIB")); 
 594     memset(pucBits
, '\0', (nBytePerLine 
* nHeight
)); 
 597     // Create and set the device-dependent bitmap 
 599     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 600     SIZEL                           vSize 
= {0, 0}; 
 601     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 602     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 604     HDC                             hDCScreen 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 609     memset(&vInfo
, '\0', 16); 
 611     vInfo
.cx              
= (ULONG
)nWidth
; 
 612     vInfo
.cy              
= (ULONG
)nHeight
; 
 614     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 616     hBmp 
= ::GpiCreateBitmap( hPS
 
 623     HPAL                            hOldPalette 
= NULLHANDLE
; 
 624     if (rImage
.GetPalette().Ok()) 
 626         hOldPalette 
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE()); 
 628 #endif // wxUSE_PALETTE 
 631     // Copy image data into DIB data and then into DDB (in a loop) 
 633     unsigned char*                  pData 
= rImage
.GetData(); 
 638     unsigned char*                  ptdata 
= pData
; 
 639     unsigned char*                  ptbits
; 
 641     if ((hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
) 
 646         vError 
= ::WinGetLastError(vHabmain
); 
 647         sError 
= wxPMErrorToStr(vError
); 
 649     for (n 
= 0; n 
< nNumDIB
; n
++) 
 651         if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 654             // Redefine height and size of the (possibly) last smaller DIB 
 655             // memory is not reallocated 
 658             vHeader
.cy      
= (DWORD
)(nHeight
); 
 659             vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 662         for (j 
= 0; j 
< nHeight
; j
++) 
 664             for (i 
= 0; i 
< nWidth
; i
++) 
 666                 *(ptbits
++) = *(ptdata 
+ 2); 
 667                 *(ptbits
++) = *(ptdata 
+ 1); 
 668                 *(ptbits
++) = *(ptdata
); 
 671             for (i 
= 0; i 
< nPadding
; i
++) 
 676         // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt 
 677         // in combination with setting the bits into the selected bitmap 
 679         if ((lScans 
= ::GpiSetBitmapBits( hPS
 
 680                                          ,0             // Start at the bottom 
 681                                          ,(LONG
)nHeight 
// One line per scan 
 689             vError 
= ::WinGetLastError(vHabmain
); 
 690             sError 
= wxPMErrorToStr(vError
); 
 692         hPSScreen 
= ::GpiCreatePS( vHabmain
 
 695                                   ,PU_PELS 
| GPIA_ASSOC
 
 698         POINTL                      vPoint
[4] = { {0, nOrigin
}, 
 700                                                   {0, 0}, {nWidth
, nHeight
} 
 704         ::GpiBitBlt( hPSScreen
 
 711         ::GpiDestroyPS(hPSScreen
); 
 714     SetHBITMAP((WXHBITMAP
)hBmp
); 
 717         ::GpiSelectPalette(hPS
, hOldPalette
); 
 718 #endif // wxUSE_PALETTE 
 721     // Similarly, created an mono-bitmap for the possible mask 
 723     if (rImage
.HasMask()) 
 727         vHeader
.cy        
= nHeight
; 
 729         vHeader
.cBitCount 
= 24; 
 730         hBmp 
= ::GpiCreateBitmap( hPS
 
 736         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
); 
 738             nHeight 
= nBmpHeight
; 
 740             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 741         vHeader
.cy 
= (DWORD
)(nHeight
); 
 744         unsigned char               cRed   
= rImage
.GetMaskRed(); 
 745         unsigned char               cGreen 
= rImage
.GetMaskGreen(); 
 746         unsigned char               cBlue  
= rImage
.GetMaskBlue(); 
 747         unsigned char               cZero 
= 0; 
 748         unsigned char               cOne 
= 255; 
 751         for (n 
= 0; n 
< nNumDIB
; n
++) 
 753             if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 756                 // Redefine height and size of the (possibly) last smaller DIB 
 757                 // memory is not reallocated 
 760                 vHeader
.cy      
= (DWORD
)(nHeight
); 
 761                 vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 764             for (int j 
= 0; j 
< nHeight
; j
++) 
 766                 for (i 
= 0; i 
< nWidth
; i
++) 
 768                     unsigned char cRedImage   
= (*(ptdata
++)) ; 
 769                     unsigned char cGreenImage 
= (*(ptdata
++)) ; 
 770                     unsigned char cBlueImage  
= (*(ptdata
++)) ; 
 772                     if ((cRedImage 
!= cRed
) || (cGreenImage 
!= cGreen
) || (cBlueImage 
!= cBlue
)) 
 785                 for (i 
= 0; i 
< nPadding
; i
++) 
 788             lScans 
= ::GpiSetBitmapBits( hPS
 
 789                                         ,0              // Start at the bottom 
 790                                         ,(LONG
)nHeight 
// One line per scan 
 794             hPSScreen 
= ::GpiCreatePS( vHabmain
 
 797                                       ,PU_PELS 
| GPIA_ASSOC
 
 799             POINTL vPoint2
[4] = { {0, nOrigin
}, 
 801                                   {0, 0}, {nWidth
, nHeight
} 
 803             ::GpiBitBlt( hPSScreen
 
 810             ::GpiDestroyPS(hPSScreen
); 
 815         // Create a wxMask object 
 817         wxMask
*                     pMask 
= new wxMask(); 
 819         pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
); 
 821         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmpOld
); 
 825     // Free allocated resources 
 827     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 829     ::DevCloseDC(hDCScreen
); 
 833 } // end of wxBitmap::CreateFromImage 
 835 wxImage 
wxBitmap::ConvertToImage() const 
 840     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 843     // Create an wxImage object 
 845     int                             nWidth        
= GetWidth(); 
 846     int                             nHeight       
= GetHeight(); 
 849     int                             nBytePerLine  
= nWidth 
* 3; 
 850     int                             nSizeDWORD    
= sizeof(DWORD
); 
 851     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 853     unsigned char*                  pData
; 
 854     unsigned char*                  lpBits
; 
 856     BITMAPINFOHEADER2               vDIBh
; 
 857     BITMAPINFO2                     vDIBInfo
; 
 861     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 862     SIZEL                           vSizlPage 
= {0,0}; 
 865     vImage
.Create( nWidth
 
 868     pData 
= vImage
.GetData(); 
 871         wxFAIL_MSG( wxT("could not allocate data for image") ); 
 874     if(nLineBoundary 
> 0) 
 876         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 877         nBytePerLine 
+= nPadding
; 
 879     wxDisplaySize( &nDevWidth
 
 883     // Create and fill a DIB header 
 885     memset(&vDIBh
, '\0', 16); 
 890     vDIBh
.cBitCount 
= 24; 
 892     memset(&vDIBInfo
, '\0', 16); 
 894     vDIBInfo
.cx              
= nWidth
; 
 895     vDIBInfo
.cy              
= nHeight
; 
 896     vDIBInfo
.cPlanes         
= 1; 
 897     vDIBInfo
.cBitCount       
= 24; 
 899     lpBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 902         wxFAIL_MSG(wxT("could not allocate data for DIB")); 
 906     memset(lpBits
, '\0', (nBytePerLine 
* nHeight
)); 
 907     hBitmap 
= (HBITMAP
)GetHBITMAP(); 
 910     // May already be selected into a PS 
 912     if ((pDC 
= GetSelectedInto()) != NULL
) 
 914         hPSMem 
= pDC
->GetHPS(); 
 918         hDCMem 
= ::DevOpenDC( vHabmain
 
 925         hPSMem 
= ::GpiCreatePS( vHabmain
 
 928                                ,PU_PELS 
| GPIA_ASSOC
 
 931     if ((hOldBitmap 
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
) 
 936         vError 
= ::WinGetLastError(vHabmain
); 
 937         sError 
= wxPMErrorToStr(vError
); 
 941     // Copy data from the device-dependent bitmap to the DIB 
 943     if ((lScans 
= ::GpiQueryBitmapBits( hPSMem
 
 953         vError 
= ::WinGetLastError(vHabmain
); 
 954         sError 
= wxPMErrorToStr(vError
); 
 958     // Copy DIB data into the wxImage object 
 962     unsigned char*                  ptdata 
= pData
; 
 963     unsigned char*                  ptbits 
= lpBits
; 
 965     for (i 
= 0; i 
< nHeight
; i
++) 
 967         for (j 
= 0; j 
< nWidth
; j
++) 
 969             *(ptdata
++) = *(ptbits
+2); 
 970             *(ptdata
++) = *(ptbits
+1); 
 971             *(ptdata
++) = *(ptbits  
); 
 976     if ((pDC 
= GetSelectedInto()) == NULL
) 
 978         ::GpiSetBitmap(hPSMem
, NULLHANDLE
); 
 979         ::GpiDestroyPS(hPSMem
); 
 980         ::DevCloseDC(hDCMem
); 
 984     // Similarly, set data according to the possible mask bitmap 
 986     if (GetMask() && GetMask()->GetMaskBitmap()) 
 988         hBitmap 
= (HBITMAP
)GetMask()->GetMaskBitmap(); 
 991         // Memory DC/PS created, color set, data copied, and memory DC/PS deleted 
 993         HDC                        hMemDC 
= ::DevOpenDC( vHabmain
 
1000         HPS                         hMemPS 
= ::GpiCreatePS( vHabmain
 
1003                                                            ,PU_PELS 
| GPIA_ASSOC
 
1005         ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0)); 
1006         ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) ); 
1007         ::GpiSetBitmap(hMemPS
, hBitmap
); 
1008         ::GpiQueryBitmapBits( hPSMem
 
1014         ::GpiSetBitmap(hMemPS
, NULLHANDLE
); 
1015         ::GpiDestroyPS(hMemPS
); 
1016         ::DevCloseDC(hMemDC
); 
1019         // Background color set to RGB(16,16,16) in consistent with wxGTK 
1021         unsigned char               ucRed 
= 16; 
1022         unsigned char               ucGreen 
= 16; 
1023         unsigned char               ucBlue 
= 16; 
1027         for (i 
= 0; i 
< nHeight
; i
++) 
1029             for (j 
= 0; j 
< nWidth
; j
++) 
1035                     *(ptdata
++)  = ucRed
; 
1036                     *(ptdata
++)  = ucGreen
; 
1037                     *(ptdata
++)  = ucBlue
; 
1043         vImage
.SetMaskColour( ucRed
 
1047         vImage
.SetMask(TRUE
); 
1051         vImage
.SetMask(FALSE
); 
1055     // Free allocated resources 
1059 } // end of wxBitmap::ConvertToImage 
1061 // ---------------------------------------------------------------------------- 
1062 // sub bitmap extraction 
1063 // ---------------------------------------------------------------------------- 
1065 wxBitmap 
wxBitmap::GetSubBitmap( 
1069     wxCHECK_MSG( Ok() && 
1070                  (rRect
.x 
>= 0) && (rRect
.y 
>= 0) && 
1071                  (rRect
.x 
+ rRect
.width 
<= GetWidth()) && 
1072                  (rRect
.y 
+ rRect
.height 
<= GetHeight()), 
1073                  wxNullBitmap
, wxT("Invalid bitmap or bitmap region") ); 
1075     wxBitmap                        
vRet( rRect
.width
 
1079     wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") ); 
1085     SIZEL                           vSize 
= {0, 0}; 
1086     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1087     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1088     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1089     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1090     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1091     POINTL                          vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
}, 
1093                                                   {rRect
.x 
+ rRect
.width
, rRect
.y 
+ rRect
.height
} 
1096     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1097     ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1107     // Copy mask if there is one 
1111         BITMAPINFOHEADER2           vBmih
; 
1113         memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1114         vBmih
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
1115         vBmih
.cx        
= rRect
.width
; 
1116         vBmih
.cy        
= rRect
.height
; 
1118         vBmih
.cBitCount 
= 24; 
1120         HBITMAP                     hBmpMask 
= ::GpiCreateBitmap( hPSDst
 
1127         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1128         ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1130         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap()); 
1131         ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
); 
1140         wxMask
*                     pMask 
= new wxMask((WXHBITMAP
)hBmpMask
); 
1141         vRet
.SetMask(pMask
); 
1144     ::GpiSetBitmap(hPSSrc
, NULL
); 
1145     ::GpiSetBitmap(hPSDst
, NULL
); 
1146     ::GpiDestroyPS(hPSSrc
); 
1147     ::GpiDestroyPS(hPSDst
); 
1148     ::DevCloseDC(hDCSrc
); 
1149     ::DevCloseDC(hDCDst
); 
1151 } // end of wxBitmap::GetSubBitmap 
1153 // ---------------------------------------------------------------------------- 
1154 // wxBitmap accessors 
1155 // ---------------------------------------------------------------------------- 
1157 void wxBitmap::SetQuality( 
1163     GetBitmapData()->m_nQuality 
= nQ
; 
1164 } // end of wxBitmap::SetQuality 
1166 void wxBitmap::SetPalette( 
1167   const wxPalette
&                  rPalette
 
1172     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
1173 } // end of wxBitmap::SetPalette 
1175 void wxBitmap::SetMask( 
1181     GetBitmapData()->m_pBitmapMask 
= pMask
; 
1182 } // end of wxBitmap::SetMask 
1184 wxBitmap 
wxBitmap::GetBitmapForDC( 
1189 } // end of wxBitmap::GetBitmapForDC 
1191 // ---------------------------------------------------------------------------- 
1193 // ---------------------------------------------------------------------------- 
1198 } // end of wxMask::wxMask 
1200 // Construct a mask from a bitmap and a colour indicating 
1201 // the transparent area 
1203   const wxBitmap
&                   rBitmap
 
1204 , const wxColour
&                   rColour
 
1211 } // end of wxMask::wxMask 
1213 // Construct a mask from a bitmap and a palette index indicating 
1214 // the transparent area 
1216   const wxBitmap
&                   rBitmap
 
1224 } // end of wxMask::wxMask 
1226 // Construct a mask from a mono bitmap (copies the bitmap). 
1228   const wxBitmap
&                   rBitmap
 
1233 } // end of wxMask::wxMask 
1238         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
1239 } // end of wxMask::~wxMask 
1241 // Create a mask from a mono bitmap (copies the bitmap). 
1242 bool wxMask::Create( 
1243   const wxBitmap
&                   rBitmap
 
1246     BITMAPINFOHEADER2               vBmih
; 
1247     SIZEL                           vSize 
= {0, 0}; 
1248     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1249     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1250     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1251     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1252     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1253     POINTL                          vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}, 
1254                                                   {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()} 
1259         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1262     if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1) 
1267     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1268     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1269     vBmih
.cx        
= rBitmap
.GetWidth(); 
1270     vBmih
.cy        
= rBitmap
.GetHeight(); 
1272     vBmih
.cBitCount 
= 24; 
1274     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1281     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1282     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1291     ::GpiDestroyPS(hPSSrc
); 
1292     ::GpiDestroyPS(hPSDst
); 
1293     ::DevCloseDC(hDCSrc
); 
1294     ::DevCloseDC(hDCDst
); 
1296 } // end of wxMask::Create 
1298 // Create a mask from a bitmap and a palette index indicating 
1299 // the transparent area 
1300 bool wxMask::Create( 
1301   const wxBitmap
&                   rBitmap
 
1307         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1310     if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok()) 
1313         unsigned char               cGreen
; 
1314         unsigned char               cBlue
; 
1316         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
1322             wxColour                
vTransparentColour( cRed
 
1327             return (Create( rBitmap
 
1333 } // end of wxMask::Create 
1335 // Create a mask from a bitmap and a colour indicating 
1336 // the transparent area 
1337 bool wxMask::Create( 
1338   const wxBitmap
&                   rBitmap
 
1339 , const wxColour
&                   rColour
 
1343     COLORREF                        vMaskColour 
= OS2RGB( rColour
.Red() 
1347     BITMAPINFOHEADER2               vBmih
; 
1348     SIZEL                           vSize 
= {0, 0}; 
1349     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
1350     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1351     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1352     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1353     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1357         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1366     // Scan the bitmap for the transparent colour and set 
1367     // the corresponding pixels in the mask to BLACK and 
1368     // the rest to WHITE 
1371     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1372     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1373     vBmih
.cx        
= rBitmap
.GetWidth(); 
1374     vBmih
.cy        
= rBitmap
.GetHeight(); 
1376     vBmih
.cBitCount 
= 1; 
1378     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1385     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1386     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1389     // This is not very efficient, but I can't think 
1390     // of a better way of doing it 
1392     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
1394         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
1396             POINTL                  vPt 
= {w
, h
}; 
1397             COLORREF                vCol 
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
); 
1398             if (vCol 
== (COLORREF
)CLR_NOINDEX
) 
1401                 // Doesn't make sense to continue 
1407             if (vCol 
== vMaskColour
) 
1409                 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0)); 
1410                 ::GpiSetPel(hPSDst
, &vPt
); 
1414                 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255)); 
1415                 ::GpiSetPel(hPSDst
, &vPt
); 
1419     ::GpiSetBitmap(hPSSrc
, NULL
); 
1420     ::GpiSetBitmap(hPSDst
, NULL
); 
1421     ::GpiDestroyPS(hPSSrc
); 
1422     ::GpiDestroyPS(hPSDst
); 
1423     ::DevCloseDC(hDCSrc
); 
1424     ::DevCloseDC(hDCDst
); 
1426 } // end of wxMask::Create 
1428 // ---------------------------------------------------------------------------- 
1430 // ---------------------------------------------------------------------------- 
1432 bool wxBitmapHandler::Create( 
1441     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1445     return(pBitmap 
? Create( pBitmap
 
1453 bool wxBitmapHandler::Load( 
1461     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1465     return(pBitmap 
? LoadFile( pBitmap
 
1473 bool wxBitmapHandler::Save( 
1475 , const wxString
&                   rName
 
1479     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1483     return(pBitmap 
? SaveFile( pBitmap
 
1489 bool wxBitmapHandler::Create( 
1490   wxBitmap
*                         WXUNUSED(pBitmap
) 
1491 , void*                             WXUNUSED(pData
) 
1492 , long                              WXUNUSED(lType
) 
1493 , int                               WXUNUSED(nWidth
) 
1494 , int                               WXUNUSED(nHeight
) 
1495 , int                               WXUNUSED(nDepth
) 
1501 bool wxBitmapHandler::LoadFile( 
1502   wxBitmap
*                         WXUNUSED(pBitmap
) 
1504 , long                              WXUNUSED(lType
) 
1505 , int                               WXUNUSED(nDesiredWidth
) 
1506 , int                               WXUNUSED(nDesiredHeight
) 
1512 bool wxBitmapHandler::SaveFile( 
1513   wxBitmap
*                         WXUNUSED(pBitmap
) 
1514 , const wxString
&                   WXUNUSED(rName
) 
1515 , int                               WXUNUSED(nType
) 
1516 , const wxPalette
*                  WXUNUSED(pPalette
) 
1522 // ---------------------------------------------------------------------------- 
1523 // Utility functions 
1524 // ---------------------------------------------------------------------------- 
1525 HBITMAP 
wxInvertMask( 
1531     HBITMAP                         hBmpInvMask 
= 0; 
1533     wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") ); 
1536     // Get width/height from the bitmap if not given 
1538     if (!nWidth 
|| !nHeight
) 
1540         BITMAPINFOHEADER2           vBmhdr
; 
1542         ::GpiQueryBitmapInfoHeader( hBmpMask
 
1545         nWidth  
= (int)vBmhdr
.cx
; 
1546         nHeight 
= (int)vBmhdr
.cy
; 
1549     BITMAPINFOHEADER2               vBmih
; 
1550     SIZEL                           vSize 
= {0, 0}; 
1551     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1552     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1553     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1554     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1555     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1556     POINTL                          vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
}, 
1557                                                   {0, 0}, {nWidth
, nHeight
} 
1560     memset(&vBmih
, '\0', 16); 
1565     vBmih
.cBitCount 
= 24; 
1567     hBmpInvMask 
= ::GpiCreateBitmap( hPSDst
 
1574     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
); 
1575     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
); 
1585     ::GpiDestroyPS(hPSSrc
); 
1586     ::GpiDestroyPS(hPSDst
); 
1587     ::DevCloseDC(hDCSrc
); 
1588     ::DevCloseDC(hDCDst
); 
1591 } // end of WxWinGdi_InvertMask