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/private.h" 
  32 #include "wx/xpmdecod.h" 
  34 // ---------------------------------------------------------------------------- 
  36 // ---------------------------------------------------------------------------- 
  38 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  39 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  41 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
  43 // ============================================================================ 
  45 // ============================================================================ 
  47 // ---------------------------------------------------------------------------- 
  49 // ---------------------------------------------------------------------------- 
  51 wxBitmapRefData::wxBitmapRefData() 
  54     m_pSelectedInto 
= NULL
; 
  57     m_hBitmap       
= (WXHBITMAP
) NULL
; 
  58 } // end of wxBitmapRefData::wxBitmapRefData 
  60 wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData 
&tocopy
) 
  62     m_nQuality 
= tocopy
.m_nQuality
; 
  63     m_pSelectedInto 
= NULL
;     // don't copy this 
  64     m_nNumColors    
= tocopy
.m_nNumColors
; 
  67     if (tocopy
.m_pBitmapMask
) 
  68         m_pBitmapMask 
= new wxMask(*tocopy
.m_pBitmapMask
); 
  70     m_hBitmap 
= wxCopyBmp(tocopy
.m_hBitmap
); 
  73 void wxBitmapRefData::Free() 
  75     if ( m_pSelectedInto 
) 
  77         wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  81         if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
)) 
  83             wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  91 } // end of wxBitmapRefData::Free 
  93 // ---------------------------------------------------------------------------- 
  95 // ---------------------------------------------------------------------------- 
  97 wxObjectRefData
* wxBitmap::CreateRefData() const 
  99     return new wxBitmapRefData
; 
 102 wxObjectRefData
* wxBitmap::CloneRefData(const wxObjectRefData
* data
) const 
 104     return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData 
*, data
)); 
 107 // this function should be called from all wxBitmap ctors 
 108 void wxBitmap::Init() 
 112     // True for all bitmaps created from bits, wxImages, Xpms 
 114 } // end of wxBitmap::Init 
 116 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
) 
 118     HPOINTER                        hIcon 
= (HPOINTER
)rIcon
.GetHandle(); 
 119     POINTERINFO                     SIconInfo
; 
 121     if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
)) 
 123         wxLogLastError(wxT("WinQueryPointerInfo")); 
 126     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 128     m_refData 
= pRefData
; 
 130     int                             nWidth 
= rIcon
.GetWidth(); 
 131     int                             nHeight 
= rIcon
.GetHeight(); 
 133     pRefData
->m_nWidth  
= nWidth
; 
 134     pRefData
->m_nHeight 
= nHeight
; 
 135     pRefData
->m_nDepth  
= wxDisplayDepth(); 
 137     pRefData
->m_hBitmap 
= (WXHBITMAP
)SIconInfo
.hbmColor
; 
 139     wxMask
*                         pMask 
= new wxMask(SIconInfo
.hbmPointer
); 
 141     pMask
->SetMaskBitmap(GetHBITMAP()); 
 145 } // end of wxBitmap::CopyFromIconOrCursor 
 147 bool wxBitmap::CopyFromCursor( 
 148   const wxCursor
&                   rCursor
 
 155     return(CopyFromIconOrCursor(rCursor
)); 
 156 } // end of wxBitmap::CopyFromCursor 
 158 bool wxBitmap::CopyFromIcon( 
 167     return CopyFromIconOrCursor(rIcon
); 
 168 } // end of wxBitmap::CopyFromIcon 
 170 wxBitmap::~wxBitmap() 
 172 } // end of wxBitmap::~wxBitmap 
 183     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 184     BITMAPINFOHEADER2               vHeader
; 
 188     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 189     SIZEL                           vSize 
= {0, 0}; 
 192     wxASSERT(vHabmain 
!= NULL
); 
 194     m_refData 
= pRefData
; 
 196     pRefData
->m_nWidth        
= nWidth
; 
 197     pRefData
->m_nHeight       
= nHeight
; 
 198     pRefData
->m_nDepth        
= nDepth
; 
 199     pRefData
->m_nNumColors    
= 0; 
 200     pRefData
->m_pSelectedInto 
= NULL
; 
 202     hDc   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 203     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 206         wxLogLastError(wxT("GpiCreatePS Failure")); 
 212         // We assume that it is in XBM format which is not quite the same as 
 213         // the format CreateBitmap() wants because the order of bytes in the 
 216         const size_t                nBytesPerLine 
