////////////////////////////////////////////////////////////////////////////
-// Name: bitmap.cpp
+// Name: src/msw/bitmap.cpp
// Purpose: wxBitmap
// Author: Julian Smart
// Modified by:
#pragma hdrstop
#endif
+#include "wx/bitmap.h"
+
#ifndef WX_PRECOMP
#include <stdio.h>
#include "wx/app.h"
#include "wx/palette.h"
#include "wx/dcmemory.h"
- #include "wx/bitmap.h"
#include "wx/icon.h"
+ #include "wx/log.h"
+ #include "wx/image.h"
#endif
#include "wx/msw/private.h"
-#include "wx/log.h"
#if wxUSE_WXDIB
-#include "wx/msw/dib.h"
+ #include "wx/msw/dib.h"
#endif
-#include "wx/image.h"
-#include "wx/xpmdecod.h"
-
#ifdef wxHAVE_RAW_BITMAP
-#include "wx/rawbmp.h"
+ #include "wx/rawbmp.h"
#endif
// missing from mingw32 header
m_selectedInto = NULL;
#endif
- // can't copy the mask as the other bitmap destroys it
+ // (deep) copy the mask if present
m_bitmapMask = NULL;
+ if (data.m_bitmapMask)
+ m_bitmapMask = new wxMask(*data.m_bitmapMask);
+
+ // FIXME: we don't copy m_hBitmap currently but we should, see wxBitmap::
+ // CloneRefData()
wxASSERT_MSG( !data.m_isDIB,
_T("can't copy bitmap locked for raw access!") );
// wxBitmap creation
// ----------------------------------------------------------------------------
-// this function should be called from all wxBitmap ctors
-void wxBitmap::Init()
-{
- // m_refData = NULL; done in the base class ctor
-}
-
wxGDIImageRefData *wxBitmap::CreateData() const
{
return new wxBitmapRefData;
if ( !data )
return NULL;
+ // FIXME: this method is backwards, it should just create a new
+ // wxBitmapRefData using its copy ctor but instead it modifies this
+ // bitmap itself and then returns its m_refData -- which works, of
+ // course (except in !wxUSE_WXDIB), but is completely illogical
wxBitmap *self = wx_const_cast(wxBitmap *, this);
#if wxUSE_WXDIB
else
#endif // wxUSE_WXDIB
{
- // don't copy the bitmap data, but do copy the size, depth, ...
+ // copy the bitmap data
self->m_refData = new wxBitmapRefData(*data);
}
+ // copy also the mask
+ wxMask * const maskSrc = data->GetMask();
+ if ( maskSrc )
+ {
+ wxBitmapRefData *selfdata = wx_static_cast(wxBitmapRefData *, m_refData);
+
+ selfdata->SetMask(new wxMask(*maskSrc));
+ }
+
return m_refData;
}
wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
{
- Init();
-
#ifndef __WXMICROWIN__
wxBitmapRefData *refData = new wxBitmapRefData;
m_refData = refData;
reversed |= (unsigned char)(val & 0x01);
val >>= 1;
}
- *dst++ = reversed;
+ *dst++ = ~reversed;
}
if ( padding )
#endif
}
-// Create from XPM data
-bool wxBitmap::CreateFromXpm(const char **data)
-{
-#if wxUSE_IMAGE && wxUSE_XPM
- Init();
-
- wxCHECK_MSG( data != NULL, false, wxT("invalid bitmap data") )
-
- wxXPMDecoder decoder;
- wxImage img = decoder.ReadData(data);
- wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") )
-
- *this = wxBitmap(img);
- return true;
-#else
- wxUnusedVar(data);
- return false;
-#endif
-}
-
wxBitmap::wxBitmap(int w, int h, int d)
{
- Init();
-
(void)Create(w, h, d);
}
wxBitmap::wxBitmap(int w, int h, const wxDC& dc)
{
- Init();
-
(void)Create(w, h, dc);
}
-wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
+wxBitmap::wxBitmap(const void* data, long type, int width, int height, int depth)
{
- Init();
-
(void)Create(data, type, width, height, depth);
}
wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
{
- Init();
-
LoadFile(filename, (int)type);
}
// wxImage to/from conversions
// ----------------------------------------------------------------------------
-#if wxUSE_WXDIB
-
bool wxBitmap::CreateFromImage(const wxImage& image, int depth)
{
return CreateFromImage(image, depth, 0);
return CreateFromImage(image, -1, dc.GetHDC());
}
+#if wxUSE_WXDIB
+
bool wxBitmap::CreateFromImage(const wxImage& image, int depth, WXHDC hdc)
{
wxCHECK_MSG( image.Ok(), false, wxT("invalid image") );
wxDIB dib(image);
if ( !dib.IsOk() )
return false;
- if (depth == -1)
- depth = dib.GetDepth(); // Get depth from image if none specified
+
+ if ( depth == -1 )
+ depth = dib.GetDepth(); // Get depth from image if none specified
// store the bitmap parameters
wxBitmapRefData *refData = new wxBitmapRefData;
return image;
}
-#endif // wxUSE_WXDIB
+#else // !wxUSE_WXDIB
+
+bool
+wxBitmap::CreateFromImage(const wxImage& WXUNUSED(image),
+ int WXUNUSED(depth),
+ WXHDC WXUNUSED(hdc))
+{
+ return false;
+}
+
+wxImage wxBitmap::ConvertToImage() const
+{
+ return wxImage();
+}
+
+#endif // wxUSE_WXDIB/!wxUSE_WXDIB
#endif // wxUSE_IMAGE
return handler->LoadFile(this, filename, type, -1, -1);
}
-#if wxUSE_IMAGE
+#if wxUSE_IMAGE && wxUSE_WXDIB
else // no bitmap handler found
{
wxImage image;
return false;
}
-bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
+bool wxBitmap::Create(const void* data, long type, int width, int height, int depth)
{
UnRef();
{
return handler->SaveFile(this, filename, type, palette);
}
-#if wxUSE_IMAGE
+#if wxUSE_IMAGE && wxUSE_WXDIB
else // no bitmap handler found
{
// FIXME what about palette? shouldn't we use it?
m_maskBitmap = 0;
}
+// Copy constructor
+wxMask::wxMask(const wxMask &mask)
+ : wxObject()
+{
+ BITMAP bmp;
+
+ HDC srcDC = CreateCompatibleDC(0);
+ HDC destDC = CreateCompatibleDC(0);
+
+ // GetBitmapDimensionEx won't work if SetBitmapDimensionEx wasn't used
+ // so we'll use GetObject() API here:
+ if (::GetObject((HGDIOBJ)mask.m_maskBitmap, sizeof(bmp), &bmp) == 0)
+ {
+ wxFAIL_MSG(wxT("Cannot retrieve the dimensions of the wxMask to copy"));
+ return;
+ }
+
+ // create our HBITMAP
+ int w = bmp.bmWidth, h = bmp.bmHeight;
+ m_maskBitmap = (WXHBITMAP)CreateCompatibleBitmap(srcDC, w, h);
+
+ // copy the mask's HBITMAP into our HBITMAP
+ SelectObject(srcDC, (HBITMAP) mask.m_maskBitmap);
+ SelectObject(destDC, (HBITMAP) m_maskBitmap);
+
+ BitBlt(destDC, 0, 0, w, h, srcDC, 0, 0, SRCCOPY);
+
+ SelectObject(srcDC, 0);
+ DeleteDC(srcDC);
+ SelectObject(destDC, 0);
+ DeleteDC(destDC);
+}
+
// Construct a mask from a bitmap and a colour indicating
// the transparent area
wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
// ----------------------------------------------------------------------------
bool wxBitmapHandler::Create(wxGDIImage *image,
- void *data,
+ const void* data,
long flags,
int width, int height, int depth)
{
wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
- return bitmap ? Create(bitmap, data, flags, width, height, depth) : false;
+ return bitmap && Create(bitmap, data, flags, width, height, depth);
}
bool wxBitmapHandler::Load(wxGDIImage *image,
{
wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
- return bitmap ? LoadFile(bitmap, name, flags, width, height) : false;
+ return bitmap && LoadFile(bitmap, name, flags, width, height);
}
bool wxBitmapHandler::Save(wxGDIImage *image,
{
wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
- return bitmap ? SaveFile(bitmap, name, type) : false;
+ return bitmap && SaveFile(bitmap, name, type);
}
bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap),
- void *WXUNUSED(data),
+ const void* WXUNUSED(data),
long WXUNUSED(type),
int WXUNUSED(width),
int WXUNUSED(height),
return 0;
}
- wxMask* mask;
- wxBitmap newbmp;
if ( bmp.HasAlpha() )
{
- // Convert alpha to a mask. NOTE: It would be better to actually put
- // the alpha into the icon instead of making a mask, but I don't have
- // time to figure that out today.
- wxImage img = bmp.ConvertToImage();
- img.ConvertAlphaToMask();
- newbmp = wxBitmap(img);
- mask = newbmp.GetMask();
- }
- else
- {
- mask = bmp.GetMask();
+ // Create an empty mask bitmap.
+ // it doesn't seem to work if we mess with the mask at all.
+ HBITMAP hMonoBitmap = CreateBitmap(bmp.GetWidth(),bmp.GetHeight(),1,1,NULL);
+
+ ICONINFO iconInfo;
+ wxZeroMemory(iconInfo);
+ iconInfo.fIcon = iconWanted; // do we want an icon or a cursor?
+ if ( !iconWanted )
+ {
+ iconInfo.xHotspot = hotSpotX;
+ iconInfo.yHotspot = hotSpotY;
+ }
+
+ iconInfo.hbmMask = hMonoBitmap;
+ iconInfo.hbmColor = GetHbitmapOf(bmp);
+
+ HICON hicon = ::CreateIconIndirect(&iconInfo);
+
+ ::DeleteObject(hMonoBitmap);
+
+ return hicon;
}
+ wxMask* mask = bmp.GetMask();
+
if ( !mask )
{
// we must have a mask for an icon, so even if it's probably incorrect,