]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mgl/bitmap.cpp
wxRichTextCtrl native caret now flashes, for wxMac/Core Graphics mode
[wxWidgets.git] / src / mgl / bitmap.cpp
index 2d7e61108ff720e0202327e40de3582dad758821..3c717d4fe9fa621ca35f8e1e71ed2bc9fde066a2 100644 (file)
 
 #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:
 //-----------------------------------------------------------------------------
@@ -51,67 +58,35 @@ static pixel_format_t gs_pixel_format_wxImage =
     {0xFF,0x00,0, 0xFF,0x08,0, 0xFF,0x10,0, 0x00,0x00,0}; // RGB 24bpp for wxImage
 
 //-----------------------------------------------------------------------------
-// wxBitmap
+// wxBitmapRefData
 //-----------------------------------------------------------------------------
 
-class wxBitmapRefData: public wxObjectRefData
+class wxBitmapRefData: public wxGDIRefData
 {
 public:
     wxBitmapRefData();
+    wxBitmapRefData(int width, int height, int bpp);
+    wxBitmapRefData(const wxBitmapRefData& data);
     virtual ~wxBitmapRefData();
 
+    virtual bool IsOk() const { return m_bitmap != NULL; }
+
     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;
-}
-
-wxBitmapRefData::~wxBitmapRefData()
-{
-    if ( m_bitmap )
-        MGL_unloadBitmap(m_bitmap);
-    delete m_mask;
-    delete m_palette;
-}
-
-//-----------------------------------------------------------------------------
 
-#define M_BMPDATA ((wxBitmapRefData *)m_refData)
-
-
-IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler,wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase)
-
-wxBitmap::wxBitmap(int width, int height, int depth)
-{
-    Create(width, height, depth);
-}
-
-
-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);
-}
+private:
+    void DoCreateBitmap(int width, int height, int depth);
+};
 
-bool wxBitmap::Create(int width, int height, int depth)
+void wxBitmapRefData::DoCreateBitmap(int width, int height, int depth)
 {
-    UnRef();
-
-    wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") );
+    m_width = width;
+    m_height = height;
+    m_bpp = depth;
 
     pixel_format_t pf_dummy;
     pixel_format_t *pf;
@@ -129,6 +104,7 @@ bool wxBitmap::Create(int width, int height, int depth)
         case 1:
         case 8:
             pf = NULL;
+            mglDepth = 8; // we emulate monochrome bitmaps using 8 bit ones
             break;
         case 15:
             pf = &gs_pixel_format_15;
@@ -144,44 +120,85 @@ bool wxBitmap::Create(int width, int height, int depth)
             break;
         default:
             wxFAIL_MSG(wxT("invalid bitmap depth"));
-            return false;
+            m_bitmap = NULL;
+            return;
     }
 
-    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;
+    m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf);
+}
 
-    if ( mglDepth != 1 )
-    {
-        M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, mglDepth, pf);
-    }
-    else
-    {
-        // 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.
+wxBitmapRefData::wxBitmapRefData()
+{
+    m_width =
+    m_height =
+    m_bpp = 0;
 
-        M_BMPDATA->m_bitmap = MyMGL_createBitmap(width, height, 8, pf);
-        SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0));
-    }
+    m_palette = NULL;
+    m_mask = NULL;
 
-    return Ok();
+    m_bitmap = NULL;
 }
 
-bool wxBitmap::CreateFromXpm(const char **bits)
+wxBitmapRefData::wxBitmapRefData(int width, int height, int bpp)
 {
-    wxCHECK_MSG( bits != NULL, false, wxT("invalid bitmap data") );
+    DoCreateBitmap(width, height, bpp);
+
+    m_palette = NULL;
+    m_mask = NULL;
+}
 
-    wxXPMDecoder decoder;
-    wxImage img = decoder.ReadData(bits);
-    wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") );
+wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData& data)
+{
+    DoCreateBitmap(data.m_width, data.m_height, data.m_bpp);
 
-    *this = wxBitmap(img);
+    m_palette = NULL; // FIXME: should copy
+    m_mask = NULL; // FIXME: should copy
+}
 
