1 ///////////////////////////////////////////////////////////////////////////// 
   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" 
  21     #include "wx/palette.h" 
  22     #include "wx/dcmemory.h" 
  23     #include "wx/bitmap.h" 
  27 #include "wx/os2/private.h" 
  30 //#include "wx/msw/dib.h" 
  33 // ---------------------------------------------------------------------------- 
  35 // ---------------------------------------------------------------------------- 
  37 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
) 
  38 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
) 
  42 // ============================================================================ 
  44 // ============================================================================ 
  46 // ---------------------------------------------------------------------------- 
  48 // ---------------------------------------------------------------------------- 
  50 wxBitmapRefData::wxBitmapRefData() 
  53     m_pSelectedInto 
= NULL
; 
  58 void wxBitmapRefData::Free() 
  60     wxASSERT_MSG( !m_pSelectedInto
, 
  61                   wxT("deleting bitmap still selected into wxMemoryDC") ); 
  65         if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) ) 
  67             wxLogLastError("GpiDeleteBitmap(hbitmap)"); 
  75 // ---------------------------------------------------------------------------- 
  77 // ---------------------------------------------------------------------------- 
  79 // this function should be called from all wxBitmap ctors 
  82     // m_refData = NULL; done in the base class ctor 
  85         wxTheBitmapList
->AddBitmap(this); 
  88 bool wxBitmap::CopyFromIconOrCursor( 
  89   const wxGDIImage
&                 rIcon
 
  92     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
  96     pRefData
->m_nWidth 
= rIcon
.GetWidth(); 
  97     pRefData
->m_nHeight 
= rIcon
.GetHeight(); 
  98     pRefData
->m_nDepth 
= wxDisplayDepth(); 
 100     pRefData
->m_hBitmap 
= (WXHBITMAP
)rIcon
.GetHandle(); 
 102     pRefData
->m_pBitmapMask 
= new wxMask(); 
 104 #if WXWIN_COMPATIBILITY_2 
 105     pRefData
->m_bOk 
= TRUE
; 
 106 #endif // WXWIN_COMPATIBILITY_2 
 110 bool wxBitmap::CopyFromCursor( 
 111   const wxCursor
&                   rCursor
 
 118     return(CopyFromIconOrCursor(rCursor
)); 
 121 bool wxBitmap::CopyFromIcon( 
 130 #if WXWIN_COMPATIBILITY_2 
 131     refData
->m_ok 
= TRUE
; 
 132 #endif // WXWIN_COMPATIBILITY_2 
 134     return CopyFromIconOrCursor(rIcon
); 
 137 wxBitmap::~wxBitmap() 
 140         wxTheBitmapList
->DeleteObject(this); 
 152     wxBitmapRefData
*                pRefData 
= new wxBitmapRefData
; 
 153     BITMAPINFOHEADER2               vHeader
; 
 157     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 158     SIZEL                           vSize 
= {0, 0}; 
 160     wxASSERT(vHabmain 
!= NULL
); 
 162     hDc 
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L); 
 164     vHeader
.cbFix           
= sizeof(vHeader
); 
 165     vHeader
.cx              
= (USHORT
)nTheWidth
; 
 166     vHeader
.cy              
= (USHORT
)nTheHeight
; 
 167     vHeader
.cPlanes         
= 1L; 
 168     vHeader
.cBitCount       
= nNoBits
; 
 169     vHeader
.ulCompression   
= BCA_UNCOMP
; 
 170     vHeader
.cxResolution    
= 0; 
 171     vHeader
.cyResolution    
= 0; 
 172     vHeader
.cclrUsed        
= 0; 
 173     vHeader
.cclrImportant   
= 0; 
 174     vHeader
.usUnits         
= BRU_METRIC
; 
 175     vHeader
.usRecording     
= BRA_BOTTOMUP
; 
 176     vHeader
.usRendering     
= BRH_NOTHALFTONED
; 
 179     vHeader
.ulColorEncoding 
= 0; 
 180     vHeader
.ulIdentifier    
= 0; 
 182     hPs 
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC 
| PU_PELS
); 
 185         wxLogLastError("GpiCreatePS Failure"); 
 188     m_refData 
= pRefData
; 
 190     pRefData
->m_nWidth 
= nTheWidth
; 
 191     pRefData
->m_nHeight 
= nTheHeight
; 
 192     pRefData
->m_nDepth 
= nNoBits
; 
 193     pRefData
->m_nNumColors 
= 0; 
 194     pRefData
->m_pSelectedInto 
= NULL
; 
 196     HBITMAP hBmp 
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
); 
 199         wxLogLastError("CreateBitmap"); 
 201     SetHBITMAP((WXHBITMAP
)hBmp
); 
 204 // Create from XPM data 
 207 , wxControl
