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 void wxBitmapRefData::Free() 
  62     if ( m_pSelectedInto 
) 
  64         wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  68         if (!::GpiDeleteBitmap((HBITMAP
)m_hBitmap
)) 
  70             wxLogLastError(wxT("GpiDeleteBitmap(hbitmap)")); 
  78 } // end of wxBitmapRefData::Free 
  80 // ---------------------------------------------------------------------------- 
  82 // ---------------------------------------------------------------------------- 
  84 // this function should be called from all wxBitmap ctors 
  89     // True for all bitmaps created from bits, wxImages, Xpms 
  91 } // end of wxBitmap::Init 
  93 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage
& rIcon
) 
  95     HPOINTER                        hIcon 
= (HPOINTER
)rIcon
.GetHandle(); 
  96     POINTERINFO                     SIconInfo
; 
  98     if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
)) 
 100         wxLogLastError(wxT("WinQueryPointerInfo")); 
 103     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 105     m_refData 
= pRefData
; 
 107     int                             nWidth 
= rIcon
.GetWidth(); 
 108     int                             nHeight 
= rIcon
.GetHeight(); 
 110     pRefData
->m_nWidth  
= nWidth
; 
 111     pRefData
->m_nHeight 
= nHeight
; 
 112     pRefData
->m_nDepth  
= wxDisplayDepth(); 
 114     pRefData
->m_hBitmap 
= (WXHBITMAP
)SIconInfo
.hbmColor
; 
 116     wxMask
*                         pMask 
= new wxMask(SIconInfo
.hbmPointer
); 
 118     pMask
->SetMaskBitmap(GetHBITMAP()); 
 122 } // end of wxBitmap::CopyFromIconOrCursor 
 124 bool wxBitmap::CopyFromCursor( 
 125   const wxCursor
&                   rCursor
 
 132     return(CopyFromIconOrCursor(rCursor
)); 
 133 } // end of wxBitmap::CopyFromCursor 
 135 bool wxBitmap::CopyFromIcon( 
 144     return CopyFromIconOrCursor(rIcon
); 
 145 } // end of wxBitmap::CopyFromIcon 
 147 wxBitmap::~wxBitmap() 
 149 } // end of wxBitmap::~wxBitmap 
 160     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 161     BITMAPINFOHEADER2               vHeader
; 
 165     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 166     SIZEL                           vSize 
= {0, 0}; 
 169     wxASSERT(vHabmain 
!= NULL
); 
 171     m_refData 
= pRefData
; 
 173     pRefData
->m_nWidth        
= nWidth
; 
 174     pRefData
->m_nHeight       
= nHeight
; 
 175     pRefData
->m_nDepth        
= nDepth
; 
 176     pRefData
->m_nNumColors    
= 0; 
 177     pRefData
->m_pSelectedInto 
= NULL
; 
 179     hDc   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 180     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 183         wxLogLastError(wxT("GpiCreatePS Failure")); 
 189         // We assume that it is in XBM format which is not quite the same as 
 190         // the format CreateBitmap() wants because the order of bytes in the 
 193         const size_t                nBytesPerLine 
= (nWidth 
+ 7) / 8; 
 194         const size_t                nPadding 
= nBytesPerLine 
% 2; 
 195         const size_t                nLen 
= nHeight 
* (nPadding 
+ nBytesPerLine
); 
 196         const char*                 pzSrc 
= zBits
; 
 200         pzData 
= (char *)malloc(nLen
); 
 202         char*                       pzDst 
= pzData
; 
 204         for (nRows 
= 0; nRows 
< nHeight
; nRows
++) 
 206             for (nCols 
= 0; nCols 
< nBytesPerLine
; nCols
++) 
 208                 unsigned char ucVal 
= *pzSrc
++; 
 209                 unsigned char ucReversed 
= 0; 
 212                 for (nBits 
= 0; nBits 
< 8; nBits
++) 
 215                     ucReversed 
= (unsigned char)(ucReversed 
| (ucVal 
& 0x01)); 
 218                 *pzDst
++ = ucReversed
; 
 227         // Bits should already be in Windows standard format 
 229         pzData 
= (char *)zBits
;    // const_cast is harmless 
 233         nDepth 
= 24; // MAX supported in PM 
 234     memset(&vHeader
, '\0', 16); 
 236     vHeader
.cx              
= (USHORT
)nWidth
; 
 237     vHeader
.cy              
= (USHORT
)nHeight
; 
 238     vHeader
.cPlanes         
= 1L; 
 239     vHeader
.cBitCount       
= (USHORT
)nDepth
; 
 240     vHeader
