X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/54a96d029f6864182e5e49e7d5b2e133be6d3d51..4aaef122cbbd5bbe0e70b824e320458e2329dd13:/src/msw/bitmap.cpp diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 97a886aff9..a44f26ea0b 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -40,6 +40,8 @@ #include "wx/icon.h" #endif +//#include "device.h" + #include "wx/msw/private.h" #include "wx/log.h" @@ -89,10 +91,12 @@ void wxBitmapRefData::Free() if ( m_hBitmap) { // printf("About to delete bitmap %d\n", (int) (HBITMAP) m_hBitmap); +#if 1 if ( !::DeleteObject((HBITMAP)m_hBitmap) ) { wxLogLastError(wxT("DeleteObject(hbitmap)")); } +#endif } delete m_bitmapMask; @@ -381,17 +385,29 @@ bool wxBitmap::Create(int w, int h, int d) bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) { #ifdef __WXMICROWIN__ + + // Set this to 1 to experiment with mask code, + // which currently doesn't work +#define USE_MASKS 0 + m_refData = new wxBitmapRefData(); // Initial attempt at a simple-minded implementation. // The bitmap will always be created at the screen depth, // so the 'depth' argument is ignored. - // TODO: transparency (create a mask image) HDC hScreenDC = ::GetDC(NULL); + // printf("Screen planes = %d, bpp = %d\n", hScreenDC->psd->planes, hScreenDC->psd->bpp); int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL); HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight()); + HBITMAP hMaskBitmap = NULL; + HBITMAP hOldMaskBitmap = NULL; + HDC hMaskDC = NULL; + unsigned char maskR = 0; + unsigned char maskG = 0; + unsigned char maskB = 0; + // printf("Created bitmap %d\n", (int) hBitmap); if (hBitmap == NULL) { @@ -399,9 +415,43 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) return FALSE; } HDC hMemDC = ::CreateCompatibleDC(hScreenDC); - ::ReleaseDC(NULL, hScreenDC); HBITMAP hOldBitmap = ::SelectObject(hMemDC, hBitmap); + ::ReleaseDC(NULL, hScreenDC); + + // created an mono-bitmap for the possible mask + bool hasMask = image.HasMask(); + + if ( hasMask ) + { +#if USE_MASKS + // FIXME: we should be able to pass bpp = 1, but + // GdBlit can't handle a different depth +#if 0 + hMaskBitmap = ::CreateBitmap( (WORD)image.GetWidth(), (WORD)image.GetHeight(), 1, 1, NULL ); +#else + hMaskBitmap = ::CreateCompatibleBitmap( hMemDC, (WORD)image.GetWidth(), (WORD)image.GetHeight()); +#endif + maskR = image.GetMaskRed(); + maskG = image.GetMaskGreen(); + maskB = image.GetMaskBlue(); + + if (!hMaskBitmap) + { + hasMask = FALSE; + } + else + { + hScreenDC = ::GetDC(NULL); + hMaskDC = ::CreateCompatibleDC(hScreenDC); + ::ReleaseDC(NULL, hScreenDC); + + hOldMaskBitmap = ::SelectObject( hMaskDC, hMaskBitmap); + } +#else + hasMask = FALSE; +#endif + } int i, j; for (i = 0; i < image.GetWidth(); i++) @@ -413,11 +463,28 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) unsigned char blue = image.GetBlue(i, j); ::SetPixel(hMemDC, i, j, PALETTERGB(red, green, blue)); + + if (hasMask) + { + // scan the bitmap for the transparent colour and set the corresponding + // pixels in the mask to BLACK and the rest to WHITE + if (maskR == red && maskG == green && maskB == blue) + ::SetPixel(hMaskDC, i, j, PALETTERGB(0, 0, 0)); + else + ::SetPixel(hMaskDC, i, j, PALETTERGB(255, 255, 255)); + } } } ::SelectObject(hMemDC, hOldBitmap); ::DeleteDC(hMemDC); + if (hasMask) + { + ::SelectObject(hMaskDC, hOldMaskBitmap); + ::DeleteDC(hMaskDC); + + ((wxBitmapRefData*)m_refData)->m_bitmapMask = new wxMask((WXHBITMAP) hMaskBitmap); + } SetWidth(image.GetWidth()); SetHeight(image.GetHeight()); @@ -1225,32 +1292,13 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) ok = FALSE; } - // this is not very efficient, but I can't think of a better way of doing - // it - for ( int w = 0; ok && (w < width); w++ ) + if ( ok ) { - for ( int h = 0; ok && (h < height); h++ ) - { - COLORREF col = GetPixel(srcDC, w, h); - if ( col == CLR_INVALID ) - { - wxLogLastError(wxT("GetPixel")); - - // doesn't make sense to continue - ok = FALSE; - - break; - } - - if ( col == maskColour ) - { - ::SetPixel(destDC, w, h, RGB(0, 0, 0)); - } - else - { - ::SetPixel(destDC, w, h, RGB(255, 255, 255)); - } - } + // this will create a monochrome bitmap with 0 points for the pixels + // which have the same value as the background colour and 1 for the + // others + ::SetBkColor(srcDC, maskColour); + ::BitBlt(destDC, 0, 0, width, height, srcDC, 0, 0, NOTSRCCOPY); } ::SelectObject(srcDC, hbmpSrcOld); @@ -1259,9 +1307,9 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) ::DeleteDC(destDC); return ok; -#else +#else // __WXMICROWIN__ return FALSE; -#endif +#endif // __WXMICROWIN__/!__WXMICROWIN__ } // ----------------------------------------------------------------------------