1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:   Region class 
   4 // Author:    Markus Holzem/Julian Smart/AUTHOR 
   5 // Created:   Fri Oct 24 10:46:34 MET 1997 
   7 // Copyright: (c) 1997 Markus Holzem/Julian Smart/AUTHOR 
   8 // Licence:   wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation "region.h" 
  15 #include "wx/region.h" 
  16 #include "wx/gdicmn.h" 
  18         IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
) 
  19         IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
, wxObject
) 
  21 //----------------------------------------------------------------------------- 
  22 // wxRegionRefData implementation 
  23 //----------------------------------------------------------------------------- 
  25 class WXDLLEXPORT wxRegionRefData 
: public wxGDIRefData 
{ 
  32         wxRegionRefData(const wxRegionRefData
& data
) 
  35         CopyRgn( data
.m_macRgn 
, m_macRgn 
) ; 
  40         DisposeRgn( m_macRgn 
) ; 
  45 #define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn) 
  46 #define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn) 
  48 //----------------------------------------------------------------------------- 
  50 //----------------------------------------------------------------------------- 
  53  * Create an empty region. 
  57     m_refData 
= new wxRegionRefData
; 
  60 wxRegion::wxRegion(WXHRGN hRegion 
) 
  62     m_refData 
= new wxRegionRefData
; 
  63     CopyRgn( hRegion 
, M_REGION 
) ; 
  66 wxRegion::wxRegion(long x
, long y
, long w
, long h
) 
  68     m_refData 
= new wxRegionRefData
; 
  69     SetRectRgn( M_REGION 
, x 
, y 
, x
+w 
, y
+h 
) ; 
  72 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
) 
  74     m_refData 
= new wxRegionRefData
; 
  75     SetRectRgn( M_REGION 
, topLeft
.x 
, topLeft
.y 
, bottomRight
.x 
, bottomRight
.y 
) ; 
  78 wxRegion::wxRegion(const wxRect
& rect
) 
  80     m_refData 
= new wxRegionRefData
; 
  81     SetRectRgn( M_REGION 
, rect
.x 
, rect
.y 
, rect
.x
+rect
.width 
, rect
.y
+rect
.height 
) ; 
  89     // m_refData unrefed in ~wxObject 
  92 //----------------------------------------------------------------------------- 
  94 //----------------------------------------------------------------------------- 
  96 //! Clear current region 
  97 void wxRegion::Clear() 
 102 //! Combine rectangle (x, y, w, h) with this. 
 103 bool wxRegion::Combine(long x
, long y
, long width
, long height
, wxRegionOp op
) 
 105         // Don't change shared data 
 108                 m_refData 
= new wxRegionRefData(); 
 110         else if (m_refData
->GetRefCount() > 1)  
 112                 wxRegionRefData
* ref 
= (wxRegionRefData
*)m_refData
; 
 114                 m_refData 
= new wxRegionRefData(*ref
); 
 116     RgnHandle rgn 
= NewRgn() ; 
 117                 SetRectRgn( rgn 
, x 
, y
, x
+width
,y 
+ height 
) ; 
 122             SectRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 125             UnionRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 128              XorRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 131             DiffRgn( M_REGION 
, rgn 
, M_REGION 
) ; 
 135                         CopyRgn( rgn 
,M_REGION 
) ; 
 144 //! Union /e region with this. 
 145 bool wxRegion::Combine(const wxRegion
& region
, wxRegionOp op
) 
 150         // Don't change shared data 
 152                 m_refData 
= new wxRegionRefData(); 
 154         else    if (m_refData
->GetRefCount() > 1)  
 156                 wxRegionRefData
* ref 
= (wxRegionRefData
*)m_refData
; 
 158                 m_refData 
= new wxRegionRefData(*ref
); 
 164             SectRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 167             UnionRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 170              XorRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 173             DiffRgn( M_REGION 
, OTHER_M_REGION(region
) , M_REGION 
) ; 
 177                         CopyRgn( OTHER_M_REGION(region
) ,M_REGION 
) ; 
 184 bool wxRegion::Combine(const wxRect
& rect
, wxRegionOp op
) 
 186     return Combine(rect
.GetLeft(), rect
.GetTop(), rect
.GetWidth(), rect
.GetHeight(), op
); 
 189 //----------------------------------------------------------------------------- 
 190 //# Information on region 
 191 //----------------------------------------------------------------------------- 
 193 // Outer bounds of region 
 194 void wxRegion::GetBox(long& x
, long& y
, long&w
, long &h
) const 
 198                 Rect box 
