diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index f173d69e39..e79dc0e935 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -24,6 +24,7 @@ class WXDLLEXPORT wxDC; class WXDLLEXPORT wxControl; class WXDLLEXPORT wxBitmap; class WXDLLEXPORT wxBitmapHandler; +class WXDLLEXPORT wxBitmapRefData; class WXDLLEXPORT wxIcon; class WXDLLEXPORT wxMask; class WXDLLEXPORT wxCursor; @@ -31,47 +32,6 @@ class WXDLLEXPORT wxControl; class WXDLLEXPORT wxImage; class WXDLLEXPORT wxPalette; -// ---------------------------------------------------------------------------- -// Bitmap data -// -// NB: this class is private, but declared here to make it possible inline -// wxBitmap functions accessing it -// ---------------------------------------------------------------------------- - -class WXDLLEXPORT wxBitmapRefData : public wxGDIImageRefData -{ -public: - wxBitmapRefData(); - virtual ~wxBitmapRefData() { Free(); } - - virtual void Free(); - -public: - int m_numColors; -#if wxUSE_PALETTE - wxPalette m_bitmapPalette; -#endif // wxUSE_PALETTE - int m_quality; - - // MSW-specific - // ------------ - - // this field is solely for error checking: we detect selecting a bitmap - // into more than one DC at once or deleting a bitmap still selected into a - // DC (both are serious programming errors under Windows) - wxDC *m_selectedInto; - - // optional mask for transparent drawing - wxMask *m_bitmapMask; - -#if wxUSE_DIB_FOR_BITMAP - WXHANDLE m_hFileMap; // file mapping handle for large DIB's -#endif - - - DECLARE_NO_COPY_CLASS(wxBitmapRefData) -}; - // ---------------------------------------------------------------------------- // wxBitmap: a mono or colour bitmap // ---------------------------------------------------------------------------- @@ -152,22 +112,32 @@ public: virtual bool LoadFile(const wxString& name, long type = wxBITMAP_TYPE_BMP_RESOURCE); virtual bool SaveFile(const wxString& name, int type, const wxPalette *cmap = NULL); - wxBitmapRefData *GetBitmapData() const { return (wxBitmapRefData *)m_refData; } - - int GetQuality() const { return (GetBitmapData() ? GetBitmapData()->m_quality : 0); } - void SetQuality(int q); + wxBitmapRefData *GetBitmapData() const + { return (wxBitmapRefData *)m_refData; } #if wxUSE_PALETTE - wxPalette* GetPalette() const { return (GetBitmapData() ? (& GetBitmapData()->m_bitmapPalette) : (wxPalette*) NULL); } + wxPalette* GetPalette() const; void SetPalette(const wxPalette& palette); #endif // wxUSE_PALETTE - wxMask *GetMask() const { return (GetBitmapData() ? GetBitmapData()->m_bitmapMask : (wxMask*) NULL); } + wxMask *GetMask() const; void SetMask(wxMask *mask) ; bool operator==(const wxBitmap& bitmap) const { return m_refData == bitmap.m_refData; } bool operator!=(const wxBitmap& bitmap) const { return m_refData != bitmap.m_refData; } +#if wxUSE_DIB_FOR_BITMAP + // returns TRUE if this bitmap is a DIB (otherwise it's a DDB) + bool IsDIB() const; +#endif // wxUSE_DIB_FOR_BITMAP + +#if WXWIN_COMPATIBILITY_2_4 + // these functions do nothing and are only there for backwards + // compatibility + wxDEPRECATED( int GetQuality() const ); + wxDEPRECATED( void SetQuality(int quality) ); +#endif // WXWIN_COMPATIBILITY_2_4 + #if WXWIN_COMPATIBILITY_2 void SetOk(bool isOk); #endif // WXWIN_COMPATIBILITY_2 @@ -184,13 +154,8 @@ public: void SetHBITMAP(WXHBITMAP bmp) { SetHandle((WXHANDLE)bmp); } WXHBITMAP GetHBITMAP() const { return (WXHBITMAP)GetHandle(); } -#if wxUSE_DIB_FOR_BITMAP - void SetHFileMap(WXHANDLE hFileMap) { GetBitmapData()->m_hFileMap = hFileMap; } - WXHANDLE GetHFileMap() const { return GetBitmapData()->m_hFileMap; } -#endif // wxUSE_DIB_FOR_BITMAP - - void SetSelectedInto(wxDC *dc) { if (GetBitmapData()) GetBitmapData()->m_selectedInto = dc; } - wxDC *GetSelectedInto() const { return (GetBitmapData() ? GetBitmapData()->m_selectedInto : (wxDC*) NULL); } + void SetSelectedInto(wxDC *dc); + wxDC *GetSelectedInto() const; // Creates a bitmap that matches the device context's depth, from an // arbitray bitmap. At present, the original bitmap must have an associated @@ -210,8 +175,7 @@ protected: // common part of all ctors void Init(); - virtual wxGDIImageRefData *CreateData() const - { return new wxBitmapRefData; } + virtual wxGDIImageRefData *CreateData() const; // creates the bitmap from XPM data, supposed to be called from ctor bool CreateFromXpm(const char **bits); @@ -223,8 +187,9 @@ protected: #if wxUSE_DIB_FOR_BITMAP void *CreateDIB(int width, int height, int depth); + void CopyDIBLine(void* src, void* dest, int count) const; -#endif +#endif // wxUSE_DIB_FOR_BITMAP private: #ifdef __WIN32__ diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 872e8056a5..bdff57bb68 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -40,8 +40,6 @@ #include "wx/icon.h" #endif -//#include "device.h" - #include "wx/msw/private.h" #include "wx/log.h" @@ -57,6 +55,60 @@ #define CLR_INVALID ((COLORREF)-1) #endif // no CLR_INVALID +// ---------------------------------------------------------------------------- +// Bitmap data +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxBitmapRefData : public wxGDIImageRefData +{ +public: + wxBitmapRefData(); + virtual ~wxBitmapRefData() { Free(); } + + virtual void Free(); + + // set the mask object to use as the mask, we take ownership of it + void SetMask(wxMask *mask) + { + delete m_bitmapMask; + m_bitmapMask = mask; + } + + // set the HBITMAP to use as the mask + void SetMask(HBITMAP hbmpMask) + { + SetMask(new wxMask((WXHBITMAP)hbmpMask)); + } + + // return the mask + wxMask *GetMask() const { return m_bitmapMask; } + +public: + int m_numColors; +#if wxUSE_PALETTE + wxPalette m_bitmapPalette; +#endif // wxUSE_PALETTE + + // MSW-specific + // ------------ + + // this field is solely for error checking: we detect selecting a bitmap + // into more than one DC at once or deleting a bitmap still selected into a + // DC (both are serious programming errors under Windows) + wxDC *m_selectedInto; + +#if wxUSE_DIB_FOR_BITMAP + // file mapping handle for large DIB's + HANDLE m_hFileMap; +#endif // wxUSE_DIB_FOR_BITMAP + +private: + // optional mask for transparent drawing + wxMask *m_bitmapMask; + + DECLARE_NO_COPY_CLASS(wxBitmapRefData) +}; + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -76,14 +128,13 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) wxBitmapRefData::wxBitmapRefData() { - m_quality = 0; m_selectedInto = NULL; m_numColors = 0; m_bitmapMask = NULL; m_hBitmap = (WXHBITMAP) NULL; #if wxUSE_DIB_FOR_BITMAP m_hFileMap = 0; -#endif +#endif // wxUSE_DIB_FOR_BITMAP } void wxBitmapRefData::Free() @@ -93,22 +144,20 @@ 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 } #if wxUSE_DIB_FOR_BITMAP - if(m_hFileMap) + if ( m_hFileMap ) { - ::CloseHandle((void*)m_hFileMap); + ::CloseHandle(m_hFileMap); + m_hFileMap = 0; } -#endif +#endif // wxUSE_DIB_FOR_BITMAP delete m_bitmapMask; m_bitmapMask = NULL; @@ -125,6 +174,11 @@ void wxBitmap::Init() } +wxGDIImageRefData *wxBitmap::CreateData() const +{ + return new wxBitmapRefData; +} + #ifdef __WIN32__ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon) @@ -155,8 +209,7 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon) // the mask returned by GetIconInfo() is inversed compared to the usual // wxWin convention - refData->m_bitmapMask = new wxMask((WXHBITMAP) - wxInvertMask(iconInfo.hbmMask, w, h)); + refData->SetMask(wxInvertMask(iconInfo.hbmMask, w, h)); // delete the old one now as we don't need it any more @@ -423,16 +476,15 @@ void *wxBitmap::CreateDIB(int width, int height, int depth) info->bmiHeader.biYPelsPerMeter = 0; info->bmiHeader.biClrUsed = 0; info->bmiHeader.biClrImportant = 0; - GetBitmapData()->m_hFileMap = - (WXHANDLE)::CreateFileMapping - ( - INVALID_HANDLE_VALUE, - 0, - PAGE_READWRITE | SEC_COMMIT, - 0, - info->bmiHeader.biSizeImage, - 0 - ); + GetBitmapData()->m_hFileMap = ::CreateFileMapping + ( + INVALID_HANDLE_VALUE, + 0, + PAGE_READWRITE | SEC_COMMIT, + 0, + info->bmiHeader.biSizeImage, + 0 + ); // No need to report an error here. If it fails, we just won't use a // file mapping and CreateDIBSection will just allocate memory for us. @@ -443,7 +495,7 @@ void *wxBitmap::CreateDIB(int width, int height, int depth) info, DIB_RGB_COLORS, &dibBits, - (HANDLE)GetBitmapData()->m_hFileMap, + GetBitmapData()->m_hFileMap, 0 ); @@ -574,7 +626,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth ) ::SelectObject(hMaskDC, hOldMaskBitmap); ::DeleteDC(hMaskDC); - ((wxBitmapRefData*)m_refData)->m_bitmapMask = new wxMask((WXHBITMAP) hMaskBitmap); + ((wxBitmapRefData*)m_refData)->SetMask(hMaskBitmap); } SetWidth(image.GetWidth()); @@ -1188,21 +1240,49 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const // wxBitmap accessors // ---------------------------------------------------------------------------- -void wxBitmap::SetQuality(int q) +wxPalette* wxBitmap::GetPalette() const { - EnsureHasData(); - - GetBitmapData()->m_quality = q; + return GetBitmapData() ? &GetBitmapData()->m_bitmapPalette + : (wxPalette *) NULL; } -#if WXWIN_COMPATIBILITY_2 -void wxBitmap::SetOk(bool isOk) +wxMask *wxBitmap::GetMask() const { - EnsureHasData(); - - GetBitmapData()->m_ok = isOk; + return GetBitmapData() ? GetBitmapData()->GetMask() : (wxMask *) NULL; +} + +wxDC *wxBitmap::GetSelectedInto() const +{ + return GetBitmapData() ? GetBitmapData()->m_selectedInto : (wxDC *) NULL; +} + +#if wxUSE_DIB_FOR_BITMAP + +bool wxBitmap::IsDIB() const +{ + return GetBitmapData() && GetBitmapData()->m_hFileMap != NULL; +} + +#endif // wxUSE_DIB_FOR_BITMAP + +#if WXWIN_COMPATIBILITY_2_4 + +int wxBitmap::GetQuality() const +{ + return 0; +} + +#endif // WXWIN_COMPATIBILITY_2_4 + +// ---------------------------------------------------------------------------- +// wxBitmap setters +// ---------------------------------------------------------------------------- + +void wxBitmap::SetSelectedInto(wxDC *dc) +{ + if ( GetBitmapData() ) + GetBitmapData()->m_selectedInto = dc; } -#endif // WXWIN_COMPATIBILITY_2 #if wxUSE_PALETTE @@ -1219,9 +1299,32 @@ void wxBitmap::SetMask(wxMask *mask) { EnsureHasData(); - GetBitmapData()->m_bitmapMask = mask; + GetBitmapData()->SetMask(mask); } +#if WXWIN_COMPATIBILITY_2 + +void wxBitmap::SetOk(bool isOk) +{ + EnsureHasData(); + + GetBitmapData()->m_ok = isOk; +} + +#endif // WXWIN_COMPATIBILITY_2 + +#if WXWIN_COMPATIBILITY_2_4 + +void wxBitmap::SetQuality(int WXUNUSED(quality)) +{ +} + +#endif // WXWIN_COMPATIBILITY_2_4 + +// ---------------------------------------------------------------------------- +// TODO: to be replaced by something better +// ---------------------------------------------------------------------------- + // 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. diff --git a/src/msw/dcprint.cpp b/src/msw/dcprint.cpp index 6ca37febea..adc0e85930 100644 --- a/src/msw/dcprint.cpp +++ b/src/msw/dcprint.cpp @@ -432,7 +432,7 @@ void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp, if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB ) { #if wxUSE_DIB_FOR_BITMAP - if(bmp.GetHFileMap()) // we already have a dib + if ( bmp.IsDIB() ) { DIBSECTION dib; if ( ::GetObject(GetHbitmapOf(bmp), @@ -561,7 +561,7 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest, int width = bmp.GetWidth(), height = bmp.GetHeight(); #if wxUSE_DIB_FOR_BITMAP - if(bmp.GetHFileMap()) // we already have a dib + if ( bmp.IsDIB() ) { DIBSECTION dib; if( ::GetObject(GetHbitmapOf(bmp), diff --git a/src/msw/gdiimage.cpp b/src/msw/gdiimage.cpp index 1b5000fa5e..4c459c5929 100644 --- a/src/msw/gdiimage.cpp +++ b/src/msw/gdiimage.cpp @@ -323,27 +323,26 @@ bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, // TODO: load colourmap. bitmap->SetHBITMAP((WXHBITMAP)::LoadBitmap(wxGetInstance(), name)); - wxBitmapRefData *data = bitmap->GetBitmapData(); - if ( bitmap->Ok() ) - { - BITMAP bm; - if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(BITMAP), (LPSTR) &bm) ) - { - wxLogLastError(wxT("GetObject(HBITMAP)")); - } - - data->m_width = bm.bmWidth; - data->m_height = bm.bmHeight; - data->m_depth = bm.bmBitsPixel; - } - else + if ( !bitmap->Ok() ) { // it's probably not found wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str()); + + return FALSE; } - return bitmap->Ok(); + BITMAP bm; + if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(BITMAP), (LPSTR) &bm) ) + { + wxLogLastError(wxT("GetObject(HBITMAP)")); + } + + bitmap->SetWidth(bm.bmWidth); + bitmap->SetHeight(bm.bmHeight); + bitmap->SetDepth(bm.bmBitsPixel); + + return TRUE; } bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,