-    return true;
+wxBitmapRefData::~wxBitmapRefData()
+{
+    if ( m_bitmap )
+        MGL_unloadBitmap(m_bitmap);
+    delete m_mask;
+    delete m_palette;
+}
+
+
+//-----------------------------------------------------------------------------
+// wxBitmap
+//-----------------------------------------------------------------------------
+
+#define M_BMPDATA ((wxBitmapRefData *)m_refData)
+
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap,wxBitmapBase)
+
+wxGDIRefData *wxBitmap::CreateGDIRefData() const
+{
+    return new wxBitmapRefData;
+}
+
+wxGDIRefData *wxBitmap::CloneGDIRefData(const wxGDIRefData *data) const
+{
+    return new wxBitmapRefData(*static_cast<const wxBitmapRefData *>(data));
+}
+
+bool wxBitmap::Create(int width, int height, int depth)
+{
+    UnRef();
+
+    wxCHECK_MSG( (width > 0) && (height > 0), false, wxT("invalid bitmap size") );
+
+    m_refData = new wxBitmapRefData(width, height, depth);
+
+    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.
+        SetMonoPalette(wxColour(255, 255, 255), wxColour(0, 0, 0));
+    }
+
+    return Ok();
 }
 
 wxBitmap::wxBitmap(const wxImage& image, int depth)
@@ -280,21 +297,6 @@ wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
     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
 {
     wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
@@ -318,7 +320,7 @@ int wxBitmap::GetDepth() const
 
 wxMask *wxBitmap::GetMask() const
 {
-    wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
+    wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
 
     return M_BMPDATA->m_mask;
 }
@@ -327,6 +329,7 @@ void wxBitmap::SetMask(wxMask *mask)
 {
     wxCHECK_RET( Ok(), wxT("invalid bitmap") );
 
+    AllocExclusive();
     delete M_BMPDATA->m_mask;
     M_BMPDATA->m_mask = mask;
 }
@@ -370,6 +373,7 @@ void wxBitmap::SetMonoPalette(const wxColour& fg, const wxColour& bg)
 {
     wxCHECK_RET( Ok(), wxT("invalid bitmap") );
 
+    AllocExclusive();
     palette_t *mono = M_BMPDATA->m_bitmap->pal;
 
     wxCHECK_RET( M_BMPDATA->m_bpp == 1, wxT("bitmap is not 1bpp") );
@@ -424,7 +428,7 @@ MGLDevCtx *wxBitmap::CreateTmpDC() const
 
 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 )
@@ -454,8 +458,6 @@ bool wxBitmap::LoadFile(const wxString &name, wxBitmapType type)
         }
     }
 
-    m_refData = new wxBitmapRefData();
-
     return handler->LoadFile(this, name, type, -1, -1);
 }
 
@@ -495,6 +497,7 @@ void wxBitmap::SetPalette(const wxPalette& palette)
     wxCHECK_RET( Ok(), wxT("invalid bitmap") );
     wxCHECK_RET( GetDepth() > 1 && GetDepth() <= 8, wxT("cannot set palette for bitmap of this depth") );
 
+    AllocExclusive();
     delete M_BMPDATA->m_palette;
     M_BMPDATA->m_palette = NULL;
 
@@ -509,21 +512,21 @@ void wxBitmap::SetPalette(const wxPalette& palette)
 
 void wxBitmap::SetHeight(int height)
 {
-    if (!m_refData) m_refData = new wxBitmapRefData();
+    AllocExclusive();
 
     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)
 {
-    if (!m_refData) m_refData = new wxBitmapRefData();
+    AllocExclusive();
 
     M_BMPDATA->m_bpp = depth;
 }
@@ -535,7 +538,7 @@ bitmap_t *wxBitmap::GetMGLbitmap_t() const
 
 // Convert wxColour into it's quantized value in lower-precision
 // pixel format (needed for masking by colour).
-wxColour wxBitmap::QuantizeColour(const wxColour& clr)
+wxColour wxBitmap::QuantizeColour(const wxColour& clr) const
 {
     pixel_format_t *pf = GetMGLbitmap_t()->pf;
 
@@ -559,7 +562,7 @@ public:
                        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),
@@ -667,7 +670,7 @@ bool wxMGLBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name,
     int w = bitmap->GetWidth(),
         h = bitmap->GetHeight();
 
-    mem.SelectObject(*bitmap);
+    mem.SelectObjectAsSource(*bitmap);
     tdc = mem.GetMGLDC();
 
     switch (type)
@@ -777,7 +780,7 @@ class wxICOBitmapHandler: public wxBitmapHandler
                            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),