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