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