= (nWidth 
+ 7) / 8; 
 217         const size_t                nPadding 
= nBytesPerLine 
% 2; 
 218         const size_t                nLen 
= nHeight 
* (nPadding 
+ nBytesPerLine
); 
 219         const char*                 pzSrc 
= zBits
; 
 223         pzData 
= (char *)malloc(nLen
); 
 225         char*                       pzDst 
= pzData
; 
 227         for (nRows 
= 0; nRows 
< nHeight
; nRows
++) 
 229             for (nCols 
= 0; nCols 
< nBytesPerLine
; nCols
++) 
 231                 unsigned char ucVal 
= *pzSrc
++; 
 232                 unsigned char ucReversed 
= 0; 
 235                 for (nBits 
= 0; nBits 
< 8; nBits
++) 
 238                     ucReversed 
= (unsigned char)(ucReversed 
| (ucVal 
& 0x01)); 
 241                 *pzDst
++ = ucReversed
; 
 250         // Bits should already be in Windows standard format 
 252         pzData 
= (char *)zBits
;    // const_cast is harmless 
 256         nDepth 
= 24; // MAX supported in PM 
 257     memset(&vHeader
, '\0', 16); 
 259     vHeader
.cx              
= (USHORT
)nWidth
; 
 260     vHeader
.cy              
= (USHORT
)nHeight
; 
 261     vHeader
.cPlanes         
= 1L; 
 262     vHeader
.cBitCount       
= (USHORT
)nDepth
; 
 263     vHeader
.usReserved      
= 0; 
 265     memset(&vInfo
, '\0', 16); 
 267     vInfo
.cx              
= (USHORT
)nWidth
; 
 268     vInfo
.cy              
= (USHORT
)nHeight
; 
 270     vInfo
