From fea35690f171f9677bd9f949c0af3dc16d1a9576 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 30 Oct 2006 19:41:46 +0000
Subject: [PATCH] Added wxMemoryDC::SelectObjectAsSource() and make
 SelectObject() unshare the bitmap to ensure that no other bitmaps are
 modified; also remove some code duplication by introducing wxMemoryDCBase
 (patch 1580745)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42755 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/bufferdc.tex       |  6 ++--
 docs/latex/wx/memorydc.tex       | 47 ++++++++++++++++++++++++++------
 include/wx/cocoa/dcmemory.h      | 13 +++++++--
 include/wx/dcmemory.h            | 33 ++++++++++++++++++++++
 include/wx/dfb/dcmemory.h        | 12 +++++---
 include/wx/gtk/dcmemory.h        | 10 +++++--
 include/wx/gtk1/dcmemory.h       | 11 ++++++--
 include/wx/mac/carbon/dcmemory.h | 14 ++++++----
 include/wx/mgl/dcmemory.h        | 11 ++++++--
 include/wx/motif/dcmemory.h      | 12 +++++---
 include/wx/msw/dcmemory.h        |  7 +++--
 include/wx/os2/dcmemory.h        |  8 ++++--
 include/wx/palmos/dcmemory.h     |  8 +++---
 include/wx/x11/dcmemory.h        | 12 +++++---
 src/common/effects.cpp           |  2 +-
 src/dfb/dcmemory.cpp             |  6 ++--
 src/generic/splash.cpp           |  2 +-
 src/gtk/dcmemory.cpp             | 18 +++---------
 src/gtk1/dcmemory.cpp            | 14 +++-------
 src/mac/carbon/dcmemory.cpp      | 15 ++--------
 src/mgl/dcmemory.cpp             | 10 ++-----
 src/motif/dcmemory.cpp           |  7 ++---
 src/msw/dc.cpp                   |  5 ++--
 src/msw/dcmemory.cpp             | 12 +-------
 src/msw/dcprint.cpp              |  3 +-
 src/os2/dcmemory.cpp             | 12 ++------
 src/palmos/dcmemory.cpp          |  8 +-----
 src/x11/dcmemory.cpp             | 15 ++--------
 28 files changed, 185 insertions(+), 148 deletions(-)

