1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:   Region class 
   4 // Author:    Stefan Csomor 
   5 // Created:   Fri Oct 24 10:46:34 MET 1997 
   7 // Copyright: (c) 1997 Stefan Csomor 
   8 // Licence:   wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "region.h" 
  15 #include "wx/region.h" 
  16 #include "wx/gdicmn.h" 
  17 #include "wx/mac/uma.h" 
  19 #if !USE_SHARED_LIBRARY 
  20     IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
) 
  21     IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
, wxObject
) 
  24 //----------------------------------------------------------------------------- 
  25 // wxRegionRefData implementation 
  26 //----------------------------------------------------------------------------- 
  28 class WXDLLEXPORT wxRegionRefData 
: public wxGDIRefData 
{ 
  35     wxRegionRefData(const wxRegionRefData
& data
) 
  39         CopyRgn( data
.m_macRgn 
, m_macRgn 
) ; 
  44         DisposeRgn( m_macRgn 
) ; 
  49 #define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn) 
  50 #define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn) 
  52 //----------------------------------------------------------------------------- 
  54 //----------------------------------------------------------------------------- 
  57  * Create an empty region. 
  61     m_refData 
= new wxRegionRefData
; 
  64 wxRegion::wxRegion(WXHRGN hRegion 
) 
  66     m_refData 
= new wxRegionRefData
; 
  67     CopyRgn( (RgnHandle
) hRegion 
, (RgnHandle
) M_REGION 
) ; 
  70 wxRegion::wxRegion(long x
, long y
, long w
, long h
) 
  72     m_refData 
= new wxRegionRefData
; 
  73     SetRectRgn( (RgnHandle
) M_REGION 
, x 
, y 
, x
+w 
, y
+h 
) ; 
  76 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
) 
  78     m_refData 
= new wxRegionRefData
; 
  79     SetRectRgn( (RgnHandle
) M_REGION 
, topLeft
.x 
, topLeft
.y 
, bottomRight
.x 
, bottomRight
.y 
) ; 
  82 wxRegion::wxRegion(const wxRect
& rect
) 
  84     m_refData 
= new wxRegionRefData
; 
  85     SetRectRgn( (RgnHandle
) M_REGION 
, rect
.x 
, rect
.y 
, rect
.x
+rect
.width 
, rect
.y
+rect
.height 
) ; 
  93     // m_refData unrefed in ~wxObject 
  96 //----------------------------------------------------------------------------- 
  98 //----------------------------------------------------------------------------- 
 100 //! Clear current region 
 101 void wxRegion::Clear() 
 106 //! Combine rectangle (x, y, w, h) with this. 
 107 bool wxRegion::Combine(long x
, long y
, long width
, long height
, wxRegionOp op
) 
 109     // Don't change shared data 
 112         m_refData 
= new wxRegionRefData(); 
 114     else if (m_refData
->GetRefCount() > 1)  
 116         wxRegionRefData
* ref 
= (wxRegionRefData
*)m_refData
; 
 118         m_refData 
= new wxRegionRefData(*ref
); 
 120     RgnHandle rgn 
= NewRgn() ; 
 121         SetRectRgn( rgn 
, x 
, y
, x
+width
,y 
+ height 
) ; 
 126             SectRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 129             UnionRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 132              XorRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 135             DiffRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 139                    CopyRgn( rgn 
,M_REGION 
) ; 
 148 //! Union /e region with this. 
 149 bool wxRegion::Combine(const wxRegion
& region
, wxRegionOp op
) 
 154     // Don't change shared data 
 156         m_refData 
= new wxRegionRefData(); 
 158     else    if (m_refData
->GetRefCount() > 1)  
 160         wxRegionRefData
* ref 
= (wxRegionRefData
*)m_refData
; 
 162         m_refData 
= new wxRegionRefData(*ref
); 
 168             SectRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 171             UnionRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 174              XorRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 177             DiffRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 181                    CopyRgn( OTHER_M_REGION(region
) ,M_REGION 
) ; 
 188 bool wxRegion::Combine(const wxRect
& rect
, wxRegionOp op
) 
 190     return Combine(rect
.GetLeft(), rect
.GetTop(), rect
.GetWidth(), rect
.GetHeight(), op
); 
 193 //----------------------------------------------------------------------------- 
 194 //# Information on region 
 195 //----------------------------------------------------------------------------- 
 197 // Outer bounds of region 
 198 void wxRegion::GetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
& w
, wxCoord
& h
) const 
 203         GetRegionBounds( M_REGION 
, &box 
) ; 
 206         w 
= box
.right 
- box
.left 
; 
 207         h 
