]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mgl/region.cpp
Make SetLocal actually work instead of crashing immediately; due to required longevit...
[wxWidgets.git] / src / mgl / region.cpp
index b9a9293ac49ff9855e55044fa989b5f67944ac45..bd1da90543a09e97ad8b1992adead768e03ab8af 100644 (file)
@@ -1,16 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:      region.cpp
-// Purpose:   Region handling for wxWindows/MGL
+// Name:      src/mgl/region.cpp
+// Purpose:   Region handling for wxWidgets/MGL
 // Author:    Vaclav Slavik
 // RCS-ID:    $Id$
 // Author:    Vaclav Slavik
 // RCS-ID:    $Id$
-// Copyright: (c) 2001 Vaclav Slavik
+// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
 // Licence:   wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // Licence:   wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "region.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -21,6 +17,7 @@
 #include "wx/region.h"
 #include "wx/gdicmn.h"
 #include "wx/thread.h"
 #include "wx/region.h"
 #include "wx/gdicmn.h"
 #include "wx/thread.h"
+#include "wx/module.h"
 
 #include <mgraph.hpp>
 
 
 #include <mgraph.hpp>
 
@@ -37,18 +34,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
 class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
 {
 public:
 class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
 {
 public:
-    wxRegionRefData()
-    {
-    }    
+    wxRegionRefData() {}
 
     wxRegionRefData(const wxRegionRefData& data)
     {
         m_region = data.m_region;
     }
 
 
     wxRegionRefData(const wxRegionRefData& data)
     {
         m_region = data.m_region;
     }
 
-    ~wxRegionRefData()
-    {
-    }
+    ~wxRegionRefData() {}
 
     MGLRegion m_region;
 };
 
     MGLRegion m_region;
 };
@@ -60,16 +53,26 @@ public:
 // wxRegion
 //-----------------------------------------------------------------------------
 
 // 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()
 {
 /*
  * Create an empty region.
  */
 wxRegion::wxRegion()
 {
-    m_refData = (wxRegionRefData *)NULL;
+    m_refData = NULL;
 }
 
 wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
 }
 
 wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
-{    
+{
     m_refData = new wxRegionRefData;
     MGLRect rect(x, y, x + w, y + h);
     M_REGION = rect;
     m_refData = new wxRegionRefData;
     MGLRect rect(x, y, x + w, y + h);
     M_REGION = rect;
@@ -78,14 +81,14 @@ wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
 {
     m_refData = new wxRegionRefData;
 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
 {
     m_refData = new wxRegionRefData;
-    MGLRect rect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
+    MGLRect rect(topLeft.x, topLeft.y, bottomRight.x+1, bottomRight.y+1);
     M_REGION = rect;
 }
 
 wxRegion::wxRegion(const wxRect& r)
 {
     m_refData = new wxRegionRefData;
     M_REGION = rect;
 }
 
 wxRegion::wxRegion(const wxRect& r)
 {
     m_refData = new wxRegionRefData;
-    MGLRect rect(r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom());
+    MGLRect rect(r.GetLeft(), r.GetTop(), r.GetRight()+1, r.GetBottom()+1);
     M_REGION = rect;
 }
 
     M_REGION = rect;
 }
 
@@ -123,7 +126,7 @@ void wxRegion::Clear()
 // Outer bounds of region
 void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
 {
 // Outer bounds of region
 void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
 {
-    if (m_refData) 
+    if (m_refData)
     {
         rect_t rect;
         rect = M_REGION.getBounds();
     {
         rect_t rect;
         rect = M_REGION.getBounds();
@@ -131,8 +134,8 @@ void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
         y = rect.top;
         w = rect.right - rect.left;
         h = rect.bottom - rect.top;
         y = rect.top;
         w = rect.right - rect.left;
         h = rect.bottom - rect.top;
-    } 
-    else 
+    }
+    else
     {
         x = y = w = h = 0;
     }
     {
         x = y = w = h = 0;
     }
@@ -148,78 +151,87 @@ wxRect wxRegion::GetBox() const
 // Is region empty?
 bool wxRegion::Empty() const
 {
 // Is region empty?
 bool wxRegion::Empty() const
 {
-    if (!m_refData) return TRUE;
-    return M_REGION.isEmpty();
+    if (!m_refData)
+        return true;
+
+    return (bool)(M_REGION.isEmpty());
 }
 
 //-----------------------------------------------------------------------------
 // Modifications
 //-----------------------------------------------------------------------------
 
 }
 
 //-----------------------------------------------------------------------------
 // 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)
 {
 // 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);
     M_REGION += MGLRect(x, y, x + width, y + height);
-    return TRUE;
+    return true;
 }
 
 bool wxRegion::Union(const wxRegion& region)
 {
 }
 
 bool wxRegion::Union(const wxRegion& region)
 {
-    Unshare();
+    AllocExclusive();
     M_REGION += M_REGION_OF(region);
     M_REGION += M_REGION_OF(region);
-    return TRUE;
+    return true;
 }
 
 // Intersect rectangle or region with this.
 bool wxRegion::Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 {
 }
 
 // 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);
     M_REGION &= MGLRect(x, y, x + width, y + height);
-    return TRUE;
+    return true;
 }
 
 bool wxRegion::Intersect(const wxRegion& region)
 {
 }
 
 bool wxRegion::Intersect(const wxRegion& region)
 {
-    Unshare();
+    AllocExclusive();
     M_REGION &= M_REGION_OF(region);
     M_REGION &= M_REGION_OF(region);
-    return TRUE;
+    return true;
 }
 
 // Subtract rectangle or region from this:
 // Combines the parts of 'this' that are not part of the second region.
 bool wxRegion::Subtract(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 {
 }
 
 // Subtract rectangle or region from this:
 // 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);
     M_REGION -= MGLRect(x, y, x + width, y + height);
-    return TRUE;
+    return true;
 }
 
 bool wxRegion::Subtract(const wxRegion& region)
 {
 }
 
 bool wxRegion::Subtract(const wxRegion& region)
 {
-    Unshare();
+    AllocExclusive();
     M_REGION -= M_REGION_OF(region);
     M_REGION -= M_REGION_OF(region);
-    return TRUE;
+    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)
 {
 }
 
 // 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;
     M_REGION = rg1 - rg2;
     MGLRect rect(x, y, x + width, y + height);
     MGLRegion rg1 = M_REGION + rect,
               rg2 = M_REGION & rect;
     M_REGION = rg1 - rg2;
-    return TRUE;    
+    return true;
 }
 
 bool wxRegion::Xor(const wxRegion& region)
 {
 }
 
 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;
     MGLRegion rg1 = M_REGION + M_REGION_OF(region),
               rg2 = M_REGION & M_REGION_OF(region);
     M_REGION = rg1 - rg2;
-    return TRUE;
+    return true;
 }
 
 
 }
 
 