*                        WXUNUSED(pAnItem
)) 
 211     (void)Create( (void *)ppData
 
 212                  ,wxBITMAP_TYPE_XPM_DATA
 
 252   const wxString
&                   rFilename
 
 263 bool wxBitmap::Create( 
 270     BITMAPINFOHEADER2               vHeader
; 
 274     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 275     SIZEL                           vSize 
= {0, 0}; 
 278     wxASSERT(vHabmain 
!= NULL
); 
 280     hpsScreen 
= ::WinGetScreenPS(HWND_DESKTOP
); 
 281     hdcScreen 
= ::GpiQueryDevice(hpsScreen
); 
 282     ::DevQueryCaps(hdcScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
); 
 284     vHeader
.cbFix           
= sizeof(vHeader
); 
 285     vHeader
.cx              
= (USHORT
)nW
; 
 286     vHeader
.cy              
= (USHORT
)nH
; 
 287     vHeader
.cPlanes         
= (USHORT
)nD
; 
 288     vHeader
.cBitCount       
= lBitCount
; 
 289     vHeader
.ulCompression   
= BCA_UNCOMP
; 
 290     vHeader
.cxResolution    
= 0; 
 291     vHeader
.cyResolution    
= 0; 
 292     vHeader
.cclrUsed        
= 0; 
 293     vHeader
.cclrImportant   
= 0; 
 294     vHeader
.usUnits         
= BRU_METRIC
; 
 295     vHeader
.usRecording     
= BRA_BOTTOMUP
; 
 296     vHeader
.usRendering     
= BRH_NOTHALFTONED
; 
 299     vHeader
.ulColorEncoding 
= 0; 
 300     vHeader
.ulIdentifier    
= 0; 
 303     m_refData 
= new wxBitmapRefData
; 
 305     GetBitmapData()->m_nWidth 
= nW
; 
 306     GetBitmapData()->m_nHeight 
= nH
; 
 307     GetBitmapData()->m_nDepth 
= nD
; 
 311         hBmp 
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
); 
 314             wxLogLastError("CreateBitmap"); 
 321         ::DevQueryCaps(hdcScreen
, CAPS_COLOR_PLANES
, 1L, &lPlanes
); 
 322         hBmp 
= ::GpiCreateBitmap(hpsScreen
, &vHeader
, 0L, NULL
, &vInfo
); 
 325             wxLogLastError("CreateBitmap"); 
 327         GetBitmapData()->m_nDepth 
= wxDisplayDepth(); 
 329     SetHBITMAP((WXHBITMAP
)hBmp
); 
 331 #if WXWIN_COMPATIBILITY_2 
 332     GetBitmapData()->m_bOk 
= hBmp 
!= 0; 
 333 #endif // WXWIN_COMPATIBILITY_2 
 338 bool wxBitmap::LoadFile( 
 339   const wxString
&                   rFilename
 
 345     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 351         m_refData 
= new wxBitmapRefData
; 
 353         return(pHandler
->LoadFile( this 
 364         if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() ) 
 367         *this = vImage
.ConvertToBitmap(); 
 373 bool wxBitmap::Create( 
 383     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 389         wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for " 
 390                        "type %d defined."), lType
); 
 395     m_refData 
= new wxBitmapRefData
; 
 397     return(pHandler
->Create( this 
 406 bool wxBitmap::SaveFile( 
 407   const wxString
&                   rFilename
 
 409 , const wxPalette
*                  pPalette
 
 412     wxBitmapHandler
*                pHandler 
= wxDynamicCast( FindHandler(lType
) 
 418         return pHandler
->SaveFile( this 
 426         // FIXME what about palette? shouldn't we use it? 
 427         wxImage                     
vImage(*this); 
 432         return(vImage
.SaveFile( rFilename
 
 438 // ---------------------------------------------------------------------------- 
 439 // wxBitmap accessors 
 440 // ---------------------------------------------------------------------------- 
 442 void wxBitmap::SetQuality( 
 448     GetBitmapData()->m_nQuality 
= nQ
; 
 451 #if WXWIN_COMPATIBILITY_2 
 452 void wxBitmap::SetOk( 
 458     GetBitmapData()->m_bOk 
= bOk
; 
 460 #endif // WXWIN_COMPATIBILITY_2 
 462 void wxBitmap::SetPalette( 
 463   const wxPalette
&                  rPalette
 
 468     GetBitmapData()->m_vBitmapPalette 
= rPalette
; 
 471 void wxBitmap::SetMask( 
 477     GetBitmapData()->m_pBitmapMask 
= pMask
; 
 480 // Will try something for OS/2 but not really sure how close 
 481 // to the msw intent this is. 
 482 wxBitmap 
wxBitmap::GetBitmapForDC( 
 487     wxBitmap                        
vTmpBitmap( this->GetWidth() 
 491     WXHBITMAP                       vOldBitmap
; 
 497     hMemoryPS 
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 498     hPs       
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 500     // TODO: Set the points 
 502     vOldBitmap 
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP()); 
 503     ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
); 
 508 // ---------------------------------------------------------------------------- 
 510 // ---------------------------------------------------------------------------- 
 517 // Construct a mask from a bitmap and a colour indicating 
 518 // the transparent area 
 520   const wxBitmap
&                   rBitmap
 
 521 , const wxColour
&                   rColour
 
 530 // Construct a mask from a bitmap and a palette index indicating 
 531 // the transparent area 
 533   const wxBitmap
&                   rBitmap
 
 543 // Construct a mask from a mono bitmap (copies the bitmap). 
 545   const wxBitmap
&                   rBitmap
 
 555         ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
); 
 558 // Create a mask from a mono bitmap (copies the bitmap). 
 560   const wxBitmap
&                   rBitmap
 
 563     BITMAPINFOHEADER2               vHeader
; 
 564     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 565     SIZEL                           vSize 
= {0, 0}; 
 570         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
 573     if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1) 
 577     vHeader
.cbFix           
= sizeof(vHeader
); 
 578     vHeader
.cx              
= (USHORT
)rBitmap
.GetWidth(); 
 579     vHeader
.cy              
= (USHORT
)rBitmap
.GetHeight(); 
 581     vHeader
.cBitCount       
= 1; 
 583     m_hMaskBitmap 
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
 
 590     HPS srcPS 
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 591     ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP()); 
 592     HPS destPS 
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 593     ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
); 
 594     // TODO: Set the point array 
 595     ::GpiBitBlt(destPS
, srcPS
, 4L, vPoint
, ROP_SRCCOPY 
, BBO_IGNORE
); 
 597     ::GpiDestroyPS(srcPS
); 
 598     ::GpiDestroyPS(destPS
); 
 602 // Create a mask from a bitmap and a palette index indicating 
 603 // the transparent area 
 605   const wxBitmap
&                   rBitmap
 
 611         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
 614     if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok()) 
 617         unsigned char               cGreen
; 
 620         if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
 
 626             wxColour                
vTransparentColour( cRed
 
 631             return (Create( rBitmap
 
 639 // Create a mask from a bitmap and a colour indicating 
 640 // the transparent area 
 642   const wxBitmap
&                   rBitmap
 
 643 , const wxColour
&                   rColour
 
 646     BITMAPINFOHEADER2               vHeader
; 
 647     DEVOPENSTRUC                    vDop 
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL 
}; 
 648     SIZEL                           vSize 
= {0, 0}; 
 653         ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
); 
 661     // scan the bitmap for the transparent colour and set 
 662     // the corresponding pixels in the mask to BLACK and 
 664     COLORREF                        vMaskColour 
= OS2RGB(rColour
.Red(), rColour
.Green(), rColour
.Blue()); 
 666     vHeader
.cbFix           
= sizeof(vHeader
); 
 667     vHeader
.cx              
= (USHORT
)rBitmap
.GetWidth(); 
 668     vHeader
.cy              
= (USHORT
)rBitmap
.GetHeight(); 
 670     vHeader
.cBitCount       
= 1; 
 672     m_hMaskBitmap 
= (WXHBITMAP
) ::GpiCreateBitmap( m_hPs
 
 679     HPS srcPS 
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 680     ::GpiSetBitmap(srcPS
, (HBITMAP
)rBitmap
.GetHBITMAP()); 
 681     HPS destPS 
= ::GpiCreatePS(vHabmain
, m_hDc
, &vSize
, PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
); 
 682     ::GpiSetBitmap(srcPS
, (HBITMAP
)m_hMaskBitmap
); 
 684     // this is not very efficient, but I can't think 
 685     // of a better way of doing it 
 686     for (int w 
= 0; w 
< rBitmap
.GetWidth(); w
++) 
 688         for (int h 
= 0; h 
< rBitmap
.GetHeight(); h
++) 
 695             COLORREF                col 
= ::GpiQueryPel(srcPS
, &vPoint
); 
 697             if (col 
== vMaskColour
) 
 699                 ::GpiSetColor(destPS
, CLR_WHITE
); 
 700                 ::GpiSetPel(destPS
, &vPoint
); 
 704                 ::GpiSetColor(destPS
, CLR_BLACK
); 
 705                 ::GpiSetPel(destPS
, &vPoint
); 
 709     ::GpiDestroyPS(srcPS
); 
 710     ::GpiDestroyPS(destPS
); 
 714 // ---------------------------------------------------------------------------- 
 716 // ---------------------------------------------------------------------------- 
 718 bool wxBitmapHandler::Create( 
 727     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
 731     return(pBitmap 
? Create( pBitmap
 
 739 bool wxBitmapHandler::Load( 
 741 , const wxString
&                   rName
 
 747     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
 751     return(pBitmap 
? LoadFile( pBitmap
 
 759 bool wxBitmapHandler::Save( 
 761 , const wxString
&                   rName
 
 765     wxBitmap
*                       pBitmap 
= wxDynamicCast( pImage
 
 769     return(pBitmap 
? SaveFile( pBitmap
 
 775 bool wxBitmapHandler::Create( 
 776   wxBitmap
*                         WXUNUSED(pBitmap
) 
 777 , void*                             WXUNUSED(pData
) 
 778 , long                              WXUNUSED(lType
) 
 779 , int                               WXUNUSED(nWidth
) 
 780 , int                               WXUNUSED(nHeight
) 
 781 , int                               WXUNUSED(nDepth
) 
 787 bool wxBitmapHandler::LoadFile( 
 788   wxBitmap
*                         WXUNUSED(pBitmap
) 
 789 , const wxString
&                   WXUNUSED(rName
) 
 790 , long                              WXUNUSED(lType
) 
 791 , int                               WXUNUSED(nDesiredWidth
) 
 792 , int                               WXUNUSED(nDesiredHeight
) 
 798 bool wxBitmapHandler::SaveFile( 
 799   wxBitmap
*                         WXUNUSED(pBitmap
) 
 800 , const wxString
&                   WXUNUSED(rName
) 
 801 , int                               WXUNUSED(nType
) 
 802 , const wxPalette
*                  WXUNUSED(pPalette
)