X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4c444f19cf1bdb3cb26bb3c123434fe23c808093..b3818fbe8e439bc9af8c20371774520a5a2bc9c7:/src/msw/bitmap.cpp diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index d3ed8bc019..e6194fcef9 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -27,6 +27,7 @@ #include "wx/utils.h" #include "wx/app.h" #include "wx/palette.h" +#include "wx/dcmemory.h" #include "wx/bitmap.h" #include "wx/icon.h" #endif @@ -36,11 +37,6 @@ #include "assert.h" -#if USE_XPM_IN_MSW -#define FOR_MSW 1 -#include "../../contrib/wxxpm/libxpm.34b/lib/xpm34.h" -#endif - #include "wx/msw/dib.h" #if !USE_SHARED_LIBRARIES @@ -65,8 +61,8 @@ wxBitmapRefData::~wxBitmapRefData(void) { if (m_selectedInto) { - char buf[200]; - sprintf(buf, "Bitmap was deleted without selecting out of wxMemoryDC %X.", (unsigned int) m_selectedInto); + wxChar buf[200]; + wxSprintf(buf, _T("Bitmap was deleted without selecting out of wxMemoryDC %X."), (unsigned int) m_selectedInto); wxFatalError(buf); } if (m_hBitmap) @@ -78,14 +74,13 @@ wxBitmapRefData::~wxBitmapRefData(void) if (m_bitmapMask) delete m_bitmapMask; m_bitmapMask = NULL; + } wxList wxBitmap::sm_handlers; wxBitmap::wxBitmap(void) { - m_refData = NULL; // new wxBitmapRefData; - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); } @@ -96,15 +91,15 @@ wxBitmap::~wxBitmap(void) wxTheBitmapList->DeleteObject(this); } -bool wxBitmap::FreeResource(bool force) +bool wxBitmap::FreeResource(bool WXUNUSED(force)) { if ( !M_BITMAPDATA ) return FALSE; if (M_BITMAPDATA->m_selectedInto) { - char buf[200]; - sprintf(buf, "Bitmap %X was deleted without selecting out of wxMemoryDC %X.", (unsigned int) this, (unsigned int) M_BITMAPDATA->m_selectedInto); + wxChar buf[200]; + wxSprintf(buf, _T("Bitmap %X was deleted without selecting out of wxMemoryDC %X."), (unsigned int) this, (unsigned int) M_BITMAPDATA->m_selectedInto); wxFatalError(buf); } if (M_BITMAPDATA->m_hBitmap) @@ -146,6 +141,12 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits wxTheBitmapList->AddBitmap(this); } +// Create from XPM data +wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem)) +{ + (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); +} + wxBitmap::wxBitmap(int w, int h, int d) { (void)Create(w, h, d); @@ -170,14 +171,6 @@ wxBitmap::wxBitmap(const wxString& filename, long type) wxTheBitmapList->AddBitmap(this); } -#if USE_XPM_IN_MSW -// Create from data -wxBitmap::wxBitmap(const char **data, wxItem *WXUNUSED(anItem)) -{ - (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); -} -#endif - bool wxBitmap::Create(int w, int h, int d) { UnRef(); @@ -194,9 +187,9 @@ bool wxBitmap::Create(int w, int h, int d) } else { - HDC dc = GetDC(NULL); + HDC dc = GetDC((HWND) NULL); M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h); - ReleaseDC(NULL, dc); + ReleaseDC((HWND) NULL, dc); M_BITMAPDATA->m_depth = wxDisplayDepth(); } if (M_BITMAPDATA->m_hBitmap) @@ -215,7 +208,7 @@ bool wxBitmap::LoadFile(const wxString& filename, long type) wxBitmapHandler *handler = FindHandler(type); if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); + wxLogWarning(_T("no bitmap handler for type %d defined."), type); return FALSE; } @@ -232,7 +225,7 @@ bool wxBitmap::Create(void *data, long type, int width, int height, int depth) wxBitmapHandler *handler = FindHandler(type); if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); + wxLogWarning(_T("no bitmap handler for type %d defined."), type); return FALSE; } @@ -245,7 +238,7 @@ bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *pal wxBitmapHandler *handler = FindHandler(type); if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); + wxLogWarning(_T("no bitmap handler for type %d defined."), type); return FALSE; } @@ -345,7 +338,7 @@ wxBitmapHandler *wxBitmap::FindHandler(const wxString& name) while ( node ) { wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetName() == name ) + if ( (handler->GetName().Cmp(name) == 0) ) return handler; node = node->Next(); } @@ -358,8 +351,8 @@ wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapTyp while ( node ) { wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetExtension() == extension && - (bitmapType == -1 || handler->GetType() == bitmapType) ) + if ( (handler->GetExtension().Cmp(extension) == 0) && + (bitmapType == -1 || (handler->GetType() == bitmapType)) ) return handler; node = node->Next(); } @@ -379,6 +372,65 @@ wxBitmapHandler *wxBitmap::FindHandler(long bitmapType) return NULL; } +// New Create/FreeDIB functions since ones in dibutils.cpp are confusing +static long createDIB(long xSize, long ySize, long bitsPerPixel, + HPALETTE hPal, LPBITMAPINFO* lpDIBHeader); +static long freeDIB(LPBITMAPINFO lpDIBHeader); + +// Creates a bitmap that matches the device context, from +// an arbitray bitmap. At present, the original bitmap must have an +// associated palette. TODO: use a default palette if no palette exists. +// Contributed by Frederic Villeneuve +wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const +{ + wxMemoryDC memDC; + wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth()); + HPALETTE hPal = (HPALETTE) NULL; + LPBITMAPINFO lpDib; + void *lpBits = (void*) NULL; + +/* + wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) ); + + tmpBitmap.SetPalette(this->GetPalette()); + memDC.SelectObject(tmpBitmap); + memDC.SetPalette(this->GetPalette()); + + hPal = (HPALETTE) this->GetPalette()->GetHPALETTE(); +*/ + if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) ) + { + tmpBitmap.SetPalette(* this->GetPalette()); + memDC.SelectObject(tmpBitmap); + memDC.SetPalette(* this->GetPalette()); + hPal = (HPALETTE) this->GetPalette()->GetHPALETTE(); + } + else + { + hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE); + wxPalette palette; + palette.SetHPALETTE( (WXHPALETTE)hPal ); + tmpBitmap.SetPalette( palette ); + memDC.SelectObject(tmpBitmap); + memDC.SetPalette( palette ); + } + + // set the height negative because in a DIB the order of the lines is reversed + createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib); + + lpBits = malloc(lpDib->bmiHeader.biSizeImage); + + ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits); + + ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(), + 0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS); + + free(lpBits); + + freeDIB(lpDib); + return (tmpBitmap); +} + /* * wxMask */ @@ -525,18 +577,18 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) -bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) +bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth)) { return FALSE; } -bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type, - int desiredWidth, int desiredHeight) +bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type), + int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight)) { return FALSE; } -bool wxBitmapHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette) +bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette)) { return FALSE; } @@ -561,24 +613,29 @@ public: }; IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) -bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth, int desiredHeight) +bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags), + int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight)) { // TODO: load colourmap. M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name); if (M_BITMAPHANDLERDATA->m_hBitmap) { - M_BITMAPHANDLERDATA->m_ok = TRUE; - BITMAP bm; - GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm); - M_BITMAPHANDLERDATA->m_width = bm.bmWidth; - M_BITMAPHANDLERDATA->m_height = bm.bmHeight; - M_BITMAPHANDLERDATA->m_depth = bm.bmPlanes; - return TRUE; + M_BITMAPHANDLERDATA->m_ok = TRUE; + BITMAP bm; + GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm); + M_BITMAPHANDLERDATA->m_width = bm.bmWidth; + M_BITMAPHANDLERDATA->m_height = bm.bmHeight; + M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel; + + if ( bitmap->IsKindOf(CLASSINFO(wxIcon)) ) + { + } + + return TRUE; } // it's probably not found - wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str()); + wxLogError(_T("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str()); return FALSE; } @@ -600,10 +657,10 @@ public: }; IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler) -bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth, int desiredHeight) +bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags), + int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight)) { -#if USE_IMAGE_LOADING_IN_MSW +#if wxUSE_IMAGE_LOADING_IN_MSW wxPalette *palette = NULL; bool success = FALSE; /* @@ -618,16 +675,19 @@ bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long fla palette = NULL; } if (palette) - M_BITMAPHANDLERDATA->m_bitmapPalette = *palette; + { + M_BITMAPHANDLERDATA->m_bitmapPalette = *palette; + delete palette; + } return success; #else return FALSE; #endif } -bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal) +bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal) { -#if USE_IMAGE_LOADING_IN_MSW +#if wxUSE_IMAGE_LOADING_IN_MSW wxPalette *actualPalette = (wxPalette *)pal; if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull())) actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette); @@ -637,188 +697,91 @@ bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type #endif } -class WXDLLEXPORT wxXPMFileHandler: public wxBitmapHandler +void wxBitmap::CleanUpHandlers(void) { - DECLARE_DYNAMIC_CLASS(wxXPMFileHandler) -public: - inline wxXPMFileHandler(void) + wxNode *node = sm_handlers.First(); + while ( node ) { - m_name = "XPM bitmap file"; - m_extension = "xpm"; - m_type = wxBITMAP_TYPE_XPM; - }; - - virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth = -1, int desiredHeight = -1); - virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL); -}; -IMPLEMENT_DYNAMIC_CLASS(wxXPMFileHandler, wxBitmapHandler) + wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); + wxNode *next = node->Next(); + delete handler; + delete node; + node = next; + } +} -bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth, int desiredHeight) +void wxBitmap::InitStandardHandlers(void) { -#if USE_XPM_IN_MSW - XImage *ximage; - XpmAttributes xpmAttr; - HDC dc; - - M_BITMAPHANDLERDATA->m_ok = FALSE; - dc = CreateCompatibleDC(NULL); - if (dc) - { - xpmAttr.valuemask = XpmReturnPixels; - int errorStatus = XpmReadFileToImage(&dc, WXSTRINGCAST name, &ximage, (XImage **) NULL, &xpmAttr); - DeleteDC(dc); - if (errorStatus == XpmSuccess) - { - M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap; - - BITMAP bm; - GetObject((HBITMAP)M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm); + AddHandler(new wxBMPResourceHandler); + AddHandler(new wxBMPFileHandler); - M_BITMAPHANDLERDATA->m_width = (bm.bmWidth); - M_BITMAPHANDLERDATA->m_height = (bm.bmHeight); - M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel); - M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels; - XpmFreeAttributes(&xpmAttr); - XImageFree(ximage); + // Not added by default: include xpmhand.h in your app + // and call these in your wxApp::OnInit. +// AddHandler(new wxXPMFileHandler); +// AddHandler(new wxXPMDataHandler); - M_BITMAPHANDLERDATA->m_ok = TRUE; - return TRUE; - } - else - { - M_BITMAPHANDLERDATA->m_ok = FALSE; - return FALSE; - } - } -#endif - - return FALSE; + AddHandler(new wxICOResourceHandler); + AddHandler(new wxICOFileHandler); } -bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette) +static long createDIB(long xSize, long ySize, long bitsPerPixel, + HPALETTE hPal, LPBITMAPINFO* lpDIBHeader) { -#if USE_XPM_IN_MSW - HDC dc = NULL; + unsigned long i, headerSize; + LPBITMAPINFO lpDIBheader = NULL; + LPPALETTEENTRY lpPe = NULL; - Visual *visual = NULL; - XImage ximage; - dc = CreateCompatibleDC(NULL); - if (dc) - { - if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap)) - { /* for following SetPixel */ - /* fill the XImage struct 'by hand' */ - ximage.width = M_BITMAPHANDLERDATA->m_width; - ximage.height = M_BITMAPHANDLERDATA->m_height; - ximage.depth = M_BITMAPHANDLERDATA->m_depth; - ximage.bitmap = (void *)M_BITMAPHANDLERDATA->m_hBitmap; - int errorStatus = XpmWriteFileFromImage(&dc, WXSTRINGCAST name, - &ximage, (XImage *) NULL, (XpmAttributes *) NULL); - - if (dc) - DeleteDC(dc); - - if (errorStatus == XpmSuccess) - return TRUE; /* no error */ - else - return FALSE; - } else return FALSE; - } else return FALSE; -#else - return FALSE; -#endif -} + // Allocate space for a DIB header + headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY))); + lpDIBheader = (BITMAPINFO *) malloc(headerSize); + lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER)); -class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler -{ - DECLARE_DYNAMIC_CLASS(wxXPMDataHandler) -public: - inline wxXPMDataHandler(void) - { - m_name = "XPM bitmap data"; - m_extension = "xpm"; - m_type = wxBITMAP_TYPE_XPM_DATA; - }; + GetPaletteEntries(hPal, 0, 256, lpPe); - virtual bool Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth = 1); -}; -IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler) -bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth) -{ -#if USE_XPM_IN_MSW - XImage *ximage; - int ErrorStatus; - XpmAttributes xpmAttr; - HDC dc; + memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER)); - M_BITMAPHANDLERDATA->m_ok = FALSE; - M_BITMAPHANDLERDATA->m_numColors = 0; - dc = CreateCompatibleDC(NULL); /* memory DC */ + // Fill in the static parts of the DIB header + lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpDIBheader->bmiHeader.biWidth = xSize; + lpDIBheader->bmiHeader.biHeight = ySize; + lpDIBheader->bmiHeader.biPlanes = 1; - if (dc) - { - xpmAttr.valuemask = XpmReturnInfos; /* get infos back */ - ErrorStatus = XpmCreateImageFromData(&dc, (char **)data, - &ximage, (XImage **) NULL, &xpmAttr); + // this value must be 1, 4, 8 or 24 so PixelDepth can only be + lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel); + lpDIBheader->bmiHeader.biCompression = BI_RGB; + lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >> +3; + lpDIBheader->bmiHeader.biClrUsed = 256; - if (ErrorStatus == XpmSuccess) - { - /* ximage is malloced and contains bitmap and attributes */ - M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ximage->bitmap; - BITMAP bm; - GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(bm), (LPSTR) & bm); + // Initialize the DIB palette + for (i = 0; i < 256; i++) { + lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags; + lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed; + lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen; + lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue; + } - M_BITMAPHANDLERDATA->m_width = (bm.bmWidth); - M_BITMAPHANDLERDATA->m_height = (bm.bmHeight); - M_BITMAPHANDLERDATA->m_depth = (bm.bmPlanes * bm.bmBitsPixel); - M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels; - XpmFreeAttributes(&xpmAttr); + *lpDIBHeader = lpDIBheader; - XImageFree(ximage); // releases the malloc, but does not detroy - // the bitmap - M_BITMAPHANDLERDATA->m_ok = TRUE; - DeleteDC(dc); - return TRUE; - } - else - { - M_BITMAPHANDLERDATA->m_ok = FALSE; -// XpmDebugError(ErrorStatus, NULL); - DeleteDC(dc); - return FALSE; - } - } -#endif + return (0); - return FALSE; } -void wxBitmap::CleanUpHandlers(void) + + +static long freeDIB(LPBITMAPINFO lpDIBHeader) { - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - wxNode *next = node->Next(); - delete handler; - delete node; - node = next; - } + + if (lpDIBHeader != NULL) { + free(lpDIBHeader); + } + + return (0); } -void wxBitmap::InitStandardHandlers(void) -{ - AddHandler(new wxBMPResourceHandler); - AddHandler(new wxBMPFileHandler); - AddHandler(new wxXPMFileHandler); - AddHandler(new wxXPMDataHandler); - AddHandler(new wxICOResourceHandler); - AddHandler(new wxICOFileHandler); -} \ No newline at end of file +