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