]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mgl/bitmap.cpp
Use the data scheme to load resources in the WebKitGTK+ implementation, rather than...
[wxWidgets.git] / src / mgl / bitmap.cpp
index 06e840311a500094f9a95cdf38e992aac7c19596..bae5a0c596669beb13ef0f034b3d1498958fe275 100644 (file)
     #include "wx/log.h"
     #include "wx/utils.h"
     #include "wx/dcmemory.h"
     #include "wx/log.h"
     #include "wx/utils.h"
     #include "wx/dcmemory.h"
+    #include "wx/icon.h"
+    #include "wx/image.h"
 #endif
 
 #endif
 
-#include "wx/icon.h"
 #include "wx/filefn.h"
 #include "wx/filefn.h"
-#include "wx/image.h"
-#include "wx/image.h"
 #include "wx/xpmdecod.h"
 
 #include "wx/mgl/private.h"
 
 #include <mgraph.hpp>
 
 #include "wx/xpmdecod.h"
 
 #include "wx/mgl/private.h"
 
 #include <mgraph.hpp>
 
+static bitmap_t *MyMGL_createBitmap(int width, int height,
+                                    int bpp, pixel_format_t *pf)
+{
+    MGLMemoryDC mdc(width, height, bpp, pf);
+    return MGL_getBitmapFromDC(mdc.getDC(), 0, 0, width, height, TRUE);
+}
+
 //-----------------------------------------------------------------------------
 // MGL pixel formats:
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // MGL pixel formats:
 //-----------------------------------------------------------------------------
