X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/32b8ec418aee4e38877d4cb79e2984c766dcc358..8cbc59fe84f046685b873cf58f6c56debe59de1c:/src/mgl/region.cpp diff --git a/src/mgl/region.cpp b/src/mgl/region.cpp index b9a9293ac4..6245737375 100644 --- a/src/mgl/region.cpp +++ b/src/mgl/region.cpp @@ -1,25 +1,26 @@ ///////////////////////////////////////////////////////////////////////////// -// 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$ -// Copyright: (c) 2001 Vaclav Slavik +// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "region.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #include "wx/region.h" -#include "wx/gdicmn.h" + +#ifndef WX_PRECOMP + #include "wx/gdicmn.h" + #include "wx/module.h" +#endif + #include "wx/thread.h" #include @@ -37,18 +38,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) class WXDLLEXPORT wxRegionRefData : public wxGDIRefData { public: - wxRegionRefData() - { - } + wxRegionRefData() {} wxRegionRefData(const wxRegionRefData& data) { m_region = data.m_region; } - ~wxRegionRefData() - { - } + virtual ~wxRegionRefData() {} MGLRegion m_region; }; @@ -60,16 +57,26 @@ public: // wxRegion //----------------------------------------------------------------------------- +wxGDIRefData *wxRegion::CreateGDIRefData() const +{ + return new wxRegionRefData; +} + +wxGDIRefData *wxRegion::CloneGDIRefData(const wxGDIRefData *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) -{ +{ m_refData = new wxRegionRefData; MGLRect rect(x, y, x + w, y + h); M_REGION = rect; @@ -78,14 +85,14 @@ wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) 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; - 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; } @@ -95,6 +102,24 @@ wxRegion::wxRegion(const MGLRegion& region) M_REGION = region; } +wxRegion::wxRegion(size_t n, const wxPoint *points, int WXUNUSED(fillStyle)) +{ + m_refData = new wxRegionRefData; + point_t *pts = new point_t[n]; + + for (size_t i = 0; i < n; i++) + { + pts[i].x = points[i].x; + pts[i].y = points[i].y; + } + + region_t* rgn = MGL_rgnPolygon(n, pts, 1, 0, 0); + + M_REGION = rgn; + + delete [] pts; +} + wxRegion::~wxRegion() { // m_refData unrefed in ~wxObject @@ -120,10 +145,17 @@ void wxRegion::Clear() // Information on region //----------------------------------------------------------------------------- +bool wxRegion::DoIsEqual(const wxRegion& WXUNUSED(region)) const +{ + wxFAIL_MSG( _T("not implemented") ); + + return false; +} + // Outer bounds of region -void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const +bool wxRegion::DoGetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const { - if (m_refData) + if (m_refData) { rect_t rect; rect = M_REGION.getBounds(); @@ -131,95 +163,72 @@ 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; - } - else + + return true; + } + else { x = y = w = h = 0; + return false; } } -wxRect wxRegion::GetBox() const -{ - wxCoord x, y, w, h; - GetBox(x, y, w, h); - return wxRect(x, y, w, h); -} - // Is region empty? -bool wxRegion::Empty() const +bool wxRegion::IsEmpty() const { - if (!m_refData) return TRUE; - return M_REGION.isEmpty(); + if (!m_refData) + return true; + + return (bool)(M_REGION.isEmpty()); } //----------------------------------------------------------------------------- // Modifications //----------------------------------------------------------------------------- -// Union rectangle or region with this. -bool wxRegion::Union(wxCoord x, wxCoord y, wxCoord width, wxCoord height) +bool wxRegion::DoOffset(wxCoord x, wxCoord y) { - Unshare(); - M_REGION += MGLRect(x, y, x + width, y + height); - return TRUE; + AllocExclusive(); + M_REGION.offset(x, y); + return true; } -bool wxRegion::Union(const wxRegion& region) +// Union rectangle or region with this. +bool wxRegion::DoUnionWithRect(const wxRect& r) { - Unshare(); - M_REGION += M_REGION_OF(region); - return TRUE; + AllocExclusive(); + M_REGION += MGLRect(r.x, r.y, r.GetRight() + 1, r.GetHeight() + 1); + return true; } -// Intersect rectangle or region with this. -bool wxRegion::Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height) +bool wxRegion::DoUnionWithRegion(const wxRegion& region) { - Unshare(); - M_REGION &= MGLRect(x, y, x + width, y + height); - return TRUE; + AllocExclusive(); + M_REGION += M_REGION_OF(region); + return true; } -bool wxRegion::Intersect(const wxRegion& region) +bool wxRegion::DoIntersect(const wxRegion& region) { - Unshare(); + AllocExclusive(); 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) +bool wxRegion::DoSubtract(const wxRegion& region) { - Unshare(); - 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(); - 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::DoXor(const wxRegion& region) { - Unshare(); + AllocExclusive(); MGLRegion rg1 = M_REGION + M_REGION_OF(region), rg2 = M_REGION & M_REGION_OF(region); M_REGION = rg1 - rg2; - return TRUE; + return true; } @@ -228,7 +237,7 @@ bool wxRegion::Xor(const wxRegion& region) //----------------------------------------------------------------------------- // Does the region contain the point (x,y)? -wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const +wxRegionContain wxRegion::DoContainsPoint(wxCoord x, wxCoord y) const { if (!m_refData) return wxOutRegion; @@ -239,69 +248,60 @@ wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const return wxOutRegion; } -// Does the region contain the point pt? -wxRegionContain wxRegion::Contains(const wxPoint& pt) const -{ - return Contains(pt.x, pt.y); -} - // Does the region contain the rectangle (x, y, w, h)? -wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const +wxRegionContain wxRegion::DoContainsRect(const wxRect& r) const { if (!m_refData) return wxOutRegion; - MGLRect rect(x, y, x + w, y + h); + MGLRect rect(r.x, r.y, r.GetRight() + 1, r.GetBottom() + 1); MGLRegion rg; - + // 1) is the rectangle entirely covered by the region? rg = MGLRegion(rect) - M_REGION; - if (rg.isEmpty()) return wxInRegion; - + if (rg.isEmpty()) + return wxInRegion; + // 2) is the rectangle completely outside the region? rg = M_REGION & rect; // intersection - if (rg.isEmpty()) return wxOutRegion; + if (rg.isEmpty()) + return wxOutRegion; // 3) neither case happened => it is partially covered: return wxPartRegion; } -// Does the region contain the rectangle rect -wxRegionContain wxRegion::Contains(const wxRect& rect) const -{ - return Contains(rect.x, rect.y, rect.width, rect.height); -} - +/////////////////////////////////////////////////////////////////////////////// +// 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 */ wxRegionIterator::wxRegionIterator() : m_currentNode(NULL) { - m_rects.DeleteContents(TRUE); + m_rects.DeleteContents(true); } wxRegionIterator::~wxRegionIterator() @@ -313,23 +313,23 @@ wxRegionIterator::~wxRegionIterator() */ wxRegionIterator::wxRegionIterator(const wxRegion& region) { - m_rects.DeleteContents(TRUE); + m_rects.DeleteContents(true); Reset(region); } /* * Reset iterator for a new /e region. */ - + 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)); } - + void wxRegionIterator::Reset(const wxRegion& region) { m_currentNode = NULL; @@ -337,10 +337,11 @@ void wxRegionIterator::Reset(const wxRegion& region) if (!region.Empty()) { - wxMutexGuiEnter(); +#if wxUSE_THREADS + wxMutexLocker lock(*gs_mutexIterator); +#endif gs_rectList = &m_rects; M_REGION_OF(region).traverse(wxMGL_region_callback); - wxMutexGuiLeave(); m_currentNode = m_rects.GetFirst(); } } @@ -396,4 +397,3 @@ wxCoord wxRegionIterator::GetH() const else return 0; } -