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::LoadFile(const wxString& filename, long type)
387 wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler);
391 m_refData = new wxBitmapRefData;
393 return handler->LoadFile(this, filename, type, -1, -1);
396 else // no bitmap handler found
399 if ( image.LoadFile( filename, type ) && image.Ok() )
401 *this = wxBitmap(image);
406 #endif // wxUSE_IMAGE
411 bool wxBitmap::LoadFile(
418 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
424 m_refData = new wxBitmapRefData;
426 return(pHandler->LoadFile( this
437 } // end of wxBitmap::LoadFile
439 bool wxBitmap::Create(
449 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
455 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for type %ld defined."), lType);
460 m_refData = new wxBitmapRefData;
462 return(pHandler->Create( this
469 } // end of wxBitmap::Create
471 bool wxBitmap::SaveFile(
472 const wxString& rFilename
474 , const wxPalette* pPalette
477 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
483 return pHandler->SaveFile( this
491 // FIXME what about palette? shouldn't we use it?
492 wxImage vImage = ConvertToImage();
497 return(vImage.SaveFile( rFilename
501 } // end of wxBitmap::SaveFile
504 // ----------------------------------------------------------------------------
505 // wxImage-wxBitmap conversion
506 // ----------------------------------------------------------------------------
508 bool wxBitmap::CreateFromImage (
509 const wxImage& rImage
513 wxCHECK_MSG(rImage.Ok(), false, wxT("invalid image"));
514 m_refData = new wxBitmapRefData();
516 int nSizeLimit = 1024 * 768 * 3;
517 int nWidth = rImage.GetWidth();
518 int nBmpHeight = rImage.GetHeight();
519 int nBytePerLine = nWidth * 3;
520 int nSizeDWORD = sizeof(DWORD);
521 int nLineBoundary = nBytePerLine % nSizeDWORD;
524 if (nLineBoundary > 0)
526 nPadding = nSizeDWORD - nLineBoundary;
527 nBytePerLine += nPadding;
531 // Calc the number of DIBs and heights of DIBs
535 int nHeight = nSizeLimit / nBytePerLine;
537 if (nHeight >= nBmpHeight)
538 nHeight = nBmpHeight;
541 nNumDIB = nBmpHeight / nHeight;
542 nHRemain = nBmpHeight % nHeight;
548 // Set bitmap parameters
550 wxCHECK_MSG(rImage.Ok(), false, wxT("invalid image"));
552 SetHeight(nBmpHeight);
558 nDepth = wxDisplayDepth();
563 // Copy the palette from the source image
565 SetPalette(rImage.GetPalette());
566 #endif // wxUSE_PALETTE
569 // Create a DIB header
571 BITMAPINFOHEADER2 vHeader;
575 // Fill in the DIB header
577 memset(&vHeader, '\0', 16);
579 vHeader.cx = (ULONG)nWidth;
580 vHeader.cy = (ULONG)nHeight;
581 vHeader.cPlanes = 1L;
582 vHeader.cBitCount = 24;
585 // Memory for DIB data
587 unsigned char* pucBits;
589 pucBits = (unsigned char *)malloc(nBytePerLine * nHeight);
592 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
595 memset(pucBits, '\0', (nBytePerLine * nHeight));
598 // Create and set the device-dependent bitmap
600 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
601 SIZEL vSize = {0, 0};
602 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
603 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
605 HDC hDCScreen = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
610 memset(&vInfo, '\0', 16);
612 vInfo.cx = (ULONG)nWidth;
613 vInfo.cy = (ULONG)nHeight;
615 vInfo.cBitCount = 24; // Set to desired count going in
617 hBmp = ::GpiCreateBitmap( hPS
624 HPAL hOldPalette = NULLHANDLE;
625 if (rImage.GetPalette().Ok())
627 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
629 #endif // wxUSE_PALETTE
632 // Copy image data into DIB data and then into DDB (in a loop)
634 unsigned char* pData = rImage.GetData();
639 unsigned char* ptdata = pData;
640 unsigned char* ptbits;
642 if ((hBmpOld = ::GpiSetBitmap(hPS, hBmp)) == HBM_ERROR)
647 vError = ::WinGetLastError(vHabmain);
648 sError = wxPMErrorToStr(vError);
650 for (n = 0; n < nNumDIB; n++)
652 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
655 // Redefine height and size of the (possibly) last smaller DIB
656 // memory is not reallocated
659 vHeader.cy = (DWORD)(nHeight);
660 vHeader.cbImage = nBytePerLine * nHeight;
663 for (j = 0; j < nHeight; j++)
665 for (i = 0; i < nWidth; i++)
667 *(ptbits++) = *(ptdata + 2);
668 *(ptbits++) = *(ptdata + 1);
669 *(ptbits++) = *(ptdata);
672 for (i = 0; i < nPadding; i++)
677 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
678 // in combination with setting the bits into the selected bitmap
680 if ((lScans = ::GpiSetBitmapBits( hPS
681 ,0 // Start at the bottom
682 ,(LONG)nHeight // One line per scan
690 vError = ::WinGetLastError(vHabmain);
691 sError = wxPMErrorToStr(vError);
693 hPSScreen = ::GpiCreatePS( vHabmain
696 ,PU_PELS | GPIA_ASSOC
699 POINTL vPoint[4] = { {0, nOrigin},
701 {0, 0}, {nWidth, nHeight}
705 ::GpiBitBlt( hPSScreen
712 ::GpiDestroyPS(hPSScreen);
715 SetHBITMAP((WXHBITMAP)hBmp);
718 ::GpiSelectPalette(hPS, hOldPalette);
719 #endif // wxUSE_PALETTE
722 // Similarly, created an mono-bitmap for the possible mask
724 if (rImage.HasMask())
728 vHeader.cy = nHeight;
730 vHeader.cBitCount = 24;
731 hBmp = ::GpiCreateBitmap( hPS
737 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
739 nHeight = nBmpHeight;
741 nHeight = nSizeLimit / nBytePerLine;
742 vHeader.cy = (DWORD)(nHeight);
745 unsigned char cRed = rImage.GetMaskRed();
746 unsigned char cGreen = rImage.GetMaskGreen();
747 unsigned char cBlue = rImage.GetMaskBlue();
748 unsigned char cZero = 0;
749 unsigned char cOne = 255;
752 for (n = 0; n < nNumDIB; n++)
754 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
757 // Redefine height and size of the (possibly) last smaller DIB
758 // memory is not reallocated
761 vHeader.cy = (DWORD)(nHeight);
762 vHeader.cbImage = nBytePerLine * nHeight;
765 for (int j = 0; j < nHeight; j++)
767 for (i = 0; i < nWidth; i++)
769 unsigned char cRedImage = (*(ptdata++)) ;
770 unsigned char cGreenImage = (*(ptdata++)) ;
771 unsigned char cBlueImage = (*(ptdata++)) ;
773 if ((cRedImage != cRed) || (cGreenImage != cGreen) || (cBlueImage != cBlue))
786 for (i = 0; i < nPadding; i++)
789 lScans = ::GpiSetBitmapBits( hPS
790 ,0 // Start at the bottom
791 ,(LONG)nHeight // One line per scan
795 hPSScreen = ::GpiCreatePS( vHabmain
798 ,PU_PELS | GPIA_ASSOC
800 POINTL vPoint2[4] = { {0, nOrigin},
802 {0, 0}, {nWidth, nHeight}
804 ::GpiBitBlt( hPSScreen
811 ::GpiDestroyPS(hPSScreen);
816 // Create a wxMask object
818 wxMask* pMask = new wxMask();
820 pMask->SetMaskBitmap((WXHBITMAP)hBmp);
822 hBmpOld = ::GpiSetBitmap(hPS, hBmpOld);
826 // Free allocated resources
828 ::GpiSetBitmap(hPS, NULLHANDLE);
830 ::DevCloseDC(hDCScreen);
834 } // end of wxBitmap::CreateFromImage
836 wxImage wxBitmap::ConvertToImage() const
841 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
844 // Create an wxImage object
846 int nWidth = GetWidth();
847 int nHeight = GetHeight();
850 int nBytePerLine = nWidth * 3;
851 int nSizeDWORD = sizeof(DWORD);
852 int nLineBoundary = nBytePerLine % nSizeDWORD;
854 unsigned char* pData;
855 unsigned char* lpBits;
857 BITMAPINFOHEADER2 vDIBh;
858 BITMAPINFO2 vDIBInfo;
862 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
863 SIZEL vSizlPage = {0,0};
864 HDC hDCMem = NULLHANDLE;
866 vImage.Create( nWidth
869 pData = vImage.GetData();
872 wxFAIL_MSG( wxT("could not allocate data for image") );
875 if(nLineBoundary > 0)
877 nPadding = nSizeDWORD - nLineBoundary;
878 nBytePerLine += nPadding;
880 wxDisplaySize( &nDevWidth
884 // Create and fill a DIB header
886 memset(&vDIBh, '\0', 16);
891 vDIBh.cBitCount = 24;
893 memset(&vDIBInfo, '\0', 16);
895 vDIBInfo.cx = nWidth;
896 vDIBInfo.cy = nHeight;
897 vDIBInfo.cPlanes = 1;
898 vDIBInfo.cBitCount = 24;
900 lpBits = (unsigned char *)malloc(nBytePerLine * nHeight);
903 wxFAIL_MSG(wxT("could not allocate data for DIB"));
907 memset(lpBits, '\0', (nBytePerLine * nHeight));
908 hBitmap = (HBITMAP)GetHBITMAP();
911 // May already be selected into a PS
913 if ((pDC = GetSelectedInto()) != NULL)
915 hPSMem = pDC->GetHPS();
919 hDCMem = ::DevOpenDC( vHabmain
926 hPSMem = ::GpiCreatePS( vHabmain
929 ,PU_PELS | GPIA_ASSOC
932 if ((hOldBitmap = ::GpiSetBitmap(hPSMem, hBitmap)) == HBM_ERROR)
937 vError = ::WinGetLastError(vHabmain);
938 sError = wxPMErrorToStr(vError);
942 // Copy data from the device-dependent bitmap to the DIB
944 if ((lScans = ::GpiQueryBitmapBits( hPSMem
954 vError = ::WinGetLastError(vHabmain);
955 sError = wxPMErrorToStr(vError);
959 // Copy DIB data into the wxImage object
963 unsigned char* ptdata = pData;
964 unsigned char* ptbits = lpBits;
966 for (i = 0; i < nHeight; i++)
968 for (j = 0; j < nWidth; j++)
970 *(ptdata++) = *(ptbits+2);
971 *(ptdata++) = *(ptbits+1);
972 *(ptdata++) = *(ptbits );
977 if ((pDC = GetSelectedInto()) == NULL)
979 ::GpiSetBitmap(hPSMem, NULLHANDLE);
980 ::GpiDestroyPS(hPSMem);
981 ::DevCloseDC(hDCMem);
985 // Similarly, set data according to the possible mask bitmap
987 if (GetMask() && GetMask()->GetMaskBitmap())
989 hBitmap = (HBITMAP)GetMask()->GetMaskBitmap();
992 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
994 HDC hMemDC = ::DevOpenDC( vHabmain
1001 HPS hMemPS = ::GpiCreatePS( vHabmain
1004 ,PU_PELS | GPIA_ASSOC
1006 ::GpiSetColor(hMemPS, OS2RGB(0, 0, 0));
1007 ::GpiSetBackColor(hMemPS, OS2RGB(255, 255, 255) );
1008 ::GpiSetBitmap(hMemPS, hBitmap);
1009 ::GpiQueryBitmapBits( hPSMem
1015 ::GpiSetBitmap(hMemPS, NULLHANDLE);
1016 ::GpiDestroyPS(hMemPS);
1017 ::DevCloseDC(hMemDC);
1020 // Background color set to RGB(16,16,16) in consistent with wxGTK
1022 unsigned char ucRed = 16;
1023 unsigned char ucGreen = 16;
1024 unsigned char ucBlue = 16;
1028 for (i = 0; i < nHeight; i++)
1030 for (j = 0; j < nWidth; j++)
1036 *(ptdata++) = ucRed;
1037 *(ptdata++) = ucGreen;
1038 *(ptdata++) = ucBlue;
1044 vImage.SetMaskColour( ucRed
1048 vImage.SetMask(true);
1052 vImage.SetMask(false);
1056 // Free allocated resources
1060 } // end of wxBitmap::ConvertToImage
1062 // ----------------------------------------------------------------------------
1063 // sub bitmap extraction
1064 // ----------------------------------------------------------------------------
1066 wxBitmap wxBitmap::GetSubBitmap(
1070 wxCHECK_MSG( Ok() &&
1071 (rRect.x >= 0) && (rRect.y >= 0) &&
1072 (rRect.x + rRect.width <= GetWidth()) &&
1073 (rRect.y + rRect.height <= GetHeight()),
1074 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
1076 wxBitmap vRet( rRect.width
1080 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
1086 SIZEL vSize = {0, 0};
1087 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1088 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1089 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1090 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1091 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1092 POINTL vPoint[4] = { {0, 0}, {rRect.width, rRect.height},
1094 {rRect.x + rRect.width, rRect.y + rRect.height}
1097 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1098 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1108 // Copy mask if there is one
1112 BITMAPINFOHEADER2 vBmih;
1114 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1115 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1116 vBmih.cx = rRect.width;
1117 vBmih.cy = rRect.height;
1119 vBmih.cBitCount = 24;
1121 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
1128 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1129 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1131 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
1132 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
1141 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
1142 vRet.SetMask(pMask);
1145 ::GpiSetBitmap(hPSSrc, NULL);
1146 ::GpiSetBitmap(hPSDst, NULL);
1147 ::GpiDestroyPS(hPSSrc);
1148 ::GpiDestroyPS(hPSDst);
1149 ::DevCloseDC(hDCSrc);
1150 ::DevCloseDC(hDCDst);
1152 } // end of wxBitmap::GetSubBitmap
1154 // ----------------------------------------------------------------------------
1155 // wxBitmap accessors
1156 // ----------------------------------------------------------------------------
1158 void wxBitmap::SetQuality(
1164 GetBitmapData()->m_nQuality = nQ;
1165 } // end of wxBitmap::SetQuality
1167 void wxBitmap::SetPalette(
1168 const wxPalette& rPalette
1173 GetBitmapData()->m_vBitmapPalette = rPalette;
1174 } // end of wxBitmap::SetPalette
1176 void wxBitmap::SetMask(
1182 GetBitmapData()->m_pBitmapMask = pMask;
1183 } // end of wxBitmap::SetMask
1185 wxBitmap wxBitmap::GetBitmapForDC(wxDC& WXUNUSED(rDc)) const
1188 } // end of wxBitmap::GetBitmapForDC
1190 // ----------------------------------------------------------------------------
1192 // ----------------------------------------------------------------------------
1197 } // end of wxMask::wxMask
1199 // Construct a mask from a bitmap and a colour indicating
1200 // the transparent area
1202 const wxBitmap& rBitmap
1203 , const wxColour& rColour
1210 } // end of wxMask::wxMask
1212 // Construct a mask from a bitmap and a palette index indicating
1213 // the transparent area
1215 const wxBitmap& rBitmap
1223 } // end of wxMask::wxMask
1225 // Construct a mask from a mono bitmap (copies the bitmap).
1227 const wxBitmap& rBitmap
1232 } // end of wxMask::wxMask
1237 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
1238 } // end of wxMask::~wxMask
1240 // Create a mask from a mono bitmap (copies the bitmap).
1241 bool wxMask::Create(
1242 const wxBitmap& rBitmap
1245 BITMAPINFOHEADER2 vBmih;
1246 SIZEL vSize = {0, 0};
1247 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1248 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1249 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1250 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1251 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1252 POINTL vPoint[4] = { {0 ,0}, {rBitmap.GetWidth(), rBitmap.GetHeight()},
1253 {0, 0}, {rBitmap.GetWidth(), rBitmap.GetHeight()}
1258 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1261 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
1266 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1267 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1268 vBmih.cx = rBitmap.GetWidth();
1269 vBmih.cy = rBitmap.GetHeight();
1271 vBmih.cBitCount = 24;
1273 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1280 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1281 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1290 ::GpiDestroyPS(hPSSrc);
1291 ::GpiDestroyPS(hPSDst);
1292 ::DevCloseDC(hDCSrc);
1293 ::DevCloseDC(hDCDst);
1295 } // end of wxMask::Create
1297 // Create a mask from a bitmap and a palette index indicating
1298 // the transparent area
1299 bool wxMask::Create(
1300 const wxBitmap& rBitmap
1306 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1309 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
1312 unsigned char cGreen;
1313 unsigned char cBlue;
1315 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
1321 wxColour vTransparentColour( cRed
1326 return (Create( rBitmap
1332 } // end of wxMask::Create
1334 // Create a mask from a bitmap and a colour indicating
1335 // the transparent area
1336 bool wxMask::Create(
1337 const wxBitmap& rBitmap
1338 , const wxColour& rColour
1342 COLORREF vMaskColour = OS2RGB( rColour.Red()
1346 BITMAPINFOHEADER2 vBmih;
1347 SIZEL vSize = {0, 0};
1348 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1349 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1350 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1351 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1352 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1356 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1365 // Scan the bitmap for the transparent colour and set
1366 // the corresponding pixels in the mask to BLACK and
1367 // the rest to WHITE
1370 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1371 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1372 vBmih.cx = rBitmap.GetWidth();
1373 vBmih.cy = rBitmap.GetHeight();
1375 vBmih.cBitCount = 1;
1377 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1384 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1385 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1388 // This is not very efficient, but I can't think
1389 // of a better way of doing it
1391 for (int w = 0; w < rBitmap.GetWidth(); w++)
1393 for (int h = 0; h < rBitmap.GetHeight(); h++)
1395 POINTL vPt = {w, h};
1396 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1397 if (vCol == (COLORREF)CLR_NOINDEX)
1400 // Doesn't make sense to continue
1406 if (vCol == vMaskColour)
1408 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1409 ::GpiSetPel(hPSDst, &vPt);
1413 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1414 ::GpiSetPel(hPSDst, &vPt);
1418 ::GpiSetBitmap(hPSSrc, NULL);
1419 ::GpiSetBitmap(hPSDst, NULL);
1420 ::GpiDestroyPS(hPSSrc);
1421 ::GpiDestroyPS(hPSDst);
1422 ::DevCloseDC(hDCSrc);
1423 ::DevCloseDC(hDCDst);
1425 } // end of wxMask::Create
1427 // ----------------------------------------------------------------------------
1429 // ----------------------------------------------------------------------------
1431 bool wxBitmapHandler::Create( wxGDIImage* pImage,
1433 long WXUNUSED(lFlags),
1438 wxBitmap* pBitmap = wxDynamicCast( pImage
1442 return(pBitmap ? Create( pBitmap
1450 bool wxBitmapHandler::Load(
1458 wxBitmap* pBitmap = wxDynamicCast( pImage
1462 return(pBitmap ? LoadFile( pBitmap
1470 bool wxBitmapHandler::Save(
1472 , const wxString& rName
1476 wxBitmap* pBitmap = wxDynamicCast( pImage
1480 return(pBitmap ? SaveFile( pBitmap
1486 bool wxBitmapHandler::Create(
1487 wxBitmap* WXUNUSED(pBitmap)
1488 , const void* WXUNUSED(pData)
1489 , long WXUNUSED(lType)
1490 , int WXUNUSED(nWidth)
1491 , int WXUNUSED(nHeight)
1492 , int WXUNUSED(nDepth)
1498 bool wxBitmapHandler::LoadFile(
1499 wxBitmap* WXUNUSED(pBitmap)
1501 , long WXUNUSED(lType)
1502 , int WXUNUSED(nDesiredWidth)
1503 , int WXUNUSED(nDesiredHeight)
1509 bool wxBitmapHandler::LoadFile(
1510 wxBitmap* WXUNUSED(pBitmap)
1511 , const wxString& WXUNUSED(rName)
1512 , long WXUNUSED(lType)
1513 , int WXUNUSED(nDesiredWidth)
1514 , int WXUNUSED(nDesiredHeight)
1520 bool wxBitmapHandler::SaveFile(
1521 wxBitmap* WXUNUSED(pBitmap)
1522 , const wxString& WXUNUSED(rName)
1523 , int WXUNUSED(nType)
1524 , const wxPalette* WXUNUSED(pPalette)
1530 // ----------------------------------------------------------------------------
1531 // Utility functions
1532 // ----------------------------------------------------------------------------
1533 HBITMAP wxInvertMask(
1539 HBITMAP hBmpInvMask = 0;
1541 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1544 // Get width/height from the bitmap if not given
1546 if (!nWidth || !nHeight)
1548 BITMAPINFOHEADER2 vBmhdr;
1550 ::GpiQueryBitmapInfoHeader( hBmpMask
1553 nWidth = (int)vBmhdr.cx;
1554 nHeight = (int)vBmhdr.cy;
1557 BITMAPINFOHEADER2 vBmih;
1558 SIZEL vSize = {0, 0};
1559 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1560 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1561 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1562 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1563 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1564 POINTL vPoint[4] = { {0 ,0}, {nWidth, nHeight},
1565 {0, 0}, {nWidth, nHeight}
1568 memset(&vBmih, '\0', 16);
1573 vBmih.cBitCount = 24;
1575 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1582 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1583 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1593 ::GpiDestroyPS(hPSSrc);
1594 ::GpiDestroyPS(hPSDst);
1595 ::DevCloseDC(hDCSrc);
1596 ::DevCloseDC(hDCDst);
1599 } // end of WxWinGdi_InvertMask
1601 HBITMAP wxFlipBmp( HBITMAP hBmp, int nWidth, int nHeight )
1603 wxCHECK_MSG( hBmp, 0, _T("invalid bitmap in wxFlipBmp") );
1606 // Get width/height from the bitmap if not given
1608 if (!nWidth || !nHeight)
1610 BITMAPINFOHEADER2 vBmhdr;
1613 ::GpiQueryBitmapInfoHeader( hBmp,
1615 nWidth = (int)vBmhdr.cx;
1616 nHeight = (int)vBmhdr.cy;
1619 BITMAPINFOHEADER2 vBmih;
1620 SIZEL vSize = {0, 0};
1621 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1622 HDC hDCSrc = ::DevOpenDC( vHabmain,
1626 (PDEVOPENDATA)&vDop,
1628 HDC hDCDst = ::DevOpenDC( vHabmain,
1632 (PDEVOPENDATA)&vDop,
1634 HPS hPSSrc = ::GpiCreatePS( vHabmain,
1637 PU_PELS | GPIA_ASSOC );
1638 HPS hPSDst = ::GpiCreatePS( vHabmain,
1641 PU_PELS | GPIA_ASSOC );
1642 POINTL vPoint[4] = { {0, nHeight},
1645 {nWidth, nHeight} };
1647 memset(&vBmih, '\0', 16);
1652 vBmih.cBitCount = 24;
1654 HBITMAP hInvBmp = ::GpiCreateBitmap( hPSDst,
1660 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmp);
1661 ::GpiSetBitmap(hPSDst, (HBITMAP) hInvBmp);
1663 ::GpiBitBlt( hPSDst,
1670 ::GpiDestroyPS(hPSSrc);
1671 ::GpiDestroyPS(hPSDst);
1672 ::DevCloseDC(hDCSrc);
1673 ::DevCloseDC(hDCDst);
1676 } // end of wxFlipBmp