@@ -52,128 +58,101 @@ static pixel_format_t gs_pixel_format_wxImage =
     {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage
 
 //-----------------------------------------------------------------------------
     {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage
 
 //-----------------------------------------------------------------------------
-// helpers
+// wxBitmapRefData
 //-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
 
-// Convert wxColour into it's quantized value in lower-precision
-// pixel format (needed for masking by colour).
-static wxColour wxQuantizeColour(const wxColour& clr, const wxBitmap& bmp)
+class wxBitmapRefData: public wxGDIRefData
 {
 {
-    pixel_format_t *pf = bmp.GetMGLbitmap_t()->pf;
-
-    if ( pf->redAdjust == 0 && pf->greenAdjust == 0 && pf->blueAdjust == 0 )
-        return clr;
-    else
-        return wxColour((unsigned char)((clr.Red() >> pf->redAdjust) << pf->redAdjust),
-                        (unsigned char)((clr.Green() >> pf->greenAdjust) << pf->greenAdjust),
-                        (unsigned char)((clr.Blue() >> pf->blueAdjust) << pf->blueAdjust));
-}
-
+public:
+    wxBitmapRefData();
+    wxBitmapRefData(int width, int height, int bpp);
+    wxBitmapRefData(const wxBitmapRefData& data);
+    virtual ~wxBitmapRefData();
 
 
+    virtual bool IsOk() const { return m_bitmap != NULL; }
 
 
-//-----------------------------------------------------------------------------
-// wxMask
-//-----------------------------------------------------------------------------
+    int             m_width;
+    int             m_height;
+    int             m_bpp;
+    wxPalette      *m_palette;
+    wxMask         *m_mask;
+    bitmap_t       *m_bitmap;
 
 
-IMPLEMENT_DYNAMIC_CLASS(wxMask,wxObject)
+private:
+    void DoCreateBitmap(int width, int height, int depth);
+};
 
 
-wxMask::wxMask()
+void wxBitmapRefData::DoCreateBitmap(int width, int height, int depth)
 {
 {
-    m_bitmap = NULL;
-}
+    m_width = width;
+    m_height = height;
+    m_bpp = depth;
 
 
-wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
-{
-    m_bitmap = NULL;
-    Create(bitmap, colour);
-}
+    pixel_format_t pf_dummy;
+    pixel_format_t *pf;
+    int mglDepth = depth;
 
 
-wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
-{
-    m_bitmap = NULL;
-    Create(bitmap, paletteIndex);
-}
+    switch ( depth )
+    {
+        case -1:
+            wxASSERT_MSG( g_displayDC, wxT("MGL display DC not created yet.") );
 
 
-wxMask::wxMask(const wxBitmap& bitmap)
-{
-    m_bitmap = NULL;
-    Create(bitmap);
-}
+            g_displayDC->getPixelFormat(pf_dummy);
+            mglDepth = g_displayDC->getBitsPerPixel();
+            pf = &pf_dummy;
+            break;
+        case 1:
+        case 8:
+            pf = NULL;
+            mglDepth = 8; // we emulate monochrome bitmaps using 8 bit ones
+            break;
+        case 15:
+            pf = &gs_pixel_format_15;
+            break;
+        case 16:
+            pf = &gs_pixel_format_16;
+            break;
+        case 24:
+            pf = &gs_pixel_format_24;
+            break;
+        case 32:
+            pf = &gs_pixel_format_32;
+            break;
+        default:
+            wxFAIL_MSG(wxT("invalid bitmap depth"));
+            m_bitmap = NULL;
+            return;
+    }
 
 
-wxMask::~wxMask()
-{
-    delete m_bitmap;
+    m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf);
 }
 
 }
 
-bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
+wxBitmapRefData::wxBitmapRefData()
 {
 {
-    delete m_bitmap;
-    m_bitmap = NULL;
-
-    wxColour clr(wxQuantizeColour(colour, bitmap));
-
-    wxImage imgSrc(bitmap.ConvertToImage());
-    imgSrc.SetMask(false);
-    wxImage image(imgSrc.ConvertToMono(clr.Red(), clr.Green(), clr.Blue()));
-    if ( !image.Ok() )
-        return false;
+    m_width =
+    m_height =
+    m_bpp = 0;
 
 
-    m_bitmap = new wxBitmap(image, 1);
+    m_palette = NULL;
+    m_mask = NULL;
 
 
-    return m_bitmap->Ok();
+    m_bitmap = NULL;
 }
 
 }
 
-bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
+wxBitmapRefData::wxBitmapRefData(int width, int height, int bpp)
 {
 {
-    unsigned char r,g,b;
-    wxPalette *pal = bitmap.GetPalette();
-
-    wxCHECK_MSG( pal, false, wxT("Cannot create mask from bitmap without palette") );
+    DoCreateBitmap(width, height, bpp);
 
 
-    pal->GetRGB(paletteIndex, &r, &g, &b);
-
-    return Create(bitmap, wxColour(r, g, b));
+    m_palette = NULL;
+    m_mask = NULL;
 }
 
 }
 
-bool wxMask::Create(const wxBitmap& bitmap)
+wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData& data)
 {
 {
-    delete m_bitmap;
-    m_bitmap = NULL;
-
-    wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap") );
-    wxCHECK_MSG( bitmap.GetDepth() == 1, false, wxT("Cannot create mask from colour bitmap") );
+    DoCreateBitmap(data.m_width, data.m_height, data.m_bpp);
 
 
-    m_bitmap = new wxBitmap(bitmap);
-    return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// wxBitmap
-//-----------------------------------------------------------------------------
-
-class wxBitmapRefData: public wxObjectRefData
-{
-public:
-    wxBitmapRefData();
-    ~wxBitmapRefData();
-
-    int             m_width;
-    int             m_height;
-    int             m_bpp;
-    wxPalette      *m_palette;
-    wxMask         *m_mask;
-    bitmap_t       *m_bitmap;
-};
-
-wxBitmapRefData::wxBitmapRefData()
-{
-    m_mask = NULL;
-    m_width = 0;
-    m_height = 0;
-    m_bpp = 0;
-    m_palette = NULL;
-    m_bitmap = NULL;
+    m_palette = NULL; // FIXME: should copy
+    m_mask = NULL; // FIXME: should copy
 }
 
 wxBitmapRefData::~wxBitmapRefData()
 }
 
 wxBitmapRefData::~wxBitmapRefData()
@@ -184,25 +163,23 @@ wxBitmapRefData::~wxBitmapRefData()
     delete m_palette;
 }
 
     delete m_palette;
 }
 
