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