.cBitCount       
= (USHORT
)nDepth
; 
 272     HBITMAP                         hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
); 
 276         wxLogLastError(wxT("CreateBitmap")); 
 280     SetHBITMAP((WXHBITMAP
)hBmp
); 
 281 } // end of wxBitmap::wxBitmap 
 294 } // end of wxBitmap::wxBitmap 
 312 } // end of wxBitmap::wxBitmap 
 324 } // end of wxBitmap::wxBitmap 
 326 bool wxBitmap::Create( 
 333     BITMAPINFOHEADER2               vHeader
; 
 335     wxASSERT(vHabmain 
!= NULL
); 
 337     m_refData 
= new wxBitmapRefData
; 
 338     GetBitmapData()->m_nWidth 
= nW
; 
 339     GetBitmapData()->m_nHeight 
= nH
; 
 340     GetBitmapData()->m_nDepth 
= nD
; 
 343     // Xpms and bitmaps from other images can also be mono's, but only 
 344     // mono's need help changing their colors with MemDC changes 
 348         DEVOPENSTRUC                vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 349         SIZEL                       vSize 
= {0, 0}; 
 350         HDC                         hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 351         HPS                         hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 355         memset(&vHeader
, '\0', 16); 
 360         vHeader
.cBitCount 
= 24; //nD; 
 362         hBmp 
= ::GpiCreateBitmap( hPS
 
 377         hPSScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 378         hDCScreen 
= ::GpiQueryDevice(hPSScreen
); 
 379         ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 384         memset(&vHeader
, '\0', 16); 
 389         vHeader
.cBitCount 
= (USHORT
)lBitCount
; 
 391         hBmp 
= ::GpiCreateBitmap( hPSScreen
 
 398         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 399         ::WinReleasePS(hPSScreen
); 
 401     SetHBITMAP((WXHBITMAP
)hBmp
); 
 404 } // end of wxBitmap::Create 
 406 bool wxBitmap::LoadFile(const wxString
& filename
, long type
) 
 410     wxBitmapHandler 
*handler 
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
); 
 414         m_refData 
= new wxBitmapRefData
; 
 416         return handler
->LoadFile(this, filename
, type
, -1, -1); 
 419     else // no bitmap handler found 
 422         if ( image
.LoadFile( filename
, type 
) && image
.Ok() ) 
 424             *this = wxBitmap(image
); 
 429 #endif // wxUSE_IMAGE 
 434 bool wxBitmap::LoadFile( 
 441     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 447         m_refData 
= new wxBitmapRefData
; 
 449         return(pHandler
->LoadFile( this 
 460 } // end of wxBitmap::LoadFile 
 462 bool wxBitmap::Create( 
 472     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 478         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
); 
 483     m_refData 
= new wxBitmapRefData
; 
 485     return(pHandler
->Create( this 
 492 } // end of wxBitmap::Create 
 494 bool wxBitmap::SaveFile( 
 495   const wxString
&                   rFilename
 
 497 , const wxPalette
*                  pPalette
 
 500     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 506         return pHandler
->SaveFile( this 
 514         // FIXME what about palette? shouldn't we use it? 
 515         wxImage                     vImage 
= ConvertToImage(); 
 520         return(vImage
.SaveFile( rFilename
 
 524 } // end of wxBitmap::SaveFile 
 527 // ---------------------------------------------------------------------------- 
 528 // wxImage-wxBitmap conversion 
 529 // ---------------------------------------------------------------------------- 
 531 bool wxBitmap::CreateFromImage ( 
 532   const wxImage
&                    rImage
 
 536     wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image")); 
 537     m_refData 
= new wxBitmapRefData(); 
 539     int                             nSizeLimit 
= 1024 * 768 * 3; 
 540     int                             nWidth 
= rImage
.GetWidth(); 
 541     int                             nBmpHeight 
= rImage
.GetHeight(); 
 542     int                             nBytePerLine 
= nWidth 
* 3; 
 543     int                             nSizeDWORD 
= sizeof(DWORD
); 
 544     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 547     if (nLineBoundary 
> 0) 
 549         nPadding 
= nSizeDWORD 
- nLineBoundary
; 
 550         nBytePerLine 
+= nPadding
; 
 554     // Calc the number of DIBs and heights of DIBs 
 558     int                             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 560     if (nHeight 
>= nBmpHeight
) 
 561         nHeight 
= nBmpHeight
; 
 564         nNumDIB  
= nBmpHeight 
/ nHeight
; 
 565         nHRemain 
= nBmpHeight 
% nHeight
; 
 571     // Set bitmap parameters 
 573     wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image")); 
 575     SetHeight(nBmpHeight
); 
 581         nDepth 
= wxDisplayDepth(); 
 586     // Copy the palette from the source image 
 588     SetPalette(rImage
.GetPalette()); 
 589 #endif // wxUSE_PALETTE 
 592     // Create a DIB header 
 594     BITMAPINFOHEADER2               vHeader
; 
 598     // Fill in the DIB header 
 600     memset(&vHeader
, '\0', 16); 
 602     vHeader
.cx              
= (ULONG
)nWidth
; 
 603     vHeader
.cy              
= (ULONG
)nHeight
; 
 604     vHeader
.cPlanes         
= 1L; 
 605     vHeader
.cBitCount       
= 24; 
 608     // Memory for DIB data 
 610     unsigned char*                  pucBits
; 
 612     pucBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 615         wxFAIL_MSG(wxT("could not allocate memory for DIB")); 
 618     memset(pucBits
, '\0', (nBytePerLine 
* nHeight
)); 
 621     // Create and set the device-dependent bitmap 
 623     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 624     SIZEL                           vSize 
= {0, 0}; 
 625     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 626     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 628     HDC                             hDCScreen 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 633     memset(&vInfo
, '\0', 16); 
 635     vInfo
.cx              
= (ULONG
)nWidth
; 
 636     vInfo
.cy              
= (ULONG
)nHeight
; 
 638     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 640     hBmp 
= ::GpiCreateBitmap( hPS
 
 647     HPAL                            hOldPalette 
= NULLHANDLE
; 
 648     if (rImage
.GetPalette().Ok()) 
 650         hOldPalette 
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE()); 
 652 #endif // wxUSE_PALETTE 
 655     // Copy image data into DIB data and then into DDB (in a loop) 
 657     unsigned char*                  pData 
= rImage
.GetData(); 
 662     unsigned char*                  ptdata 
= pData
; 
 663     unsigned char*                  ptbits
; 
 665     if ((hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
) 
 670         vError 
= ::WinGetLastError(vHabmain
); 
 671         sError 
= wxPMErrorToStr(vError
); 
 673     for (n 
= 0; n 
< nNumDIB
; n
++) 
 675         if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 678             // Redefine height and size of the (possibly) last smaller DIB 
 679             // memory is not reallocated 
 682             vHeader
.cy      
= (DWORD
)(nHeight
); 
 683             vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 686         for (j 
= 0; j 
< nHeight
; j
++) 
 688             for (i 
= 0; i 
< nWidth
; i
++) 
 690                 *(ptbits
++) = *(ptdata 
+ 2); 
 691                 *(ptbits
++) = *(ptdata 
+ 1); 
 692                 *(ptbits
++) = *(ptdata
); 
 695             for (i 
= 0; i 
< nPadding
; i
++) 
 700         // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt 
 701         // in combination with setting the bits into the selected bitmap 
 703         if ((lScans 
= ::GpiSetBitmapBits( hPS
 
 704                                          ,0             // Start at the bottom 
 705                                          ,(LONG
)nHeight 
// One line per scan 
 713             vError 
= ::WinGetLastError(vHabmain
); 
 714             sError 
= wxPMErrorToStr(vError
); 
 716         hPSScreen 
= ::GpiCreatePS( vHabmain
 
 719                                   ,PU_PELS 
| GPIA_ASSOC
 
 722         POINTL                      vPoint
[4] = { {0, nOrigin
}, 
 724                                                   {0, 0}, {nWidth
, nHeight
} 
 728         ::GpiBitBlt( hPSScreen
 
 735         ::GpiDestroyPS(hPSScreen
); 
 738     SetHBITMAP((WXHBITMAP
)hBmp
); 
 741         ::GpiSelectPalette(hPS
, hOldPalette
); 
 742 #endif // wxUSE_PALETTE 
 745     // Similarly, created an mono-bitmap for the possible mask 
 747     if (rImage
.HasMask()) 
 751         vHeader
.cy        
= nHeight
; 
 753         vHeader
.cBitCount 
= 24; 
 754         hBmp 
= ::GpiCreateBitmap( hPS
 
 760         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
); 
 762             nHeight 
= nBmpHeight
; 
 764             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 765         vHeader
.cy 
= (DWORD
)(nHeight
); 
 768         unsigned char               cRed   
= rImage
.GetMaskRed(); 
 769         unsigned char               cGreen 
= rImage
.GetMaskGreen(); 
 770         unsigned char               cBlue  
= rImage
.GetMaskBlue(); 
 771         unsigned char               cZero 
= 0; 
 772         unsigned char               cOne 
= 255; 
 775         for (n 
= 0; n 
< nNumDIB
; n
++) 
 777             if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 780                 // Redefine height and size of the (possibly) last smaller DIB 
 781                 // memory is not reallocated 
 784                 vHeader
.cy      
= (DWORD
)(nHeight
); 
 785                 vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 788             for (int j 
= 0; j 
< nHeight
; j
++) 
 790                 for (i 
= 0; i 
< nWidth
; i
++) 
 792                     unsigned char cRedImage   
= (*(ptdata
++)) ; 
 793                     unsigned char cGreenImage 
= (*(ptdata
++)) ; 
 794                     unsigned char cBlueImage  
= (*(ptdata
++)) ; 
 796                     if ((cRedImage 
!= cRed
) || (cGreenImage 
!= cGreen
) || (cBlueImage 
!= cBlue
)) 
 809                 for (i 
= 0; i 
< nPadding
; i
++) 
 812             lScans 
= ::GpiSetBitmapBits( hPS
 
 813                                         ,0              // Start at the bottom 
 814                                         ,(LONG
)nHeight 
// One line per scan 
 818             hPSScreen 
= ::GpiCreatePS( vHabmain
 
 821                                       ,PU_PELS 
| GPIA_ASSOC
 
 823             POINTL vPoint2
[4] = { {0, nOrigin
}, 
 825                                   {0, 0}, {nWidth
, nHeight
} 
 827             ::GpiBitBlt( hPSScreen
 
 834             ::GpiDestroyPS(hPSScreen
); 
 839         // Create a wxMask object 
 841         wxMask
*                     pMask 
= new wxMask(); 
 843         pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
); 
 845         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmpOld
); 
 849     // Free allocated resources 
 851     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 853     ::DevCloseDC(hDCScreen
); 
 857 } // end of wxBitmap::CreateFromImage 
 859 wxImage 
wxBitmap::ConvertToImage() const 
 864     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 867     // Create an wxImage object 
 869     int                             nWidth        
= GetWidth(); 
 870     int                             nHeight       
= GetHeight(); 
 873     int                             nBytePerLine  
= nWidth 
* 3; 
 874     int                             nSizeDWORD    
= sizeof(DWORD
); 
 875     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 877     unsigned char*                  pData
; 
 878     unsigned char*                  lpBits
; 
 880     BITMAPINFOHEADER2               vDIBh
; 
 881     BITMAPINFO2                     vDIBInfo
; 
 885     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 886     SIZEL                           vSizlPage 
= {0,0}; 
 887     HDC                             hDCMem 
= NULLHANDLE
; 
 889     vImage
.Create( nWidth
 
 892     pData 
= vImage
.GetData(); 
 895         wxFAIL_MSG( wxT("could not allocate data for image") ); 
 898     if(nLineBoundary 
> 0) 
 900         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 901         nBytePerLine 
+= nPadding
; 
 903     wxDisplaySize( &nDevWidth
 
 907     // Create and fill a DIB header 
 909     memset(&vDIBh
, '\0', 16); 
 914     vDIBh
.cBitCount 
= 24; 
 916     memset(&vDIBInfo
, '\0', 16); 
 918     vDIBInfo
.cx              
= nWidth
; 
 919     vDIBInfo
.cy              
= nHeight
; 
 920     vDIBInfo
.cPlanes         
= 1; 
 921     vDIBInfo
.cBitCount       
= 24; 
 923     lpBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 926         wxFAIL_MSG(wxT("could not allocate data for DIB")); 
 930     memset(lpBits
, '\0', (nBytePerLine 
* nHeight
)); 
 931     hBitmap 
= (HBITMAP
)GetHBITMAP(); 
 934     // May already be selected into a PS 
 936     if ((pDC 
= GetSelectedInto()) != NULL
) 
 938         hPSMem 
= pDC
->GetHPS(); 
 942         hDCMem 
= ::DevOpenDC( vHabmain
 
 949         hPSMem 
= ::GpiCreatePS( vHabmain
 
 952                                ,PU_PELS 
| GPIA_ASSOC
 
 955     if ((hOldBitmap 
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
) 
 960         vError 
= ::WinGetLastError(vHabmain
); 
 961         sError 
= wxPMErrorToStr(vError
); 
 965     // Copy data from the device-dependent bitmap to the DIB 
 967     if ((lScans 
= ::GpiQueryBitmapBits( hPSMem
 
 977         vError 
= ::WinGetLastError(vHabmain
); 
 978         sError 
= wxPMErrorToStr(vError
); 
 982     // Copy DIB data into the wxImage object 
 986     unsigned char*                  ptdata 
= pData
; 
 987     unsigned char*                  ptbits 
= lpBits
; 
 989     for (i 
= 0; i 
< nHeight
; i
++) 
 991         for (j 
= 0; j 
< nWidth
; j
++) 
 993             *(ptdata
++) = *(ptbits
+2); 
 994             *(ptdata
++) = *(ptbits
+1); 
 995             *(ptdata
++) = *(ptbits  
); 
1000     if ((pDC 
= GetSelectedInto()) == NULL
) 
1002         ::GpiSetBitmap(hPSMem
, NULLHANDLE
); 
1003         ::GpiDestroyPS(hPSMem
); 
1004         ::DevCloseDC(hDCMem
); 
1008     // Similarly, set data according to the possible mask bitmap 
1010     if (GetMask() && GetMask()->GetMaskBitmap()) 
1012         hBitmap 
= (HBITMAP
)GetMask()->GetMaskBitmap(); 
1015         // Memory DC/PS created, color set, data copied, and memory DC/PS deleted 
1017         HDC                        hMemDC 
= ::DevOpenDC( vHabmain
 
1021                                                         ,(PDEVOPENDATA
)&vDop
 
1024         HPS                         hMemPS 
= ::GpiCreatePS( vHabmain
 
1027                                                            ,PU_PELS 
| GPIA_ASSOC
 
1029         ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0)); 
1030         ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) ); 
1031         ::GpiSetBitmap(hMemPS
, hBitmap
); 
1032         ::GpiQueryBitmapBits( hPSMem
 
1038         ::GpiSetBitmap(hMemPS
, NULLHANDLE
); 
1039         ::GpiDestroyPS(hMemPS
); 
1040         ::DevCloseDC(hMemDC
); 
1043         // Background color set to RGB(16,16,16) in consistent with wxGTK 
1045         unsigned char               ucRed 
= 16; 
1046         unsigned char               ucGreen 
= 16; 
1047         unsigned char               ucBlue 
= 16; 
1051         for (i 
= 0; i 
< nHeight
; i
++) 
1053             for (j 
= 0; j 
< nWidth
; j
++) 
1059                     *(ptdata
++)  = ucRed
; 
1060                     *(ptdata
++)  = ucGreen
; 
1061                     *(ptdata
++)  = ucBlue
; 
1067         vImage
.SetMaskColour( ucRed
 
1071         vImage
.SetMask(true); 
1075         vImage
.SetMask(false); 
1079     // Free allocated resources 
1083 } // end of wxBitmap::ConvertToImage 
1085 // ---------------------------------------------------------------------------- 
1086 // sub bitmap extraction 
1087 // ---------------------------------------------------------------------------- 
1089 wxBitmap 
wxBitmap::GetSubBitmap( 
1093     wxCHECK_MSG( Ok() && 
1094                  (rRect
.x 
>= 0) && (rRect
.y 
>= 0) && 
1095                  (rRect
.x 
+ rRect
.width 
<= GetWidth()) && 
1096                  (rRect
.y 
+ rRect
.height 
<= GetHeight()), 
1097                  wxNullBitmap
, wxT("Invalid bitmap or bitmap region") ); 
1099     wxBitmap                        
vRet( rRect
.width
 
1103     wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") ); 
1109     SIZEL                           vSize 
= {0, 0}; 
1110     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1111     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1112     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1113     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1114     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1115     POINTL                          vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
}, 
1117                                                   {rRect
.x 
+ rRect
.width
, rRect
.y 
+ rRect
.height
} 
1120     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1121     ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1131     // Copy mask if there is one 
1135         BITMAPINFOHEADER2           vBmih
; 
1137         memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1138         vBmih
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
1139         vBmih
.cx        
= rRect
.width
; 
1140         vBmih
.cy        
= rRect
.height
; 
1142         vBmih
.cBitCount 
= 24; 
1144         HBITMAP                     hBmpMask 
= ::GpiCreateBitmap( hPSDst
 
1151         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1152         ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1154         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap()); 
1155         ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
); 
1164         wxMask
*                     pMask 
= new wxMask((WXHBITMAP
)hBmpMask
); 
1165         vRet
.SetMask(pMask
); 
1168     ::GpiSetBitmap(hPSSrc
, NULL
); 
1169     ::GpiSetBitmap(hPSDst
, NULL
); 
1170     ::GpiDestroyPS(hPSSrc
); 
1171     ::GpiDestroyPS(hPSDst
); 
1172     ::DevCloseDC(hDCSrc
); 
1173     ::DevCloseDC(hDCDst
); 
1175 } // end of wxBitmap::GetSubBitmap 
1177 // ---------------------------------------------------------------------------- 
1178 // wxBitmap accessors 
1179 // ---------------------------------------------------------------------------- 
1181 void wxBitmap::SetQuality( 
1187     GetBitmapData()->m_nQuality 
= nQ
; 
1188 } // end of wxBitmap::SetQuality 
1190 void wxBitmap::SetPalette( 
1191   const wxPalette
&                  rPalette
 
1196     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
1197 } // end of wxBitmap::SetPalette 
1199 void wxBitmap::SetMask( 
1205     GetBitmapData()->m_pBitmapMask 
= pMask
; 
1206 } // end of wxBitmap::SetMask 
1208 wxBitmap 
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const 
1211 } // end of wxBitmap::GetBitmapForDC 
1213 // ---------------------------------------------------------------------------- 
1215 // ---------------------------------------------------------------------------- 
1220 } // end of wxMask::wxMask 
1222 wxMask::wxMask(const wxMask
& tocopy
) 
1224     m_hMaskBitmap 
= wxCopyBmp(tocopy
.m_hMaskBitmap
); 
1225 } // end of wxMask::wxMask 
1227 // Construct a mask from a bitmap and a colour indicating 
1228 // the transparent area 
1230   const wxBitmap
&                   rBitmap
 
1231 , const wxColour
&                   rColour
 
1238 } // end of wxMask::wxMask 
1240 // Construct a mask from a bitmap and a palette index indicating 
1241 // the transparent area 
1243   const wxBitmap
&                   rBitmap
 
1251 } // end of wxMask::wxMask 
1253 // Construct a mask from a mono bitmap (copies the bitmap). 
1255   const wxBitmap
&                   rBitmap
 
1260 } // end of wxMask::wxMask 
1265         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
1266 } // end of wxMask::~wxMask 
1268 // Create a mask from a mono bitmap (copies the bitmap). 
1269 bool wxMask::Create( 
1270   const wxBitmap
&                   rBitmap
 
1273     BITMAPINFOHEADER2               vBmih
; 
1274     SIZEL                           vSize 
= {0, 0}; 
1275     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1276     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1277     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1278     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1279     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1280     POINTL                          vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}, 
1281                                                   {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()} 
1286         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1289     if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1) 
1294     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1295     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1296     vBmih
.cx        
= rBitmap
.GetWidth(); 
1297     vBmih
.cy        
= rBitmap
.GetHeight(); 
1299     vBmih
.cBitCount 
= 24; 
1301     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1308     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1309     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1318     ::GpiDestroyPS(hPSSrc
); 
1319     ::GpiDestroyPS(hPSDst
); 
1320     ::DevCloseDC(hDCSrc
); 
1321     ::DevCloseDC(hDCDst
); 
1323 } // end of wxMask::Create 
1325 // Create a mask from a bitmap and a palette index indicating 
1326 // the transparent area 
1327 bool wxMask::Create( 
1328   const wxBitmap
&                   rBitmap
 
1334         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1337     if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok()) 
1340         unsigned char               cGreen
; 
1341         unsigned char               cBlue
; 
1343         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
1349             wxColour                
vTransparentColour( cRed
 
1354             return (Create( rBitmap
 
1360 } // end of wxMask::Create 
1362 // Create a mask from a bitmap and a colour indicating 
1363 // the transparent area 
1364 bool wxMask::Create( 
1365   const wxBitmap
&                   rBitmap
 
1366 , const wxColour
&                   rColour
 
1370     COLORREF                        vMaskColour 
= OS2RGB( rColour
.Red() 
1374     BITMAPINFOHEADER2               vBmih
; 
1375     SIZEL                           vSize 
= {0, 0}; 
1376     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
1377     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1378     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1379     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1380     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1384         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1393     // Scan the bitmap for the transparent colour and set 
1394     // the corresponding pixels in the mask to BLACK and 
1395     // the rest to WHITE 
1398     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1399     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1400     vBmih
.cx        
= rBitmap
.GetWidth(); 
1401     vBmih
.cy        
= rBitmap
.GetHeight(); 
1403     vBmih
.cBitCount 
= 1; 
1405     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1412     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1413     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1416     // This is not very efficient, but I can't think 
1417     // of a better way of doing it 
1419     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
1421         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
1423             POINTL                  vPt 
= {w
, h
}; 
1424             COLORREF                vCol 
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
); 
1425             if (vCol 
== (COLORREF
)CLR_NOINDEX
) 
1428                 // Doesn't make sense to continue 
1434             if (vCol 
== vMaskColour
) 
1436                 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0)); 
1437                 ::GpiSetPel(hPSDst
, &vPt
); 
1441                 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255)); 
1442                 ::GpiSetPel(hPSDst
, &vPt
); 
1446     ::GpiSetBitmap(hPSSrc
, NULL
); 
1447     ::GpiSetBitmap(hPSDst
, NULL
); 
1448     ::GpiDestroyPS(hPSSrc
); 
1449     ::GpiDestroyPS(hPSDst
); 
1450     ::DevCloseDC(hDCSrc
); 
1451     ::DevCloseDC(hDCDst
); 
1453 } // end of wxMask::Create 
1455 // ---------------------------------------------------------------------------- 
1457 // ---------------------------------------------------------------------------- 
1459 bool wxBitmapHandler::Create( wxGDIImage
* pImage
, 
1461                               long        WXUNUSED(lFlags
), 
1466     wxBitmap
* pBitmap 
= wxDynamicCast( pImage
 
1470     return(pBitmap 
? Create( pBitmap
 
1478 bool wxBitmapHandler::Load( 
1486     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1490     return(pBitmap 
? LoadFile( pBitmap
 
1498 bool wxBitmapHandler::Save( 
1500 , const wxString
&                   rName
 
1504     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1508     return(pBitmap 
? SaveFile( pBitmap
 
1514 bool wxBitmapHandler::Create( 
1515   wxBitmap
*                         WXUNUSED(pBitmap
) 
1516 , const void*                       WXUNUSED(pData
) 
1517 , long                              WXUNUSED(lType
) 
1518 , int                               WXUNUSED(nWidth
) 
1519 , int                               WXUNUSED(nHeight
) 
1520 , int                               WXUNUSED(nDepth
) 
1526 bool wxBitmapHandler::LoadFile( 
1527   wxBitmap
*                         WXUNUSED(pBitmap
) 
1529 , long                              WXUNUSED(lType
) 
1530 , int                               WXUNUSED(nDesiredWidth
) 
1531 , int                               WXUNUSED(nDesiredHeight
) 
1537 bool wxBitmapHandler::LoadFile( 
1538   wxBitmap
*                         WXUNUSED(pBitmap
) 
1539 , const wxString
&                   WXUNUSED(rName
) 
1540 , long                              WXUNUSED(lType
) 
1541 , int                               WXUNUSED(nDesiredWidth
) 
1542 , int                               WXUNUSED(nDesiredHeight
) 
1548 bool wxBitmapHandler::SaveFile( 
1549   wxBitmap
*                         WXUNUSED(pBitmap
) 
1550 , const wxString
&                   WXUNUSED(rName
) 
1551 , int                               WXUNUSED(nType
) 
1552 , const wxPalette
*                  WXUNUSED(pPalette
) 
1558 // ---------------------------------------------------------------------------- 
1559 // Utility functions 
1560 // ---------------------------------------------------------------------------- 
1561 HBITMAP 
wxInvertMask( 
1567     HBITMAP                         hBmpInvMask 
= 0; 
1569     wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") ); 
1572     // Get width/height from the bitmap if not given 
1574     if (!nWidth 
|| !nHeight
) 
1576         BITMAPINFOHEADER2           vBmhdr
; 
1578         ::GpiQueryBitmapInfoHeader( hBmpMask
 
1581         nWidth  
= (int)vBmhdr
.cx
; 
1582         nHeight 
= (int)vBmhdr
.cy
; 
1585     BITMAPINFOHEADER2               vBmih
; 
1586     SIZEL                           vSize 
= {0, 0}; 
1587     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1588     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1589     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1590     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1591     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1592     POINTL                          vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
}, 
1593                                                   {0, 0}, {nWidth
, nHeight
} 
1596     memset(&vBmih
, '\0', 16); 
1601     vBmih
.cBitCount 
= 24; 
1603     hBmpInvMask 
= ::GpiCreateBitmap( hPSDst
 
1610     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
); 
1611     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
); 
1621     ::GpiDestroyPS(hPSSrc
); 
1622     ::GpiDestroyPS(hPSDst
); 
1623     ::DevCloseDC(hDCSrc
); 
1624     ::DevCloseDC(hDCDst
); 
1627 } // end of WxWinGdi_InvertMask 
1629 HBITMAP 
wxCopyBmp( HBITMAP hBmp
, bool flip
, int nWidth
, int nHeight 
) 
1631     wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxCopyBmp") ); 
1634     // Get width/height from the bitmap if not given 
1636     if (!nWidth 
|| !nHeight
) 
1638         BITMAPINFOHEADER2 vBmhdr
; 
1641         ::GpiQueryBitmapInfoHeader( hBmp
, 
1643         nWidth        
= (int)vBmhdr
.cx
; 
1644         nHeight       
= (int)vBmhdr
.cy
; 
1647     BITMAPINFOHEADER2 vBmih
; 
1648     SIZEL             vSize     
= {0, 0}; 
1649     DEVOPENSTRUC      vDop      
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1650     HDC               hDCSrc    
= ::DevOpenDC(  vHabmain
, 
1654                                                 (PDEVOPENDATA
)&vDop
, 
1656     HDC               hDCDst    
= ::DevOpenDC(  vHabmain
, 
1660                                                 (PDEVOPENDATA
)&vDop
, 
1662     HPS               hPSSrc    
= ::GpiCreatePS(  vHabmain
, 
1665                                                   PU_PELS 
| GPIA_ASSOC  
); 
1666     HPS               hPSDst    
= ::GpiCreatePS(  vHabmain
, 
1669                                                   PU_PELS 
| GPIA_ASSOC  
); 
1670     POINTL            vPoint
[4] = { {0,      nHeight
}, 
1673                                     {nWidth
, nHeight
} }; 
1677         vPoint
[1].y 
= nHeight
; 
1679     memset(&vBmih
, '\0', 16); 
1684     vBmih
.cBitCount 
= 24; 
1686     HBITMAP hInvBmp 
= ::GpiCreateBitmap(  hPSDst
, 
1692     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
); 
1693     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
); 
1695     ::GpiBitBlt(  hPSDst
, 
1702     ::GpiDestroyPS(hPSSrc
); 
1703     ::GpiDestroyPS(hPSDst
); 
1704     ::DevCloseDC(hDCSrc
); 
1705     ::DevCloseDC(hDCDst
); 
1708 } // end of wxFlipBmp