+
+//-----------------------------------------------------------------------------
+// wxBitmap
 //-----------------------------------------------------------------------------
 
 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
 
 //-----------------------------------------------------------------------------
 
 #define M_BMPDATA ((wxBitmapRefData *)m_refData)
 
-
-IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler,wxObject)
 IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase)
 
 IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase)
 
-wxBitmap::wxBitmap(int width, int height, int depth)
+wxGDIRefData *wxBitmap::CreateGDIRefData() const
 {
 {
-    Create(width, height, depth);
+    return new wxBitmapRefData;
 }
 
 }
 
-
-static bitmap_t *MyMGL_createBitmap(int width, int height,
-                                    int bpp, pixel_format_t *pf)
+wxGDIRefData *wxBitmap::CloneGDIRefData(const wxGDIRefData *data) const
 {
 {
-    MGLMemoryDC mdc(width, height, bpp, pf);
-    return MGL_getBitmapFromDC(mdc.getDC(), 0, 0, width, height, TRUE);
+    return new wxBitmapRefData(*static_cast<const wxBitmapRefData *>(data));
 }
 
 bool wxBitmap::Create(int width, int height, int depth)
 }
 
 bool wxBitmap::Create(int width, int height, int depth)
@@ -211,82 +188,24 @@ bool wxBitmap::Create(int width, int height, int depth)
 
     wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") );
 
 
     wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") );
 
-    pixel_format_t pf_dummy;
-    pixel_format_t *pf;
-    int mglDepth = depth;
+    m_refData = new wxBitmapRefData(width, height, depth);
 
 
-    switch ( depth )
-    {
-        case -1:
-            wxASSERT_MSG( g_displayDC, wxT("MGL display DC not created yet.") );
-
-            g_displayDC->getPixelFormat(pf_dummy);
-            mglDepth = g_displayDC->getBitsPerPixel();
-            pf = &pf_dummy;
-            break;
-        case 1:
-        case 8:
-            pf = NULL;
-            break;
-        case 15:
-            pf = &gs_pixel_format_15;
-            break;
-        case 16:
-            pf = &gs_pixel_format_16;
-            break;
-        case 24:
-            pf = &gs_pixel_format_24;
-            break;
-        case 32:
-            pf = &gs_pixel_format_32;
-            break;
-        default:
-            wxFAIL_MSG(wxT("invalid bitmap depth"));
-            return false;
-    }
-
-    m_refData = new wxBitmapRefData();
-    M_BMPDATA->m_mask = (wxMask *) NULL;
-    M_BMPDATA->m_palette = (wxPalette *) NULL;
-    M_BMPDATA->m_width = width;
-    M_BMPDATA->m_height = height;
-    M_BMPDATA->m_bpp = mglDepth;
-
-    if ( mglDepth != 1 )
-    {
-        M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf);
-    }
-    else
+    if ( depth == 1 )
     {
         // MGL does not support mono DCs, so we have to emulate them with
         // 8bpp ones. We do that by using a special palette with color 0
         // set to black and all other colors set to white.
     {
         // MGL does not support mono DCs, so we have to emulate them with
         // 8bpp ones. We do that by using a special palette with color 0
         // set to black and all other colors set to white.
-
-        M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, 8, pf);
         SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0));
     }
 
         SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0));
     }
 
