/////////////////////////////////////////////////////////////////////////////
// Name: region.cpp
-// Purpose: Region handling for wxWindows/MGL
+// Purpose: Region handling for wxWidgets/MGL
// Author: Vaclav Slavik
// RCS-ID: $Id$
-// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
+// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "region.h"
#endif
#include "wx/region.h"
#include "wx/gdicmn.h"
#include "wx/thread.h"
+#include "wx/module.h"
#include <mgraph.hpp>
class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
{
public:
- wxRegionRefData()
- {
- }
+ wxRegionRefData() {}
wxRegionRefData(const wxRegionRefData& data)
{
m_region = data.m_region;
}
- ~wxRegionRefData()
- {
- }
+ ~wxRegionRefData() {}
MGLRegion m_region;
};
// wxRegion
//-----------------------------------------------------------------------------
+wxObjectRefData *wxRegion::CreateRefData() const
+{
+ return new wxRegionRefData;
+}
+
+wxObjectRefData *wxRegion::CloneRefData(const wxObjectRefData *data) const
+{
+ return new wxRegionRefData(*(wxRegionRefData *)data);
+}
+
/*
* Create an empty region.
*/
wxRegion::wxRegion()
{
- m_refData = (wxRegionRefData *)NULL;
+ m_refData = NULL;
}
wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
// Modifications
//-----------------------------------------------------------------------------
+bool wxRegion::Offset(wxCoord x, wxCoord y)
+{
+ AllocExclusive();
+ M_REGION.offset(x, y);
+ return TRUE;
+}
+
// Union rectangle or region with this.
bool wxRegion::Union(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- Unshare();
+ AllocExclusive();
M_REGION += MGLRect(x, y, x + width, y + height);
return TRUE;
}
bool wxRegion::Union(const wxRegion& region)
{
- Unshare();
+ AllocExclusive();
M_REGION += M_REGION_OF(region);
return TRUE;
}
// Intersect rectangle or region with this.
bool wxRegion::Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- Unshare();
+ AllocExclusive();
M_REGION &= MGLRect(x, y, x + width, y + height);
return TRUE;
}
bool wxRegion::Intersect(const wxRegion& region)
{
- Unshare();
+ AllocExclusive();
M_REGION &= M_REGION_OF(region);
return TRUE;
}
// Combines the parts of 'this' that are not part of the second region.
bool wxRegion::Subtract(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- Unshare();
+ AllocExclusive();
M_REGION -= MGLRect(x, y, x + width, y + height);
return TRUE;
}
bool wxRegion::Subtract(const wxRegion& region)
{
- Unshare();
+ AllocExclusive();
M_REGION -= M_REGION_OF(region);
return TRUE;
}
// XOR: the union of two combined regions except for any overlapping areas.
bool wxRegion::Xor(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- Unshare();
+ AllocExclusive();
MGLRect rect(x, y, x + width, y + height);
MGLRegion rg1 = M_REGION + rect,
rg2 = M_REGION & rect;
bool wxRegion::Xor(const wxRegion& region)
{
- Unshare();
+ AllocExclusive();
MGLRegion rg1 = M_REGION + M_REGION_OF(region),
rg2 = M_REGION & M_REGION_OF(region);
M_REGION = rg1 - rg2;
}
+///////////////////////////////////////////////////////////////////////////////
+// wxRegionIterator //
+///////////////////////////////////////////////////////////////////////////////
+
+#if wxUSE_THREADS
+static wxMutex *gs_mutexIterator;
-void wxRegion::Unshare()
+class wxMglRegionModule : public wxModule
{
- if (!m_refData)
+public:
+ virtual bool OnInit()
{
- m_refData = new wxRegionRefData();
+ gs_mutexIterator = new wxMutex();
+ return TRUE;
}
- else
+ virtual void OnExit()
{
- wxRegionRefData* ref = new wxRegionRefData(*(wxRegionRefData*)m_refData);
- UnRef();
- m_refData = ref;
+ wxDELETE(gs_mutexIterator);
}
-}
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// wxRegionIterator //
-///////////////////////////////////////////////////////////////////////////////
+ DECLARE_DYNAMIC_CLASS(wxMglRegionModule)
+};
+IMPLEMENT_DYNAMIC_CLASS(wxMglRegionModule, wxModule)
+#endif
/*
* Initialize empty iterator
static wxRegionRectList *gs_rectList;
-static void wxMGL_region_callback(const rect_t *r)
+static void MGLAPI wxMGL_region_callback(const rect_t *r)
{
gs_rectList->Append(new wxRect(r->left, r->top,
r->right - r->left, r->bottom - r->top));
if (!region.Empty())
{
- wxMutexGuiEnter();
+#if wxUSE_THREADS
+ wxMutexLocker(*gs_mutexIterator);
+#endif
gs_rectList = &m_rects;
M_REGION_OF(region).traverse(wxMGL_region_callback);
- wxMutexGuiLeave();
m_currentNode = m_rects.GetFirst();
}
}
else
return 0;
}
-