1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  11 #pragma implementation "region.h" 
  14 #include "wx/region.h" 
  23 #define NULL ((void*)0L) 
  26 //----------------------------------------------------------------------------- 
  28 //----------------------------------------------------------------------------- 
  30 class wxRegionRefData
: public wxObjectRefData
 
  43 wxRegionRefData::wxRegionRefData() 
  45     m_region 
= (GdkRegion 
*) NULL
; 
  48 wxRegionRefData::~wxRegionRefData() 
  50     if (m_region
) gdk_region_destroy( m_region 
); 
  52     wxNode 
*node 
= m_rects
.First(); 
  55         wxRect 
*r 
= (wxRect
*)node
->Data(); 
  61 //----------------------------------------------------------------------------- 
  63 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  65 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
); 
  67 wxRegion::wxRegion( long x
, long y
, long w
, long h 
) 
  69     m_refData 
= new wxRegionRefData(); 
  70     GdkRegion 
*reg 
= gdk_region_new(); 
  76     M_REGIONDATA
->m_region 
= gdk_region_union_with_rect( reg
, &rect 
); 
  77     gdk_region_destroy( reg 
); 
  78     M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) ); 
  81 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight 
) 
  83     m_refData 
= new wxRegionRefData(); 
  84     GdkRegion 
*reg 
= gdk_region_new(); 
  88     rect
.width 
= bottomRight
.x 
- rect
.x
; 
  89     rect
.height 
= bottomRight
.y 
- rect
.y
; 
  90     M_REGIONDATA
->m_region 
= gdk_region_union_with_rect( reg
, &rect 
); 
  91     gdk_region_destroy( reg 
); 
  92     M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) ); 
  95 wxRegion::wxRegion( const wxRect
& rect 
) 
  97     m_refData 
= new wxRegionRefData(); 
  98     GdkRegion 
*reg 
= gdk_region_new(); 
 102     g_rect
.width 
= rect
.width
; 
 103     g_rect
.height 
= rect
.height
; 
 104     M_REGIONDATA
->m_region 
= gdk_region_union_with_rect( reg
, &g_rect 
); 
 105     gdk_region_destroy( reg 
); 
 107     wxNode 
*node 
= M_REGIONDATA
->m_rects
.First(); 
 110         wxRect 
*r 
= (wxRect
*)node
->Data(); 
 111         M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) ); 
 118     m_refData 
= new wxRegionRefData(); 
 119     M_REGIONDATA
->m_region 
= gdk_region_new(); 
 122 wxRegion::~wxRegion() 
 126 bool wxRegion::operator == ( const wxRegion
& region 
) 
 128     return m_refData 
== region
.m_refData
;  
 131 bool wxRegion::operator != ( const wxRegion
& region 
) 
 133     return m_refData 
!= region
.m_refData
;  
 136 void wxRegion::Clear() 
 139     m_refData 
= new wxRegionRefData(); 
 140     M_REGIONDATA
->m_region 
= gdk_region_new(); 
 143 bool wxRegion::Union( long x
, long y
, long width
, long height 
) 
 149     rect
.height 
= height
; 
 150     GdkRegion 
*reg 
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect 
); 
 151     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 152     M_REGIONDATA
->m_region 
= reg
; 
 153     M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) ); 
 157 bool wxRegion::Union( const wxRect
& rect 
) 
 162     g_rect
.width 
= rect
.width
; 
 163     g_rect
.height 
= rect
.height
; 
 164     GdkRegion 
*reg 
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect 
); 
 165     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 166     M_REGIONDATA
->m_region 
= reg
; 
 167     M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) ); 
 171 bool wxRegion::Union( const wxRegion
& region 
) 
 173     GdkRegion 
*reg 
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 174     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 175     M_REGIONDATA
->m_region 
= reg
; 
 177     wxNode 
*node 
= region
.GetRectList()->First(); 
 180         wxRect 
*r 
= (wxRect
*)node
->Data(); 
 181         M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) ); 
 188 bool wxRegion::Intersect( long x
, long y
, long width
, long height 
) 
 190     wxRegion 
reg( x
, y
, width
, height 
); 
 195 bool wxRegion::Intersect( const wxRect
& rect 
) 
 197     wxRegion 
reg( rect 
); 
 202 bool wxRegion::Intersect( const wxRegion
& region 
) 
 204     GdkRegion 
*reg 
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 205     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 206     M_REGIONDATA
->m_region 
= reg
; 
 210 bool wxRegion::Subtract( long x
, long y
, long width
, long height 
) 
 212     wxRegion 
reg( x
, y
, width
, height 
); 
 217 bool wxRegion::Subtract( const wxRect
& rect 
) 
 219     wxRegion 