-    return Ok();
-}
-
-bool wxBitmap::CreateFromXpm(const char **bits)
-{
-    wxCHECK_MSG( bits != NULL, false, wxT("invalid bitmap data") );
-
-    wxXPMDecoder decoder;
-    wxImage img = decoder.ReadData(bits);
-    wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") );
-
-    *this = wxBitmap(img);
-
-    return true;
+    return IsOk();
 }
 
 wxBitmap::wxBitmap(const wxImage& image, int depth)
 {
     long width, height;
 
 }
 
 wxBitmap::wxBitmap(const wxImage& image, int depth)
 {
     long width, height;
 
-    wxCHECK_RET( image.Ok(), wxT("invalid image") );
+    wxCHECK_RET( image.IsOk(), wxT("invalid image") );
 
     width = image.GetWidth();
     height = image.GetHeight();
 
     width = image.GetWidth();
     height = image.GetHeight();
@@ -318,14 +237,14 @@ wxBitmap::wxBitmap(const wxImage& image, int depth)
 
 wxImage wxBitmap::ConvertToImage() const
 {
 
 wxImage wxBitmap::ConvertToImage() const
 {
-    wxCHECK_MSG( Ok(), wxImage(), wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), wxImage(), wxT("invalid bitmap") );
 
     int width, height;
     width = GetWidth();
     height = GetHeight();
 
     wxImage image(width, height);
 
     int width, height;
     width = GetWidth();
     height = GetHeight();
 
     wxImage image(width, height);
-    wxASSERT_MSG( image.Ok(), wxT("cannot create image") );
+    wxASSERT_MSG( image.IsOk(), wxT("cannot create image") );
 
     MGLMemoryDC idc(width, height, 24, &gs_pixel_format_wxImage,
                     width * 3, (void*)image.GetData(), NULL);
 
     MGLMemoryDC idc(width, height, 24, &gs_pixel_format_wxImage,
                     width * 3, (void*)image.GetData(), NULL);
@@ -378,53 +297,39 @@ wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
     delete bdc;
 }
 
     delete bdc;
 }
 
-bool wxBitmap::operator == (const wxBitmap& bmp) const
-{
-    return (m_refData == bmp.m_refData);
-}
-
-bool wxBitmap::operator != (const wxBitmap& bmp) const
-{
-    return (m_refData != bmp.m_refData);
-}
-
-bool wxBitmap::Ok() const
-{
-    return (m_refData != NULL && M_BMPDATA->m_bitmap != NULL);
-}
-
 int wxBitmap::GetHeight() const
 {
 int wxBitmap::GetHeight() const
 {
-    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_height;
 }
 
 int wxBitmap::GetWidth() const
 {
 
     return M_BMPDATA->m_height;
 }
 
 int wxBitmap::GetWidth() const
 {
-    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_width;
 }
 
 int wxBitmap::GetDepth() const
 {
 
     return M_BMPDATA->m_width;
 }
 
 int wxBitmap::GetDepth() const
 {
-    wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_bpp;
 }
 
 wxMask *wxBitmap::GetMask() const
 {
 
     return M_BMPDATA->m_bpp;
 }
 
 wxMask *wxBitmap::GetMask() const
 {
-    wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_mask;
 }
 
 void wxBitmap::SetMask(wxMask *mask)
 {
 
     return M_BMPDATA->m_mask;
 }
 
 void wxBitmap::SetMask(wxMask *mask)
 {
-    wxCHECK_RET( Ok(), wxT("invalid bitmap") );
+    wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
 
 
+    AllocExclusive();
     delete M_BMPDATA->m_mask;
     M_BMPDATA->m_mask = mask;
 }
     delete M_BMPDATA->m_mask;
     M_BMPDATA->m_mask = mask;
 }