= (**M_REGION
).rgnBBox 
; 
 201         w 
= box
.right 
- box
.left 
; 
 202         h 
= box
.bottom 
- box
.top 
; 
 210 wxRect 
wxRegion::GetBox() const 
 214     return wxRect(x
, y
, w
, h
); 
 218 bool wxRegion::Empty() const 
 220     return EmptyRgn( M_REGION 
) ; 
 223 const WXHRGN 
wxRegion::GetWXHRGN() const 
 228 //----------------------------------------------------------------------------- 
 230 //----------------------------------------------------------------------------- 
 232 // Does the region contain the point (x,y)? 
 233 wxRegionContain 
wxRegion::Contains(long x
, long y
) const 
 238     // TODO. Return wxInRegion if within region. 
 244 // Does the region contain the point pt? 
 245 wxRegionContain 
wxRegion::Contains(const wxPoint
& pt
) const 
 250     Point p 
= { pt
.y 
, pt
.x 
} ; 
 251     if (PtInRgn( p 
, M_REGION 
) ) 
 257 // Does the region contain the rectangle (x, y, w, h)? 
 258 wxRegionContain 
wxRegion::Contains(long x
, long y
, long w
, long h
) const 
 263     Rect rect 
= { y 
, x 
, y 
+ h 
, x 
+ w 
} ; 
 264     if (RectInRgn( &rect 
, M_REGION 
) ) 
 270 // Does the region contain the rectangle rect 
 271 wxRegionContain 
wxRegion::Contains(const wxRect
& rect
) const 
 280     h 
= rect
.GetHeight(); 
 281     return Contains(x
, y
, w
, h
); 
 284 /////////////////////////////////////////////////////////////////////////////// 
 286 //                                                         wxRegionIterator                                                              // 
 288 /////////////////////////////////////////////////////////////////////////////// 
 291  * Initialize empty iterator 
 293 wxRegionIterator::wxRegionIterator() : m_current(0), m_numRects(0), m_rects(NULL
) 
 297 wxRegionIterator::~wxRegionIterator() 
 304  * Initialize iterator for region 
 306 wxRegionIterator::wxRegionIterator(const wxRegion
& region
) 
 314  * Reset iterator for a new /e region. 
 316 void wxRegionIterator::Reset(const wxRegion
& region
) 
 326         if (m_region
.Empty()) 
 330         // we cannot dissolve it into rects on mac 
 331         m_rects 
= new wxRect
[1]; 
 332         Rect rect 
= (**OTHER_M_REGION( region 
)).rgnBBox 
; 
 333         m_rects
[0].x 
= rect
.left
; 
 334         m_rects
[0].y 
= rect
.top
; 
 335         m_rects
[0].width 
= rect
.right 
- rect
.left
; 
 336         m_rects
[0].height 
= rect
.bottom 
- rect
.top
; 
 342  * Increment iterator. The rectangle returned is the one after the 
 345 void wxRegionIterator::operator ++ () 
 347         if (m_current 
< m_numRects
) 
 352  * Increment iterator. The rectangle returned is the one before the 
 355 void wxRegionIterator::operator ++ (int) 
 357         if (m_current 
< m_numRects
) 
 361 long wxRegionIterator::GetX() const 
 363         if (m_current 
< m_numRects
) 
 364                 return m_rects
[m_current
].x
; 
 368 long wxRegionIterator::GetY() const 
 370         if (m_current 
< m_numRects
) 
 371                 return m_rects
[m_current
].y
; 
 375 long wxRegionIterator::GetW() const 
 377         if (m_current 
< m_numRects
) 
 378                 return m_rects
[m_current
].width 
; 
 382 long wxRegionIterator::GetH() const 
 384         if (m_current 
< m_numRects
) 
 385                 return m_rects
[m_current
].height
;