1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/dcbufcmn.cpp
3 // Purpose: Buffered DC implementation
4 // Author: Ron Lee, Jaakko Salli
6 // Created: Sep-20-2006
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #include "wx/dcbuffer.h"
29 #include "wx/module.h"
32 // ============================================================================
34 // ============================================================================
36 IMPLEMENT_DYNAMIC_CLASS(wxBufferedDC
,wxMemoryDC
)
37 IMPLEMENT_ABSTRACT_CLASS(wxBufferedPaintDC
,wxBufferedDC
)
39 // ----------------------------------------------------------------------------
40 // wxSharedDCBufferManager: helper class maintaining backing store bitmap
41 // ----------------------------------------------------------------------------
43 class wxSharedDCBufferManager
: public wxModule
46 wxSharedDCBufferManager() { }
48 virtual bool OnInit() { return true; }
49 virtual void OnExit() { wxDELETE(ms_buffer
); }
51 static wxBitmap
* GetBuffer(int w
, int h
)
53 if ( ms_usingSharedBuffer
)
54 return new wxBitmap(w
, h
);
57 w
> ms_buffer
->GetWidth() ||
58 h
> ms_buffer
->GetHeight() )
62 // we must always return a valid bitmap but creating a bitmap of
63 // size 0 would fail, so create a 1*1 bitmap in this case
69 ms_buffer
= new wxBitmap(w
, h
);
72 ms_usingSharedBuffer
= true;
76 static void ReleaseBuffer(wxBitmap
* buffer
)
78 if ( buffer
== ms_buffer
)
80 wxASSERT_MSG( ms_usingSharedBuffer
, wxT("shared buffer already released") );
81 ms_usingSharedBuffer
= false;
90 static wxBitmap
*ms_buffer
;
91 static bool ms_usingSharedBuffer
;
93 DECLARE_DYNAMIC_CLASS(wxSharedDCBufferManager
)
96 wxBitmap
* wxSharedDCBufferManager::ms_buffer
= NULL
;
97 bool wxSharedDCBufferManager::ms_usingSharedBuffer
= false;
99 IMPLEMENT_DYNAMIC_CLASS(wxSharedDCBufferManager
, wxModule
)
101 // ============================================================================
103 // ============================================================================
105 void wxBufferedDC::UseBuffer(wxCoord w
, wxCoord h
)
107 wxCHECK_RET( w
>= -1 && h
>= -1, "Invalid buffer size" );
109 if ( !m_buffer
|| !m_buffer
->IsOk() )
111 if ( w
== -1 || h
== -1 )
112 m_dc
->GetSize(&w
, &h
);
114 m_buffer
= wxSharedDCBufferManager::GetBuffer(w
, h
);
115 m_style
|= wxBUFFER_USES_SHARED_BUFFER
;
119 m_area
= m_buffer
->GetSize();
121 SelectObject(*m_buffer
);
123 // now that the DC is valid we can inherit the attributes (fonts, colours,
124 // layout direction, ...) from the original DC
125 if ( m_dc
&& m_dc
->IsOk() )
126 CopyAttributes(*m_dc
);
129 void wxBufferedDC::UnMask()
131 wxCHECK_RET( m_dc
, wxT("no underlying wxDC?") );
132 wxASSERT_MSG( m_buffer
&& m_buffer
->IsOk(), wxT("invalid backing store") );
137 // Ensure the scale matches the device
138 SetUserScale(1.0, 1.0);
140 if ( m_style
& wxBUFFER_CLIENT_AREA
)
141 GetDeviceOrigin(&x
, &y
);
143 // It's possible that the buffer may be bigger than the area that needs to
144 // be drawn (the client size of the window is smaller than the bitmap, or
145 // a shared bitmap has been reused for a smaller area, etc.) so avoid
146 // blitting too much if possible, but only use the real DC size if the
147 // wxBUFFER_VIRTUAL_AREA style is not set.
148 int width
= m_area
.GetWidth(),
149 height
= m_area
.GetHeight();
151 if (! m_style
& wxBUFFER_VIRTUAL_AREA
)
155 m_dc
->GetSize(&widthDC
, &heightDC
);
156 width
= wxMin(width
, widthDC
);
157 height
= wxMin(height
, heightDC
);
160 m_dc
->Blit(0, 0, width
, height
, this, -x
, -y
);
163 if ( m_style
& wxBUFFER_USES_SHARED_BUFFER
)
164 wxSharedDCBufferManager::ReleaseBuffer(m_buffer
);