reg( rect 
); 
 224 bool wxRegion::Subtract( const wxRegion
& region 
) 
 226     GdkRegion 
*reg 
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 227     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 228     M_REGIONDATA
->m_region 
= reg
; 
 232 bool wxRegion::Xor( long x
, long y
, long width
, long height 
) 
 234     wxRegion 
reg( x
, y
, width
, height 
); 
 239 bool wxRegion::Xor( const wxRect
& rect 
) 
 241     wxRegion 
reg( rect 
); 
 246 bool wxRegion::Xor( const wxRegion
& region 
) 
 248     GdkRegion 
*reg 
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 249     gdk_region_destroy( M_REGIONDATA
->m_region 
); 
 250     M_REGIONDATA
->m_region 
= reg
; 
 252     wxNode 
*node 
= region
.GetRectList()->First(); 
 255         wxRect 
*r 
= (wxRect
*)node
->Data(); 
 256         M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) ); 
 263 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h 
) const 
 269     wxNode 
*node 
= GetRectList()->First(); 
 272         wxRect 
*r 
= (wxRect
*)node
->Data(); 
 273         if (node 
== GetRectList()->First()) 
 292             if (r
->width
+r
->x 
> x
+w
)  
 294                 w 
= r
->x 
+ r
->width 
- x
; 
 296             if (r
->height
+r
->y 
> y
+h
)  
 298                 h 
= r
->y 
+ r
->height 
- y
; 
 305 wxRect 
wxRegion::GetBox() const 
 311     GetBox( x
, y
, w
, h 
); 
 312     return wxRect( x
, y
, w
, h 
); 
 315 bool wxRegion::Empty() const 
 317     return gdk_region_empty( M_REGIONDATA
->m_region 
); 
 320 wxRegionContain 
wxRegion::Contains( long x
, long y 
) const 
 322     if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y 
)) 
 328 wxRegionContain 
wxRegion::Contains( long x
, long y
, long w
, long h 
) const 
 335     GdkOverlapType res 
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect 
); 
 338         case GDK_OVERLAP_RECTANGLE_IN
:   return wxInRegion
; 
 339         case GDK_OVERLAP_RECTANGLE_OUT
:  return wxOutRegion
; 
 340         case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
; 
 345 wxRegionContain 
wxRegion::Contains(const wxPoint
& pt
) const 
 347     return Contains( pt
.x
, pt
.y 
); 
 350 wxRegionContain 
wxRegion::Contains(const wxRect
& rect
) const 
 352     return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 355 GdkRegion 
*wxRegion::GetRegion() const 
 357     return M_REGIONDATA
->m_region
; 
 360 wxList 
*wxRegion::GetRectList() const 
 362     return &(M_REGIONDATA
->m_rects
); 
 365 //----------------------------------------------------------------------------- 
 367 //----------------------------------------------------------------------------- 
 369 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
); 
 371 wxRegionIterator::wxRegionIterator() 
 376 wxRegionIterator::wxRegionIterator( const wxRegion
& region 
) 
 382 void wxRegionIterator::Reset( const wxRegion
& region 
) 
 388 wxRegionIterator::operator bool () const  
 390     return m_current 
< m_region
.GetRectList()->Number();  
 393 bool wxRegionIterator::HaveRects() const  
 395     return m_current 
< m_region
.GetRectList()->Number();  
 398 void wxRegionIterator::operator ++ () 
 400     if (m_current 
< m_region
.GetRectList()->Number()) ++m_current
; 
 403 void wxRegionIterator::operator ++ (int) 
 405     if (m_current 
< m_region
.GetRectList()->Number()) ++m_current
; 
 408 wxCoord 
wxRegionIterator::GetX() const 
 410     wxNode 
*node 
= m_region
.GetRectList()->Nth( m_current 
); 
 412     wxRect 
*r 
= (wxRect
*)node
->Data(); 
 416 wxCoord 
wxRegionIterator::GetY() const 
 418     wxNode 
*node 
= m_region
.GetRectList()->Nth( m_current 
); 
 420     wxRect 
*r 
= (wxRect
*)node
->Data(); 
 424 wxCoord 
wxRegionIterator::GetW() const 
 426     wxNode 
*node 
= m_region
.GetRectList()->Nth( m_current 
); 
 428     wxRect 
*r 
= (wxRect
*)node
->Data(); 
 432 wxCoord 
wxRegionIterator::GetH() const 
 434     wxNode 
*node 
= m_region
.GetRectList()->Nth( m_current 
); 
 436     wxRect 
*r 
= (wxRect
*)node
->Data();