= box
.bottom 
- box
.top 
; 
 215 wxRect 
wxRegion::GetBox() const 
 219     return wxRect(x
, y
, w
, h
); 
 223 bool wxRegion::Empty() const 
 225     return EmptyRgn( M_REGION 
) ; 
 228 const WXHRGN 
wxRegion::GetWXHRGN() const 
 233 //----------------------------------------------------------------------------- 
 235 //----------------------------------------------------------------------------- 
 237 // Does the region contain the point (x,y)? 
 238 wxRegionContain 
wxRegion::Contains(long x
, long y
) const 
 243     // TODO. Return wxInRegion if within region. 
 249 // Does the region contain the point pt? 
 250 wxRegionContain 
wxRegion::Contains(const wxPoint
& pt
) const 
 255     Point p 
= { pt
.y 
, pt
.x 
} ; 
 256     if (PtInRgn( p 
, M_REGION 
) ) 
 262 // Does the region contain the rectangle (x, y, w, h)? 
 263 wxRegionContain 
wxRegion::Contains(long x
, long y
, long w
, long h
) const 
 268     Rect rect 
= { y 
, x 
, y 
+ h 
, x 
+ w 
} ; 
 269     if (RectInRgn( &rect 
, M_REGION 
) ) 
 275 // Does the region contain the rectangle rect 
 276 wxRegionContain 
wxRegion::Contains(const wxRect
& rect
) const 
 285     h 
= rect
.GetHeight(); 
 286     return Contains(x
, y
, w
, h
); 
 289 /////////////////////////////////////////////////////////////////////////////// 
 291 //                               wxRegionIterator                            // 
 293 /////////////////////////////////////////////////////////////////////////////// 
 296  * Initialize empty iterator 
 298 wxRegionIterator::wxRegionIterator() 
 299     : m_current(0), m_numRects(0), m_rects(NULL
) 
 303 wxRegionIterator::~wxRegionIterator() 
 311 wxRegionIterator::wxRegionIterator(const wxRegionIterator
& iterator
) 
 313     , m_current(iterator
.m_current
) 
 317     SetRects(iterator
.m_numRects
, iterator
.m_rects
); 
 320 wxRegionIterator
& wxRegionIterator::operator=(const wxRegionIterator
& iterator
) 
 322     m_current  
= iterator
.m_current
; 
 323     SetRects(iterator
.m_numRects
, iterator
.m_rects
); 
 328  * Set iterator rects for region 
 330 void wxRegionIterator::SetRects(long numRects
, wxRect 
*rects
) 
 339         m_rects 
= new wxRect
[numRects
]; 
 340         for (i 
= 0; i 
< numRects
; i
++) 
 341             m_rects
[i
] = rects
[i
]; 
 343     m_numRects 
= numRects
; 
 347  * Initialize iterator for region 
 349 wxRegionIterator::wxRegionIterator(const wxRegion
& region
) 
 357  * Reset iterator for a new /e region. 
 359 void wxRegionIterator::Reset(const wxRegion
& region
) 
 369     if (m_region
.Empty()) 
 373         // we cannot dissolve it into rects on mac 
 374         m_rects 
= new wxRect
[1]; 
 376         GetRegionBounds( OTHER_M_REGION( region 
) , &rect 
) ; 
 377         m_rects
[0].x 
= rect
.left
; 
 378         m_rects
[0].y 
= rect
.top
; 
 379         m_rects
[0].width 
= rect
.right 
- rect
.left
; 
 380         m_rects
[0].height 
= rect
.bottom 
- rect
.top
; 
 386  * Increment iterator. The rectangle returned is the one after the 
 389 wxRegionIterator
& wxRegionIterator::operator ++ () 
 391     if (m_current 
< m_numRects
) 
 397  * Increment iterator. The rectangle returned is the one before the 
 400 wxRegionIterator 
wxRegionIterator::operator ++ (int) 
 402     wxRegionIterator 
previous(*this); 
 404     if (m_current 
< m_numRects
) 
 410 long wxRegionIterator::GetX() const 
 412     if (m_current 
< m_numRects
) 
 413         return m_rects
[m_current
].x
; 
 417 long wxRegionIterator::GetY() const 
 419     if (m_current 
< m_numRects
) 
 420         return m_rects
[m_current
].y
; 
 424 long wxRegionIterator::GetW() const 
 426     if (m_current 
< m_numRects
) 
 427         return m_rects
[m_current
].width 
; 
 431 long wxRegionIterator::GetH() const 
 433     if (m_current 
< m_numRects
) 
 434         return m_rects
[m_current
].height
;