@@ -438,13 +343,13 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon)
 
 wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
 {
 
 wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
 {
-    wxCHECK_MSG( Ok() &&
+    wxCHECK_MSG( IsOk() &&
                  (rect.x >= 0) && (rect.y >= 0) &&
                  (rect.x+rect.width <= M_BMPDATA->m_width) && (rect.y+rect.height <= M_BMPDATA->m_height),
                  wxNullBitmap, wxT("invalid bitmap or bitmap region") );
 
     wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
                  (rect.x >= 0) && (rect.y >= 0) &&
                  (rect.x+rect.width <= M_BMPDATA->m_width) && (rect.y+rect.height <= M_BMPDATA->m_height),
                  wxNullBitmap, wxT("invalid bitmap or bitmap region") );
 
     wxBitmap ret( rect.width, rect.height, M_BMPDATA->m_bpp );
-    wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
+    wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") );
 
     if ( GetPalette() )
         ret.SetPalette(*GetPalette());
 
     if ( GetPalette() )
         ret.SetPalette(*GetPalette());
@@ -457,7 +362,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
 
     if ( GetMask() )
     {
 
     if ( GetMask() )
     {
-        wxBitmap submask = GetMask()->GetBitmap()->GetSubBitmap(rect);
+        wxBitmap submask = GetMask()->GetBitmap().GetSubBitmap(rect);
         ret.SetMask(new wxMask(submask));
     }
 
         ret.SetMask(new wxMask(submask));
     }
 
@@ -466,8 +371,9 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& rect) const
 
 void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg)
 {
 
 void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg)
 {
-    wxCHECK_RET( Ok(), wxT("invalid bitmap") );
+    wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
 
 
+    AllocExclusive();
     palette_t *mono = M_BMPDATA->m_bitmap->pal;
 
     wxCHECK_RET( M_BMPDATA->m_bpp == 1, wxT("bitmap is not 1bpp") );
     palette_t *mono = M_BMPDATA->m_bitmap->pal;
 
     wxCHECK_RET( M_BMPDATA->m_bpp == 1, wxT("bitmap is not 1bpp") );
@@ -488,7 +394,7 @@ void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg)
 
 MGLDevCtx *wxBitmap::CreateTmpDC() const
 {
 
 MGLDevCtx *wxBitmap::CreateTmpDC() const
 {
-    wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
 
     MGLDevCtx *tdc = new MGLMemoryDC(GetWidth(), GetHeight(),
                                      M_BMPDATA->m_bitmap->bitsPerPixel,
 
     MGLDevCtx *tdc = new MGLMemoryDC(GetWidth(), GetHeight(),
                                      M_BMPDATA->m_bitmap->bitsPerPixel,
@@ -522,7 +428,7 @@ MGLDevCtx *wxBitmap::CreateTmpDC() const
 
 bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
 {
 
 bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
 {
-    UnRef();
+    AllocExclusive();
 
     if ( type == wxBITMAP_TYPE_BMP || type == wxBITMAP_TYPE_PNG ||
          type == wxBITMAP_TYPE_PCX || type == wxBITMAP_TYPE_JPEG )
 
     if ( type == wxBITMAP_TYPE_BMP || type == wxBITMAP_TYPE_PNG ||
          type == wxBITMAP_TYPE_PCX || type == wxBITMAP_TYPE_JPEG )
@@ -540,7 +446,7 @@ bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
     if ( handler == NULL )
     {
         wxImage image;
     if ( handler == NULL )
     {
         wxImage image;
-        if ( !image.LoadFile(name, type) || !image.Ok() )
+        if ( !image.LoadFile(name, type) || !image.IsOk() )
         {
             wxLogError("no bitmap handler for type %d defined.", type);
             return false;
         {
             wxLogError("no bitmap handler for type %d defined.", type);
             return false;
@@ -552,14 +458,12 @@ bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
         }
     }
 
         }
     }
 
-    m_refData = new wxBitmapRefData();
-
     return handler->LoadFile(this, name, type, -1, -1);
 }
 
 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
 {
     return handler->LoadFile(this, name, type, -1, -1);
 }
 
 bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const
 {
-    wxCHECK_MSG( Ok(), false, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), false, wxT("invalid bitmap") );
 
     wxBitmapHandler *handler = FindHandler(type);
 
 
     wxBitmapHandler *handler = FindHandler(type);
 
@@ -569,7 +473,7 @@ bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPal
         if ( palette )
             image.SetPalette(*palette);
 
         if ( palette )
             image.SetPalette(*palette);
 
-        if ( image.Ok() )
+        if ( image.IsOk() )
             return image.SaveFile(filename, type);
         else
         {
             return image.SaveFile(filename, type);
         else
         {
@@ -583,20 +487,20 @@ bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPal
 
 wxPalette *wxBitmap::GetPalette() const
 {
 
 wxPalette *wxBitmap::GetPalette() const
 {
-    wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
+    wxCHECK_MSG( IsOk(), NULL, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_palette;
 }
 
 void wxBitmap::SetPalette(const wxPalette& palette)
 {
 
     return M_BMPDATA->m_palette;
 }
 
 void wxBitmap::SetPalette(const wxPalette& palette)
 {
-    wxCHECK_RET( Ok(), wxT("invalid bitmap") );
+    wxCHECK_RET( IsOk(), wxT("invalid bitmap") );
     wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
 
     wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
 
-    delete M_BMPDATA->m_palette;
-    M_BMPDATA->m_palette = NULL;
+    AllocExclusive();
+    wxDELETE(M_BMPDATA->m_palette);
 
 
-    if ( !palette.Ok() ) return;
+    if ( !palette.IsOk() ) return;
 
     M_BMPDATA->m_palette = new wxPalette(palette);
 
 
     M_BMPDATA->m_palette = new wxPalette(palette);
 
@@ -607,21 +511,21 @@ void wxBitmap::SetPalette(const wxPalette& palette)
 
 void wxBitmap::SetHeight(int height)
 {
 
 void wxBitmap::SetHeight(int height)
 {
-    if (!m_refData) m_refData = new wxBitmapRefData();
+    AllocExclusive();
 
     M_BMPDATA->m_height = height;
 }
 
 void wxBitmap::SetWidth(int width)
 {
 
     M_BMPDATA->m_height = height;
 }
 
 void wxBitmap::SetWidth(int width)
 {
-    if (!m_refData) m_refData = new wxBitmapRefData();
+    AllocExclusive();
 
     M_BMPDATA->m_width = width;
 }
 
 void wxBitmap::SetDepth(int depth)
 {
 
     M_BMPDATA->m_width = width;
 }
 
 void wxBitmap::SetDepth(int depth)
 {
-    if (!m_refData) m_refData = new wxBitmapRefData();
+    AllocExclusive();
 
     M_BMPDATA->m_bpp = depth;
 }
 
     M_BMPDATA->m_bpp = depth;
 }
@@ -631,6 +535,19 @@ bitmap_t *wxBitmap::GetMGLbitmap_t() const
     return M_BMPDATA->m_bitmap;
 }
 
     return M_BMPDATA->m_bitmap;
 }
 
+// Convert wxColour into it's quantized value in lower-precision
+// pixel format (needed for masking by colour).
+wxColour wxBitmap::QuantizeColour(const wxColour& clr) const
+{
+    pixel_format_t *pf = GetMGLbitmap_t()->pf;
+
+    if ( pf->redAdjust == 0 && pf->greenAdjust == 0 && pf->blueAdjust == 0 )
+        return clr;
+    else
+        return wxColour((unsigned char)((clr.Red() >> pf->redAdjust) << pf->redAdjust),
+                        (unsigned char)((clr.Green() >> pf->greenAdjust) << pf->greenAdjust),
+                        (unsigned char)((clr.Blue() >> pf->blueAdjust) << pf->blueAdjust));
+}
 
 
 //-----------------------------------------------------------------------------
 
 
 //-----------------------------------------------------------------------------
@@ -644,7 +561,7 @@ public:
                        const wxString& extension, const wxString& name);
 
     virtual bool Create(wxBitmap *WXUNUSED(bitmap),
                        const wxString& extension, const wxString& name);
 
     virtual bool Create(wxBitmap *WXUNUSED(bitmap),
-                        void *WXUNUSED(data),
+                        const void* WXUNUSED(data),
                         long WXUNUSED(flags),
                         int WXUNUSED(width),
                         int WXUNUSED(height),
                         long WXUNUSED(flags),
                         int WXUNUSED(width),
                         int WXUNUSED(height),
@@ -697,7 +614,7 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
             if ( !MGL_getBitmapSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
             if ( !MGL_getBitmapSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
-            if ( !bitmap->Ok() ) return false;
+            if ( !bitmap->IsOk() ) return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadBitmapIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadBitmapIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
@@ -708,7 +625,7 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
             if ( !MGL_getJPEGSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
             if ( !MGL_getJPEGSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
-            if ( !bitmap->Ok() ) return false;
+            if ( !bitmap->IsOk() ) return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadJPEGIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadJPEGIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
@@ -719,7 +636,7 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
             if ( !MGL_getPNGSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
             if ( !MGL_getPNGSize(fullname.mb_str(), &width, &height, &bpp, &pf) )
                 return false;
             bitmap->Create(width, height, -1);
-            if ( !bitmap->Ok() ) return false;
+            if ( !bitmap->IsOk() ) return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadPNGIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadPNGIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
@@ -730,7 +647,7 @@ bool wxMGLBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
             if ( !MGL_getPCXSize(fullname.mb_str(), &width, &height, &bpp) )
                 return false;
             bitmap->Create(width, height, -1);
             if ( !MGL_getPCXSize(fullname.mb_str(), &width, &height, &bpp) )
                 return false;
             bitmap->Create(width, height, -1);
-            if ( !bitmap->Ok() ) return false;
+            if ( !bitmap->IsOk() ) return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadPCXIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
             dc.SelectObject(*bitmap);
             if ( !dc.GetMGLDC()->loadPCXIntoDC(fullname.mb_str(), 0, 0, TRUE) )
                 return false;
@@ -752,7 +669,7 @@ bool wxMGLBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name,
     int w = bitmap->GetWidth(),
         h = bitmap->GetHeight();
 
     int w = bitmap->GetWidth(),
         h = bitmap->GetHeight();
 
-    mem.SelectObject(*bitmap);
+    mem.SelectObjectAsSource(*bitmap);
     tdc = mem.GetMGLDC();
 
     switch (type)
     tdc = mem.GetMGLDC();
 
     switch (type)
@@ -815,7 +732,7 @@ bool wxPNGBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name,
     if ( bmp == NULL ) return false;
 
     bitmap->Create(bmp->width, bmp->height, -1);
     if ( bmp == NULL ) return false;
 
     bitmap->Create(bmp->width, bmp->height, -1);
-    if ( !bitmap->Ok() ) return false;
+    if ( !bitmap->IsOk() ) return false;
 
     // convert bmp to display's depth and write it to *bitmap:
     wxMemoryDC dc;
 
     // convert bmp to display's depth and write it to *bitmap:
     wxMemoryDC dc;
@@ -862,7 +779,7 @@ class wxICOBitmapHandler: public wxBitmapHandler
                            const wxString& extension, const wxString& name);
 
         virtual bool Create(wxBitmap *WXUNUSED(bitmap),
                            const wxString& extension, const wxString& name);
 
         virtual bool Create(wxBitmap *WXUNUSED(bitmap),
-                            void *WXUNUSED(data),
+                            const void* WXUNUSED(data),
                             long WXUNUSED(flags),
                             int WXUNUSED(width),
                             int WXUNUSED(height),
                             long WXUNUSED(flags),
                             int WXUNUSED(width),
                             int WXUNUSED(height),