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