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