@@ -253,11 +265,11 @@ wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) c
 
     MGLRect rect(x, y, x + w, y + h);
     MGLRegion rg;
 
     MGLRect rect(x, y, x + w, y + h);
     MGLRegion rg;
-    
+
     // 1) is the rectangle entirely covered by the region?
     rg = MGLRegion(rect) - M_REGION;
     if (rg.isEmpty()) return wxInRegion;
     // 1) is the rectangle entirely covered by the region?
     rg = MGLRegion(rect) - M_REGION;
     if (rg.isEmpty()) return wxInRegion;
-    
+
     // 2) is the rectangle completely outside the region?
     rg = M_REGION & rect; // intersection
     if (rg.isEmpty()) return wxOutRegion;
     // 2) is the rectangle completely outside the region?
     rg = M_REGION & rect; // intersection
     if (rg.isEmpty()) return wxOutRegion;
@@ -273,35 +285,37 @@ wxRegionContain wxRegion::Contains(const wxRect& rect) const
 }
 
 
 }
 
 
+///////////////////////////////////////////////////////////////////////////////
+//                               wxRegionIterator                                 //
+///////////////////////////////////////////////////////////////////////////////
 
 
-void wxRegion::Unshare()
+#if wxUSE_THREADS
+static wxMutex *gs_mutexIterator;
+
+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
  */
 wxRegionIterator::wxRegionIterator() : m_currentNode(NULL)
 {
 
 /*
  * Initialize empty iterator
  */
 wxRegionIterator::wxRegionIterator() : m_currentNode(NULL)
 {
-    m_rects.DeleteContents(TRUE);
+    m_rects.DeleteContents(true);
 }
 
 wxRegionIterator::~wxRegionIterator()
 }
 
 wxRegionIterator::~wxRegionIterator()
@@ -313,23 +327,23 @@ wxRegionIterator::~wxRegionIterator()
  */
 wxRegionIterator::wxRegionIterator(const wxRegion& region)
 {
  */
 wxRegionIterator::wxRegionIterator(const wxRegion& region)
 {
-    m_rects.DeleteContents(TRUE);
+    m_rects.DeleteContents(true);
     Reset(region);
 }
 
 /*
  * Reset iterator for a new /e region.
  */
     Reset(region);
 }
 
 /*
  * Reset iterator for a new /e region.
  */
+
 
 static wxRegionRectList *gs_rectList;
 
 
 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, 
+    gs_rectList->Append(new wxRect(r->left, r->top,
                                    r->right - r->left, r->bottom - r->top));
 }
                                    r->right - r->left, r->bottom - r->top));
 }
+
 void wxRegionIterator::Reset(const wxRegion& region)
 {
     m_currentNode = NULL;
 void wxRegionIterator::Reset(const wxRegion& region)
 {
     m_currentNode = NULL;
@@ -337,10 +351,11 @@ void wxRegionIterator::Reset(const wxRegion& region)
 
     if (!region.Empty())
     {
 
     if (!region.Empty())
     {
-        wxMutexGuiEnter();
+#if wxUSE_THREADS
+        wxMutexLocker lock(*gs_mutexIterator);
+#endif
         gs_rectList = &m_rects;
         M_REGION_OF(region).traverse(wxMGL_region_callback);
         gs_rectList = &m_rects;
         M_REGION_OF(region).traverse(wxMGL_region_callback);
-        wxMutexGuiLeave();
         m_currentNode = m_rects.GetFirst();
     }
 }
         m_currentNode = m_rects.GetFirst();
     }
 }
@@ -396,4 +411,3 @@ wxCoord wxRegionIterator::GetH() const
     else
         return 0;
 }
     else
         return 0;
 }
-