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"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
42 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
44 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 wxBitmapRefData::wxBitmapRefData()
57 m_pSelectedInto
= NULL
;
60 m_hBitmap
= (WXHBITMAP
) NULL
;
61 } // end of wxBitmapRefData::wxBitmapRefData
63 void wxBitmapRefData::Free()
65 wxASSERT_MSG( !m_pSelectedInto
,
66 wxT("deleting bitmap still selected into wxMemoryDC") );
70 if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) )
72 wxLogLastError("GpiDeleteBitmap(hbitmap)");
78 } // end of wxBitmapRefData::Free
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
84 // this function should be called from all wxBitmap ctors
87 // m_refData = NULL; done in the base class ctor
90 wxTheBitmapList
->AddBitmap(this);
91 } // end of wxBitmap::Init
93 bool wxBitmap::CopyFromIconOrCursor(
94 const wxGDIImage
& rIcon
97 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
98 POINTERINFO SIconInfo
;
100 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
102 wxLogLastError(wxT("WinQueryPointerInfo"));
105 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
107 m_refData
= pRefData
;
109 int nWidth
= rIcon
.GetWidth();
110 int nHeight
= rIcon
.GetHeight();
112 pRefData
->m_nWidth
= nWidth
;
113 pRefData
->m_nHeight
= nHeight
;
114 pRefData
->m_nDepth
= wxDisplayDepth();
116 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
119 // No mask in the Info struct in OS/2
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()
150 wxTheBitmapList
->DeleteObject(this);
151 } // end of wxBitmap::~wxBitmap
162 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
163 BITMAPINFOHEADER2 vHeader
;
167 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
168 SIZEL vSize
= {0, 0};
170 wxASSERT(vHabmain
!= NULL
);
172 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
174 vHeader
.cbFix
= sizeof(vHeader
);
175 vHeader
.cx
= (USHORT
)nTheWidth
;
176 vHeader
.cy
= (USHORT
)nTheHeight
;
177 vHeader
.cPlanes
= 1L;
178 vHeader
.cBitCount
= nNoBits
;
179 vHeader
.ulCompression
= BCA_UNCOMP
;
180 vHeader
.cxResolution
= 0;
181 vHeader
.cyResolution
= 0;
182 vHeader
.cclrUsed
= 0;
183 vHeader
.cclrImportant
= 0;
184 vHeader
.usUnits
= BRU_METRIC
;
185 vHeader
.usRecording
= BRA_BOTTOMUP
;
186 vHeader
.usRendering
= BRH_NOTHALFTONED
;
189 vHeader
.ulColorEncoding
= 0;
190 vHeader
.ulIdentifier
= 0;
192 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
195 wxLogLastError("GpiCreatePS Failure");
198 m_refData
= pRefData
;
200 pRefData
->m_nWidth
= nTheWidth
;
201 pRefData
->m_nHeight
= nTheHeight
;
202 pRefData
->m_nDepth
= nNoBits
;
203 pRefData
->m_nNumColors
= 0;
204 pRefData
->m_pSelectedInto
= NULL
;
206 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
209 wxLogLastError("CreateBitmap");
211 SetHBITMAP((WXHBITMAP
)hBmp
);
212 } // end of wxBitmap::wxBitmap
215 // Create from XPM data
223 (void)Create( (void *)ppData
224 ,wxBITMAP_TYPE_XPM_DATA
229 } // end of wxBitmap::wxBitmap
237 (void)Create( (void *)ppData
238 ,wxBITMAP_TYPE_XPM_DATA
243 } // end of wxBitmap::wxBitmap
257 } // end of wxBitmap::wxBitmap
275 } // end of wxBitmap::wxBitmap
278 const wxString
& rFilename
287 } // end of wxBitmap::wxBitmap
289 bool wxBitmap::Create(
296 BITMAPINFOHEADER2 vHeader
;
298 wxASSERT(vHabmain
!= NULL
);
300 m_refData
= new wxBitmapRefData
;
301 GetBitmapData()->m_nWidth
= nW
;
302 GetBitmapData()->m_nHeight
= nH
;
303 GetBitmapData()->m_nDepth
= nD
;
307 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
308 SIZEL vSize
= {0, 0};
309 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
310 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
312 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
313 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
317 vHeader
.cBitCount
= nD
;
319 hBmp
= ::GpiCreateBitmap( hPS
334 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
335 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
336 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
338 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
339 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
343 vHeader
.cBitCount
= lBitCount
;
345 hBmp
= ::GpiCreateBitmap( hPSScreen
352 GetBitmapData()->m_nDepth
= wxDisplayDepth();
353 ::WinReleasePS(hPSScreen
);
355 SetHBITMAP((WXHBITMAP
)hBmp
);
357 #if WXWIN_COMPATIBILITY_2
358 GetBitmapData()->m_bOk
= hBmp
!= 0;
359 #endif // WXWIN_COMPATIBILITY_2
362 } // end of wxBitmap::Create
364 bool wxBitmap::LoadFile(
365 const wxString
& rFilename
369 HPS hPs
= NULLHANDLE
;
373 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
379 m_refData
= new wxBitmapRefData
;
381 return(pHandler
->LoadFile( this
393 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
396 *this = vImage
.ConvertToBitmap();
400 } // end of wxBitmap::LoadFile
402 bool wxBitmap::Create(
412 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
418 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
419 "type %d defined."), lType
);
424 m_refData
= new wxBitmapRefData
;
426 return(pHandler
->Create( this
433 } // end of wxBitmap::Create
435 bool wxBitmap::SaveFile(
436 const wxString
& rFilename
438 , const wxPalette
* pPalette
441 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
447 return pHandler
->SaveFile( this
455 // FIXME what about palette? shouldn't we use it?
456 wxImage
vImage(*this);
461 return(vImage
.SaveFile( rFilename
465 } // end of wxBitmap::SaveFile
468 // ----------------------------------------------------------------------------
469 // wxImage-wxBitmap convertion
470 // ----------------------------------------------------------------------------
472 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth
)
474 wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") )
478 int sizeLimit = 1024*768*3;
480 // width and height of the device-dependent bitmap
481 int width = GetWidth();
482 int bmpHeight = GetHeight();
484 // calc the number of bytes per scanline and padding
485 int bytePerLine = width*3;
486 int sizeDWORD = sizeof( DWORD );
487 int lineBoundary = bytePerLine % sizeDWORD;
489 if( lineBoundary > 0 )
491 padding = sizeDWORD - lineBoundary;
492 bytePerLine += padding;
494 // calc the number of DIBs and heights of DIBs
497 int height = sizeLimit/bytePerLine;
498 if( height >= bmpHeight )
502 numDIB = bmpHeight / height;
503 hRemain = bmpHeight % height;
504 if( hRemain >0 ) numDIB++;
507 // set bitmap parameters
509 wxCHECK_MSG( Ok(), bitmap, wxT("invalid image") );
510 bitmap.SetWidth( width );
511 bitmap.SetHeight( bmpHeight );
512 bitmap.SetDepth( wxDisplayDepth() );
514 // create a DIB header
515 int headersize = sizeof(BITMAPINFOHEADER);
516 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
517 wxCHECK_MSG( lpDIBh, bitmap, wxT("could not allocate memory for DIB header") );
518 // Fill in the DIB header
519 lpDIBh->bmiHeader.biSize = headersize;
520 lpDIBh->bmiHeader.biWidth = (DWORD)width;
521 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
522 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
523 // the general formula for biSizeImage:
524 // ( ( ( ((DWORD)width*24) +31 ) & ~31 ) >> 3 ) * height;
525 lpDIBh->bmiHeader.biPlanes = 1;
526 lpDIBh->bmiHeader.biBitCount = 24;
527 lpDIBh->bmiHeader.biCompression = BI_RGB;
528 lpDIBh->bmiHeader.biClrUsed = 0;
529 // These seem not really needed for our purpose here.
530 lpDIBh->bmiHeader.biClrImportant = 0;
531 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
532 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
533 // memory for DIB data
534 unsigned char *lpBits;
535 lpBits = (unsigned char *)malloc( lpDIBh->bmiHeader.biSizeImage );
538 wxFAIL_MSG( wxT("could not allocate memory for DIB") );
543 // create and set the device-dependent bitmap
544 HDC hdc = ::GetDC(NULL);
545 HDC memdc = ::CreateCompatibleDC( hdc );
547 hbitmap = ::CreateCompatibleBitmap( hdc, width, bmpHeight );
548 ::SelectObject( memdc, hbitmap);
550 // copy image data into DIB data and then into DDB (in a loop)
551 unsigned char *data = GetData();
554 unsigned char *ptdata = data;
555 unsigned char *ptbits;
557 for( n=0; n<numDIB; n++ )
559 if( numDIB > 1 && n == numDIB-1 && hRemain > 0 )
561 // redefine height and size of the (possibly) last smaller DIB
562 // memory is not reallocated
564 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
565 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
569 for( j=0; j<height; j++ )
571 for( i=0; i<width; i++ )
573 *(ptbits++) = *(ptdata+2);
574 *(ptbits++) = *(ptdata+1);
575 *(ptbits++) = *(ptdata );
578 for( i=0; i< padding; i++ ) *(ptbits++) = 0;
580 ::StretchDIBits( memdc, 0, origin, width, height,\
581 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
583 // if numDIB = 1, lines below can also be used
584 // hbitmap = CreateDIBitmap( hdc, &(lpDIBh->bmiHeader), CBM_INIT, lpBits, lpDIBh, DIB_RGB_COLORS );
585 // The above line is equivalent to the following two lines.
586 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
587 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
588 // or the following lines
589 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
590 // HDC memdc = ::CreateCompatibleDC( hdc );
591 // ::SelectObject( memdc, hbitmap);
592 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
593 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
594 // ::SelectObject( memdc, 0 );
595 // ::DeleteDC( memdc );
597 bitmap.SetHBITMAP( (WXHBITMAP) hbitmap );
599 // similarly, created an mono-bitmap for the possible mask
602 hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
603 ::SelectObject( memdc, hbitmap);
604 if( numDIB == 1 ) height = bmpHeight;
605 else height = sizeLimit/bytePerLine;
606 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
607 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
609 unsigned char r = GetMaskRed();
610 unsigned char g = GetMaskGreen();
611 unsigned char b = GetMaskBlue();
612 unsigned char zero = 0, one = 255;
614 for( n=0; n<numDIB; n++ )
616 if( numDIB > 1 && n == numDIB - 1 && hRemain > 0 )
618 // redefine height and size of the (possibly) last smaller DIB
619 // memory is not reallocated
621 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
622 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
625 for( int j=0; j<height; j++ )
627 for(i=0; i<width; i++ )
629 if( (*(ptdata++)!=r) | (*(ptdata++)!=g) | (*(ptdata++)!=b) )
642 for( i=0; i< padding; i++ ) *(ptbits++) = zero;
644 ::StretchDIBits( memdc, 0, origin, width, height,\
645 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
648 // create a wxMask object
649 wxMask *mask = new wxMask();
650 mask->SetMaskBitmap( (WXHBITMAP) hbitmap );
651 bitmap.SetMask( mask );
654 // free allocated resources
655 ::SelectObject( memdc, 0 );
657 ::ReleaseDC(NULL, hdc);
661 // check the wxBitmap object
662 if( bitmap.GetHBITMAP() )
663 bitmap.SetOk( TRUE );
665 bitmap.SetOk( FALSE );
671 wxImage
wxBitmap::ConvertToImage() const
675 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
677 // create an wxImage object
678 int width
= GetWidth();
679 int height
= GetHeight();
680 image
.Create( width
, height
);
681 unsigned char *data
= image
.GetData();
684 wxFAIL_MSG( wxT("could not allocate data for image") );
688 // calc the number of bytes per scanline and padding in the DIB
689 int bytePerLine
= width
*3;
690 int sizeDWORD
= sizeof( DWORD
);
691 int lineBoundary
= bytePerLine
% sizeDWORD
;
693 if( lineBoundary
> 0 )
695 padding
= sizeDWORD
- lineBoundary
;
696 bytePerLine
+= padding
;
700 // create a DIB header
701 int headersize = sizeof(BITMAPINFOHEADER);
702 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
705 wxFAIL_MSG( wxT("could not allocate data for DIB header") );
709 // Fill in the DIB header
710 lpDIBh->bmiHeader.biSize = headersize;
711 lpDIBh->bmiHeader.biWidth = width;
712 lpDIBh->bmiHeader.biHeight = -height;
713 lpDIBh->bmiHeader.biSizeImage = bytePerLine * height;
714 lpDIBh->bmiHeader.biPlanes = 1;
715 lpDIBh->bmiHeader.biBitCount = 24;
716 lpDIBh->bmiHeader.biCompression = BI_RGB;
717 lpDIBh->bmiHeader.biClrUsed = 0;
718 // These seem not really needed for our purpose here.
719 lpDIBh->bmiHeader.biClrImportant = 0;
720 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
721 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
722 // memory for DIB data
723 unsigned char *lpBits;
724 lpBits = (unsigned char *) malloc( lpDIBh->bmiHeader.biSizeImage );
727 wxFAIL_MSG( wxT("could not allocate data for DIB") );
733 // copy data from the device-dependent bitmap to the DIB
734 HDC hdc = ::GetDC(NULL);
736 hbitmap = (HBITMAP) bitmap.GetHBITMAP();
737 ::GetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
739 // copy DIB data into the wxImage object
741 unsigned char *ptdata = data;
742 unsigned char *ptbits = lpBits;
743 for( i=0; i<height; i++ )
745 for( j=0; j<width; j++ )
747 *(ptdata++) = *(ptbits+2);
748 *(ptdata++) = *(ptbits+1);
749 *(ptdata++) = *(ptbits );
755 // similarly, set data according to the possible mask bitmap
756 if( bitmap.GetMask() && bitmap.GetMask()->GetMaskBitmap() )
758 hbitmap = (HBITMAP) bitmap.GetMask()->GetMaskBitmap();
759 // memory DC created, color set, data copied, and memory DC deleted
760 HDC memdc = ::CreateCompatibleDC( hdc );
761 ::SetTextColor( memdc, RGB( 0, 0, 0 ) );
762 ::SetBkColor( memdc, RGB( 255, 255, 255 ) );
763 ::GetDIBits( memdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
765 // background color set to RGB(16,16,16) in consistent with wxGTK
766 unsigned char r=16, g=16, b=16;
769 for( i=0; i<height; i++ )
771 for( j=0; j<width; j++ )
785 SetMaskColour( r, g, b );
792 // free allocated resources
793 ::ReleaseDC(NULL, hdc);
802 // ----------------------------------------------------------------------------
803 // sub bitmap extraction
804 // ----------------------------------------------------------------------------
806 wxBitmap
wxBitmap::GetSubBitmap(
811 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
812 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
813 (rRect
.y
+ rRect
.height
<= GetHeight()),
814 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
816 wxBitmap
vRet( rRect
.width
820 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
826 SIZEL vSize
= {0, 0};
827 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
828 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
829 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
830 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
831 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
832 POINTL vPoint
[4] = { rRect
.x
, rRect
.y
,
833 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
,
834 0, 0, GetWidth(), GetHeight()
837 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
838 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
848 // Copy mask if there is one
852 BITMAPINFOHEADER2 vBmih
;
854 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
855 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
856 vBmih
.cx
= rRect
.width
;
857 vBmih
.cy
= rRect
.height
;
861 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
868 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
869 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
871 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
872 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
881 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
885 ::GpiSetBitmap(hPSSrc
, NULL
);
886 ::GpiSetBitmap(hPSDst
, NULL
);
887 ::GpiDestroyPS(hPSSrc
);
888 ::GpiDestroyPS(hPSDst
);
889 ::DevCloseDC(hDCSrc
);
890 ::DevCloseDC(hDCDst
);
892 } // end of wxBitmap::GetSubBitmap
894 // ----------------------------------------------------------------------------
895 // wxBitmap accessors
896 // ----------------------------------------------------------------------------
898 void wxBitmap::SetQuality(
904 GetBitmapData()->m_nQuality
= nQ
;
905 } // end of wxBitmap::SetQuality
907 #if WXWIN_COMPATIBILITY_2
908 void wxBitmap::SetOk(
914 GetBitmapData()->m_bOk
= bOk
;
915 } // end of wxBitmap::SetOk
916 #endif // WXWIN_COMPATIBILITY_2
918 void wxBitmap::SetPalette(
919 const wxPalette
& rPalette
924 GetBitmapData()->m_vBitmapPalette
= rPalette
;
925 } // end of wxBitmap::SetPalette
927 void wxBitmap::SetMask(
933 GetBitmapData()->m_pBitmapMask
= pMask
;
934 } // end of wxBitmap::SetMask
937 // Will try something for OS/2 but not really sure how close
938 // to the msw intent this is.
940 wxBitmap
wxBitmap::GetBitmapForDC(
945 wxBitmap
vTmpBitmap( this->GetWidth()
949 WXHBITMAP vOldBitmap
;
955 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
956 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
958 // TODO: Set the points
960 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
961 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
964 } // end of wxBitmap::GetBitmapForDC
966 // ----------------------------------------------------------------------------
968 // ----------------------------------------------------------------------------
973 } // end of wxMask::wxMask
975 // Construct a mask from a bitmap and a colour indicating
976 // the transparent area
978 const wxBitmap
& rBitmap
979 , const wxColour
& rColour
986 } // end of wxMask::wxMask
988 // Construct a mask from a bitmap and a palette index indicating
989 // the transparent area
991 const wxBitmap
& rBitmap
999 } // end of wxMask::wxMask
1001 // Construct a mask from a mono bitmap (copies the bitmap).
1003 const wxBitmap
& rBitmap
1008 } // end of wxMask::wxMask
1013 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1014 } // end of wxMask::~wxMask
1016 // Create a mask from a mono bitmap (copies the bitmap).
1017 bool wxMask::Create(
1018 const wxBitmap
& rBitmap
1021 BITMAPINFOHEADER2 vBmih
;
1022 SIZEL vSize
= {0, 0};
1023 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1024 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1025 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1026 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1027 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1028 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1029 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1034 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1037 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1042 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1043 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1044 vBmih
.cx
= rBitmap
.GetWidth();
1045 vBmih
.cy
= rBitmap
.GetHeight();
1047 vBmih
.cBitCount
= 1;
1049 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1056 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1057 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1066 ::GpiDestroyPS(hPSSrc
);
1067 ::GpiDestroyPS(hPSDst
);
1068 ::DevCloseDC(hDCSrc
);
1069 ::DevCloseDC(hDCDst
);
1071 } // end of wxMask::Create
1073 // Create a mask from a bitmap and a palette index indicating
1074 // the transparent area
1075 bool wxMask::Create(
1076 const wxBitmap
& rBitmap
1082 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1085 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1088 unsigned char cGreen
;
1089 unsigned char cBlue
;
1091 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1097 wxColour
vTransparentColour( cRed
1102 return (Create( rBitmap
1108 } // end of wxMask::Create
1110 // Create a mask from a bitmap and a colour indicating
1111 // the transparent area
1112 bool wxMask::Create(
1113 const wxBitmap
& rBitmap
1114 , const wxColour
& rColour
1118 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1122 BITMAPINFOHEADER2 vBmih
;
1123 SIZEL vSize
= {0, 0};
1124 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1125 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1126 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1127 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1128 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1129 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1130 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1135 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1144 // Scan the bitmap for the transparent colour and set
1145 // the corresponding pixels in the mask to BLACK and
1146 // the rest to WHITE
1149 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1150 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1151 vBmih
.cx
= rBitmap
.GetWidth();
1152 vBmih
.cy
= rBitmap
.GetHeight();
1154 vBmih
.cBitCount
= 1;
1156 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1163 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1164 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1167 // This is not very efficient, but I can't think
1168 // of a better way of doing it
1170 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1172 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1174 POINTL vPt
= {w
, h
};
1175 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1176 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1179 // Doesn't make sense to continue
1185 if (vCol
== vMaskColour
)
1187 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1188 ::GpiSetPel(hPSDst
, &vPt
);
1192 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1193 ::GpiSetPel(hPSDst
, &vPt
);
1197 ::GpiSetBitmap(hPSSrc
, NULL
);
1198 ::GpiSetBitmap(hPSDst
, NULL
);
1199 ::GpiDestroyPS(hPSSrc
);
1200 ::GpiDestroyPS(hPSDst
);
1201 ::DevCloseDC(hDCSrc
);
1202 ::DevCloseDC(hDCDst
);
1204 } // end of wxMask::Create
1206 // ----------------------------------------------------------------------------
1208 // ----------------------------------------------------------------------------
1210 bool wxBitmapHandler::Create(
1219 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1223 return(pBitmap
? Create( pBitmap
1231 bool wxBitmapHandler::Load(
1233 , const wxString
& rName
1240 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1244 return(pBitmap
? LoadFile( pBitmap
1253 bool wxBitmapHandler::Save(
1255 , const wxString
& rName
1259 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1263 return(pBitmap
? SaveFile( pBitmap
1269 bool wxBitmapHandler::Create(
1270 wxBitmap
* WXUNUSED(pBitmap
)
1271 , void* WXUNUSED(pData
)
1272 , long WXUNUSED(lType
)
1273 , int WXUNUSED(nWidth
)
1274 , int WXUNUSED(nHeight
)
1275 , int WXUNUSED(nDepth
)
1281 bool wxBitmapHandler::LoadFile(
1282 wxBitmap
* WXUNUSED(pBitmap
)
1283 , const wxString
& WXUNUSED(rName
)
1285 , long WXUNUSED(lType
)
1286 , int WXUNUSED(nDesiredWidth
)
1287 , int WXUNUSED(nDesiredHeight
)
1293 bool wxBitmapHandler::SaveFile(
1294 wxBitmap
* WXUNUSED(pBitmap
)
1295 , const wxString
& WXUNUSED(rName
)
1296 , int WXUNUSED(nType
)
1297 , const wxPalette
* WXUNUSED(pPalette
)
1303 // ----------------------------------------------------------------------------
1304 // Utility functions
1305 // ----------------------------------------------------------------------------
1306 HBITMAP
wxInvertMask(
1312 HBITMAP hBmpInvMask
= 0;
1314 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1317 // Get width/height from the bitmap if not given
1319 if (!nWidth
|| !nHeight
)
1321 BITMAPINFOHEADER2 vBmhdr
;
1323 ::GpiQueryBitmapInfoHeader( hBmpMask
1326 nWidth
= (int)vBmhdr
.cx
;
1327 nHeight
= (int)vBmhdr
.cy
;
1330 BITMAPINFOHEADER2 vBmih
;
1331 SIZEL vSize
= {0, 0};
1332 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1333 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1334 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1335 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1336 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1337 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1338 0, 0, nWidth
, nHeight
1341 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1342 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1346 vBmih
.cBitCount
= 1;
1348 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1355 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1356 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1366 ::GpiDestroyPS(hPSSrc
);
1367 ::GpiDestroyPS(hPSDst
);
1368 ::DevCloseDC(hDCSrc
);
1369 ::DevCloseDC(hDCDst
);
1372 } // end of WxWinGdi_InvertMask