+#if wxUSE_DC_CACHEING
+
+/*
+ * This implementation is a bit ugly and uses the old-fashioned wxList class, so I will
+ * improve it in due course, either using arrays, or simply storing pointers to one
+ * entry for the bitmap, and two for the DCs. -- JACS
+ */
+
+// ---------------------------------------------------------------------------
+// wxDCCacheEntry
+// ---------------------------------------------------------------------------
+
+wxList wxDC::m_svBitmapCache;
+wxList wxDC::m_svDCCache;
+
+wxDCCacheEntry::wxDCCacheEntry(
+ WXHBITMAP hBitmap
+, int nWidth
+, int nHeight
+, int nDepth
+)
+{
+ m_hBitmap = hBitmap;
+ m_hPS = NULLHANDLE;
+ m_nWidth = nWidth;
+ m_nHeight = nHeight;
+ m_nDepth = nDepth;
+} // end of wxDCCacheEntry::wxDCCacheEntry
+
+wxDCCacheEntry::wxDCCacheEntry(
+ HPS hPS
+, int nDepth
+)
+{
+ m_hBitmap = NULLHANDLE;
+ m_hPS = hPS;
+ m_nWidth = 0;
+ m_nHeight = 0;
+ m_nDepth = nDepth;
+} // end of wxDCCacheEntry::wxDCCacheEntry
+
+wxDCCacheEntry::~wxDCCacheEntry()
+{
+ if (m_hBitmap)
+ ::GpiDeleteBitmap(m_hBitmap);
+ if (m_hPS)
+ ::GpiDestroyPS(m_hPS);
+} // end of wxDCCacheEntry::~wxDCCacheEntry
+
+wxDCCacheEntry* wxDC::FindBitmapInCache(
+ HPS hPS
+, int nWidth
+, int nHeight
+)
+{
+ int nDepth = 24; // we'll fix this later ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL);
+ wxNode* pNode = m_svBitmapCache.First();
+ BITMAPINFOHEADER2 vBmpHdr;
+
+ while(pNode)
+ {
+ wxDCCacheEntry* pEntry = (wxDCCacheEntry*)pNode->Data();
+
+ if (pEntry->m_nDepth == nDepth)
+ {
+ memset(&vBmpHdr, 0, sizeof(BITMAPINFOHEADER2));
+
+ if (pEntry->m_nWidth < nWidth || pEntry->m_nHeight < nHeight)
+ {
+ ::GpiDeleteBitmap((HBITMAP)pEntry->m_hBitmap);
+ vBmpHdr.cbFix = sizeof(BITMAPINFOHEADER2);
+ vBmpHdr.cx = nWidth;
+ vBmpHdr.cy = nHeight;
+ vBmpHdr.cPlanes = 1;
+ vBmpHdr.cBitCount = nDepth;
+
+ pEntry->m_hBitmap = (WXHBITMAP) ::GpiCreateBitmap( hPS
+ ,&vBmpHdr
+ ,0L, NULL, NULL
+ );
+ if (!pEntry->m_hBitmap)
+ {
+ wxLogLastError(wxT("CreateCompatibleBitmap"));
+ }
+ pEntry->m_nWidth = nWidth;
+ pEntry->m_nHeight = nHeight;
+ return pEntry;
+ }
+ return pEntry;
+ }
+ pNode = pNode->Next();
+ }
+ memset(&vBmpHdr, 0, sizeof(BITMAPINFOHEADER2));
+ vBmpHdr.cbFix = sizeof(BITMAPINFOHEADER2);
+ vBmpHdr.cx = nWidth;
+ vBmpHdr.cy = nHeight;
+ vBmpHdr.cPlanes = 1;
+ vBmpHdr.cBitCount = nDepth;
+
+ WXHBITMAP hBitmap = (WXHBITMAP) ::GpiCreateBitmap( hPS
+ ,&vBmpHdr
+ ,0L, NULL, NULL
+ );
+ if (!hBitmap)
+ {
+ wxLogLastError(wxT("CreateCompatibleBitmap"));
+ }
+ wxDCCacheEntry* pEntry = new wxDCCacheEntry( hBitmap
+ ,nWidth
+ ,nHeight
+ ,nDepth
+ );
+ AddToBitmapCache(pEntry);
+ return pEntry;
+} // end of FindBitmapInCache
+
+wxDCCacheEntry* wxDC::FindDCInCache(
+ wxDCCacheEntry* pNotThis
+, HPS hPS
+)
+{
+ int nDepth = 24; // we'll fix this up later ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL);
+ wxNode* pNode = m_svDCCache.First();
+
+ while(pNode)
+ {
+ wxDCCacheEntry* pEntry = (wxDCCacheEntry*)pNode->Data();
+
+ //
+ // Don't return the same one as we already have
+ //
+ if (!pNotThis || (pNotThis != pEntry))
+ {
+ if (pEntry->m_nDepth == nDepth)
+ {
+ return pEntry;
+ }
+ }
+ pNode = pNode->Next();
+ }
+ wxDCCacheEntry* pEntry = new wxDCCacheEntry( hPS
+ ,nDepth
+ );
+ AddToDCCache(pEntry);
+ return pEntry;
+} // end of wxDC::FindDCInCache
+
+void wxDC::AddToBitmapCache(
+ wxDCCacheEntry* pEntry
+)
+{
+ m_svBitmapCache.Append(pEntry);
+} // end of wxDC::AddToBitmapCache
+
+void wxDC::AddToDCCache(
+ wxDCCacheEntry* pEntry
+)
+{
+ m_svDCCache.Append(pEntry);
+} // end of wxDC::AddToDCCache
+
+void wxDC::ClearCache()
+{
+ m_svBitmapCache.DeleteContents(TRUE);
+ m_svBitmapCache.Clear();
+ m_svBitmapCache.DeleteContents(FALSE);
+ m_svDCCache.DeleteContents(TRUE);
+ m_svDCCache.Clear();
+ m_svDCCache.DeleteContents(FALSE);
+} // end of wxDC::ClearCache
+
+// Clean up cache at app exit
+class wxDCModule : public wxModule
+{
+public:
+ virtual bool OnInit() { return TRUE; }
+ virtual void OnExit() { wxDC::ClearCache(); }
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxDCModule)
+}; // end of CLASS wxDCModule
+
+IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
+
+#endif // ndef for wxUSE_DC_CACHEING
+