Toolbar updates
[wxWidgets.git] / src / os2 / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: David Webster
5 // Modified by:
6 // Created: 08/08/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "bitmap.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifndef WX_PRECOMP
20 #include <stdio.h>
21
22 #include "wx/list.h"
23 #include "wx/utils.h"
24 #include "wx/app.h"
25 #include "wx/palette.h"
26 #include "wx/dcmemory.h"
27 #include "wx/bitmap.h"
28 #include "wx/icon.h"
29 #endif
30
31 #include "wx/os2/private.h"
32 #include "wx/log.h"
33
34 //#include "wx/msw/dib.h"
35 #include "wx/image.h"
36 #include "wx/xpmdecod.h"
37
38 // ----------------------------------------------------------------------------
39 // macros
40 // ----------------------------------------------------------------------------
41
42 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
43 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
44
45 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
46
47 // ============================================================================
48 // implementation
49 // ============================================================================
50
51 // ----------------------------------------------------------------------------
52 // wxBitmapRefData
53 // ----------------------------------------------------------------------------
54
55 wxBitmapRefData::wxBitmapRefData()
56 {
57 m_nQuality = 0;
58 m_pSelectedInto = NULL;
59 m_nNumColors = 0;
60 m_pBitmapMask = NULL;
61 m_hBitmap = (WXHBITMAP) NULL;
62 } // end of wxBitmapRefData::wxBitmapRefData
63
64 void wxBitmapRefData::Free()
65 {
66 if ( m_pSelectedInto )
67 {
68 wxLogLastError("GpiDeleteBitmap(hbitmap)");
69 }
70 if (m_hBitmap)
71 {
72 if (!::GpiDeleteBitmap((HBITMAP)m_hBitmap))
73 {
74 wxLogLastError("GpiDeleteBitmap(hbitmap)");
75 }
76 }
77 if (m_pBitmapMask)
78 {
79 delete m_pBitmapMask;
80 m_pBitmapMask = NULL;
81 }
82 } // end of wxBitmapRefData::Free
83
84 // ----------------------------------------------------------------------------
85 // wxBitmap creation
86 // ----------------------------------------------------------------------------
87
88 // this function should be called from all wxBitmap ctors
89 void wxBitmap::Init()
90 {
91 m_bIsMono = FALSE;
92 //
93 // True for all bitmaps created from bits, wxImages, Xpms
94 //
95 } // end of wxBitmap::Init
96
97 bool wxBitmap::CopyFromIconOrCursor(
98 const wxGDIImage& rIcon
99 )
100 {
101 HPOINTER hIcon = (HPOINTER)rIcon.GetHandle();
102 POINTERINFO SIconInfo;
103
104 if (!::WinQueryPointerInfo(hIcon, &SIconInfo))
105 {
106 wxLogLastError(wxT("WinQueryPointerInfo"));
107 return FALSE;
108 }
109 wxBitmapRefData* pRefData = new wxBitmapRefData;
110
111 m_refData = pRefData;
112
113 int nWidth = rIcon.GetWidth();
114 int nHeight = rIcon.GetHeight();
115
116 pRefData->m_nWidth = nWidth;
117 pRefData->m_nHeight = nHeight;
118 pRefData->m_nDepth = wxDisplayDepth();
119
120 pRefData->m_hBitmap = (WXHBITMAP)SIconInfo.hbmColor;
121
122 wxMask* pMask = new wxMask(SIconInfo.hbmPointer);
123
124 pMask->SetMaskBitmap(GetHBITMAP());
125 SetMask(pMask);
126
127 return(TRUE);
128 } // end of wxBitmap::CopyFromIconOrCursor
129
130 bool wxBitmap::CopyFromCursor(
131 const wxCursor& rCursor
132 )
133 {
134 UnRef();
135
136 if (!rCursor.Ok())
137 return(FALSE);
138 return(CopyFromIconOrCursor(rCursor));
139 } // end of wxBitmap::CopyFromCursor
140
141 bool wxBitmap::CopyFromIcon(
142 const wxIcon& rIcon
143 )
144 {
145 UnRef();
146
147 if (!rIcon.Ok())
148 return(FALSE);
149
150 return CopyFromIconOrCursor(rIcon);
151 } // end of wxBitmap::CopyFromIcon
152
153 wxBitmap::~wxBitmap()
154 {
155 } // end of wxBitmap::~wxBitmap
156
157 wxBitmap::wxBitmap(
158 const char zBits[]
159 , int nWidth
160 , int nHeight
161 , int nDepth
162 )
163 {
164 Init();
165
166 wxBitmapRefData* pRefData = new wxBitmapRefData;
167 BITMAPINFOHEADER2 vHeader;
168 BITMAPINFO2 vInfo;
169 HDC hDc;
170 HPS hPs;
171 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
172 SIZEL vSize = {0, 0};
173 char* pzData;
174
175 wxASSERT(vHabmain != NULL);
176
177 m_refData = pRefData;
178
179 pRefData->m_nWidth = nWidth;
180 pRefData->m_nHeight = nHeight;
181 pRefData->m_nDepth = nDepth;
182 pRefData->m_nNumColors = 0;
183 pRefData->m_pSelectedInto = NULL;
184
185 hDc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
186 hPs = ::GpiCreatePS(vHabmain, hDc, &vSize, GPIA_ASSOC | PU_PELS);
187 if (hPs == 0)
188 {
189 wxLogLastError("GpiCreatePS Failure");
190 }
191
192 if (nDepth == 1)
193 {
194 //
195 // We assume that it is in XBM format which is not quite the same as
196 // the format CreateBitmap() wants because the order of bytes in the
197 // line is inversed!
198 //
199 const size_t nBytesPerLine = (nWidth + 7) / 8;
200 const size_t nPadding = nBytesPerLine % 2;
201 const size_t nLen = nHeight * (nPadding + nBytesPerLine);
202 const char* pzSrc = zBits;
203 int nRows;
204 size_t nCols;
205
206 pzData = (char *)malloc(nLen);
207
208 char* pzDst = pzData;
209
210 for (nRows = 0; nRows < nHeight; nRows++)
211 {
212 for (nCols = 0; nCols < nBytesPerLine; nCols++)
213 {
214 unsigned char ucVal = *pzSrc++;
215 unsigned char ucReversed = 0;
216 int nBits;
217
218 for (nBits = 0; nBits < 8; nBits++)
219 {
220 ucReversed <<= 1;
221 ucReversed |= (ucVal & 0x01);
222 ucVal >>= 1;
223 }
224 *pzDst++ = ucReversed;
225 }
226 if (nPadding)
227 *pzDst++ = 0;
228 }
229 }
230 else
231 {
232 //
233 // Bits should already be in Windows standard format
234 //
235 pzData = (char *)zBits; // const_cast is harmless
236 }
237
238 if (nDepth > 24)
239 nDepth = 24; // MAX supported in PM
240 memset(&vHeader, '\0', 16);
241 vHeader.cbFix = 16;
242 vHeader.cx = (USHORT)nWidth;
243 vHeader.cy = (USHORT)nHeight;
244 vHeader.cPlanes = 1L;
245 vHeader.cBitCount = nDepth;
246 vHeader.usReserved = 0;
247
248 memset(&vInfo, '\0', 16);
249 vInfo.cbFix = 16;
250 vInfo.cx = (USHORT)nWidth;
251 vInfo.cy = (USHORT)nHeight;
252 vInfo.cPlanes = 1L;
253 vInfo.cBitCount = nDepth;
254
255 HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, CBM_INIT, (PBYTE)pzData, &vInfo);
256
257 if (!hBmp)
258 {
259 wxLogLastError("CreateBitmap");
260 }
261 ::GpiDestroyPS(hPs);
262 ::DevCloseDC(hDc);
263 SetHBITMAP((WXHBITMAP)hBmp);
264 } // end of wxBitmap::wxBitmap
265
266 wxBitmap::wxBitmap(
267 int nW
268 , int nH
269 , int nD
270 )
271 {
272 Init();
273 (void)Create( nW
274 ,nH
275 ,nD
276 );
277 } // end of wxBitmap::wxBitmap
278
279 wxBitmap::wxBitmap(
280 void* pData
281 , long lType
282 , int nWidth
283 , int nHeight
284 , int nDepth
285 )
286 {
287 Init();
288
289 (void)Create( pData
290 ,lType
291 ,nWidth
292 ,nHeight
293 ,nDepth
294 );
295 } // end of wxBitmap::wxBitmap
296
297 wxBitmap::wxBitmap(
298 const wxString& rFilename
299 , long lType
300 )
301 {
302 Init();
303 LoadFile( rFilename
304 ,(int)lType
305 );
306 } // end of wxBitmap::wxBitmap
307
308 bool wxBitmap::Create(
309 int nW
310 , int nH
311 , int nD
312 )
313 {
314 HBITMAP hBmp;
315 BITMAPINFOHEADER2 vHeader;
316
317 wxASSERT(vHabmain != NULL);
318 UnRef();
319 m_refData = new wxBitmapRefData;
320 GetBitmapData()->m_nWidth = nW;
321 GetBitmapData()->m_nHeight = nH;
322 GetBitmapData()->m_nDepth = nD;
323
324 //
325 // Xpms and bitmaps from other images can also be mono's, but only
326 // mono's need help changing their colors with MemDC changes
327 //
328 if (nD > 0)
329 {
330 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
331 SIZEL vSize = {0, 0};
332 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
333 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
334
335 if (nD == 1)
336 m_bIsMono = TRUE;
337 memset(&vHeader, '\0', 16);
338 vHeader.cbFix = 16;
339 vHeader.cx = nW;
340 vHeader.cy = nH;
341 vHeader.cPlanes = 1;
342 vHeader.cBitCount = 24; //nD;
343
344 hBmp = ::GpiCreateBitmap( hPS
345 ,&vHeader
346 ,0L
347 ,NULL
348 ,NULL
349 );
350 ::GpiDestroyPS(hPS);
351 ::DevCloseDC(hDC);
352 }
353 else
354 {
355 HPS hPSScreen;
356 HDC hDCScreen;
357 LONG lBitCount;
358
359 hPSScreen = ::WinGetScreenPS(HWND_DESKTOP);
360 hDCScreen = ::GpiQueryDevice(hPSScreen);
361 ::DevQueryCaps(hDCScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
362
363 if (lBitCount > 24)
364 lBitCount = 24;
365
366 memset(&vHeader, '\0', 16);
367 vHeader.cbFix = 16;
368 vHeader.cx = nW;
369 vHeader.cy = nH;
370 vHeader.cPlanes = 1;
371 vHeader.cBitCount = lBitCount;
372
373 hBmp = ::GpiCreateBitmap( hPSScreen
374 ,&vHeader
375 ,0L
376 ,NULL
377 ,NULL
378 );
379
380 GetBitmapData()->m_nDepth = wxDisplayDepth();
381 ::WinReleasePS(hPSScreen);
382 }
383 SetHBITMAP((WXHBITMAP)hBmp);
384
385 #if WXWIN_COMPATIBILITY_2
386 GetBitmapData()->m_bOk = hBmp != 0;
387 #endif // WXWIN_COMPATIBILITY_2
388
389 return Ok();
390 } // end of wxBitmap::Create
391
392 bool wxBitmap::CreateFromXpm(
393 const char** ppData
394 )
395 {
396 #if wxUSE_IMAGE && wxUSE_XPM
397 Init();
398
399 wxCHECK_MSG(ppData != NULL, FALSE, wxT("invalid bitmap data"))
400
401 wxXPMDecoder vDecoder;
402 wxImage vImg = vDecoder.ReadData(ppData);
403
404 wxCHECK_MSG(vImg.Ok(), FALSE, wxT("invalid bitmap data"))
405
406 *this = wxBitmap(vImg);
407 return TRUE;
408 #else
409 return FALSE;
410 #endif
411 } // end of wxBitmap::CreateFromXpm
412
413 bool wxBitmap::LoadFile(
414 const wxString& rFilename
415 , long lType
416 )
417 {
418 HPS hPs = NULLHANDLE;
419
420 UnRef();
421
422 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
423 ,wxBitmapHandler
424 );
425
426 if (pHandler)
427 {
428 m_refData = new wxBitmapRefData;
429
430 return(pHandler->LoadFile( this
431 ,rFilename
432 ,hPs
433 ,lType
434 , -1
435 , -1
436 ));
437 }
438 else
439 {
440 wxImage vImage;
441
442 if (!vImage.LoadFile(rFilename, lType) || !vImage.Ok() )
443 return(FALSE);
444
445 *this = wxBitmap(vImage);
446
447 return(TRUE);
448 }
449 } // end of wxBitmap::LoadFile
450
451 bool wxBitmap::Create(
452 void* pData
453 , long lType
454 , int nWidth
455 , int nHeight
456 , int nDepth
457 )
458 {
459 UnRef();
460
461 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
462 ,wxBitmapHandler
463 );
464
465 if (!pHandler)
466 {
467 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
468 "type %d defined."), lType);
469
470 return(FALSE);
471 }
472
473 m_refData = new wxBitmapRefData;
474
475 return(pHandler->Create( this
476 ,pData
477 ,lType
478 ,nWidth
479 ,nHeight
480 ,nDepth
481 ));
482 } // end of wxBitmap::Create
483
484 bool wxBitmap::SaveFile(
485 const wxString& rFilename
486 , int lType
487 , const wxPalette* pPalette
488 )
489 {
490 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
491 ,wxBitmapHandler
492 );
493
494 if (pHandler)
495 {
496 return pHandler->SaveFile( this
497 ,rFilename
498 ,lType
499 ,pPalette
500 );
501 }
502 else
503 {
504 // FIXME what about palette? shouldn't we use it?
505 wxImage vImage = ConvertToImage();
506
507 if (!vImage.Ok())
508 return(FALSE);
509
510 return(vImage.SaveFile( rFilename
511 ,lType
512 ));
513 }
514 } // end of wxBitmap::SaveFile
515
516
517 // ----------------------------------------------------------------------------
518 // wxImage-wxBitmap convertion
519 // ----------------------------------------------------------------------------
520
521 bool wxBitmap::CreateFromImage (
522 const wxImage& rImage
523 , int nDepth
524 )
525 {
526 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
527 m_refData = new wxBitmapRefData();
528
529 int nSizeLimit = 1024 * 768 * 3;
530 int nWidth = rImage.GetWidth();
531 int nBmpHeight = rImage.GetHeight();
532 int nBytePerLine = nWidth * 3;
533 int nSizeDWORD = sizeof(DWORD);
534 int nLineBoundary = nBytePerLine % nSizeDWORD;
535 int nPadding = 0;
536
537 if (nLineBoundary > 0)
538 {
539 nPadding = nSizeDWORD - nLineBoundary;
540 nBytePerLine += nPadding;
541 }
542
543 //
544 // Calc the number of DIBs and heights of DIBs
545 //
546 int nNumDIB = 1;
547 int nHRemain = 0;
548 int nHeight = nSizeLimit / nBytePerLine;
549
550 if (nHeight >= nBmpHeight)
551 nHeight = nBmpHeight;
552 else
553 {
554 nNumDIB = nBmpHeight / nHeight;
555 nHRemain = nBmpHeight % nHeight;
556 if (nHRemain > 0)
557 nNumDIB++;
558 }
559
560 //
561 // Set bitmap parameters
562 //
563 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
564 SetWidth(nWidth);
565 SetHeight(nBmpHeight);
566 if (nDepth == 1)
567 m_bIsMono = TRUE;
568 else
569 m_bIsMono = FALSE;
570 if (nDepth == -1)
571 nDepth = wxDisplayDepth();
572 SetDepth(nDepth);
573
574 #if wxUSE_PALETTE
575 //
576 // Copy the palette from the source image
577 //
578 SetPalette(rImage.GetPalette());
579 #endif // wxUSE_PALETTE
580
581 //
582 // Create a DIB header
583 //
584 BITMAPINFOHEADER2 vHeader;
585 BITMAPINFO2 vInfo;
586
587 //
588 // Fill in the DIB header
589 //
590 memset(&vHeader, '\0', 16);
591 vHeader.cbFix = 16;
592 vHeader.cx = (ULONG)nWidth;
593 vHeader.cy = (ULONG)nHeight;
594 vHeader.cPlanes = 1L;
595 vHeader.cBitCount = 24;
596
597 //
598 // Memory for DIB data
599 //
600 unsigned char* pucBits;
601
602 pucBits = (unsigned char *)malloc(nBytePerLine * nHeight);
603 if(!pucBits)
604 {
605 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
606 return FALSE;
607 }
608 memset(pucBits, '\0', (nBytePerLine * nHeight));
609
610 //
611 // Create and set the device-dependent bitmap
612 //
613 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
614 SIZEL vSize = {0, 0};
615 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
616 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
617 LONG lScans;
618 HDC hDCScreen = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
619 HPS hPSScreen;
620 HBITMAP hBmp;
621 HBITMAP hBmpOld;
622
623 memset(&vInfo, '\0', 16);
624 vInfo.cbFix = 16;
625 vInfo.cx = (ULONG)nWidth;
626 vInfo.cy = (ULONG)nHeight;
627 vInfo.cPlanes = 1;
628 vInfo.cBitCount = 24; // Set to desired count going in
629
630 hBmp = ::GpiCreateBitmap( hPS
631 ,&vHeader
632 ,0L
633 ,NULL
634 ,NULL
635 );
636 #if wxUSE_PALETTE
637 HPAL hOldPalette = NULLHANDLE;
638 if (rImage.GetPalette().Ok())
639 {
640 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
641 }
642 #endif // wxUSE_PALETTE
643
644 //
645 // Copy image data into DIB data and then into DDB (in a loop)
646 //
647 unsigned char* pData = rImage.GetData();
648 int i;
649 int j;
650 int n;
651 int nOrigin = 0;
652 unsigned char* ptdata = pData;
653 unsigned char* ptbits;
654
655 if ((hBmpOld = ::GpiSetBitmap(hPS, hBmp)) == HBM_ERROR)
656 {
657 ERRORID vError;
658 wxString sError;
659
660 vError = ::WinGetLastError(vHabmain);
661 sError = wxPMErrorToStr(vError);
662 }
663 for (n = 0; n < nNumDIB; n++)
664 {
665 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
666 {
667 //
668 // Redefine height and size of the (possibly) last smaller DIB
669 // memory is not reallocated
670 //
671 nHeight = nHRemain;
672 vHeader.cy = (DWORD)(nHeight);
673 vHeader.cbImage = nBytePerLine * nHeight;
674 }
675 ptbits = pucBits;
676 for (j = 0; j < nHeight; j++)
677 {
678 for (i = 0; i < nWidth; i++)
679 {
680 *(ptbits++) = *(ptdata + 2);
681 *(ptbits++) = *(ptdata + 1);
682 *(ptbits++) = *(ptdata);
683 ptdata += 3;
684 }
685 for (i = 0; i < nPadding; i++)
686 *(ptbits++) = 0;
687 }
688
689 //
690 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
691 // in combination with setting the bits into the selected bitmap
692 //
693 if ((lScans = ::GpiSetBitmapBits( hPS
694 ,0 // Start at the bottom
695 ,(LONG)nHeight // One line per scan
696 ,(PBYTE)pucBits
697 ,&vInfo
698 )) == GPI_ALTERROR)
699 {
700 ERRORID vError;
701 wxString sError;
702
703 vError = ::WinGetLastError(vHabmain);
704 sError = wxPMErrorToStr(vError);
705 }
706 hPSScreen = ::GpiCreatePS( vHabmain
707 ,hDCScreen
708 ,&vSize
709 ,PU_PELS | GPIA_ASSOC
710 );
711
712 POINTL vPoint[4] = { 0, nOrigin,
713 nWidth, nHeight,
714 0, 0, nWidth, nHeight
715 };
716
717
718 ::GpiBitBlt( hPSScreen
719 ,hPS
720 ,4
721 ,vPoint
722 ,ROP_SRCCOPY
723 ,BBO_IGNORE
724 );
725 ::GpiDestroyPS(hPSScreen);
726 nOrigin += nHeight;
727 }
728 SetHBITMAP((WXHBITMAP)hBmp);
729 #if wxUSE_PALETTE
730 if (hOldPalette)
731 ::GpiSelectPalette(hPS, hOldPalette);
732 #endif // wxUSE_PALETTE
733
734 //
735 // Similarly, created an mono-bitmap for the possible mask
736 //
737 if (rImage.HasMask())
738 {
739 vHeader.cbFix = 16;
740 vHeader.cx = nWidth;
741 vHeader.cy = nHeight;
742 vHeader.cPlanes = 1;
743 vHeader.cBitCount = 24;
744 hBmp = ::GpiCreateBitmap( hPS
745 ,&vHeader
746 ,0L
747 ,NULL
748 ,NULL
749 );
750 hBmpOld = ::GpiSetBitmap(hPS, hBmp);
751 if (nNumDIB == 1)
752 nHeight = nBmpHeight;
753 else
754 nHeight = nSizeLimit / nBytePerLine;
755 vHeader.cy = (DWORD)(nHeight);
756 nOrigin = 0;
757
758 unsigned char cRed = rImage.GetMaskRed();
759 unsigned char cGreen = rImage.GetMaskGreen();
760 unsigned char cBlue = rImage.GetMaskBlue();
761 unsigned char cZero = 0;
762 unsigned char cOne = 255;
763
764 ptdata = pData;
765 for (n = 0; n < nNumDIB; n++)
766 {
767 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
768 {
769 //
770 // Redefine height and size of the (possibly) last smaller DIB
771 // memory is not reallocated
772 //
773 nHeight = nHRemain;
774 vHeader.cy = (DWORD)(nHeight);
775 vHeader.cbImage = nBytePerLine * nHeight;
776 }
777 ptbits = pucBits;
778 for (int j = 0; j < nHeight; j++)
779 {
780 for (i = 0; i < nWidth; i++)
781 {
782 unsigned char cRedImage = (*(ptdata++)) ;
783 unsigned char cGreenImage = (*(ptdata++)) ;
784 unsigned char cBlueImage = (*(ptdata++)) ;
785
786 if ((cRedImage != cRed) || (cGreenImage != cGreen) || (cBlueImage != cBlue))
787 {
788 *(ptbits++) = cOne;
789 *(ptbits++) = cOne;
790 *(ptbits++) = cOne;
791 }
792 else
793 {
794 *(ptbits++) = cZero;
795 *(ptbits++) = cZero;
796 *(ptbits++) = cZero;
797 }
798 }
799 for (i = 0; i < nPadding; i++)
800 *(ptbits++) = cZero;
801 }
802 lScans = ::GpiSetBitmapBits( hPS
803 ,0 // Start at the bottom
804 ,(LONG)nHeight // One line per scan
805 ,(PBYTE)pucBits
806 ,&vInfo
807 );
808 hPSScreen = ::GpiCreatePS( vHabmain
809 ,hDCScreen
810 ,&vSize
811 ,PU_PELS | GPIA_ASSOC
812 );
813 POINTL vPoint2[4] = { 0, nOrigin,
814 nWidth, nHeight,
815 0, 0, nWidth, nHeight
816 };
817 ::GpiBitBlt( hPSScreen
818 ,hPS
819 ,4
820 ,vPoint2
821 ,ROP_SRCCOPY
822 ,BBO_IGNORE
823 );
824 ::GpiDestroyPS(hPSScreen);
825 nOrigin += nHeight;
826 }
827
828 //
829 // Create a wxMask object
830 //
831 wxMask* pMask = new wxMask();
832
833 pMask->SetMaskBitmap((WXHBITMAP)hBmp);
834 SetMask(pMask);
835 hBmpOld = ::GpiSetBitmap(hPS, hBmpOld);
836 }
837
838 //
839 // Free allocated resources
840 //
841 ::GpiSetBitmap(hPS, NULLHANDLE);
842 ::GpiDestroyPS(hPS);
843 ::DevCloseDC(hDCScreen);
844 ::DevCloseDC(hDC);
845 free(pucBits);
846 return TRUE;
847 } // end of wxBitmap::CreateFromImage
848
849 wxImage wxBitmap::ConvertToImage() const
850 {
851 wxImage vImage;
852 wxDC* pDC;
853
854 wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
855
856 //
857 // Create an wxImage object
858 //
859 int nWidth = GetWidth();
860 int nHeight = GetHeight();
861 int nDevWidth;
862 int nDevHeight;
863 int nBytePerLine = nWidth * 3;
864 int nSizeDWORD = sizeof(DWORD);
865 int nLineBoundary = nBytePerLine % nSizeDWORD;
866 int nPadding = 0;
867 unsigned char* pData;
868 unsigned char* lpBits;
869 long lScans;
870 BITMAPINFOHEADER2 vDIBh;
871 BITMAPINFO2 vDIBInfo;
872 HPS hPSMem;
873 HPS hPS;
874 HBITMAP hBitmap;
875 HBITMAP hOldBitmap;
876 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
877 SIZEL vSizlPage = {0,0};
878 HDC hDCMem;
879
880 vImage.Create( nWidth
881 ,nHeight
882 );
883 pData = vImage.GetData();
884 if(!pData)
885 {
886 wxFAIL_MSG( wxT("could not allocate data for image") );
887 return wxNullImage;
888 }
889 if(nLineBoundary > 0)
890 {
891 nPadding = nSizeDWORD - nLineBoundary;
892 nBytePerLine += nPadding;
893 }
894 wxDisplaySize( &nDevWidth
895 ,&nDevHeight
896 );
897 //
898 // Create and fill a DIB header
899 //
900 memset(&vDIBh, '\0', 16);
901 vDIBh.cbFix = 16;
902 vDIBh.cx = nWidth;
903 vDIBh.cy = nHeight;
904 vDIBh.cPlanes = 1;
905 vDIBh.cBitCount = 24;
906
907 memset(&vDIBInfo, '\0', 16);
908 vDIBInfo.cbFix = 16;
909 vDIBInfo.cx = nWidth;
910 vDIBInfo.cy = nHeight;
911 vDIBInfo.cPlanes = 1;
912 vDIBInfo.cBitCount = 24;
913
914 lpBits = (unsigned char *)malloc(nBytePerLine * nHeight);
915 if (!lpBits)
916 {
917 wxFAIL_MSG(wxT("could not allocate data for DIB"));
918 free(pData);
919 return wxNullImage;
920 }
921 memset(lpBits, '\0', (nBytePerLine * nHeight));
922 hBitmap = (HBITMAP)GetHBITMAP();
923
924 //
925 // May already be selected into a PS
926 //
927 if ((pDC = GetSelectedInto()) != NULL)
928 {
929 hPSMem = pDC->GetHPS();
930 }
931 else
932 {
933 hDCMem = ::DevOpenDC( vHabmain
934 ,OD_MEMORY
935 ,"*"
936 ,5L
937 ,(PDEVOPENDATA)&vDop
938 ,NULLHANDLE
939 );
940 hPSMem = ::GpiCreatePS( vHabmain
941 ,hDCMem
942 ,&vSizlPage
943 ,PU_PELS | GPIA_ASSOC
944 );
945 }
946 if ((hOldBitmap = ::GpiSetBitmap(hPSMem, hBitmap)) == HBM_ERROR)
947 {
948 ERRORID vError;
949 wxString sError;
950
951 vError = ::WinGetLastError(vHabmain);
952 sError = wxPMErrorToStr(vError);
953 }
954
955 //
956 // Copy data from the device-dependent bitmap to the DIB
957 //
958 if ((lScans = ::GpiQueryBitmapBits( hPSMem
959 ,0L
960 ,(LONG)nHeight
961 ,(PBYTE)lpBits
962 ,&vDIBInfo
963 )) == GPI_ALTERROR)
964 {
965 ERRORID vError;
966 wxString sError;
967
968 vError = ::WinGetLastError(vHabmain);
969 sError = wxPMErrorToStr(vError);
970 }
971
972 //
973 // Copy DIB data into the wxImage object
974 //
975 int i;
976 int j;
977 unsigned char* ptdata = pData;
978 unsigned char* ptbits = lpBits;
979
980 for (i = 0; i < nHeight; i++)
981 {
982 for (j = 0; j < nWidth; j++)
983 {
984 *(ptdata++) = *(ptbits+2);
985 *(ptdata++) = *(ptbits+1);
986 *(ptdata++) = *(ptbits );
987 ptbits += 3;
988 }
989 ptbits += nPadding;
990 }
991 if ((pDC = GetSelectedInto()) == NULL)
992 {
993 ::GpiSetBitmap(hPSMem, NULLHANDLE);
994 ::GpiDestroyPS(hPSMem);
995 ::DevCloseDC(hDCMem);
996 }
997
998 //
999 // Similarly, set data according to the possible mask bitmap
1000 //
1001 if (GetMask() && GetMask()->GetMaskBitmap())
1002 {
1003 hBitmap = (HBITMAP)GetMask()->GetMaskBitmap();
1004
1005 //
1006 // Memory DC/PS created, color set, data copied, and memory DC/PS deleted
1007 //
1008 HDC hMemDC = ::DevOpenDC( vHabmain
1009 ,OD_MEMORY
1010 ,"*"
1011 ,5L
1012 ,(PDEVOPENDATA)&vDop
1013 ,NULLHANDLE
1014 );
1015 HPS hMemPS = ::GpiCreatePS( vHabmain
1016 ,hMemDC
1017 ,&vSizlPage
1018 ,PU_PELS | GPIA_ASSOC
1019 );
1020 ::GpiSetColor(hMemPS, OS2RGB(0, 0, 0));
1021 ::GpiSetBackColor(hMemPS, OS2RGB(255, 255, 255) );
1022 ::GpiSetBitmap(hMemPS, hBitmap);
1023 ::GpiQueryBitmapBits( hPSMem
1024 ,0L
1025 ,(LONG)nHeight
1026 ,(PBYTE)lpBits
1027 ,&vDIBInfo
1028 );
1029 ::GpiSetBitmap(hMemPS, NULLHANDLE);
1030 ::GpiDestroyPS(hMemPS);
1031 ::DevCloseDC(hMemDC);
1032
1033 //
1034 // Background color set to RGB(16,16,16) in consistent with wxGTK
1035 //
1036 unsigned char ucRed = 16;
1037 unsigned char ucGreen = 16;
1038 unsigned char ucBlue = 16;
1039
1040 ptdata = pData;
1041 ptbits = lpBits;
1042 for (i = 0; i < nHeight; i++)
1043 {
1044 for (j = 0; j < nWidth; j++)
1045 {
1046 if (*ptbits != 0)
1047 ptdata += 3;
1048 else
1049 {
1050 *(ptdata++) = ucRed;
1051 *(ptdata++) = ucGreen;
1052 *(ptdata++) = ucBlue;
1053 }
1054 ptbits += 3;
1055 }
1056 ptbits += nPadding;
1057 }
1058 vImage.SetMaskColour( ucRed
1059 ,ucGreen
1060 ,ucBlue
1061 );
1062 vImage.SetMask(TRUE);
1063 }
1064 else
1065 {
1066 vImage.SetMask(FALSE);
1067 }
1068
1069 //
1070 // Free allocated resources
1071 //
1072 free(lpBits);
1073 return vImage;
1074 } // end of wxBitmap::ConvertToImage
1075
1076 // ----------------------------------------------------------------------------
1077 // sub bitmap extraction
1078 // ----------------------------------------------------------------------------
1079
1080 wxBitmap wxBitmap::GetSubBitmap(
1081 const wxRect& rRect
1082 ) const
1083 {
1084 wxCHECK_MSG( Ok() &&
1085 (rRect.x >= 0) && (rRect.y >= 0) &&
1086 (rRect.x + rRect.width <= GetWidth()) &&
1087 (rRect.y + rRect.height <= GetHeight()),
1088 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
1089
1090 wxBitmap vRet( rRect.width
1091 ,rRect.height
1092 ,GetDepth()
1093 );
1094 wxASSERT_MSG( vRet.Ok(), wxT("GetSubBitmap error") );
1095
1096
1097 //
1098 // Copy bitmap data
1099 //
1100 SIZEL vSize = {0, 0};
1101 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1102 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1103 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1104 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1105 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1106 POINTL vPoint[4] = { 0, 0, rRect.width, rRect.height,
1107 rRect.x, rRect.y,
1108 rRect.x + rRect.width, rRect.y + rRect.height
1109 };
1110
1111 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1112 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1113 ::GpiBitBlt( hPSDst
1114 ,hPSSrc
1115 ,4L
1116 ,vPoint
1117 ,ROP_SRCCOPY
1118 ,BBO_IGNORE
1119 );
1120
1121 //
1122 // Copy mask if there is one
1123 //
1124 if (GetMask())
1125 {
1126 BITMAPINFOHEADER2 vBmih;
1127
1128 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1129 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1130 vBmih.cx = rRect.width;
1131 vBmih.cy = rRect.height;
1132 vBmih.cPlanes = 1;
1133 vBmih.cBitCount = 24;
1134
1135 HBITMAP hBmpMask = ::GpiCreateBitmap( hPSDst
1136 ,&vBmih
1137 ,0L
1138 ,NULL
1139 ,NULL
1140 );
1141
1142 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetHBITMAP());
1143 ::GpiSetBitmap(hPSDst, (HBITMAP) vRet.GetHBITMAP());
1144
1145 ::GpiSetBitmap(hPSSrc, (HBITMAP) GetMask()->GetMaskBitmap());
1146 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpMask);
1147 ::GpiBitBlt( hPSDst
1148 ,hPSSrc
1149 ,4L
1150 ,vPoint
1151 ,ROP_SRCCOPY
1152 ,BBO_IGNORE
1153 );
1154
1155 wxMask* pMask = new wxMask((WXHBITMAP)hBmpMask);
1156 vRet.SetMask(pMask);
1157 }
1158
1159 ::GpiSetBitmap(hPSSrc, NULL);
1160 ::GpiSetBitmap(hPSDst, NULL);
1161 ::GpiDestroyPS(hPSSrc);
1162 ::GpiDestroyPS(hPSDst);
1163 ::DevCloseDC(hDCSrc);
1164 ::DevCloseDC(hDCDst);
1165 return vRet;
1166 } // end of wxBitmap::GetSubBitmap
1167
1168 // ----------------------------------------------------------------------------
1169 // wxBitmap accessors
1170 // ----------------------------------------------------------------------------
1171
1172 void wxBitmap::SetQuality(
1173 int nQ
1174 )
1175 {
1176 EnsureHasData();
1177
1178 GetBitmapData()->m_nQuality = nQ;
1179 } // end of wxBitmap::SetQuality
1180
1181 #if WXWIN_COMPATIBILITY_2
1182 void wxBitmap::SetOk(
1183 bool bOk
1184 )
1185 {
1186 EnsureHasData();
1187
1188 GetBitmapData()->m_bOk = bOk;
1189 } // end of wxBitmap::SetOk
1190 #endif // WXWIN_COMPATIBILITY_2
1191
1192 void wxBitmap::SetPalette(
1193 const wxPalette& rPalette
1194 )
1195 {
1196 EnsureHasData();
1197
1198 GetBitmapData()->m_vBitmapPalette = rPalette;
1199 } // end of wxBitmap::SetPalette
1200
1201 void wxBitmap::SetMask(
1202 wxMask* pMask
1203 )
1204 {
1205 EnsureHasData();
1206
1207 GetBitmapData()->m_pBitmapMask = pMask;
1208 } // end of wxBitmap::SetMask
1209
1210 wxBitmap wxBitmap::GetBitmapForDC(
1211 wxDC& rDc
1212 ) const
1213 {
1214 return(*this);
1215 } // end of wxBitmap::GetBitmapForDC
1216
1217 // ----------------------------------------------------------------------------
1218 // wxMask
1219 // ----------------------------------------------------------------------------
1220
1221 wxMask::wxMask()
1222 {
1223 m_hMaskBitmap = 0;
1224 } // end of wxMask::wxMask
1225
1226 // Construct a mask from a bitmap and a colour indicating
1227 // the transparent area
1228 wxMask::wxMask(
1229 const wxBitmap& rBitmap
1230 , const wxColour& rColour
1231 )
1232 {
1233 m_hMaskBitmap = 0;
1234 Create( rBitmap
1235 ,rColour
1236 );
1237 } // end of wxMask::wxMask
1238
1239 // Construct a mask from a bitmap and a palette index indicating
1240 // the transparent area
1241 wxMask::wxMask(
1242 const wxBitmap& rBitmap
1243 , int nPaletteIndex
1244 )
1245 {
1246 m_hMaskBitmap = 0;
1247 Create( rBitmap
1248 ,nPaletteIndex
1249 );
1250 } // end of wxMask::wxMask
1251
1252 // Construct a mask from a mono bitmap (copies the bitmap).
1253 wxMask::wxMask(
1254 const wxBitmap& rBitmap
1255 )
1256 {
1257 m_hMaskBitmap = 0;
1258 Create(rBitmap);
1259 } // end of wxMask::wxMask
1260
1261 wxMask::~wxMask()
1262 {
1263 if (m_hMaskBitmap)
1264 ::GpiDeleteBitmap((HBITMAP)m_hMaskBitmap);
1265 } // end of wxMask::~wxMask
1266
1267 // Create a mask from a mono bitmap (copies the bitmap).
1268 bool wxMask::Create(
1269 const wxBitmap& rBitmap
1270 )
1271 {
1272 BITMAPINFOHEADER2 vBmih;
1273 SIZEL vSize = {0, 0};
1274 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1275 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1276 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1277 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1278 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1279 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1280 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1281 };
1282
1283 if (m_hMaskBitmap)
1284 {
1285 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1286 m_hMaskBitmap = 0;
1287 }
1288 if (!rBitmap.Ok() || rBitmap.GetDepth() != 1)
1289 {
1290 return(FALSE);
1291 }
1292
1293 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1294 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1295 vBmih.cx = rBitmap.GetWidth();
1296 vBmih.cy = rBitmap.GetHeight();
1297 vBmih.cPlanes = 1;
1298 vBmih.cBitCount = 24;
1299
1300 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1301 ,&vBmih
1302 ,0L
1303 ,NULL
1304 ,NULL
1305 );
1306
1307 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1308 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1309 ::GpiBitBlt( hPSDst
1310 ,hPSSrc
1311 ,4L
1312 ,vPoint
1313 ,ROP_SRCCOPY
1314 ,BBO_IGNORE
1315 );
1316
1317 ::GpiDestroyPS(hPSSrc);
1318 ::GpiDestroyPS(hPSDst);
1319 ::DevCloseDC(hDCSrc);
1320 ::DevCloseDC(hDCDst);
1321 return(TRUE);
1322 } // end of wxMask::Create
1323
1324 // Create a mask from a bitmap and a palette index indicating
1325 // the transparent area
1326 bool wxMask::Create(
1327 const wxBitmap& rBitmap
1328 , int nPaletteIndex
1329 )
1330 {
1331 if (m_hMaskBitmap)
1332 {
1333 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1334 m_hMaskBitmap = 0;
1335 }
1336 if (rBitmap.Ok() && rBitmap.GetPalette()->Ok())
1337 {
1338 unsigned char cRed;
1339 unsigned char cGreen;
1340 unsigned char cBlue;
1341
1342 if (rBitmap.GetPalette()->GetRGB( nPaletteIndex
1343 ,&cRed
1344 ,&cGreen
1345 ,&cBlue
1346 ))
1347 {
1348 wxColour vTransparentColour( cRed
1349 ,cGreen
1350 ,cBlue
1351 );
1352
1353 return (Create( rBitmap
1354 ,vTransparentColour
1355 ));
1356 }
1357 }
1358 return(FALSE);
1359 } // end of wxMask::Create
1360
1361 // Create a mask from a bitmap and a colour indicating
1362 // the transparent area
1363 bool wxMask::Create(
1364 const wxBitmap& rBitmap
1365 , const wxColour& rColour
1366 )
1367 {
1368 bool bOk = TRUE;
1369 COLORREF vMaskColour = OS2RGB( rColour.Red()
1370 ,rColour.Green()
1371 ,rColour.Blue()
1372 );
1373 BITMAPINFOHEADER2 vBmih;
1374 SIZEL vSize = {0, 0};
1375 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1376 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1377 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1378 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1379 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1380 POINTL vPoint[4] = { 0 ,0, rBitmap.GetWidth(), rBitmap.GetHeight(),
1381 0, 0, rBitmap.GetWidth(), rBitmap.GetHeight()
1382 };
1383
1384 if (m_hMaskBitmap)
1385 {
1386 ::GpiDeleteBitmap((HBITMAP) m_hMaskBitmap);
1387 m_hMaskBitmap = 0;
1388 }
1389 if (!rBitmap.Ok())
1390 {
1391 return(FALSE);
1392 }
1393
1394 //
1395 // Scan the bitmap for the transparent colour and set
1396 // the corresponding pixels in the mask to BLACK and
1397 // the rest to WHITE
1398 //
1399
1400 memset(&vBmih, '\0', sizeof(BITMAPINFOHEADER2));
1401 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1402 vBmih.cx = rBitmap.GetWidth();
1403 vBmih.cy = rBitmap.GetHeight();
1404 vBmih.cPlanes = 1;
1405 vBmih.cBitCount = 1;
1406
1407 m_hMaskBitmap = ::GpiCreateBitmap( hPSDst
1408 ,&vBmih
1409 ,0L
1410 ,NULL
1411 ,NULL
1412 );
1413
1414 ::GpiSetBitmap(hPSSrc, (HBITMAP) rBitmap.GetHBITMAP());
1415 ::GpiSetBitmap(hPSDst, (HBITMAP) m_hMaskBitmap);
1416
1417 //
1418 // This is not very efficient, but I can't think
1419 // of a better way of doing it
1420 //
1421 for (int w = 0; w < rBitmap.GetWidth(); w++)
1422 {
1423 for (int h = 0; h < rBitmap.GetHeight(); h++)
1424 {
1425 POINTL vPt = {w, h};
1426 COLORREF vCol = (COLORREF)::GpiQueryPel(hPSSrc, &vPt);
1427 if (vCol == (COLORREF)CLR_NOINDEX)
1428 {
1429 //
1430 // Doesn't make sense to continue
1431 //
1432 bOk = FALSE;
1433 break;
1434 }
1435
1436 if (vCol == vMaskColour)
1437 {
1438 ::GpiSetColor(hPSDst, OS2RGB(0, 0, 0));
1439 ::GpiSetPel(hPSDst, &vPt);
1440 }
1441 else
1442 {
1443 ::GpiSetColor(hPSDst, OS2RGB(255, 255, 255));
1444 ::GpiSetPel(hPSDst, &vPt);
1445 }
1446 }
1447 }
1448 ::GpiSetBitmap(hPSSrc, NULL);
1449 ::GpiSetBitmap(hPSDst, NULL);
1450 ::GpiDestroyPS(hPSSrc);
1451 ::GpiDestroyPS(hPSDst);
1452 ::DevCloseDC(hDCSrc);
1453 ::DevCloseDC(hDCDst);
1454 return(TRUE);
1455 } // end of wxMask::Create
1456
1457 // ----------------------------------------------------------------------------
1458 // wxBitmapHandler
1459 // ----------------------------------------------------------------------------
1460
1461 bool wxBitmapHandler::Create(
1462 wxGDIImage* pImage
1463 , void* pData
1464 , long lFlags
1465 , int nWidth
1466 , int nHeight
1467 , int nDepth
1468 )
1469 {
1470 wxBitmap* pBitmap = wxDynamicCast( pImage
1471 ,wxBitmap
1472 );
1473
1474 return(pBitmap ? Create( pBitmap
1475 ,pData
1476 ,nWidth
1477 ,nHeight
1478 ,nDepth
1479 ) : FALSE);
1480 }
1481
1482 bool wxBitmapHandler::Load(
1483 wxGDIImage* pImage
1484 , const wxString& rName
1485 , HPS hPs
1486 , long lFlags
1487 , int nWidth
1488 , int nHeight
1489 )
1490 {
1491 wxBitmap* pBitmap = wxDynamicCast( pImage
1492 ,wxBitmap
1493 );
1494
1495 return(pBitmap ? LoadFile( pBitmap
1496 ,rName
1497 ,hPs
1498 ,lFlags
1499 ,nWidth
1500 ,nHeight
1501 ) : FALSE);
1502 }
1503
1504 bool wxBitmapHandler::Save(
1505 wxGDIImage* pImage
1506 , const wxString& rName
1507 , int lType
1508 )
1509 {
1510 wxBitmap* pBitmap = wxDynamicCast( pImage
1511 ,wxBitmap
1512 );
1513
1514 return(pBitmap ? SaveFile( pBitmap
1515 ,rName
1516 ,lType
1517 ) : FALSE);
1518 }
1519
1520 bool wxBitmapHandler::Create(
1521 wxBitmap* WXUNUSED(pBitmap)
1522 , void* WXUNUSED(pData)
1523 , long WXUNUSED(lType)
1524 , int WXUNUSED(nWidth)
1525 , int WXUNUSED(nHeight)
1526 , int WXUNUSED(nDepth)
1527 )
1528 {
1529 return(FALSE);
1530 }
1531
1532 bool wxBitmapHandler::LoadFile(
1533 wxBitmap* WXUNUSED(pBitmap)
1534 , const wxString& WXUNUSED(rName)
1535 , HPS WXUNUSED(hPs)
1536 , long WXUNUSED(lType)
1537 , int WXUNUSED(nDesiredWidth)
1538 , int WXUNUSED(nDesiredHeight)
1539 )
1540 {
1541 return(FALSE);
1542 }
1543
1544 bool wxBitmapHandler::SaveFile(
1545 wxBitmap* WXUNUSED(pBitmap)
1546 , const wxString& WXUNUSED(rName)
1547 , int WXUNUSED(nType)
1548 , const wxPalette* WXUNUSED(pPalette)
1549 )
1550 {
1551 return(FALSE);
1552 }
1553
1554 // ----------------------------------------------------------------------------
1555 // Utility functions
1556 // ----------------------------------------------------------------------------
1557 HBITMAP wxInvertMask(
1558 HBITMAP hBmpMask
1559 , int nWidth
1560 , int nHeight
1561 )
1562 {
1563 HBITMAP hBmpInvMask = 0;
1564
1565 wxCHECK_MSG( hBmpMask, 0, _T("invalid bitmap in wxInvertMask") );
1566
1567 //
1568 // Get width/height from the bitmap if not given
1569 //
1570 if (!nWidth || !nHeight)
1571 {
1572 BITMAPINFOHEADER2 vBmhdr;
1573
1574 ::GpiQueryBitmapInfoHeader( hBmpMask
1575 ,&vBmhdr
1576 );
1577 nWidth = (int)vBmhdr.cx;
1578 nHeight = (int)vBmhdr.cy;
1579 }
1580
1581 BITMAPINFOHEADER2 vBmih;
1582 SIZEL vSize = {0, 0};
1583 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
1584 HDC hDCSrc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1585 HDC hDCDst = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
1586 HPS hPSSrc = ::GpiCreatePS(vHabmain, hDCSrc, &vSize, PU_PELS | GPIA_ASSOC);
1587 HPS hPSDst = ::GpiCreatePS(vHabmain, hDCDst, &vSize, PU_PELS | GPIA_ASSOC);
1588 POINTL vPoint[4] = { 0 ,0, nWidth, nHeight,
1589 0, 0, nWidth, nHeight
1590 };
1591
1592 memset(&vBmih, '\0', 16);
1593 vBmih.cbFix = 16;
1594 vBmih.cx = nWidth;
1595 vBmih.cy = nHeight;
1596 vBmih.cPlanes = 1;
1597 vBmih.cBitCount = 24;
1598
1599 hBmpInvMask = ::GpiCreateBitmap( hPSDst
1600 ,&vBmih
1601 ,0L
1602 ,NULL
1603 ,NULL
1604 );
1605
1606 ::GpiSetBitmap(hPSSrc, (HBITMAP) hBmpMask);
1607 ::GpiSetBitmap(hPSDst, (HBITMAP) hBmpInvMask);
1608
1609 ::GpiBitBlt( hPSDst
1610 ,hPSSrc
1611 ,4L
1612 ,vPoint
1613 ,ROP_SRCINVERT
1614 ,BBO_IGNORE
1615 );
1616
1617 ::GpiDestroyPS(hPSSrc);
1618 ::GpiDestroyPS(hPSDst);
1619 ::DevCloseDC(hDCSrc);
1620 ::DevCloseDC(hDCDst);
1621
1622 return hBmpInvMask;
1623 } // end of WxWinGdi_InvertMask
1624