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