1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "bitmap.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
31 #include "wx/os2/private.h"
34 //#include "wx/msw/dib.h"
36 #include "wx/xpmdecod.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 wxBitmapRefData::wxBitmapRefData()
58 m_pSelectedInto
= NULL
;
61 m_hBitmap
= (WXHBITMAP
) NULL
;
62 } // end of wxBitmapRefData::wxBitmapRefData
64 void wxBitmapRefData::Free()
66 wxASSERT_MSG( !m_pSelectedInto
,
67 wxT("deleting bitmap still selected into wxMemoryDC") );
71 if ( !::GpiDeleteBitmap((HBITMAP
)m_hBitmap
) )
73 wxLogLastError("GpiDeleteBitmap(hbitmap)");
79 } // end of wxBitmapRefData::Free
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 // this function should be called from all wxBitmap ctors
88 // m_refData = NULL; done in the base class ctor
91 wxTheBitmapList
->AddBitmap(this);
92 } // end of wxBitmap::Init
94 bool wxBitmap::CopyFromIconOrCursor(
95 const wxGDIImage
& rIcon
98 HPOINTER hIcon
= (HPOINTER
)rIcon
.GetHandle();
99 POINTERINFO SIconInfo
;
101 if (!::WinQueryPointerInfo(hIcon
, &SIconInfo
))
103 wxLogLastError(wxT("WinQueryPointerInfo"));
106 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
108 m_refData
= pRefData
;
110 int nWidth
= rIcon
.GetWidth();
111 int nHeight
= rIcon
.GetHeight();
113 pRefData
->m_nWidth
= nWidth
;
114 pRefData
->m_nHeight
= nHeight
;
115 pRefData
->m_nDepth
= wxDisplayDepth();
117 pRefData
->m_hBitmap
= (WXHBITMAP
)SIconInfo
.hbmColor
;
120 // No mask in the Info struct in OS/2
123 } // end of wxBitmap::CopyFromIconOrCursor
125 bool wxBitmap::CopyFromCursor(
126 const wxCursor
& rCursor
133 return(CopyFromIconOrCursor(rCursor
));
134 } // end of wxBitmap::CopyFromCursor
136 bool wxBitmap::CopyFromIcon(
145 return CopyFromIconOrCursor(rIcon
);
146 } // end of wxBitmap::CopyFromIcon
148 wxBitmap::~wxBitmap()
151 wxTheBitmapList
->DeleteObject(this);
152 } // end of wxBitmap::~wxBitmap
163 wxBitmapRefData
* pRefData
= new wxBitmapRefData
;
164 BITMAPINFOHEADER2 vHeader
;
168 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
169 SIZEL vSize
= {0, 0};
171 wxASSERT(vHabmain
!= NULL
);
173 hDc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, (PSZ
)"*", 1L, (PDEVOPENDATA
)&vDop
, 0L);
175 vHeader
.cbFix
= sizeof(vHeader
);
176 vHeader
.cx
= (USHORT
)nTheWidth
;
177 vHeader
.cy
= (USHORT
)nTheHeight
;
178 vHeader
.cPlanes
= 1L;
179 vHeader
.cBitCount
= nNoBits
;
180 vHeader
.ulCompression
= BCA_UNCOMP
;
181 vHeader
.cxResolution
= 0;
182 vHeader
.cyResolution
= 0;
183 vHeader
.cclrUsed
= 0;
184 vHeader
.cclrImportant
= 0;
185 vHeader
.usUnits
= BRU_METRIC
;
186 vHeader
.usRecording
= BRA_BOTTOMUP
;
187 vHeader
.usRendering
= BRH_NOTHALFTONED
;
190 vHeader
.ulColorEncoding
= 0;
191 vHeader
.ulIdentifier
= 0;
193 hPs
= ::GpiCreatePS(vHabmain
, hDc
, &vSize
, GPIA_ASSOC
| PU_PELS
);
196 wxLogLastError("GpiCreatePS Failure");
199 m_refData
= pRefData
;
201 pRefData
->m_nWidth
= nTheWidth
;
202 pRefData
->m_nHeight
= nTheHeight
;
203 pRefData
->m_nDepth
= nNoBits
;
204 pRefData
->m_nNumColors
= 0;
205 pRefData
->m_pSelectedInto
= NULL
;
207 HBITMAP hBmp
= ::GpiCreateBitmap(hPs
, &vHeader
, 0L, NULL
, &vInfo
);
210 wxLogLastError("CreateBitmap");
212 SetHBITMAP((WXHBITMAP
)hBmp
);
213 } // end of wxBitmap::wxBitmap
227 } // end of wxBitmap::wxBitmap
245 } // end of wxBitmap::wxBitmap
248 const wxString
& rFilename
257 } // end of wxBitmap::wxBitmap
259 bool wxBitmap::Create(
266 BITMAPINFOHEADER2 vHeader
;
268 wxASSERT(vHabmain
!= NULL
);
270 m_refData
= new wxBitmapRefData
;
271 GetBitmapData()->m_nWidth
= nW
;
272 GetBitmapData()->m_nHeight
= nH
;
273 GetBitmapData()->m_nDepth
= nD
;
277 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
278 SIZEL vSize
= {0, 0};
279 HDC hDC
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
280 HPS hPS
= ::GpiCreatePS(vHabmain
, hDC
, &vSize
, PU_PELS
| GPIA_ASSOC
);
282 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
283 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
287 vHeader
.cBitCount
= nD
;
289 hBmp
= ::GpiCreateBitmap( hPS
304 hPSScreen
= ::WinGetScreenPS(HWND_DESKTOP
);
305 hDCScreen
= ::GpiQueryDevice(hPSScreen
);
306 ::DevQueryCaps(hDCScreen
, CAPS_COLOR_BITCOUNT
, 1L, &lBitCount
);
308 memset(&vHeader
, '\0', sizeof(BITMAPINFOHEADER2
));
309 vHeader
.cbFix
= sizeof(BITMAPINFOHEADER2
);
313 vHeader
.cBitCount
= lBitCount
;
315 hBmp
= ::GpiCreateBitmap( hPSScreen
322 GetBitmapData()->m_nDepth
= wxDisplayDepth();
323 ::WinReleasePS(hPSScreen
);
325 SetHBITMAP((WXHBITMAP
)hBmp
);
327 #if WXWIN_COMPATIBILITY_2
328 GetBitmapData()->m_bOk
= hBmp
!= 0;
329 #endif // WXWIN_COMPATIBILITY_2
332 } // end of wxBitmap::Create
334 bool wxBitmap::CreateFromXpm(
338 #if wxUSE_IMAGE && wxUSE_XPM
341 wxCHECK_MSG(ppData
!= NULL
, FALSE
, wxT("invalid bitmap data"))
343 wxXPMDecoder vDecoder
;
344 wxImage vImg
= vDecoder
.ReadData(ppData
);
346 wxCHECK_MSG(vImg
.Ok(), FALSE
, wxT("invalid bitmap data"))
348 *this = wxBitmap(vImg
);
353 } // end of wxBitmap::CreateFromXpm
355 bool wxBitmap::LoadFile(
356 const wxString
& rFilename
360 HPS hPs
= NULLHANDLE
;
364 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
370 m_refData
= new wxBitmapRefData
;
372 return(pHandler
->LoadFile( this
384 if (!vImage
.LoadFile(rFilename
, lType
) || !vImage
.Ok() )
387 *this = wxBitmap(vImage
);
391 } // end of wxBitmap::LoadFile
393 bool wxBitmap::Create(
403 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
409 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
410 "type %d defined."), lType
);
415 m_refData
= new wxBitmapRefData
;
417 return(pHandler
->Create( this
424 } // end of wxBitmap::Create
426 bool wxBitmap::SaveFile(
427 const wxString
& rFilename
429 , const wxPalette
* pPalette
432 wxBitmapHandler
* pHandler
= wxDynamicCast( FindHandler(lType
)
438 return pHandler
->SaveFile( this
446 // FIXME what about palette? shouldn't we use it?
447 wxImage vImage
= ConvertToImage();
452 return(vImage
.SaveFile( rFilename
456 } // end of wxBitmap::SaveFile
459 // ----------------------------------------------------------------------------
460 // wxImage-wxBitmap convertion
461 // ----------------------------------------------------------------------------
463 bool wxBitmap::CreateFromImage( const wxImage
& image
, int depth
)
465 wxCHECK_MSG( image
.Ok(), FALSE
, wxT("invalid image") )
469 int sizeLimit = 1024*768*3;
471 // width and height of the device-dependent bitmap
472 int width = GetWidth();
473 int bmpHeight = GetHeight();
475 // calc the number of bytes per scanline and padding
476 int bytePerLine = width*3;
477 int sizeDWORD = sizeof( DWORD );
478 int lineBoundary = bytePerLine % sizeDWORD;
480 if( lineBoundary > 0 )
482 padding = sizeDWORD - lineBoundary;
483 bytePerLine += padding;
485 // calc the number of DIBs and heights of DIBs
488 int height = sizeLimit/bytePerLine;
489 if( height >= bmpHeight )
493 numDIB = bmpHeight / height;
494 hRemain = bmpHeight % height;
495 if( hRemain >0 ) numDIB++;
498 // set bitmap parameters
500 wxCHECK_MSG( Ok(), bitmap, wxT("invalid image") );
501 bitmap.SetWidth( width );
502 bitmap.SetHeight( bmpHeight );
503 bitmap.SetDepth( wxDisplayDepth() );
505 // create a DIB header
506 int headersize = sizeof(BITMAPINFOHEADER);
507 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
508 wxCHECK_MSG( lpDIBh, bitmap, wxT("could not allocate memory for DIB header") );
509 // Fill in the DIB header
510 lpDIBh->bmiHeader.biSize = headersize;
511 lpDIBh->bmiHeader.biWidth = (DWORD)width;
512 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
513 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
514 // the general formula for biSizeImage:
515 // ( ( ( ((DWORD)width*24) +31 ) & ~31 ) >> 3 ) * height;
516 lpDIBh->bmiHeader.biPlanes = 1;
517 lpDIBh->bmiHeader.biBitCount = 24;
518 lpDIBh->bmiHeader.biCompression = BI_RGB;
519 lpDIBh->bmiHeader.biClrUsed = 0;
520 // These seem not really needed for our purpose here.
521 lpDIBh->bmiHeader.biClrImportant = 0;
522 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
523 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
524 // memory for DIB data
525 unsigned char *lpBits;
526 lpBits = (unsigned char *)malloc( lpDIBh->bmiHeader.biSizeImage );
529 wxFAIL_MSG( wxT("could not allocate memory for DIB") );
534 // create and set the device-dependent bitmap
535 HDC hdc = ::GetDC(NULL);
536 HDC memdc = ::CreateCompatibleDC( hdc );
538 hbitmap = ::CreateCompatibleBitmap( hdc, width, bmpHeight );
539 ::SelectObject( memdc, hbitmap);
541 // copy image data into DIB data and then into DDB (in a loop)
542 unsigned char *data = GetData();
545 unsigned char *ptdata = data;
546 unsigned char *ptbits;
548 for( n=0; n<numDIB; n++ )
550 if( numDIB > 1 && n == numDIB-1 && hRemain > 0 )
552 // redefine height and size of the (possibly) last smaller DIB
553 // memory is not reallocated
555 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
556 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
560 for( j=0; j<height; j++ )
562 for( i=0; i<width; i++ )
564 *(ptbits++) = *(ptdata+2);
565 *(ptbits++) = *(ptdata+1);
566 *(ptbits++) = *(ptdata );
569 for( i=0; i< padding; i++ ) *(ptbits++) = 0;
571 ::StretchDIBits( memdc, 0, origin, width, height,\
572 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
574 // if numDIB = 1, lines below can also be used
575 // hbitmap = CreateDIBitmap( hdc, &(lpDIBh->bmiHeader), CBM_INIT, lpBits, lpDIBh, DIB_RGB_COLORS );
576 // The above line is equivalent to the following two lines.
577 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
578 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
579 // or the following lines
580 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
581 // HDC memdc = ::CreateCompatibleDC( hdc );
582 // ::SelectObject( memdc, hbitmap);
583 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
584 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
585 // ::SelectObject( memdc, 0 );
586 // ::DeleteDC( memdc );
588 bitmap.SetHBITMAP( (WXHBITMAP) hbitmap );
590 // similarly, created an mono-bitmap for the possible mask
593 hbitmap = ::CreateBitmap( (WORD)width, (WORD)bmpHeight, 1, 1, NULL );
594 ::SelectObject( memdc, hbitmap);
595 if( numDIB == 1 ) height = bmpHeight;
596 else height = sizeLimit/bytePerLine;
597 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
598 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
600 unsigned char r = GetMaskRed();
601 unsigned char g = GetMaskGreen();
602 unsigned char b = GetMaskBlue();
603 unsigned char zero = 0, one = 255;
605 for( n=0; n<numDIB; n++ )
607 if( numDIB > 1 && n == numDIB - 1 && hRemain > 0 )
609 // redefine height and size of the (possibly) last smaller DIB
610 // memory is not reallocated
612 lpDIBh->bmiHeader.biHeight = (DWORD)(-height);
613 lpDIBh->bmiHeader.biSizeImage = bytePerLine*height;
616 for( int j=0; j<height; j++ )
618 for(i=0; i<width; i++ )
620 if( (*(ptdata++)!=r) | (*(ptdata++)!=g) | (*(ptdata++)!=b) )
633 for( i=0; i< padding; i++ ) *(ptbits++) = zero;
635 ::StretchDIBits( memdc, 0, origin, width, height,\
636 0, 0, width, height, lpBits, lpDIBh, DIB_RGB_COLORS, SRCCOPY);
639 // create a wxMask object
640 wxMask *mask = new wxMask();
641 mask->SetMaskBitmap( (WXHBITMAP) hbitmap );
642 bitmap.SetMask( mask );
645 // free allocated resources
646 ::SelectObject( memdc, 0 );
648 ::ReleaseDC(NULL, hdc);
652 // check the wxBitmap object
653 if( bitmap.GetHBITMAP() )
654 bitmap.SetOk( TRUE );
656 bitmap.SetOk( FALSE );
662 wxImage
wxBitmap::ConvertToImage() const
666 wxCHECK_MSG( Ok(), wxNullImage
, wxT("invalid bitmap") );
668 // create an wxImage object
669 int width
= GetWidth();
670 int height
= GetHeight();
671 image
.Create( width
, height
);
672 unsigned char *data
= image
.GetData();
675 wxFAIL_MSG( wxT("could not allocate data for image") );
679 // calc the number of bytes per scanline and padding in the DIB
680 int bytePerLine
= width
*3;
681 int sizeDWORD
= sizeof( DWORD
);
682 int lineBoundary
= bytePerLine
% sizeDWORD
;
684 if( lineBoundary
> 0 )
686 padding
= sizeDWORD
- lineBoundary
;
687 bytePerLine
+= padding
;
691 // create a DIB header
692 int headersize = sizeof(BITMAPINFOHEADER);
693 LPBITMAPINFO lpDIBh = (BITMAPINFO *) malloc( headersize );
696 wxFAIL_MSG( wxT("could not allocate data for DIB header") );
700 // Fill in the DIB header
701 lpDIBh->bmiHeader.biSize = headersize;
702 lpDIBh->bmiHeader.biWidth = width;
703 lpDIBh->bmiHeader.biHeight = -height;
704 lpDIBh->bmiHeader.biSizeImage = bytePerLine * height;
705 lpDIBh->bmiHeader.biPlanes = 1;
706 lpDIBh->bmiHeader.biBitCount = 24;
707 lpDIBh->bmiHeader.biCompression = BI_RGB;
708 lpDIBh->bmiHeader.biClrUsed = 0;
709 // These seem not really needed for our purpose here.
710 lpDIBh->bmiHeader.biClrImportant = 0;
711 lpDIBh->bmiHeader.biXPelsPerMeter = 0;
712 lpDIBh->bmiHeader.biYPelsPerMeter = 0;
713 // memory for DIB data
714 unsigned char *lpBits;
715 lpBits = (unsigned char *) malloc( lpDIBh->bmiHeader.biSizeImage );
718 wxFAIL_MSG( wxT("could not allocate data for DIB") );
724 // copy data from the device-dependent bitmap to the DIB
725 HDC hdc = ::GetDC(NULL);
727 hbitmap = (HBITMAP) bitmap.GetHBITMAP();
728 ::GetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
730 // copy DIB data into the wxImage object
732 unsigned char *ptdata = data;
733 unsigned char *ptbits = lpBits;
734 for( i=0; i<height; i++ )
736 for( j=0; j<width; j++ )
738 *(ptdata++) = *(ptbits+2);
739 *(ptdata++) = *(ptbits+1);
740 *(ptdata++) = *(ptbits );
746 // similarly, set data according to the possible mask bitmap
747 if( bitmap.GetMask() && bitmap.GetMask()->GetMaskBitmap() )
749 hbitmap = (HBITMAP) bitmap.GetMask()->GetMaskBitmap();
750 // memory DC created, color set, data copied, and memory DC deleted
751 HDC memdc = ::CreateCompatibleDC( hdc );
752 ::SetTextColor( memdc, RGB( 0, 0, 0 ) );
753 ::SetBkColor( memdc, RGB( 255, 255, 255 ) );
754 ::GetDIBits( memdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS );
756 // background color set to RGB(16,16,16) in consistent with wxGTK
757 unsigned char r=16, g=16, b=16;
760 for( i=0; i<height; i++ )
762 for( j=0; j<width; j++ )
776 SetMaskColour( r, g, b );
783 // free allocated resources
784 ::ReleaseDC(NULL, hdc);
793 // ----------------------------------------------------------------------------
794 // sub bitmap extraction
795 // ----------------------------------------------------------------------------
797 wxBitmap
wxBitmap::GetSubBitmap(
802 (rRect
.x
>= 0) && (rRect
.y
>= 0) &&
803 (rRect
.x
+ rRect
.width
<= GetWidth()) &&
804 (rRect
.y
+ rRect
.height
<= GetHeight()),
805 wxNullBitmap
, wxT("Invalid bitmap or bitmap region") );
807 wxBitmap
vRet( rRect
.width
811 wxASSERT_MSG( vRet
.Ok(), wxT("GetSubBitmap error") );
817 SIZEL vSize
= {0, 0};
818 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
819 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
820 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
821 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
822 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
823 POINTL vPoint
[4] = { rRect
.x
, rRect
.y
,
824 rRect
.x
+ rRect
.width
, rRect
.y
+ rRect
.height
,
825 0, 0, GetWidth(), GetHeight()
828 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
829 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
839 // Copy mask if there is one
843 BITMAPINFOHEADER2 vBmih
;
845 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
846 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
847 vBmih
.cx
= rRect
.width
;
848 vBmih
.cy
= rRect
.height
;
852 HBITMAP hBmpMask
= ::GpiCreateBitmap( hPSDst
859 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetHBITMAP());
860 ::GpiSetBitmap(hPSDst
, (HBITMAP
) vRet
.GetHBITMAP());
862 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) GetMask()->GetMaskBitmap());
863 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpMask
);
872 wxMask
* pMask
= new wxMask((WXHBITMAP
)hBmpMask
);
876 ::GpiSetBitmap(hPSSrc
, NULL
);
877 ::GpiSetBitmap(hPSDst
, NULL
);
878 ::GpiDestroyPS(hPSSrc
);
879 ::GpiDestroyPS(hPSDst
);
880 ::DevCloseDC(hDCSrc
);
881 ::DevCloseDC(hDCDst
);
883 } // end of wxBitmap::GetSubBitmap
885 // ----------------------------------------------------------------------------
886 // wxBitmap accessors
887 // ----------------------------------------------------------------------------
889 void wxBitmap::SetQuality(
895 GetBitmapData()->m_nQuality
= nQ
;
896 } // end of wxBitmap::SetQuality
898 #if WXWIN_COMPATIBILITY_2
899 void wxBitmap::SetOk(
905 GetBitmapData()->m_bOk
= bOk
;
906 } // end of wxBitmap::SetOk
907 #endif // WXWIN_COMPATIBILITY_2
909 void wxBitmap::SetPalette(
910 const wxPalette
& rPalette
915 GetBitmapData()->m_vBitmapPalette
= rPalette
;
916 } // end of wxBitmap::SetPalette
918 void wxBitmap::SetMask(
924 GetBitmapData()->m_pBitmapMask
= pMask
;
925 } // end of wxBitmap::SetMask
928 // Will try something for OS/2 but not really sure how close
929 // to the msw intent this is.
931 wxBitmap
wxBitmap::GetBitmapForDC(
936 wxBitmap
vTmpBitmap( this->GetWidth()
940 WXHBITMAP vOldBitmap
;
946 hMemoryPS
= ::GpiCreatePS(vHabmain
, (HDC
)vMemDC
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
947 hPs
= ::GpiCreatePS(vHabmain
, (HDC
)rDc
.GetHDC(), &vSize
, PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
);
949 // TODO: Set the points
951 vOldBitmap
= (WXHBITMAP
)::GpiSetBitmap(hPs
, (HBITMAP
)vTmpBitmap
.GetHBITMAP());
952 ::GpiBitBlt(hPs
, hMemoryPS
, 4L, vPoint
, ROP_SRCCOPY
, BBO_IGNORE
);
955 } // end of wxBitmap::GetBitmapForDC
957 // ----------------------------------------------------------------------------
959 // ----------------------------------------------------------------------------
964 } // end of wxMask::wxMask
966 // Construct a mask from a bitmap and a colour indicating
967 // the transparent area
969 const wxBitmap
& rBitmap
970 , const wxColour
& rColour
977 } // end of wxMask::wxMask
979 // Construct a mask from a bitmap and a palette index indicating
980 // the transparent area
982 const wxBitmap
& rBitmap
990 } // end of wxMask::wxMask
992 // Construct a mask from a mono bitmap (copies the bitmap).
994 const wxBitmap
& rBitmap
999 } // end of wxMask::wxMask
1004 ::GpiDeleteBitmap((HBITMAP
)m_hMaskBitmap
);
1005 } // end of wxMask::~wxMask
1007 // Create a mask from a mono bitmap (copies the bitmap).
1008 bool wxMask::Create(
1009 const wxBitmap
& rBitmap
1012 BITMAPINFOHEADER2 vBmih
;
1013 SIZEL vSize
= {0, 0};
1014 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1015 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1016 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1017 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1018 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1019 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1020 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1025 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1028 if (!rBitmap
.Ok() || rBitmap
.GetDepth() != 1)
1033 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1034 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1035 vBmih
.cx
= rBitmap
.GetWidth();
1036 vBmih
.cy
= rBitmap
.GetHeight();
1038 vBmih
.cBitCount
= 1;
1040 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1047 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1048 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1057 ::GpiDestroyPS(hPSSrc
);
1058 ::GpiDestroyPS(hPSDst
);
1059 ::DevCloseDC(hDCSrc
);
1060 ::DevCloseDC(hDCDst
);
1062 } // end of wxMask::Create
1064 // Create a mask from a bitmap and a palette index indicating
1065 // the transparent area
1066 bool wxMask::Create(
1067 const wxBitmap
& rBitmap
1073 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1076 if (rBitmap
.Ok() && rBitmap
.GetPalette()->Ok())
1079 unsigned char cGreen
;
1080 unsigned char cBlue
;
1082 if (rBitmap
.GetPalette()->GetRGB( nPaletteIndex
1088 wxColour
vTransparentColour( cRed
1093 return (Create( rBitmap
1099 } // end of wxMask::Create
1101 // Create a mask from a bitmap and a colour indicating
1102 // the transparent area
1103 bool wxMask::Create(
1104 const wxBitmap
& rBitmap
1105 , const wxColour
& rColour
1109 COLORREF vMaskColour
= OS2RGB( rColour
.Red()
1113 BITMAPINFOHEADER2 vBmih
;
1114 SIZEL vSize
= {0, 0};
1115 DEVOPENSTRUC vDop
= { NULL
, "DISPLAY", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1116 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1117 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1118 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1119 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1120 POINTL vPoint
[4] = { 0 ,0, rBitmap
.GetWidth(), rBitmap
.GetHeight(),
1121 0, 0, rBitmap
.GetWidth(), rBitmap
.GetHeight()
1126 ::GpiDeleteBitmap((HBITMAP
) m_hMaskBitmap
);
1135 // Scan the bitmap for the transparent colour and set
1136 // the corresponding pixels in the mask to BLACK and
1137 // the rest to WHITE
1140 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1141 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1142 vBmih
.cx
= rBitmap
.GetWidth();
1143 vBmih
.cy
= rBitmap
.GetHeight();
1145 vBmih
.cBitCount
= 1;
1147 m_hMaskBitmap
= ::GpiCreateBitmap( hPSDst
1154 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) rBitmap
.GetHBITMAP());
1155 ::GpiSetBitmap(hPSDst
, (HBITMAP
) m_hMaskBitmap
);
1158 // This is not very efficient, but I can't think
1159 // of a better way of doing it
1161 for (int w
= 0; w
< rBitmap
.GetWidth(); w
++)
1163 for (int h
= 0; h
< rBitmap
.GetHeight(); h
++)
1165 POINTL vPt
= {w
, h
};
1166 COLORREF vCol
= (COLORREF
)::GpiQueryPel(hPSSrc
, &vPt
);
1167 if (vCol
== (COLORREF
)CLR_NOINDEX
)
1170 // Doesn't make sense to continue
1176 if (vCol
== vMaskColour
)
1178 ::GpiSetColor(hPSDst
, OS2RGB(0, 0, 0));
1179 ::GpiSetPel(hPSDst
, &vPt
);
1183 ::GpiSetColor(hPSDst
, OS2RGB(255, 255, 255));
1184 ::GpiSetPel(hPSDst
, &vPt
);
1188 ::GpiSetBitmap(hPSSrc
, NULL
);
1189 ::GpiSetBitmap(hPSDst
, NULL
);
1190 ::GpiDestroyPS(hPSSrc
);
1191 ::GpiDestroyPS(hPSDst
);
1192 ::DevCloseDC(hDCSrc
);
1193 ::DevCloseDC(hDCDst
);
1195 } // end of wxMask::Create
1197 // ----------------------------------------------------------------------------
1199 // ----------------------------------------------------------------------------
1201 bool wxBitmapHandler::Create(
1210 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1214 return(pBitmap
? Create( pBitmap
1222 bool wxBitmapHandler::Load(
1224 , const wxString
& rName
1231 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1235 return(pBitmap
? LoadFile( pBitmap
1244 bool wxBitmapHandler::Save(
1246 , const wxString
& rName
1250 wxBitmap
* pBitmap
= wxDynamicCast( pImage
1254 return(pBitmap
? SaveFile( pBitmap
1260 bool wxBitmapHandler::Create(
1261 wxBitmap
* WXUNUSED(pBitmap
)
1262 , void* WXUNUSED(pData
)
1263 , long WXUNUSED(lType
)
1264 , int WXUNUSED(nWidth
)
1265 , int WXUNUSED(nHeight
)
1266 , int WXUNUSED(nDepth
)
1272 bool wxBitmapHandler::LoadFile(
1273 wxBitmap
* WXUNUSED(pBitmap
)
1274 , const wxString
& WXUNUSED(rName
)
1276 , long WXUNUSED(lType
)
1277 , int WXUNUSED(nDesiredWidth
)
1278 , int WXUNUSED(nDesiredHeight
)
1284 bool wxBitmapHandler::SaveFile(
1285 wxBitmap
* WXUNUSED(pBitmap
)
1286 , const wxString
& WXUNUSED(rName
)
1287 , int WXUNUSED(nType
)
1288 , const wxPalette
* WXUNUSED(pPalette
)
1294 // ----------------------------------------------------------------------------
1295 // Utility functions
1296 // ----------------------------------------------------------------------------
1297 HBITMAP
wxInvertMask(
1303 HBITMAP hBmpInvMask
= 0;
1305 wxCHECK_MSG( hBmpMask
, 0, _T("invalid bitmap in wxInvertMask") );
1308 // Get width/height from the bitmap if not given
1310 if (!nWidth
|| !nHeight
)
1312 BITMAPINFOHEADER2 vBmhdr
;
1314 ::GpiQueryBitmapInfoHeader( hBmpMask
1317 nWidth
= (int)vBmhdr
.cx
;
1318 nHeight
= (int)vBmhdr
.cy
;
1321 BITMAPINFOHEADER2 vBmih
;
1322 SIZEL vSize
= {0, 0};
1323 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
1324 HDC hDCSrc
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1325 HDC hDCDst
= ::DevOpenDC(vHabmain
, OD_MEMORY
, "*", 5L, (PDEVOPENDATA
)&vDop
, NULLHANDLE
);
1326 HPS hPSSrc
= ::GpiCreatePS(vHabmain
, hDCSrc
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1327 HPS hPSDst
= ::GpiCreatePS(vHabmain
, hDCDst
, &vSize
, PU_PELS
| GPIA_ASSOC
);
1328 POINTL vPoint
[4] = { 0 ,0, nWidth
, nHeight
,
1329 0, 0, nWidth
, nHeight
1332 memset(&vBmih
, '\0', sizeof(BITMAPINFOHEADER2
));
1333 vBmih
.cbFix
= sizeof(BITMAPINFOHEADER2
);
1337 vBmih
.cBitCount
= 1;
1339 hBmpInvMask
= ::GpiCreateBitmap( hPSDst
1346 ::GpiSetBitmap(hPSSrc
, (HBITMAP
) hBmpMask
);
1347 ::GpiSetBitmap(hPSDst
, (HBITMAP
) hBmpInvMask
);
1357 ::GpiDestroyPS(hPSSrc
);
1358 ::GpiDestroyPS(hPSDst
);
1359 ::DevCloseDC(hDCSrc
);
1360 ::DevCloseDC(hDCDst
);
1363 } // end of WxWinGdi_InvertMask