diff --git a/docs/latex/wx/bufferdc.tex b/docs/latex/wx/bufferdc.tex
index 903c40d6b4..19d4970eea 100644
--- a/docs/latex/wx/bufferdc.tex
+++ b/docs/latex/wx/bufferdc.tex
@@ -62,7 +62,7 @@ buffering on the systems which already do it automatically.
 
 \func{}{wxBufferedDC}{\param{wxDC *}{dc}, \param{const wxSize\& }{area}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
-\func{}{wxBufferedDC}{\param{wxDC *}{dc}, \param{const wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
+\func{}{wxBufferedDC}{\param{wxDC *}{dc}, \param{wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
 If you use the first, default, constructor, you must call one of the 
 \helpref{Init}{wxbuffereddcinit} methods later in order to use the object.
@@ -93,7 +93,7 @@ device context).}
 
 \func{void}{Init}{\param{wxDC *}{dc}, \param{const wxSize\& }{area}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
-\func{void}{Init}{\param{wxDC *}{dc}, \param{const wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
+\func{void}{Init}{\param{wxDC *}{dc}, \param{wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
 These functions initialize the object created using the default constructor.
 Please see \helpref{constructors documentation}{wxbuffereddcctor} for details.
@@ -143,7 +143,7 @@ already does this internally for the real underlying wxPaintDC.
 
 \membersection{wxBufferedPaintDC::wxBufferedPaintDC}\label{wxbufferedpaintdcctor}
 
-\func{}{wxBufferedPaintDC}{\param{wxWindow *}{window}, \param{const wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
+\func{}{wxBufferedPaintDC}{\param{wxWindow *}{window}, \param{wxBitmap\& }{buffer}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
 \func{}{wxBufferedPaintDC}{\param{wxWindow *}{window}, \param{int }{style = wxBUFFER\_CLIENT\_AREA}}
 
diff --git a/docs/latex/wx/memorydc.tex b/docs/latex/wx/memorydc.tex
index eadaa1d991..d2fddb79d1 100644
--- a/docs/latex/wx/memorydc.tex
+++ b/docs/latex/wx/memorydc.tex
@@ -41,26 +41,55 @@ can be reselected into another memory DC.
 
 \membersection{wxMemoryDC::wxMemoryDC}\label{wxmemorydcctor}
 
-\func{}{wxMemoryDC}{\param{const wxBitmap\& }{bitmap = wxNullBitmap}}
+\func{}{wxMemoryDC}{\void}
 
 Constructs a new memory device context.
 
-Use the {\it Ok} member to test whether the constructor was successful
-in creating a usable device context. If you don't pass a valid bitmap
-to the constructor, don't forget to select a bitmap into the DC before
-drawing on it.
+Use the \helpref{IsOk}{wxdcisok} member to test whether the constructor was successful
+in creating a usable device context.
+Don't forget to select a bitmap into the DC before drawing on it.
+
+\func{}{wxMemoryDC}{\param{wxBitmap\& }{bitmap}}
+
+Constructs a new memory device context and calls \helpref{SelectObject}{wxmemorydcselectobject}
+with the given bitmap.
+Use the \helpref{IsOk}{wxdcisok} member to test whether the constructor was successful
+in creating a usable device context.
+
 
 \membersection{wxMemoryDC::SelectObject}\label{wxmemorydcselectobject}
 
-\func{void}{SelectObject}{\param{const wxBitmap\& }{bitmap}}
+\func{void}{SelectObject}{\param{wxBitmap\& }{bitmap}}
+
+Works exactly like \helpref{SelectObjectAsSource}{wxmemorydcselectobjectassource} but
+this is the function you should use when you select a bitmap because you want to modify
+it, e.g. drawing on this DC.
+
+Be careful to use this function and not \helpref{SelectObjectAsSource}{wxmemorydcselectobjectassource}
+when you want to modify the bitmap you are selecting otherwise you may incurr in some
+problems related to wxBitmap being a reference counted object
+(see \helpref{reference counting overview}{trefcount}).
+
+\wxheading{See also}
+
+\helpref{wxDC::DrawBitmap}{wxdcdrawbitmap}
+
+
+
+\membersection{wxMemoryDC::SelectObjectAsSource}\label{wxmemorydcselectobjectassource}
+
+\func{void}{SelectObjectAsSource}{\param{const wxBitmap\& }{bitmap}}
 
 Selects the given bitmap into the device context, to use as the memory
 bitmap. Selecting the bitmap into a memory DC allows you to draw into
-the DC (and therefore the bitmap) and also to use {\bf Blit} to copy
+the DC (and therefore the bitmap) and also to use \helpref{wxDC::Blit}{wxdcblit} to copy
 the bitmap to a window. For this purpose, you may find \helpref{wxDC::DrawIcon}{wxdcdrawicon}\rtfsp
 easier to use instead.
 
-If the argument is wxNullBitmap (or some other uninitialised wxBitmap) the current bitmap is selected out of the device
-context, and the original bitmap restored, allowing the current bitmap to
+If the argument is wxNullBitmap (or some other uninitialised wxBitmap) the current bitmap is
+selected out of the device context, and the original bitmap restored, allowing the current bitmap to
 be destroyed safely.
 
+\wxheading{See also}
+
+\helpref{wxMemoryDC::SelectObject}{wxmemorydcselectobject}
diff --git a/include/wx/cocoa/dcmemory.h b/include/wx/cocoa/dcmemory.h
index e5126c6896..f71534cfcb 100644
--- a/include/wx/cocoa/dcmemory.h
+++ b/include/wx/cocoa/dcmemory.h
@@ -14,15 +14,19 @@
 
 #include "wx/dc.h"
 
-class WXDLLEXPORT wxMemoryDC: public wxDC
+class WXDLLEXPORT wxMemoryDC: public wxDC, public wxMemoryDCBase
 {
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
+
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC(void);
-    virtual void SelectObject(const wxBitmap& bitmap);
+
     virtual void DoGetSize(int *width, int *height) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
+
 protected:
     wxBitmap m_selectedBitmap;
     WX_NSImage m_cocoaNSImage;
@@ -34,6 +38,9 @@ protected:
     virtual bool CocoaDoBlitOnFocusedDC(wxCoord xdest, wxCoord ydest,
         wxCoord width, wxCoord height, wxCoord xsrc, wxCoord ysrc,
         int logicalFunc, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask);
+
+private:
+    void Init();
 };
 
 #endif
diff --git a/include/wx/dcmemory.h b/include/wx/dcmemory.h
index d1cf8efde9..55e6724e95 100644
--- a/include/wx/dcmemory.h
+++ b/include/wx/dcmemory.h
@@ -14,6 +14,39 @@
 
 #include "wx/defs.h"
 
+// NOTE: different native implementations of wxMemoryDC will derive from
+//       different wxDC classes (wxPaintDC, wxWindowDC, etc), so that
+//       we cannot derive wxMemoryDCBase from wxDC and then use it as the
+//       only base class for native impl of wxMemoryDC...
+class wxMemoryDCBase
+{
+public:
+    wxMemoryDCBase() { }
+
+    // avoid warnings about having virtual functions but non virtual dtor
+    virtual ~wxMemoryDCBase() { }
+
+    // select the given bitmap to draw on it
+    void SelectObject(wxBitmap& bmp)
+    {
+        // make sure that the given wxBitmap is not sharing its data with other
+        // wxBitmap instances as its contents will be modified by any drawing
+        // operation done on this DC
+        if (bmp.IsOk())
+            bmp.UnShare();
+
+        DoSelect(bmp);
+    }
+
+    // select the given bitmap for read-only
+    virtual void SelectObjectAsSource(const wxBitmap& bmp)
+    {
+        DoSelect(bmp);
+    }
+
+    virtual void DoSelect(const wxBitmap& bmp) = 0;
+};
+
 #if defined(__WXPALMOS__)
 #include "wx/palmos/dcmemory.h"
 #elif defined(__WXMSW__)
diff --git a/include/wx/dfb/dcmemory.h b/include/wx/dfb/dcmemory.h
index 86ce650a72..d5b1a72d9b 100644
--- a/include/wx/dfb/dcmemory.h
+++ b/include/wx/dfb/dcmemory.h
@@ -14,19 +14,23 @@
 #include "wx/dc.h"
 #include "wx/bitmap.h"
 
-class WXDLLIMPEXP_CORE wxMemoryDC : public wxDC
+class WXDLLIMPEXP_CORE wxMemoryDC : public wxDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC(wxDC *dc); // create compatible DC
 
-    virtual void SelectObject(const wxBitmap& bitmap);
-
     // implementation from now on:
 
     wxBitmap GetSelectedObject() const { return m_bmp; }
 
+protected:
+    virtual void DoSelect(const wxBitmap& bitmap);
+
 private:
+    void Init();
+
     wxBitmap m_bmp;
 
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
diff --git a/include/wx/gtk/dcmemory.h b/include/wx/gtk/dcmemory.h
index a8d6434ad3..4afeaf4bce 100644
--- a/include/wx/gtk/dcmemory.h
+++ b/include/wx/gtk/dcmemory.h
@@ -23,13 +23,13 @@ class WXDLLIMPEXP_CORE wxMemoryDC;
 // wxMemoryDC
 //-----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC
+class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() : wxWindowDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) : wxWindowDC() { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC();
-    virtual void SelectObject( const wxBitmap& bitmap );
 
     // these get reimplemented for mono-bitmaps to behave
     // more like their Win32 couterparts. They now interpret
@@ -47,6 +47,10 @@ public:
 
 protected:
     void DoGetSize( int *width, int *height ) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
+
+private:
+    void Init();
     virtual wxBitmap DoGetAsBitmap(const wxRect *subrect) const 
     { return subrect == NULL ? GetSelectedBitmap() : GetSelectedBitmap().GetSubBitmap(*subrect); }
 
diff --git a/include/wx/gtk1/dcmemory.h b/include/wx/gtk1/dcmemory.h
index ba5b573e5f..691d757776 100644
--- a/include/wx/gtk1/dcmemory.h
+++ b/include/wx/gtk1/dcmemory.h
@@ -23,13 +23,13 @@ class WXDLLIMPEXP_CORE wxMemoryDC;
 // wxMemoryDC
 //-----------------------------------------------------------------------------
 
-class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC
+class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC();
-    virtual void SelectObject( const wxBitmap& bitmap );
     void DoGetSize( int *width, int *height ) const;
 
     // these get reimplemented for mono-bitmaps to behave
@@ -45,7 +45,12 @@ public:
     // implementation
     wxBitmap  m_selected;
 
+protected:
+    virtual void DoSelect(const wxBitmap& bitmap);
+
 private:
+    void Init();
+
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 };
 
diff --git a/include/wx/mac/carbon/dcmemory.h b/include/wx/mac/carbon/dcmemory.h
index 58a26fee28..d2eb3d4acc 100644
--- a/include/wx/mac/carbon/dcmemory.h
+++ b/include/wx/mac/carbon/dcmemory.h
@@ -14,15 +14,16 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLEXPORT wxMemoryDC: public wxPaintDC
+class WXDLLEXPORT wxMemoryDC: public wxPaintDC, public wxMemoryDCBase
 {
   DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 
-  public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+public:
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC(void);
-    virtual void SelectObject( const wxBitmap& bitmap );
+
     const wxBitmap& GetSelectedBitmap() const { return m_selected; }
     wxBitmap    GetSelectedBitmap() { return m_selected; }
 
@@ -32,8 +33,11 @@ protected:
     virtual void DoGetSize( int *width, int *height ) const;
     virtual wxBitmap DoGetAsBitmap(const wxRect *subrect) const 
     { return subrect == NULL ? GetSelectedBitmap() : GetSelectedBitmap().GetSubBitmap(*subrect); }
+    virtual void DoSelect(const wxBitmap& bitmap);
+
+private:
+    void Init();
 
-  private:
     wxBitmap  m_selected;
 };
 
diff --git a/include/wx/mgl/dcmemory.h b/include/wx/mgl/dcmemory.h
index 8bda585ff4..39804f20f1 100644
--- a/include/wx/mgl/dcmemory.h
+++ b/include/wx/mgl/dcmemory.h
@@ -23,13 +23,13 @@ class WXDLLEXPORT wxMemoryDC;
 // wxMemoryDC
 //-----------------------------------------------------------------------------
 
-class WXDLLEXPORT wxMemoryDC : public wxDC
+class WXDLLEXPORT wxMemoryDC : public wxDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC(wxDC *dc); // Create compatible DC
     virtual ~wxMemoryDC();
-    virtual void SelectObject(const wxBitmap& bitmap);
 
     // these get reimplemented for mono-bitmaps to behave
     // more like their Win32 couterparts. They now interpret
@@ -45,7 +45,12 @@ public:
     
     wxBitmap GetSelectedObject() const { return m_selected; }
 
+protected:
+    virtual void DoSelect(const wxBitmap& bitmap);
+
 private:
+    void Init();
+
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 };
 
diff --git a/include/wx/motif/dcmemory.h b/include/wx/motif/dcmemory.h
index 0d453f5505..6cce52c26b 100644
--- a/include/wx/motif/dcmemory.h
+++ b/include/wx/motif/dcmemory.h
@@ -14,24 +14,28 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC
+class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC, public wxMemoryDCBase
 {
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC();
 
-    virtual void SelectObject( const wxBitmap& bitmap );
-
     void DoGetSize( int *width, int *height ) const;
 
     wxBitmap& GetBitmap() const { return (wxBitmap&) m_bitmap; }
 
+protected:
+    virtual void DoSelect(const wxBitmap& bitmap);
+
 private:
     friend class wxPaintDC;
 
+    void Init();
+
     wxBitmap  m_bitmap;
 };
 
diff --git a/include/wx/msw/dcmemory.h b/include/wx/msw/dcmemory.h
index 1e138b2e32..20f2005856 100644
--- a/include/wx/msw/dcmemory.h
+++ b/include/wx/msw/dcmemory.h
@@ -14,18 +14,19 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLEXPORT wxMemoryDC : public wxDC
+class WXDLLEXPORT wxMemoryDC : public wxDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { CreateCompatible(NULL); Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { CreateCompatible(NULL); Init(); SelectObject(bitmap); }
     wxMemoryDC(wxDC *dc); // Create compatible DC
 
-    virtual void SelectObject(const wxBitmap& bitmap);
 
 protected:
     // override some base class virtuals
     virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height);
     virtual void DoGetSize(int* width, int* height) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
 
     // create DC compatible with the given one or screen if dc == NULL
     bool CreateCompatible(wxDC *dc);
diff --git a/include/wx/os2/dcmemory.h b/include/wx/os2/dcmemory.h
index 33001f619e..07927df52c 100644
--- a/include/wx/os2/dcmemory.h
+++ b/include/wx/os2/dcmemory.h
@@ -14,18 +14,20 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLEXPORT wxMemoryDC: public wxDC
+class WXDLLEXPORT wxMemoryDC: public wxDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { CreateCompatible(NULL); Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { CreateCompatible(NULL); Init(); SelectObject(bitmap); }
     wxMemoryDC(wxDC* pDC); // Create compatible DC
 
-    virtual void SelectObject(const wxBitmap& rBitmap);
 protected:
     // override some base class virtuals
     virtual void DoGetSize( int* pWidth
                            ,int* pHeight
                           ) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
+
     // create DC compatible with the given one or screen if dc == NULL
     bool CreateCompatible(wxDC* pDC);
 
diff --git a/include/wx/palmos/dcmemory.h b/include/wx/palmos/dcmemory.h
index 56d6c305f4..580ea68bbc 100644
--- a/include/wx/palmos/dcmemory.h
+++ b/include/wx/palmos/dcmemory.h
@@ -14,18 +14,18 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLEXPORT wxMemoryDC : public wxDC
+class WXDLLEXPORT wxMemoryDC : public wxDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC(wxDC *dc); // Create compatible DC
 
-    virtual void SelectObject(const wxBitmap& bitmap);
-
 protected:
     // override some base class virtuals
     virtual void DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height);
     virtual void DoGetSize(int* width, int* height) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
 
     // create DC compatible with the given one or screen if dc == NULL
     bool CreateCompatible(wxDC *dc);
diff --git a/include/wx/x11/dcmemory.h b/include/wx/x11/dcmemory.h
index 40c97fc7f0..0a86134f66 100644
--- a/include/wx/x11/dcmemory.h
+++ b/include/wx/x11/dcmemory.h
@@ -14,19 +14,23 @@
 
 #include "wx/dcclient.h"
 
-class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC
+class WXDLLIMPEXP_CORE wxMemoryDC : public wxWindowDC, public wxMemoryDCBase
 {
 public:
-    wxMemoryDC( const wxBitmap& bitmap = wxNullBitmap );
+    wxMemoryDC() { Init(); }
+    wxMemoryDC(wxBitmap& bitmap) { Init(); SelectObject(bitmap); }
     wxMemoryDC( wxDC *dc ); // Create compatible DC
     virtual ~wxMemoryDC();
-    virtual void SelectObject( const wxBitmap& bitmap );
 
     // implementation
     wxBitmap  m_selected;
 
 protected:
-    void DoGetSize( int *width, int *height ) const;
+    virtual void DoGetSize( int *width, int *height ) const;
+    virtual void DoSelect(const wxBitmap& bitmap);
+
+private:
+    void Init();
 
     DECLARE_DYNAMIC_CLASS(wxMemoryDC)
 };
diff --git a/src/common/effects.cpp b/src/common/effects.cpp
index e72542ecf4..4439ff42ba 100644
--- a/src/common/effects.cpp
+++ b/src/common/effects.cpp
@@ -102,7 +102,7 @@ bool wxEffects::TileBitmap(const wxRect& rect, wxDC& dc, const wxBitmap& bitmap)
     }
 #endif // wxUSE_PALETTE
 
-    dcMem.SelectObject(bitmap);
+    dcMem.SelectObjectAsSource(bitmap);
 
     int i, j;
     for (i = rect.x; i < rect.x + rect.width; i += w)
diff --git a/src/dfb/dcmemory.cpp b/src/dfb/dcmemory.cpp
index 036fcb81e1..eb83b923d3 100644
--- a/src/dfb/dcmemory.cpp
+++ b/src/dfb/dcmemory.cpp
@@ -39,17 +39,15 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
+void wxMemoryDC::Init()
 {
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC(wxDC *WXUNUSED(dc))
 {
 }
 
-void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
+void wxMemoryDC::DoSelect(const wxBitmap& bitmap)
 {
     m_bmp = bitmap;
 
diff --git a/src/generic/splash.cpp b/src/generic/splash.cpp
index 7695803aab..3fded78761 100644
--- a/src/generic/splash.cpp
+++ b/src/generic/splash.cpp
@@ -149,7 +149,7 @@ static void wxDrawSplashBitmap(wxDC& dc, const wxBitmap& bitmap, int WXUNUSED(x)
     }
 #endif // USE_PALETTE_IN_SPLASH
 
-    dcMem.SelectObject(bitmap);
+    dcMem.SelectObjectAsSource(bitmap);
     dc.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), & dcMem, 0, 0);
     dcMem.SelectObject(wxNullBitmap);
 
diff --git a/src/gtk/dcmemory.cpp b/src/gtk/dcmemory.cpp
index f24a06e95e..47c9a673f5 100644
--- a/src/gtk/dcmemory.cpp
+++ b/src/gtk/dcmemory.cpp
@@ -21,8 +21,7 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxWindowDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-   : wxWindowDC()
+void wxMemoryDC::Init()
 {
     m_ok = false;
 
@@ -34,22 +33,12 @@ wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
     pango_context_set_language( m_context, gtk_get_default_language() );
     m_layout = pango_layout_new( m_context );
     m_fontdesc = pango_font_description_copy( pango_context_get_font_description( m_context ) );
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
   : wxWindowDC()
 {
-    m_ok = false;
-
-    m_cmap = gtk_widget_get_default_colormap();
-
-    m_context = gdk_pango_context_get();
-    pango_context_set_language( m_context, gtk_get_default_language() );
-    m_layout = pango_layout_new( m_context );
-    m_fontdesc = pango_font_description_copy( pango_context_get_font_description( m_context ) );
+    Init();
 }
 
 wxMemoryDC::~wxMemoryDC()
@@ -57,9 +46,10 @@ wxMemoryDC::~wxMemoryDC()
     g_object_unref(m_context);
 }
 
-void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
 {
     Destroy();
+
     m_selected = bitmap;
     if (m_selected.Ok())
     {
diff --git a/src/gtk1/dcmemory.cpp b/src/gtk1/dcmemory.cpp
index add3cc54f5..a27cce1041 100644
--- a/src/gtk1/dcmemory.cpp
+++ b/src/gtk1/dcmemory.cpp
@@ -21,33 +21,27 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxWindowDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-    : wxWindowDC()
+void wxMemoryDC::Init()
 {
     m_ok = false;
 
     m_cmap = gtk_widget_get_default_colormap();
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
           : wxWindowDC()
 {
-    m_ok = false;
-
-    m_cmap = gtk_widget_get_default_colormap();
-
+    Init();
 }
 
 wxMemoryDC::~wxMemoryDC()
 {
 }
 
-void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
 {
     Destroy();
+
     m_selected = bitmap;
     if (m_selected.Ok())
     {
diff --git a/src/mac/carbon/dcmemory.cpp b/src/mac/carbon/dcmemory.cpp
index ba8ecbe271..f2519aef95 100644
--- a/src/mac/carbon/dcmemory.cpp
+++ b/src/mac/carbon/dcmemory.cpp
@@ -22,8 +22,7 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-: m_selected()
+void wxMemoryDC::Init()
 {
     m_ok = true;
     SetBackground(*wxWHITE_BRUSH);
@@ -31,20 +30,12 @@ wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
     SetPen(*wxBLACK_PEN);
     SetFont(*wxNORMAL_FONT);
     m_ok = false;
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
 : m_selected()
 {
-    m_ok = true;
-    SetBackground(*wxWHITE_BRUSH);
-    SetBrush(*wxWHITE_BRUSH);
-    SetPen(*wxBLACK_PEN);
-    SetFont(*wxNORMAL_FONT);
-    m_ok = false;
+    Init();
 }
 
 wxMemoryDC::~wxMemoryDC()
@@ -63,7 +54,7 @@ wxMemoryDC::~wxMemoryDC()
     }
 }
 
-void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
 {
     if ( m_selected.Ok() )
     {
diff --git a/src/mgl/dcmemory.cpp b/src/mgl/dcmemory.cpp
index 6017861c05..d09e8080f8 100644
--- a/src/mgl/dcmemory.cpp
+++ b/src/mgl/dcmemory.cpp
@@ -24,25 +24,21 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxWindowDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-    : wxDC()
+void wxMemoryDC::Init()
 {
     m_isMemDC = true;
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC(wxDC *WXUNUSED(dc)) : wxDC()
 {
-    m_isMemDC = true;
+    Init();
 }
 
 wxMemoryDC::~wxMemoryDC()
 {
 }
 
-void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
+void wxMemoryDC::DoSelect(const wxBitmap& bitmap)
 {
     if ( bitmap.Ok() )
     {
diff --git a/src/motif/dcmemory.cpp b/src/motif/dcmemory.cpp
index 789dac864d..81f4da0b3e 100644
--- a/src/motif/dcmemory.cpp
+++ b/src/motif/dcmemory.cpp
@@ -35,7 +35,7 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxWindowDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
+void wxMemoryDC::Init()
 {
     m_ok = true;
     m_display = wxGetDisplay();
@@ -57,9 +57,6 @@ wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
     SetBrush (* wxWHITE_BRUSH);
     SetPen (* wxBLACK_PEN);
     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-    
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC( wxDC* dc )
@@ -92,7 +89,7 @@ wxMemoryDC::~wxMemoryDC(void)
 {
 }
 
-void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
 {
     m_bitmap = bitmap;
 
diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp
index f22685ba97..8c7a50a982 100644
--- a/src/msw/dc.cpp
+++ b/src/msw/dc.cpp
@@ -930,7 +930,7 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
         // transparent pen) one pixel smaller in both directions and we want them
         // to have the same size regardless of which pen is used - adjust
 
-        // I wonder if this shouldn´t be done after the LOG2DEV() conversions. RR.
+        // I wonder if this shouldnt be done after the LOG2DEV() conversions. RR.
         if ( m_pen.GetStyle() == wxTRANSPARENT )
         {
             // Apparently not needed for WinCE (see e.g. Life! demo)
@@ -1245,7 +1245,8 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
             // Rather than reproduce wxDC::Blit, let's do it at the wxWin API
             // level
             wxMemoryDC memDC;
-            memDC.SelectObject(bmp);
+
+            memDC.SelectObjectAsSource(bmp);
 
             Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
 
diff --git a/src/msw/dcmemory.cpp b/src/msw/dcmemory.cpp
index 36ff844b21..5565670444 100644
--- a/src/msw/dcmemory.cpp
+++ b/src/msw/dcmemory.cpp
@@ -47,16 +47,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 // wxMemoryDC
 // ----------------------------------------------------------------------------
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-{
-    CreateCompatible(NULL);
-
-    Init();
-    
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
-}
-
 wxMemoryDC::wxMemoryDC(wxDC *dc)
 {
     wxCHECK_RET( dc, _T("NULL dc in wxMemoryDC ctor") );
@@ -91,7 +81,7 @@ bool wxMemoryDC::CreateCompatible(wxDC *dc)
     return m_ok;
 }
 
-void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap)
 {
     // select old bitmap out of the device context
     if ( m_oldBitmap )
diff --git a/src/msw/dcprint.cpp b/src/msw/dcprint.cpp
index 32dad051fe..2450426227 100644
--- a/src/msw/dcprint.cpp
+++ b/src/msw/dcprint.cpp
@@ -399,7 +399,8 @@ void wxPrinterDC::DoDrawBitmap(const wxBitmap& bmp,
     {
         // no support for StretchDIBits() or an error occurred if we got here
         wxMemoryDC memDC;
-        memDC.SelectObject(bmp);
+
+        memDC.SelectObjectAsSource(bmp);
 
         Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
 
diff --git a/src/os2/dcmemory.cpp b/src/os2/dcmemory.cpp
index 770e42bce4..1332c9d2fb 100644
--- a/src/os2/dcmemory.cpp
+++ b/src/os2/dcmemory.cpp
@@ -28,15 +28,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 // Memory DC
 /////////////////////////////////////////////////////////////////////////////
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-{
-    CreateCompatible(NULL);
-    Init();
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
-} // end of wxMemoryDC::wxMemoryDC
-
 wxMemoryDC::wxMemoryDC(
   wxDC*                             pOldDC
 )
@@ -121,7 +112,7 @@ bool wxMemoryDC::CreateCompatible( wxDC* WXUNUSED(pDC) )
     return m_ok;
 } // end of wxMemoryDC::CreateCompatible
 
-void wxMemoryDC::SelectObject(
+void wxMemoryDC::DoSelect(
   const wxBitmap&                   rBitmap
 )
 {
@@ -168,6 +159,7 @@ void wxMemoryDC::SelectObject(
                    );
         m_vSelectedBitmap.SetSelectedInto(NULL);
     }
+
     m_vSelectedBitmap = rBitmap;
 
 
diff --git a/src/palmos/dcmemory.cpp b/src/palmos/dcmemory.cpp
index 96487eba36..5211678a18 100644
--- a/src/palmos/dcmemory.cpp
+++ b/src/palmos/dcmemory.cpp
@@ -45,12 +45,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
 // wxMemoryDC
 // ----------------------------------------------------------------------------
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-{
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
-}
-
 wxMemoryDC::wxMemoryDC(wxDC *dc)
 {
 }
@@ -64,7 +58,7 @@ bool wxMemoryDC::CreateCompatible(wxDC *dc)
     return false;
 }
 
-void wxMemoryDC::SelectObject(const wxBitmap& bitmap)
+void wxMemoryDC::DoSelect(const wxBitmap& bitmap)
 {
 }
 
diff --git a/src/x11/dcmemory.cpp b/src/x11/dcmemory.cpp
index f5a4bddb64..f2019230e0 100644
--- a/src/x11/dcmemory.cpp
+++ b/src/x11/dcmemory.cpp
@@ -23,8 +23,7 @@
 
 IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxWindowDC)
 
-wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
-    : wxWindowDC()
+void wxMemoryDC::Init()
 {
     m_ok = false;
 
@@ -32,27 +31,19 @@ wxMemoryDC::wxMemoryDC( const wxBitmap& bitmap )
 
     int screen = DefaultScreen( wxGlobalDisplay() );
     m_cmap = (WXColormap) DefaultColormap( wxGlobalDisplay(), screen );
-
-    if ( bitmap.IsOk() )
-        SelectObject(bitmap);
 }
 
 wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
   : wxWindowDC()
 {
-    m_ok = false;
-
-    m_display = (WXDisplay *) wxGlobalDisplay();
-
-    int screen = DefaultScreen( wxGlobalDisplay() );
-    m_cmap = (WXColormap) DefaultColormap( wxGlobalDisplay(), screen );
+    Init();
 }
 
 wxMemoryDC::~wxMemoryDC()
 {
 }
 
-void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
 {
     Destroy();
 
-- 
2.50.0