.usReserved      
= 0; 
 242     memset(&vInfo
, '\0', 16); 
 244     vInfo
.cx              
= (USHORT
)nWidth
; 
 245     vInfo
.cy              
= (USHORT
)nHeight
; 
 247     vInfo
.cBitCount       
= (USHORT
)nDepth
; 
 249     HBITMAP                         hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, CBM_INIT
, (PBYTE
)pzData
, &vInfo
); 
 253         wxLogLastError(wxT("CreateBitmap")); 
 257     SetHBITMAP((WXHBITMAP
)hBmp
); 
 258 } // end of wxBitmap::wxBitmap 
 271 } // end of wxBitmap::wxBitmap 
 289 } // end of wxBitmap::wxBitmap 
 301 } // end of wxBitmap::wxBitmap 
 303 bool wxBitmap::Create( 
 310     BITMAPINFOHEADER2               vHeader
; 
 312     wxASSERT(vHabmain 
!= NULL
); 
 314     m_refData 
= new wxBitmapRefData
; 
 315     GetBitmapData()->m_nWidth 
= nW
; 
 316     GetBitmapData()->m_nHeight 
= nH
; 
 317     GetBitmapData()->m_nDepth 
= nD
; 
 320     // Xpms and bitmaps from other images can also be mono's, but only 
 321     // mono's need help changing their colors with MemDC changes 
 325         DEVOPENSTRUC                vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 326         SIZEL                       vSize 
= {0, 0}; 
 327         HDC                         hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 328         HPS                         hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 332         memset(&vHeader
, '\0', 16); 
 337         vHeader
.cBitCount 
= 24; //nD; 
 339         hBmp 
= ::GpiCreateBitmap( hPS
 
 354         hPSScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 355         hDCScreen 
= ::GpiQueryDevice(hPSScreen
); 
 356         ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 361         memset(&vHeader
, '\0', 16); 
 366         vHeader
.cBitCount 
= (USHORT
)lBitCount
; 
 368         hBmp 
= ::GpiCreateBitmap( hPSScreen
 
 375         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 376         ::WinReleasePS(hPSScreen
); 
 378     SetHBITMAP((WXHBITMAP
)hBmp
); 
 381 } // end of wxBitmap::Create 
 383 bool wxBitmap::CreateFromXpm( 
 387 #if wxUSE_IMAGE && wxUSE_XPM 
 390     wxCHECK_MSG(ppData 
!= NULL
, false, wxT("invalid bitmap data")); 
 392     wxXPMDecoder                    vDecoder
; 
 393     wxImage                         vImg 
= vDecoder
.ReadData(ppData
); 
 395     wxCHECK_MSG(vImg
.Ok(), false, wxT("invalid bitmap data")); 
 397     *this = wxBitmap(vImg
); 
 402 } // end of wxBitmap::CreateFromXpm 
 404 bool wxBitmap::LoadFile(const wxString
& filename
, long type
) 
 408     wxBitmapHandler 
*handler 
= wxDynamicCast(FindHandler(type
), wxBitmapHandler
); 
 412         m_refData 
= new wxBitmapRefData
; 
 414         return handler
->LoadFile(this, filename
, type
, -1, -1); 
 417     else // no bitmap handler found 
 420         if ( image
.LoadFile( filename
, type 
) && image
.Ok() ) 
 422             *this = wxBitmap(image
); 
 427 #endif // wxUSE_IMAGE 
 432 bool wxBitmap::LoadFile( 
 439     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 445         m_refData 
= new wxBitmapRefData
; 
 447         return(pHandler
->LoadFile( this 
 458 } // end of wxBitmap::LoadFile 
 460 bool wxBitmap::Create( 
 470     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 476         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType
); 
 481     m_refData 
= new wxBitmapRefData
; 
 483     return(pHandler
->Create( this 
 490 } // end of wxBitmap::Create 
 492 bool wxBitmap::SaveFile( 
 493   const wxString
&                   rFilename
 
 495 , const wxPalette
*                  pPalette
 
 498     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 504         return pHandler
->SaveFile( this 
 512         // FIXME what about palette? shouldn't we use it? 
 513         wxImage                     vImage 
= ConvertToImage(); 
 518         return(vImage
.SaveFile( rFilename
 
 522 } // end of wxBitmap::SaveFile 
 525 // ---------------------------------------------------------------------------- 
 526 // wxImage-wxBitmap conversion 
 527 // ---------------------------------------------------------------------------- 
 529 bool wxBitmap::CreateFromImage ( 
 530   const wxImage
&                    rImage
 
 534     wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image")); 
 535     m_refData 
= new wxBitmapRefData(); 
 537     int                             nSizeLimit 
= 1024 * 768 * 3; 
 538     int                             nWidth 
= rImage
.GetWidth(); 
 539     int                             nBmpHeight 
= rImage
.GetHeight(); 
 540     int                             nBytePerLine 
= nWidth 
* 3; 
 541     int                             nSizeDWORD 
= sizeof(DWORD
); 
 542     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 545     if (nLineBoundary 
> 0) 
 547         nPadding 
= nSizeDWORD 
- nLineBoundary
; 
 548         nBytePerLine 
+= nPadding
; 
 552     // Calc the number of DIBs and heights of DIBs 
 556     int                             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 558     if (nHeight 
>= nBmpHeight
) 
 559         nHeight 
= nBmpHeight
; 
 562         nNumDIB  
= nBmpHeight 
/ nHeight
; 
 563         nHRemain 
= nBmpHeight 
% nHeight
; 
 569     // Set bitmap parameters 
 571     wxCHECK_MSG(rImage
.Ok(), false, wxT("invalid image")); 
 573     SetHeight(nBmpHeight
); 
 579         nDepth 
= wxDisplayDepth(); 
 584     // Copy the palette from the source image 
 586     SetPalette(rImage
.GetPalette()); 
 587 #endif // wxUSE_PALETTE 
 590     // Create a DIB header 
 592     BITMAPINFOHEADER2               vHeader
; 
 596     // Fill in the DIB header 
 598     memset(&vHeader
, '\0', 16); 
 600     vHeader
.cx              
= (ULONG
)nWidth
; 
 601     vHeader
.cy              
= (ULONG
)nHeight
; 
 602     vHeader
.cPlanes         
= 1L; 
 603     vHeader
.cBitCount       
= 24; 
 606     // Memory for DIB data 
 608     unsigned char*                  pucBits
; 
 610     pucBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 613         wxFAIL_MSG(wxT("could not allocate memory for DIB")); 
 616     memset(pucBits
, '\0', (nBytePerLine 
* nHeight
)); 
 619     // Create and set the device-dependent bitmap 
 621     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 622     SIZEL                           vSize 
= {0, 0}; 
 623     HDC                             hDC   
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 624     HPS                             hPS   
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
 626     HDC                             hDCScreen 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
 631     memset(&vInfo
, '\0', 16); 
 633     vInfo
.cx              
= (ULONG
)nWidth
; 
 634     vInfo
.cy              
= (ULONG
)nHeight
; 
 636     vInfo
.cBitCount       
= 24; // Set to desired count going in 
 638     hBmp 
= ::GpiCreateBitmap( hPS
 
 645     HPAL                            hOldPalette 
= NULLHANDLE
; 
 646     if (rImage
.GetPalette().Ok()) 
 648         hOldPalette 
= ::GpiSelectPalette(hPS
, (HPAL
)rImage
.GetPalette().GetHPALETTE()); 
 650 #endif // wxUSE_PALETTE 
 653     // Copy image data into DIB data and then into DDB (in a loop) 
 655     unsigned char*                  pData 
= rImage
.GetData(); 
 660     unsigned char*                  ptdata 
= pData
; 
 661     unsigned char*                  ptbits
; 
 663     if ((hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
)) == HBM_ERROR
) 
 668         vError 
= ::WinGetLastError(vHabmain
); 
 669         sError 
= wxPMErrorToStr(vError
); 
 671     for (n 
= 0; n 
< nNumDIB
; n
++) 
 673         if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 676             // Redefine height and size of the (possibly) last smaller DIB 
 677             // memory is not reallocated 
 680             vHeader
.cy      
= (DWORD
)(nHeight
); 
 681             vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 684         for (j 
= 0; j 
< nHeight
; j
++) 
 686             for (i 
= 0; i 
< nWidth
; i
++) 
 688                 *(ptbits
++) = *(ptdata 
+ 2); 
 689                 *(ptbits
++) = *(ptdata 
+ 1); 
 690                 *(ptbits
++) = *(ptdata
); 
 693             for (i 
= 0; i 
< nPadding
; i
++) 
 698         // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt 
 699         // in combination with setting the bits into the selected bitmap 
 701         if ((lScans 
= ::GpiSetBitmapBits( hPS
 
 702                                          ,0             // Start at the bottom 
 703                                          ,(LONG
)nHeight 
// One line per scan 
 711             vError 
= ::WinGetLastError(vHabmain
); 
 712             sError 
= wxPMErrorToStr(vError
); 
 714         hPSScreen 
= ::GpiCreatePS( vHabmain
 
 717                                   ,PU_PELS 
| GPIA_ASSOC
 
 720         POINTL                      vPoint
[4] = { {0, nOrigin
}, 
 722                                                   {0, 0}, {nWidth
, nHeight
} 
 726         ::GpiBitBlt( hPSScreen
 
 733         ::GpiDestroyPS(hPSScreen
); 
 736     SetHBITMAP((WXHBITMAP
)hBmp
); 
 739         ::GpiSelectPalette(hPS
, hOldPalette
); 
 740 #endif // wxUSE_PALETTE 
 743     // Similarly, created an mono-bitmap for the possible mask 
 745     if (rImage
.HasMask()) 
 749         vHeader
.cy        
= nHeight
; 
 751         vHeader
.cBitCount 
= 24; 
 752         hBmp 
= ::GpiCreateBitmap( hPS
 
 758         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmp
); 
 760             nHeight 
= nBmpHeight
; 
 762             nHeight 
= nSizeLimit 
/ nBytePerLine
; 
 763         vHeader
.cy 
= (DWORD
)(nHeight
); 
 766         unsigned char               cRed   
= rImage
.GetMaskRed(); 
 767         unsigned char               cGreen 
= rImage
.GetMaskGreen(); 
 768         unsigned char               cBlue  
= rImage
.GetMaskBlue(); 
 769         unsigned char               cZero 
= 0; 
 770         unsigned char               cOne 
= 255; 
 773         for (n 
= 0; n 
< nNumDIB
; n
++) 
 775             if (nNumDIB 
> 1 && n 
== nNumDIB 
- 1 && nHRemain 
> 0) 
 778                 // Redefine height and size of the (possibly) last smaller DIB 
 779                 // memory is not reallocated 
 782                 vHeader
.cy      
= (DWORD
)(nHeight
); 
 783                 vHeader
.cbImage 
= nBytePerLine 
* nHeight
; 
 786             for (int j 
= 0; j 
< nHeight
; j
++) 
 788                 for (i 
= 0; i 
< nWidth
; i
++) 
 790                     unsigned char cRedImage   
= (*(ptdata
++)) ; 
 791                     unsigned char cGreenImage 
= (*(ptdata
++)) ; 
 792                     unsigned char cBlueImage  
= (*(ptdata
++)) ; 
 794                     if ((cRedImage 
!= cRed
) || (cGreenImage 
!= cGreen
) || (cBlueImage 
!= cBlue
)) 
 807                 for (i 
= 0; i 
< nPadding
; i
++) 
 810             lScans 
= ::GpiSetBitmapBits( hPS
 
 811                                         ,0              // Start at the bottom 
 812                                         ,(LONG
)nHeight 
// One line per scan 
 816             hPSScreen 
= ::GpiCreatePS( vHabmain
 
 819                                       ,PU_PELS 
| GPIA_ASSOC
 
 821             POINTL vPoint2
[4] = { {0, nOrigin
}, 
 823                                   {0, 0}, {nWidth
, nHeight
} 
 825             ::GpiBitBlt( hPSScreen
 
 832             ::GpiDestroyPS(hPSScreen
); 
 837         // Create a wxMask object 
 839         wxMask
*                     pMask 
= new wxMask(); 
 841         pMask
->SetMaskBitmap((WXHBITMAP
)hBmp
); 
 843         hBmpOld 
= ::GpiSetBitmap(hPS
, hBmpOld
); 
 847     // Free allocated resources 
 849     ::GpiSetBitmap(hPS
, NULLHANDLE
); 
 851     ::DevCloseDC(hDCScreen
); 
 855 } // end of wxBitmap::CreateFromImage 
 857 wxImage 
wxBitmap::ConvertToImage() const 
 862     wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") ); 
 865     // Create an wxImage object 
 867     int                             nWidth        
= GetWidth(); 
 868     int                             nHeight       
= GetHeight(); 
 871     int                             nBytePerLine  
= nWidth 
* 3; 
 872     int                             nSizeDWORD    
= sizeof(DWORD
); 
 873     int                             nLineBoundary 
= nBytePerLine 
% nSizeDWORD
; 
 875     unsigned char*                  pData
; 
 876     unsigned char*                  lpBits
; 
 878     BITMAPINFOHEADER2               vDIBh
; 
 879     BITMAPINFO2                     vDIBInfo
; 
 883     DEVOPENSTRUC                    vDop  
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 884     SIZEL                           vSizlPage 
= {0,0}; 
 885     HDC                             hDCMem 
= NULLHANDLE
; 
 887     vImage
.Create( nWidth
 
 890     pData 
= vImage
.GetData(); 
 893         wxFAIL_MSG( wxT("could not allocate data for image") ); 
 896     if(nLineBoundary 
> 0) 
 898         nPadding     
= nSizeDWORD 
- nLineBoundary
; 
 899         nBytePerLine 
+= nPadding
; 
 901     wxDisplaySize( &nDevWidth
 
 905     // Create and fill a DIB header 
 907     memset(&vDIBh
, '\0', 16); 
 912     vDIBh
.cBitCount 
= 24; 
 914     memset(&vDIBInfo
, '\0', 16); 
 916     vDIBInfo
.cx              
= nWidth
; 
 917     vDIBInfo
.cy              
= nHeight
; 
 918     vDIBInfo
.cPlanes         
= 1; 
 919     vDIBInfo
.cBitCount       
= 24; 
 921     lpBits 
= (unsigned char *)malloc(nBytePerLine 
* nHeight
); 
 924         wxFAIL_MSG(wxT("could not allocate data for DIB")); 
 928     memset(lpBits
, '\0', (nBytePerLine 
* nHeight
)); 
 929     hBitmap 
= (HBITMAP
)GetHBITMAP(); 
 932     // May already be selected into a PS 
 934     if ((pDC 
= GetSelectedInto()) != NULL
) 
 936         hPSMem 
= pDC
->GetHPS(); 
 940         hDCMem 
= ::DevOpenDC( vHabmain
 
 947         hPSMem 
= ::GpiCreatePS( vHabmain
 
 950                                ,PU_PELS 
| GPIA_ASSOC
 
 953     if ((hOldBitmap 
= ::GpiSetBitmap(hPSMem
, hBitmap
)) == HBM_ERROR
) 
 958         vError 
= ::WinGetLastError(vHabmain
); 
 959         sError 
= wxPMErrorToStr(vError
); 
 963     // Copy data from the device-dependent bitmap to the DIB 
 965     if ((lScans 
= ::GpiQueryBitmapBits( hPSMem
 
 975         vError 
= ::WinGetLastError(vHabmain
); 
 976         sError 
= wxPMErrorToStr(vError
); 
 980     // Copy DIB data into the wxImage object 
 984     unsigned char*                  ptdata 
= pData
; 
 985     unsigned char*                  ptbits 
= lpBits
; 
 987     for (i 
= 0; i 
< nHeight
; i
++) 
 989         for (j 
= 0; j 
< nWidth
; j
++) 
 991             *(ptdata
++) = *(ptbits
+2); 
 992             *(ptdata
++) = *(ptbits
+1); 
 993             *(ptdata
++) = *(ptbits  
); 
 998     if ((pDC 
= GetSelectedInto()) == NULL
) 
1000         ::GpiSetBitmap(hPSMem
, NULLHANDLE
); 
1001         ::GpiDestroyPS(hPSMem
); 
1002         ::DevCloseDC(hDCMem
); 
1006     // Similarly, set data according to the possible mask bitmap 
1008     if (GetMask() && GetMask()->GetMaskBitmap()) 
1010         hBitmap 
= (HBITMAP
)GetMask()->GetMaskBitmap(); 
1013         // Memory DC/PS created, color set, data copied, and memory DC/PS deleted 
1015         HDC                        hMemDC 
= ::DevOpenDC( vHabmain
 
1019                                                         ,(PDEVOPENDATA
)&vDop
 
1022         HPS                         hMemPS 
= ::GpiCreatePS( vHabmain
 
1025                                                            ,PU_PELS 
| GPIA_ASSOC
 
1027         ::GpiSetColor(hMemPS
, OS2RGB(0, 0, 0)); 
1028         ::GpiSetBackColor(hMemPS
, OS2RGB(255, 255, 255) ); 
1029         ::GpiSetBitmap(hMemPS
, hBitmap
); 
1030         ::GpiQueryBitmapBits( hPSMem
 
1036         ::GpiSetBitmap(hMemPS
, NULLHANDLE
); 
1037         ::GpiDestroyPS(hMemPS
); 
1038         ::DevCloseDC(hMemDC
); 
1041         // Background color set to RGB(16,16,16) in consistent with wxGTK 
1043         unsigned char               ucRed 
= 16; 
1044         unsigned char               ucGreen 
= 16; 
1045         unsigned char               ucBlue 
= 16; 
1049         for (i 
= 0; i 
< nHeight
; i
++) 
1051             for (j 
= 0; j 
< nWidth
; j
++) 
1057                     *(ptdata
++)  = ucRed
; 
1058                     *(ptdata
++)  = ucGreen
; 
1059                     *(ptdata
++)  = ucBlue
; 
1065         vImage
.SetMaskColour( ucRed
 
1069         vImage
.SetMask(true); 
1073         vImage
.SetMask(false); 
1077     // Free allocated resources 
1081 } // end of wxBitmap::ConvertToImage 
1083 // ---------------------------------------------------------------------------- 
1084 // sub bitmap extraction 
1085 // ---------------------------------------------------------------------------- 
1087 wxBitmap 
wxBitmap::GetSubBitmap( 
1091     wxCHECK_MSG( Ok() && 
1092                  (rRect
.x 
>= 0) && (rRect
.y 
>= 0) && 
1093                  (rRect
.x 
+ rRect
.width 
<= GetWidth()) && 
1094                  (rRect
.y 
+ rRect
.height 
<= GetHeight()), 
1095                  wxNullBitmap
, wxT("Invalid bitmap or bitmap region") ); 
1097     wxBitmap                        
vRet( rRect
.width
 
1101     wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") ); 
1107     SIZEL                           vSize 
= {0, 0}; 
1108     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1109     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1110     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1111     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1112     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1113     POINTL                          vPoint
[4] = { {0, 0}, {rRect
.width
, rRect
.height
}, 
1115                                                   {rRect
.x 
+ rRect
.width
, rRect
.y 
+ rRect
.height
} 
1118     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1119     ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1129     // Copy mask if there is one 
1133         BITMAPINFOHEADER2           vBmih
; 
1135         memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1136         vBmih
.cbFix     
= sizeof(BITMAPINFOHEADER2
); 
1137         vBmih
.cx        
= rRect
.width
; 
1138         vBmih
.cy        
= rRect
.height
; 
1140         vBmih
.cBitCount 
= 24; 
1142         HBITMAP                     hBmpMask 
= ::GpiCreateBitmap( hPSDst
 
1149         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP()); 
1150         ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP()); 
1152         ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap()); 
1153         ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
); 
1162         wxMask
*                     pMask 
= new wxMask((WXHBITMAP
)hBmpMask
); 
1163         vRet
.SetMask(pMask
); 
1166     ::GpiSetBitmap(hPSSrc
, NULL
); 
1167     ::GpiSetBitmap(hPSDst
, NULL
); 
1168     ::GpiDestroyPS(hPSSrc
); 
1169     ::GpiDestroyPS(hPSDst
); 
1170     ::DevCloseDC(hDCSrc
); 
1171     ::DevCloseDC(hDCDst
); 
1173 } // end of wxBitmap::GetSubBitmap 
1175 // ---------------------------------------------------------------------------- 
1176 // wxBitmap accessors 
1177 // ---------------------------------------------------------------------------- 
1179 void wxBitmap::SetQuality( 
1185     GetBitmapData()->m_nQuality 
= nQ
; 
1186 } // end of wxBitmap::SetQuality 
1188 void wxBitmap::SetPalette( 
1189   const wxPalette
&                  rPalette
 
1194     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
1195 } // end of wxBitmap::SetPalette 
1197 void wxBitmap::SetMask( 
1203     GetBitmapData()->m_pBitmapMask 
= pMask
; 
1204 } // end of wxBitmap::SetMask 
1206 wxBitmap 
wxBitmap::GetBitmapForDC(wxDC
& WXUNUSED(rDc
)) const 
1209 } // end of wxBitmap::GetBitmapForDC 
1211 // ---------------------------------------------------------------------------- 
1213 // ---------------------------------------------------------------------------- 
1218 } // end of wxMask::wxMask 
1220 // Construct a mask from a bitmap and a colour indicating 
1221 // the transparent area 
1223   const wxBitmap
&                   rBitmap
 
1224 , const wxColour
&                   rColour
 
1231 } // end of wxMask::wxMask 
1233 // Construct a mask from a bitmap and a palette index indicating 
1234 // the transparent area 
1236   const wxBitmap
&                   rBitmap
 
1244 } // end of wxMask::wxMask 
1246 // Construct a mask from a mono bitmap (copies the bitmap). 
1248   const wxBitmap
&                   rBitmap
 
1253 } // end of wxMask::wxMask 
1258         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
1259 } // end of wxMask::~wxMask 
1261 // Create a mask from a mono bitmap (copies the bitmap). 
1262 bool wxMask::Create( 
1263   const wxBitmap
&                   rBitmap
 
1266     BITMAPINFOHEADER2               vBmih
; 
1267     SIZEL                           vSize 
= {0, 0}; 
1268     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1269     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1270     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1271     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1272     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1273     POINTL                          vPoint
[4] = { {0 ,0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()}, 
1274                                                   {0, 0}, {rBitmap
.GetWidth(), rBitmap
.GetHeight()} 
1279         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1282     if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1) 
1287     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1288     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1289     vBmih
.cx        
= rBitmap
.GetWidth(); 
1290     vBmih
.cy        
= rBitmap
.GetHeight(); 
1292     vBmih
.cBitCount 
= 24; 
1294     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1301     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1302     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1311     ::GpiDestroyPS(hPSSrc
); 
1312     ::GpiDestroyPS(hPSDst
); 
1313     ::DevCloseDC(hDCSrc
); 
1314     ::DevCloseDC(hDCDst
); 
1316 } // end of wxMask::Create 
1318 // Create a mask from a bitmap and a palette index indicating 
1319 // the transparent area 
1320 bool wxMask::Create( 
1321   const wxBitmap
&                   rBitmap
 
1327         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1330     if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok()) 
1333         unsigned char               cGreen
; 
1334         unsigned char               cBlue
; 
1336         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
1342             wxColour                
vTransparentColour( cRed
 
1347             return (Create( rBitmap
 
1353 } // end of wxMask::Create 
1355 // Create a mask from a bitmap and a colour indicating 
1356 // the transparent area 
1357 bool wxMask::Create( 
1358   const wxBitmap
&                   rBitmap
 
1359 , const wxColour
&                   rColour
 
1363     COLORREF                        vMaskColour 
= OS2RGB( rColour
.Red() 
1367     BITMAPINFOHEADER2               vBmih
; 
1368     SIZEL                           vSize 
= {0, 0}; 
1369     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
1370     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1371     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1372     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1373     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1377         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
1386     // Scan the bitmap for the transparent colour and set 
1387     // the corresponding pixels in the mask to BLACK and 
1388     // the rest to WHITE 
1391     memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
)); 
1392     vBmih
.cbFix     
=  sizeof(BITMAPINFOHEADER2
); 
1393     vBmih
.cx        
= rBitmap
.GetWidth(); 
1394     vBmih
.cy        
= rBitmap
.GetHeight(); 
1396     vBmih
.cBitCount 
= 1; 
1398     m_hMaskBitmap 
= ::GpiCreateBitmap( hPSDst
 
1405     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP()); 
1406     ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
); 
1409     // This is not very efficient, but I can't think 
1410     // of a better way of doing it 
1412     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
1414         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
1416             POINTL                  vPt 
= {w
, h
}; 
1417             COLORREF                vCol 
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
); 
1418             if (vCol 
== (COLORREF
)CLR_NOINDEX
) 
1421                 // Doesn't make sense to continue 
1427             if (vCol 
== vMaskColour
) 
1429                 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0)); 
1430                 ::GpiSetPel(hPSDst
, &vPt
); 
1434                 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255)); 
1435                 ::GpiSetPel(hPSDst
, &vPt
); 
1439     ::GpiSetBitmap(hPSSrc
, NULL
); 
1440     ::GpiSetBitmap(hPSDst
, NULL
); 
1441     ::GpiDestroyPS(hPSSrc
); 
1442     ::GpiDestroyPS(hPSDst
); 
1443     ::DevCloseDC(hDCSrc
); 
1444     ::DevCloseDC(hDCDst
); 
1446 } // end of wxMask::Create 
1448 // ---------------------------------------------------------------------------- 
1450 // ---------------------------------------------------------------------------- 
1452 bool wxBitmapHandler::Create( wxGDIImage
* pImage
, 
1454                               long        WXUNUSED(lFlags
), 
1459     wxBitmap
* pBitmap 
= wxDynamicCast( pImage
 
1463     return(pBitmap 
? Create( pBitmap
 
1471 bool wxBitmapHandler::Load( 
1479     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1483     return(pBitmap 
? LoadFile( pBitmap
 
1491 bool wxBitmapHandler::Save( 
1493 , const wxString
&                   rName
 
1497     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
1501     return(pBitmap 
? SaveFile( pBitmap
 
1507 bool wxBitmapHandler::Create( 
1508   wxBitmap
*                         WXUNUSED(pBitmap
) 
1509 , void*                             WXUNUSED(pData
) 
1510 , long                              WXUNUSED(lType
) 
1511 , int                               WXUNUSED(nWidth
) 
1512 , int                               WXUNUSED(nHeight
) 
1513 , int                               WXUNUSED(nDepth
) 
1519 bool wxBitmapHandler::LoadFile( 
1520   wxBitmap
*                         WXUNUSED(pBitmap
) 
1522 , long                              WXUNUSED(lType
) 
1523 , int                               WXUNUSED(nDesiredWidth
) 
1524 , int                               WXUNUSED(nDesiredHeight
) 
1530 bool wxBitmapHandler::LoadFile( 
1531   wxBitmap
*                         WXUNUSED(pBitmap
) 
1532 , const wxString
&                   WXUNUSED(rName
) 
1533 , long                              WXUNUSED(lType
) 
1534 , int                               WXUNUSED(nDesiredWidth
) 
1535 , int                               WXUNUSED(nDesiredHeight
) 
1541 bool wxBitmapHandler::SaveFile( 
1542   wxBitmap
*                         WXUNUSED(pBitmap
) 
1543 , const wxString
&                   WXUNUSED(rName
) 
1544 , int                               WXUNUSED(nType
) 
1545 , const wxPalette
*                  WXUNUSED(pPalette
) 
1551 // ---------------------------------------------------------------------------- 
1552 // Utility functions 
1553 // ---------------------------------------------------------------------------- 
1554 HBITMAP 
wxInvertMask( 
1560     HBITMAP                         hBmpInvMask 
= 0; 
1562     wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") ); 
1565     // Get width/height from the bitmap if not given 
1567     if (!nWidth 
|| !nHeight
) 
1569         BITMAPINFOHEADER2           vBmhdr
; 
1571         ::GpiQueryBitmapInfoHeader( hBmpMask
 
1574         nWidth  
= (int)vBmhdr
.cx
; 
1575         nHeight 
= (int)vBmhdr
.cy
; 
1578     BITMAPINFOHEADER2               vBmih
; 
1579     SIZEL                           vSize 
= {0, 0}; 
1580     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1581     HDC                             hDCSrc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1582     HDC                             hDCDst 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
); 
1583     HPS                             hPSSrc 
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1584     HPS                             hPSDst 
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS 
| GPIA_ASSOC
); 
1585     POINTL                          vPoint
[4] = { {0 ,0}, {nWidth
, nHeight
}, 
1586                                                   {0, 0}, {nWidth
, nHeight
} 
1589     memset(&vBmih
, '\0', 16); 
1594     vBmih
.cBitCount 
= 24; 
1596     hBmpInvMask 
= ::GpiCreateBitmap( hPSDst
 
1603     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
); 
1604     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
); 
1614     ::GpiDestroyPS(hPSSrc
); 
1615     ::GpiDestroyPS(hPSDst
); 
1616     ::DevCloseDC(hDCSrc
); 
1617     ::DevCloseDC(hDCDst
); 
1620 } // end of WxWinGdi_InvertMask 
1622 HBITMAP 
wxFlipBmp( HBITMAP hBmp
, int nWidth
, int nHeight 
) 
1624     wxCHECK_MSG( hBmp
, 0, _T("invalid bitmap in wxFlipBmp") ); 
1627     // Get width/height from the bitmap if not given 
1629     if (!nWidth 
|| !nHeight
) 
1631         BITMAPINFOHEADER2 vBmhdr
; 
1634         ::GpiQueryBitmapInfoHeader( hBmp
, 
1636         nWidth        
= (int)vBmhdr
.cx
; 
1637         nHeight       
= (int)vBmhdr
.cy
; 
1640     BITMAPINFOHEADER2 vBmih
; 
1641     SIZEL             vSize     
= {0, 0}; 
1642     DEVOPENSTRUC      vDop      
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
1643     HDC               hDCSrc    
= ::DevOpenDC(  vHabmain
, 
1647                                                 (PDEVOPENDATA
)&vDop
, 
1649     HDC               hDCDst    
= ::DevOpenDC(  vHabmain
, 
1653                                                 (PDEVOPENDATA
)&vDop
, 
1655     HPS               hPSSrc    
= ::GpiCreatePS(  vHabmain
, 
1658                                                   PU_PELS 
| GPIA_ASSOC  
); 
1659     HPS               hPSDst    
= ::GpiCreatePS(  vHabmain
, 
1662                                                   PU_PELS 
| GPIA_ASSOC  
); 
1663     POINTL            vPoint
[4] = { {0,      nHeight
}, 
1666                                     {nWidth
, nHeight
} }; 
1668     memset(&vBmih
, '\0', 16); 
1673     vBmih
.cBitCount 
= 24; 
1675     HBITMAP hInvBmp 
= ::GpiCreateBitmap(  hPSDst
, 
1681     ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmp
); 
1682     ::GpiSetBitmap(hPSDst
, (HBITMAP
) hInvBmp
); 
1684     ::GpiBitBlt(  hPSDst
, 
1691     ::GpiDestroyPS(hPSSrc
); 
1692     ::GpiDestroyPS(hPSDst
); 
1693     ::DevCloseDC(hDCSrc
); 
1694     ::DevCloseDC(hDCDst
); 
1697 } // end of wxFlipBmp