fix for wxRegion::Intersect

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8435 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-09-28 15:45:41 +00:00
parent 3ab62a0f7f
commit bf4014c8de
4 changed files with 140 additions and 36 deletions

View File

@@ -56,12 +56,10 @@ public:
wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight ); wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight );
wxRegion( const wxRect& rect ); wxRegion( const wxRect& rect );
wxRegion(); wxRegion();
~wxRegion(); virtual ~wxRegion();
inline wxRegion( const wxRegion& r ): wxGDIObject() wxRegion( const wxRegion& r ) { Ref(r); }
{ Ref(r); } wxRegion& operator = ( const wxRegion& r ) { Ref(r); return *this; }
inline wxRegion& operator = ( const wxRegion& r )
{ Ref(r); return (*this); }
bool operator == ( const wxRegion& region ); bool operator == ( const wxRegion& region );
bool operator != ( const wxRegion& region ); bool operator != ( const wxRegion& region );
@@ -99,8 +97,12 @@ public:
wxList *GetRectList() const; wxList *GetRectList() const;
GdkRegion *GetRegion() const; GdkRegion *GetRegion() const;
protected:
// helper of Intersect()
bool IntersectRegionOnly(const wxRegion& reg);
private: private:
DECLARE_DYNAMIC_CLASS(wxRegion); DECLARE_DYNAMIC_CLASS(wxRegion);
}; };
class wxRegionIterator: public wxObject class wxRegionIterator: public wxObject
@@ -124,7 +126,7 @@ public:
wxCoord GetWidth() const { return GetW(); } wxCoord GetWidth() const { return GetW(); }
wxCoord GetH() const; wxCoord GetH() const;
wxCoord GetHeight() const { return GetH(); } wxCoord GetHeight() const { return GetH(); }
wxRect GetRect() const { return wxRect(GetX(), GetY(), GetWidth(), GetHeight()); } wxRect GetRect() const;
private: private:
size_t m_current; size_t m_current;

View File

@@ -56,12 +56,10 @@ public:
wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight ); wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight );
wxRegion( const wxRect& rect ); wxRegion( const wxRect& rect );
wxRegion(); wxRegion();
~wxRegion(); virtual ~wxRegion();
inline wxRegion( const wxRegion& r ): wxGDIObject() wxRegion( const wxRegion& r ) { Ref(r); }
{ Ref(r); } wxRegion& operator = ( const wxRegion& r ) { Ref(r); return *this; }
inline wxRegion& operator = ( const wxRegion& r )
{ Ref(r); return (*this); }
bool operator == ( const wxRegion& region ); bool operator == ( const wxRegion& region );
bool operator != ( const wxRegion& region ); bool operator != ( const wxRegion& region );
@@ -99,8 +97,12 @@ public:
wxList *GetRectList() const; wxList *GetRectList() const;
GdkRegion *GetRegion() const; GdkRegion *GetRegion() const;
protected:
// helper of Intersect()
bool IntersectRegionOnly(const wxRegion& reg);
private: private:
DECLARE_DYNAMIC_CLASS(wxRegion); DECLARE_DYNAMIC_CLASS(wxRegion);
}; };
class wxRegionIterator: public wxObject class wxRegionIterator: public wxObject
@@ -124,7 +126,7 @@ public:
wxCoord GetWidth() const { return GetW(); } wxCoord GetWidth() const { return GetW(); }
wxCoord GetH() const; wxCoord GetH() const;
wxCoord GetHeight() const { return GetH(); } wxCoord GetHeight() const { return GetH(); }
wxRect GetRect() const { return wxRect(GetX(), GetY(), GetWidth(), GetHeight()); } wxRect GetRect() const;
private: private:
size_t m_current; size_t m_current;

View File

@@ -231,6 +231,23 @@ bool wxRegion::Intersect( const wxRect& rect )
return TRUE; 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 ) bool wxRegion::Intersect( const wxRegion& region )
{ {
if (region.IsNull()) if (region.IsNull())
@@ -243,13 +260,36 @@ bool wxRegion::Intersect( const wxRegion& region )
return TRUE; return TRUE;
} }
#ifdef __WXGTK20__ if ( !IntersectRegionOnly(region) )
gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); {
#else GetRectList()->Clear();
GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
gdk_region_destroy( M_REGIONDATA->m_region ); return FALSE;
M_REGIONDATA->m_region = reg; }
#endif
// 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; return TRUE;
} }
@@ -522,4 +562,14 @@ wxCoord wxRegionIterator::GetH() const
return r->height; 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;
}

View File

@@ -231,6 +231,23 @@ bool wxRegion::Intersect( const wxRect& rect )
return TRUE; 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 ) bool wxRegion::Intersect( const wxRegion& region )
{ {
if (region.IsNull()) if (region.IsNull())
@@ -243,13 +260,36 @@ bool wxRegion::Intersect( const wxRegion& region )
return TRUE; return TRUE;
} }
#ifdef __WXGTK20__ if ( !IntersectRegionOnly(region) )
gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() ); {
#else GetRectList()->Clear();
GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
gdk_region_destroy( M_REGIONDATA->m_region ); return FALSE;
M_REGIONDATA->m_region = reg; }
#endif
// 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; return TRUE;
} }
@@ -522,4 +562,14 @@ wxCoord wxRegionIterator::GetH() const
return r->height; 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;
}