1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dcbufcmn.cpp
3 // Purpose: Buffered DC implementation
4 // Author: Ron Lee, Jaakko Salli
6 // Created: Sep-20-2006
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/dcbuffer.h"
30 #include "wx/module.h"
33 // ============================================================================
35 // ============================================================================
37 IMPLEMENT_DYNAMIC_CLASS(wxBufferedDC
,wxMemoryDC
)
38 IMPLEMENT_ABSTRACT_CLASS(wxBufferedPaintDC
,wxBufferedDC
)
40 // ----------------------------------------------------------------------------
41 // wxSharedDCBufferManager: helper class maintaining backing store bitmap
42 // ----------------------------------------------------------------------------
44 class wxSharedDCBufferManager
: public wxModule
47 wxSharedDCBufferManager() { }
49 virtual bool OnInit() { return true; }
50 virtual void OnExit() { wxDELETE(ms_buffer
); }
52 static wxBitmap
* GetBuffer(int w
, int h
)
54 if ( ms_usingSharedBuffer
)
55 return new wxBitmap(w
, h
);
58 w
> ms_buffer
->GetWidth() ||
59 h
> ms_buffer
->GetHeight() )
63 // we must always return a valid bitmap but creating a bitmap of
64 // size 0 would fail, so create a 1*1 bitmap in this case
70 ms_buffer
= new wxBitmap(w
, h
);
73 ms_usingSharedBuffer
= true;
77 static void ReleaseBuffer(wxBitmap
* buffer
)
79 if ( buffer
== ms_buffer
)
81 wxASSERT_MSG( ms_usingSharedBuffer
, wxT("shared buffer already released") );
82 ms_usingSharedBuffer
= false;
91 static wxBitmap
*ms_buffer
;
92 static bool ms_usingSharedBuffer
;
94 DECLARE_DYNAMIC_CLASS(wxSharedDCBufferManager
)
97 wxBitmap
* wxSharedDCBufferManager::ms_buffer
= NULL
;
98 bool wxSharedDCBufferManager::ms_usingSharedBuffer
= false;
100 IMPLEMENT_DYNAMIC_CLASS(wxSharedDCBufferManager
, wxModule
)
102 // ============================================================================
104 // ============================================================================
106 void wxBufferedDC::UseBuffer(wxCoord w
, wxCoord h
)
108 if ( !m_buffer
|| !m_buffer
->IsOk() )
110 if ( w
== -1 || h
== -1 )
111 m_dc
->GetSize(&w
, &h
);
113 m_buffer
= wxSharedDCBufferManager::GetBuffer(w
, h
);
114 m_style
|= wxBUFFER_USES_SHARED_BUFFER
;
117 SelectObject(*m_buffer
);
119 // now that the DC is valid we can inherit the attributes (fonts, colours,
120 // layout direction, ...) from the original DC
121 if ( m_dc
&& m_dc
->IsOk() )
122 CopyAttributes(*m_dc
);
125 void wxBufferedDC::UnMask()
127 wxCHECK_RET( m_dc
, wxT("no underlying wxDC?") );
128 wxASSERT_MSG( m_buffer
&& m_buffer
->IsOk(), wxT("invalid backing store") );
133 // Ensure the scale matches the device
134 SetUserScale(1.0, 1.0);
136 if ( m_style
& wxBUFFER_CLIENT_AREA
)
137 GetDeviceOrigin(&x
, &y
);
139 // avoid blitting too much: if we were created for a bigger bitmap (and
140 // reused for a smaller one later) we should only blit the real bitmap area
141 // and not the full allocated back buffer
145 m_dc
->GetSize(&widthDC
, &heightDC
);
147 int widthBuf
= m_buffer
->GetWidth(),
148 heightBuf
= m_buffer
->GetHeight();
151 wxMin(widthDC
, widthBuf
), wxMin(heightDC
, heightBuf
),
156 if ( m_style
& wxBUFFER_USES_SHARED_BUFFER
)
157 wxSharedDCBufferManager::ReleaseBuffer(m_buffer
);