OS/2 Image processing updates along with some statusbar 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
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 } // end of wxBitmap::Init
91
92 bool wxBitmap::CopyFromIconOrCursor(
93 const wxGDIImage& rIcon
94 )
95 {
96 HPOINTER hIcon = (HPOINTER)rIcon.GetHandle();
97 POINTERINFO SIconInfo;
98
99 if (!::WinQueryPointerInfo(hIcon, &SIconInfo))
100 {
101 wxLogLastError(wxT("WinQueryPointerInfo"));
102 return FALSE;
103 }
104 wxBitmapRefData* pRefData = new wxBitmapRefData;
105
106 m_refData = pRefData;
107
108 int nWidth = rIcon.GetWidth();
109 int nHeight = rIcon.GetHeight();
110
111 pRefData->m_nWidth = nWidth;
112 pRefData->m_nHeight = nHeight;
113 pRefData->m_nDepth = wxDisplayDepth();
114
115 pRefData->m_hBitmap = (WXHBITMAP)SIconInfo.hbmColor;
116
117 wxMask* pMask = new wxMask(SIconInfo.hbmPointer);
118
119 pMask->SetMaskBitmap(GetHBITMAP());
120 SetMask(pMask);
121
122 return(TRUE);
123 } // end of wxBitmap::CopyFromIconOrCursor
124
125 bool wxBitmap::CopyFromCursor(
126 const wxCursor& rCursor
127 )
128 {
129 UnRef();
130
131 if (!rCursor.Ok())
132 return(FALSE);
133 return(CopyFromIconOrCursor(rCursor));
134 } // end of wxBitmap::CopyFromCursor
135
136 bool wxBitmap::CopyFromIcon(
137 const wxIcon& rIcon
138 )
139 {
140 UnRef();
141
142 if (!rIcon.Ok())
143 return(FALSE);
144
145 return CopyFromIconOrCursor(rIcon);
146 } // end of wxBitmap::CopyFromIcon
147
148 wxBitmap::~wxBitmap()
149 {
150 } // end of wxBitmap::~wxBitmap
151
152 wxBitmap::wxBitmap(
153 const char zBits[]
154 , int nWidth
155 , int nHeight
156 , int nDepth
157 )
158 {
159 Init();
160
161 wxBitmapRefData* pRefData = new wxBitmapRefData;
162 BITMAPINFOHEADER2 vHeader;
163 BITMAPINFO2 vInfo;
164 HDC hDc;
165 HPS hPs;
166 DEVOPENSTRUC vDop = { NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
167 SIZEL vSize = {0, 0};
168 char* pzData;
169
170 wxASSERT(vHabmain != NULL);
171
172 m_refData = pRefData;
173
174 pRefData->m_nWidth = nWidth;
175 pRefData->m_nHeight = nHeight;
176 pRefData->m_nDepth = nDepth;
177 pRefData->m_nNumColors = 0;
178 pRefData->m_pSelectedInto = NULL;
179
180 hDc = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
181 hPs = ::GpiCreatePS(vHabmain, hDc, &vSize, GPIA_ASSOC | PU_PELS);
182 if (hPs == 0)
183 {
184 wxLogLastError("GpiCreatePS Failure");
185 }
186
187 if (nDepth == 1)
188 {
189 //
190 // We assume that it is in XBM format which is not quite the same as
191 // the format CreateBitmap() wants because the order of bytes in the
192 // line is inversed!
193 //
194 const size_t nBytesPerLine = (nWidth + 7) / 8;
195 const size_t nPadding = nBytesPerLine % 2;
196 const size_t nLen = nHeight * (nPadding + nBytesPerLine);
197 const char* pzSrc = zBits;
198 int nRows;
199 size_t nCols;
200
201 pzData = (char *)malloc(nLen);
202
203 char* pzDst = pzData;
204
205 for (nRows = 0; nRows < nHeight; nRows++)
206 {
207 for (nCols = 0; nCols < nBytesPerLine; nCols++)
208 {
209 unsigned char ucVal = *pzSrc++;
210 unsigned char ucReversed = 0;
211 int nBits;
212
213 for (nBits = 0; nBits < 8; nBits++)
214 {
215 ucReversed <<= 1;
216 ucReversed |= (ucVal & 0x01);
217 ucVal >>= 1;
218 }
219 *pzDst++ = ucReversed;
220 }
221 if (nPadding)
222 *pzDst++ = 0;
223 }
224 }
225 else
226 {
227 //
228 // Bits should already be in Windows standard format
229 //
230 pzData = (char *)zBits; // const_cast is harmless
231 }
232
233 if (nDepth > 24)
234 nDepth = 24; // MAX supported in PM
235 memset(&vHeader, '\0', 16);
236 vHeader.cbFix = 16;
237 vHeader.cx = (USHORT)nWidth;
238 vHeader.cy = (USHORT)nHeight;
239 vHeader.cPlanes = 1L;
240 vHeader.cBitCount = nDepth;
241 vHeader.usReserved = 0;
242
243 memset(&vInfo, '\0', 16);
244 vInfo.cbFix = 16;
245 vInfo.cx = (USHORT)nWidth;
246 vInfo.cy = (USHORT)nHeight;
247 vInfo.cPlanes = 1L;
248 vInfo.cBitCount = nDepth;
249
250 HBITMAP hBmp = ::GpiCreateBitmap(hPs, &vHeader, CBM_INIT, (PBYTE)pzData, &vInfo);
251
252 if (!hBmp)
253 {
254 wxLogLastError("CreateBitmap");
255 }
256 ::GpiDestroyPS(hPs);
257 ::DevCloseDC(hDc);
258 SetHBITMAP((WXHBITMAP)hBmp);
259 } // end of wxBitmap::wxBitmap
260
261 wxBitmap::wxBitmap(
262 int nW
263 , int nH
264 , int nD
265 )
266 {
267 Init();
268
269 (void)Create( nW
270 ,nH
271 ,nD
272 );
273 } // end of wxBitmap::wxBitmap
274
275 wxBitmap::wxBitmap(
276 void* pData
277 , long lType
278 , int nWidth
279 , int nHeight
280 , int nDepth
281 )
282 {
283 Init();
284
285 (void)Create( pData
286 ,lType
287 ,nWidth
288 ,nHeight
289 ,nDepth
290 );
291 } // end of wxBitmap::wxBitmap
292
293 wxBitmap::wxBitmap(
294 const wxString& rFilename
295 , long lType
296 )
297 {
298 Init();
299
300 LoadFile( rFilename
301 ,(int)lType
302 );
303 } // end of wxBitmap::wxBitmap
304
305 bool wxBitmap::Create(
306 int nW
307 , int nH
308 , int nD
309 )
310 {
311 HBITMAP hBmp;
312 BITMAPINFOHEADER2 vHeader;
313
314 wxASSERT(vHabmain != NULL);
315 UnRef();
316 m_refData = new wxBitmapRefData;
317 GetBitmapData()->m_nWidth = nW;
318 GetBitmapData()->m_nHeight = nH;
319 GetBitmapData()->m_nDepth = nD;
320
321 //
322 // Xpms and bitmaps from other images can also be mono's, but only
323 // mono's need help changing their colors with MemDC changes
324 //
325 if (nD == 1)
326 m_bIsMono = TRUE;
327 if (nD > 0)
328 {
329 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
330 SIZEL vSize = {0, 0};
331 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
332 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
333
334 memset(&vHeader, '\0', 16);
335 vHeader.cbFix = 16;
336 vHeader.cx = nW;
337 vHeader.cy = nH;
338 vHeader.cPlanes = 1;
339 vHeader.cBitCount = 24; //nD;
340
341 hBmp = ::GpiCreateBitmap( hPS
342 ,&vHeader
343 ,0L
344 ,NULL
345 ,NULL
346 );
347 ::GpiDestroyPS(hPS);
348 ::DevCloseDC(hDC);
349 }
350 else
351 {
352 HPS hPSScreen;
353 HDC hDCScreen;
354 LONG lBitCount;
355
356 hPSScreen = ::WinGetScreenPS(HWND_DESKTOP);
357 hDCScreen = ::GpiQueryDevice(hPSScreen);
358 ::DevQueryCaps(hDCScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
359
360 if (lBitCount > 24)
361 lBitCount = 24;
362
363 memset(&vHeader, '\0', 16);
364 vHeader.cbFix = 16;
365 vHeader.cx = nW;
366 vHeader.cy = nH;
367 vHeader.cPlanes = 1;
368 vHeader.cBitCount = lBitCount;
369
370 hBmp = ::GpiCreateBitmap( hPSScreen
371 ,&vHeader
372 ,0L
373 ,NULL
374 ,NULL
375 );
376
377 GetBitmapData()->m_nDepth = wxDisplayDepth();
378 ::WinReleasePS(hPSScreen);
379 }
380 SetHBITMAP((WXHBITMAP)hBmp);
381
382 #if WXWIN_COMPATIBILITY_2
383 GetBitmapData()->m_bOk = hBmp != 0;
384 #endif // WXWIN_COMPATIBILITY_2
385
386 return Ok();
387 } // end of wxBitmap::Create
388
389 bool wxBitmap::CreateFromXpm(
390 const char** ppData
391 )
392 {
393 #if wxUSE_IMAGE && wxUSE_XPM
394 Init();
395
396 wxCHECK_MSG(ppData != NULL, FALSE, wxT("invalid bitmap data"))
397
398 wxXPMDecoder vDecoder;
399 wxImage vImg = vDecoder.ReadData(ppData);
400
401 wxCHECK_MSG(vImg.Ok(), FALSE, wxT("invalid bitmap data"))
402
403 *this = wxBitmap(vImg);
404 return TRUE;
405 #else
406 return FALSE;
407 #endif
408 } // end of wxBitmap::CreateFromXpm
409
410 bool wxBitmap::LoadFile(
411 const wxString& rFilename
412 , long lType
413 )
414 {
415 HPS hPs = NULLHANDLE;
416
417 UnRef();
418
419 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
420 ,wxBitmapHandler
421 );
422
423 if (pHandler)
424 {
425 m_refData = new wxBitmapRefData;
426
427 return(pHandler->LoadFile( this
428 ,rFilename
429 ,hPs
430 ,lType
431 , -1
432 , -1
433 ));
434 }
435 else
436 {
437 wxImage vImage;
438
439 if (!vImage.LoadFile(rFilename, lType) || !vImage.Ok() )
440 return(FALSE);
441
442 *this = wxBitmap(vImage);
443
444 return(TRUE);
445 }
446 } // end of wxBitmap::LoadFile
447
448 bool wxBitmap::Create(
449 void* pData
450 , long lType
451 , int nWidth
452 , int nHeight
453 , int nDepth
454 )
455 {
456 UnRef();
457
458 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
459 ,wxBitmapHandler
460 );
461
462 if (!pHandler)
463 {
464 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
465 "type %d defined."), lType);
466
467 return(FALSE);
468 }
469
470 m_refData = new wxBitmapRefData;
471
472 return(pHandler->Create( this
473 ,pData
474 ,lType
475 ,nWidth
476 ,nHeight
477 ,nDepth
478 ));
479 } // end of wxBitmap::Create
480
481 bool wxBitmap::SaveFile(
482 const wxString& rFilename
483 , int lType
484 , const wxPalette* pPalette
485 )
486 {
487 wxBitmapHandler* pHandler = wxDynamicCast( FindHandler(lType)
488 ,wxBitmapHandler
489 );
490
491 if (pHandler)
492 {
493 return pHandler->SaveFile( this
494 ,rFilename
495 ,lType
496 ,pPalette
497 );
498 }
499 else
500 {
501 // FIXME what about palette? shouldn't we use it?
502 wxImage vImage = ConvertToImage();
503
504 if (!vImage.Ok())
505 return(FALSE);
506
507 return(vImage.SaveFile( rFilename
508 ,lType
509 ));
510 }
511 } // end of wxBitmap::SaveFile
512
513
514 // ----------------------------------------------------------------------------
515 // wxImage-wxBitmap convertion
516 // ----------------------------------------------------------------------------
517
518 bool wxBitmap::CreateFromImage (
519 const wxImage& rImage
520 , int nDepth
521 )
522 {
523 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
524 m_refData = new wxBitmapRefData();
525
526
527 int nSizeLimit = 1024 * 768 * 3;
528 int nWidth = rImage.GetWidth();
529 int nBmpHeight = rImage.GetHeight();
530 int nBytePerLine = nWidth * 3;
531 int nSizeDWORD = sizeof(DWORD);
532 int nLineBoundary = nBytePerLine % nSizeDWORD;
533 int nPadding = 0;
534
535 if (nLineBoundary > 0)
536 {
537 nPadding = nSizeDWORD - nLineBoundary;
538 nBytePerLine += nPadding;
539 }
540
541 //
542 // Calc the number of DIBs and heights of DIBs
543 //
544 int nNumDIB = 1;
545 int nHRemain = 0;
546 int nHeight = nSizeLimit / nBytePerLine;
547
548 if (nHeight >= nBmpHeight)
549 nHeight = nBmpHeight;
550 else
551 {
552 nNumDIB = nBmpHeight / nHeight;
553 nHRemain = nBmpHeight % nHeight;
554 if (nHRemain > 0)
555 nNumDIB++;
556 }
557
558 //
559 // Set bitmap parameters
560 //
561 wxCHECK_MSG(rImage.Ok(), FALSE, wxT("invalid image"));
562 SetWidth(nWidth);
563 SetHeight(nBmpHeight);
564 if (nDepth == -1)
565 nDepth = wxDisplayDepth();
566 SetDepth(nDepth);
567
568 #if wxUSE_PALETTE
569 //
570 // Copy the palette from the source image
571 //
572 SetPalette(rImage.GetPalette());
573 #endif // wxUSE_PALETTE
574
575 //
576 // Create a DIB header
577 //
578 BITMAPINFOHEADER2 vHeader;
579 BITMAPINFO2 vInfo;
580
581 //
582 // Fill in the DIB header
583 //
584 memset(&vHeader, '\0', 16);
585 vHeader.cbFix = 16;
586 vHeader.cx = (ULONG)nWidth;
587 vHeader.cy = (ULONG)nHeight;
588 vHeader.cPlanes = 1L;
589 vHeader.cBitCount = 24;
590
591 //
592 // Memory for DIB data
593 //
594 unsigned char* pucBits;
595
596 pucBits = (unsigned char *)malloc(nBytePerLine * nHeight);
597 if(!pucBits)
598 {
599 wxFAIL_MSG(wxT("could not allocate memory for DIB"));
600 return FALSE;
601 }
602 memset(pucBits, '\0', (nBytePerLine * nHeight));
603
604 //
605 // Create and set the device-dependent bitmap
606 //
607 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
608 SIZEL vSize = {0, 0};
609 HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
610 HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC);
611 LONG lScans;
612 HDC hDCScreen = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE);
613 HPS hPSScreen;
614 HBITMAP hBmp;
615 HBITMAP hBmpOld;
616
617 memset(&vInfo, '\0', 16);
618 vInfo.cbFix = 16;
619 vInfo.cx = (ULONG)nWidth;
620 vInfo.cy = (ULONG)nHeight;
621 vInfo.cPlanes = 1;
622 vInfo.cBitCount = 24; // Set to desired count going in
623
624 hBmp = ::GpiCreateBitmap( hPS
625 ,&vHeader
626 ,0L
627 ,NULL
628 ,NULL
629 );
630 #if wxUSE_PALETTE
631 HPAL hOldPalette = NULLHANDLE;
632 if (rImage.GetPalette().Ok())
633 {
634 hOldPalette = ::GpiSelectPalette(hPS, (HPAL)rImage.GetPalette().GetHPALETTE());
635 }
636 #endif // wxUSE_PALETTE
637
638 //
639 // Copy image data into DIB data and then into DDB (in a loop)
640 //
641 unsigned char* pData = rImage.GetData();
642 int i;
643 int j;
644 int n;
645 int nOrigin = 0;
646 unsigned char* ptdata = pData;
647 unsigned char* ptbits;
648
649 if ((hBmpOld = ::GpiSetBitmap(hPS, hBmp)) == HBM_ERROR)
650 {
651 ERRORID vError;
652 wxString sError;
653
654 vError = ::WinGetLastError(vHabmain);
655 sError = wxPMErrorToStr(vError);
656 }
657 for (n = 0; n < nNumDIB; n++)
658 {
659 if (nNumDIB > 1 && n == nNumDIB - 1 && nHRemain > 0)
660 {
661 //
662 // Redefine height and size of the (possibly) last smaller DIB
663 // memory is not reallocated
664 //
665 nHeight = nHRemain;
666 vHeader.cy = (DWORD)(nHeight);
667 vHeader.cbImage = nBytePerLine * nHeight;
668 }
669 ptbits = pucBits;
670 for (j = 0; j < nHeight; j++)
671 {
672 for (i = 0; i < nWidth; i++)
673 {
674 *(ptbits++) = *(ptdata + 2);
675 *(ptbits++) = *(ptdata + 1);
676 *(ptbits++) = *(ptdata);
677 ptdata += 3;
678 }
679 for (i = 0; i < nPadding; i++)
680 *(ptbits++) = 0;
681 }
682
683 //
684 // Have to do something similar to WIN32's StretchDIBits, use GpiBitBlt
685 // in combination with setting the bits into the selected bitmap
686 //
687 if ((lScans = ::GpiSetBitmapBits( hPS
688 ,0 // Start at the bottom
689 ,(LONG)nHeight // One line per scan
690 ,(PBYTE)pucBits
691 ,&vInfo
692 )) == GPI_ALTERROR)
693 {
694 ERRORID vError;
695 wxString sError;
696
697 vError = ::WinGetLastError(vHabmain);
698 sError = wxPMErrorToStr(vError);
699 }
700 //
701 // Debug stuff
702 //
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 if ((hOldBitmap = ::GpiSetBitmap(hPSMem, hBitmap)) == HBM_ERROR)
943 {
944 ERRORID vError;
945 wxString sError;
946
947 vError = ::WinGetLastError(vHabmain);
948 sError = wxPMErrorToStr(vError);
949 }
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 = 1;
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 = 1;
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', sizeof(BITMAPINFOHEADER2));
1590 vBmih.cbFix = sizeof(BITMAPINFOHEADER2);
1591 vBmih.cx = nWidth;
1592 vBmih.cy = nHeight;
1593 vBmih.cPlanes = 1;
1594 vBmih.cBitCount = 1;
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