From bf4014c8de91af92a244c8b17ac6211ad08822bd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 28 Sep 2000 15:45:41 +0000 Subject: [PATCH] fix for wxRegion::Intersect git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8435 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/region.h | 16 +++++---- include/wx/gtk1/region.h | 16 +++++---- src/gtk/region.cpp | 72 ++++++++++++++++++++++++++++++++++------ src/gtk1/region.cpp | 72 ++++++++++++++++++++++++++++++++++------ 4 files changed, 140 insertions(+), 36 deletions(-) diff --git a/include/wx/gtk/region.h b/include/wx/gtk/region.h index 7369192305..f4ef0f25d8 100644 --- a/include/wx/gtk/region.h +++ b/include/wx/gtk/region.h @@ -56,12 +56,10 @@ public: wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight ); wxRegion( const wxRect& rect ); wxRegion(); - ~wxRegion(); + virtual ~wxRegion(); - inline wxRegion( const wxRegion& r ): wxGDIObject() - { Ref(r); } - inline wxRegion& operator = ( const wxRegion& r ) - { Ref(r); return (*this); } + wxRegion( const wxRegion& r ) { Ref(r); } + wxRegion& operator = ( const wxRegion& r ) { Ref(r); return *this; } bool operator == ( const wxRegion& region ); bool operator != ( const wxRegion& region ); @@ -99,8 +97,12 @@ public: wxList *GetRectList() const; GdkRegion *GetRegion() const; +protected: + // helper of Intersect() + bool IntersectRegionOnly(const wxRegion& reg); + private: - DECLARE_DYNAMIC_CLASS(wxRegion); + DECLARE_DYNAMIC_CLASS(wxRegion); }; class wxRegionIterator: public wxObject @@ -124,7 +126,7 @@ public: wxCoord GetWidth() const { return GetW(); } wxCoord GetH() const; wxCoord GetHeight() const { return GetH(); } - wxRect GetRect() const { return wxRect(GetX(), GetY(), GetWidth(), GetHeight()); } + wxRect GetRect() const; private: size_t m_current; diff --git a/include/wx/gtk1/region.h b/include/wx/gtk1/region.h index 7369192305..f4ef0f25d8 100644 --- a/include/wx/gtk1/region.h +++ b/include/wx/gtk1/region.h @@ -56,12 +56,10 @@ public: wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight ); wxRegion( const wxRect& rect ); wxRegion(); - ~wxRegion(); + virtual ~wxRegion(); - inline wxRegion( const wxRegion& r ): wxGDIObject() - { Ref(r); } - inline wxRegion& operator = ( const wxRegion& r ) - { Ref(r); return (*this); } + wxRegion( const wxRegion& r ) { Ref(r); } + wxRegion& operator = ( const wxRegion& r ) { Ref(r); return *this; } bool operator == ( const wxRegion& region ); bool operator != ( const wxRegion& region ); @@ -99,8 +97,12 @@ public: wxList *GetRectList() const; GdkRegion *GetRegion() const; +protected: + // helper of Intersect() + bool IntersectRegionOnly(const wxRegion& reg); + private: - DECLARE_DYNAMIC_CLASS(wxRegion); + DECLARE_DYNAMIC_CLASS(wxRegion); }; class wxRegionIterator: public wxObject @@ -124,7 +126,7 @@ public: wxCoord GetWidth() const { return GetW(); } wxCoord GetH() const; wxCoord GetHeight() const { return GetH(); } - wxRect GetRect() const { return wxRect(GetX(), GetY(), GetWidth(), GetHeight()); } + wxRect GetRect() const; private: size_t m_current; diff --git a/src/gtk/region.cpp b/src/gtk/region.cpp index 9cf22c23eb..687eadf05b 100644 --- a/src/gtk/region.cpp +++ b/src/gtk/region.cpp @@ -164,7 +164,7 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) M_REGIONDATA->m_region = reg; #endif } - + M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) ); return TRUE; @@ -212,7 +212,7 @@ bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } - + wxRegion reg( x, y, width, height ); Intersect( reg ); return TRUE; @@ -225,12 +225,29 @@ bool wxRegion::Intersect( const wxRect& rect ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } - + wxRegion reg( rect ); Intersect( reg ); return TRUE; } +// this helper function just computes the region intersection without updating +// the list of rectangles each region maintaints: this allows us to call it +// from Intersect() itself without going into infinite recursion as we would +// if we called Intersect() itself recursively +bool wxRegion::IntersectRegionOnly(const wxRegion& region) +{ +#ifdef __WXGTK20__ + gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); +#else + GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() ); + gdk_region_destroy( M_REGIONDATA->m_region ); + M_REGIONDATA->m_region = reg; +#endif + + return TRUE; +} + bool wxRegion::Intersect( const wxRegion& region ) { if (region.IsNull()) @@ -242,14 +259,37 @@ bool wxRegion::Intersect( const wxRegion& region ) M_REGIONDATA->m_region = gdk_region_new(); return TRUE; } - -#ifdef __WXGTK20__ - gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); -#else - GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() ); - gdk_region_destroy( M_REGIONDATA->m_region ); - M_REGIONDATA->m_region = reg; -#endif + + if ( !IntersectRegionOnly(region) ) + { + GetRectList()->Clear(); + + return FALSE; + } + + // we need to update the rect list as well + wxList& list = *GetRectList(); + wxNode *node = list.First(); + while (node) + { + wxRect *r = (wxRect*)node->Data(); + + wxRegion regCopy = region; + if ( regCopy.IntersectRegionOnly(*r) ) + { + // replace the node with the intersection + *r = regCopy.GetBox(); + } + else + { + // TODO remove the rect from the list + r->width = 0; + r->height = 0; + } + + node = node->Next(); + } + return TRUE; } @@ -522,4 +562,14 @@ wxCoord wxRegionIterator::GetH() const return r->height; } +wxRect wxRegionIterator::GetRect() const +{ + wxRect r; + wxNode *node = m_region.GetRectList()->Nth( m_current ); + + if (node) + r = *((wxRect*)node->Data()); + + return r; +} diff --git a/src/gtk1/region.cpp b/src/gtk1/region.cpp index 9cf22c23eb..687eadf05b 100644 --- a/src/gtk1/region.cpp +++ b/src/gtk1/region.cpp @@ -164,7 +164,7 @@ bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) M_REGIONDATA->m_region = reg; #endif } - + M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) ); return TRUE; @@ -212,7 +212,7 @@ bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } - + wxRegion reg( x, y, width, height ); Intersect( reg ); return TRUE; @@ -225,12 +225,29 @@ bool wxRegion::Intersect( const wxRect& rect ) m_refData = new wxRegionRefData(); M_REGIONDATA->m_region = gdk_region_new(); } - + wxRegion reg( rect ); Intersect( reg ); return TRUE; } +// this helper function just computes the region intersection without updating +// the list of rectangles each region maintaints: this allows us to call it +// from Intersect() itself without going into infinite recursion as we would +// if we called Intersect() itself recursively +bool wxRegion::IntersectRegionOnly(const wxRegion& region) +{ +#ifdef __WXGTK20__ + gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); +#else + GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() ); + gdk_region_destroy( M_REGIONDATA->m_region ); + M_REGIONDATA->m_region = reg; +#endif + + return TRUE; +} + bool wxRegion::Intersect( const wxRegion& region ) { if (region.IsNull()) @@ -242,14 +259,37 @@ bool wxRegion::Intersect( const wxRegion& region ) M_REGIONDATA->m_region = gdk_region_new(); return TRUE; } - -#ifdef __WXGTK20__ - gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); -#else - GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() ); - gdk_region_destroy( M_REGIONDATA->m_region ); - M_REGIONDATA->m_region = reg; -#endif + + if ( !IntersectRegionOnly(region) ) + { + GetRectList()->Clear(); + + return FALSE; + } + + // we need to update the rect list as well + wxList& list = *GetRectList(); + wxNode *node = list.First(); + while (node) + { + wxRect *r = (wxRect*)node->Data(); + + wxRegion regCopy = region; + if ( regCopy.IntersectRegionOnly(*r) ) + { + // replace the node with the intersection + *r = regCopy.GetBox(); + } + else + { + // TODO remove the rect from the list + r->width = 0; + r->height = 0; + } + + node = node->Next(); + } + return TRUE; } @@ -522,4 +562,14 @@ wxCoord wxRegionIterator::GetH() const return r->height; } +wxRect wxRegionIterator::GetRect() const +{ + wxRect r; + wxNode *node = m_region.GetRectList()->Nth( m_current ); + + if (node) + r = *((wxRect*)node->Data()); + + return r; +}