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"
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
)
38 CopyRgn( data
.m_macRgn
, m_macRgn
) ;
43 DisposeRgn( m_macRgn
) ;
48 #define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn)
49 #define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn)
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
56 * Create an empty region.
60 m_refData
= new wxRegionRefData
;
63 wxRegion::wxRegion(WXHRGN hRegion
)
65 m_refData
= new wxRegionRefData
;
66 CopyRgn( hRegion
, M_REGION
) ;
69 wxRegion::wxRegion(long x
, long y
, long w
, long h
)
71 m_refData
= new wxRegionRefData
;
72 SetRectRgn( M_REGION
, x
, y
, x
+w
, y
+h
) ;
75 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
77 m_refData
= new wxRegionRefData
;
78 SetRectRgn( M_REGION
, topLeft
.x
, topLeft
.y
, bottomRight
.x
, bottomRight
.y
) ;
81 wxRegion::wxRegion(const wxRect
& rect
)
83 m_refData
= new wxRegionRefData
;
84 SetRectRgn( M_REGION
, rect
.x
, rect
.y
, rect
.x
+rect
.width
, rect
.y
+rect
.height
) ;
92 // m_refData unrefed in ~wxObject
95 //-----------------------------------------------------------------------------
97 //-----------------------------------------------------------------------------
99 //! Clear current region
100 void wxRegion::Clear()
105 //! Combine rectangle (x, y, w, h) with this.
106 bool wxRegion::Combine(long x
, long y
, long width
, long height
, wxRegionOp op
)
108 // Don't change shared data
111 m_refData
= new wxRegionRefData();
113 else if (m_refData
->GetRefCount() > 1)
115 wxRegionRefData
* ref
= (wxRegionRefData
*)m_refData
;
117 m_refData
= new wxRegionRefData(*ref
);
119 RgnHandle rgn
= NewRgn() ;
120 SetRectRgn( rgn
, x
, y
, x
+width
,y
+ height
) ;
125 SectRgn( M_REGION
, rgn
, M_REGION
) ;
128 UnionRgn( M_REGION
, rgn
, M_REGION
) ;
131 XorRgn( M_REGION
, rgn
, M_REGION
) ;
134 DiffRgn( M_REGION
, rgn
, M_REGION
) ;
138 CopyRgn( rgn
,M_REGION
) ;
147 //! Union /e region with this.
148 bool wxRegion::Combine(const wxRegion
& region
, wxRegionOp op
)
153 // Don't change shared data
155 m_refData
= new wxRegionRefData();
157 else if (m_refData
->GetRefCount() > 1)
159 wxRegionRefData
* ref
= (wxRegionRefData
*)m_refData
;
161 m_refData
= new wxRegionRefData(*ref
);
167 SectRgn( M_REGION
, OTHER_M_REGION(region
) , M_REGION
) ;
170 UnionRgn( M_REGION
, OTHER_M_REGION(region
) , M_REGION
) ;
173 XorRgn( M_REGION
, OTHER_M_REGION(region
) , M_REGION
) ;
176 DiffRgn( M_REGION
, OTHER_M_REGION(region
) , M_REGION
) ;
180 CopyRgn( OTHER_M_REGION(region
) ,M_REGION
) ;
187 bool wxRegion::Combine(const wxRect
& rect
, wxRegionOp op
)
189 return Combine(rect
.GetLeft(), rect
.GetTop(), rect
.GetWidth(), rect
.GetHeight(), op
);
192 //-----------------------------------------------------------------------------
193 //# Information on region
194 //-----------------------------------------------------------------------------
196 // Outer bounds of region
197 void wxRegion::GetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
& w
, wxCoord
& h
) const
202 GetRegionBounds( M_REGION
, &box
) ;
205 w
= box
.right
- box
.left
;
206 h
= box
.bottom
- box
.top
;
214 wxRect
wxRegion::GetBox() const
218 return wxRect(x
, y
, w
, h
);
222 bool wxRegion::Empty() const
224 return EmptyRgn( M_REGION
) ;
227 const WXHRGN
wxRegion::GetWXHRGN() const
232 //-----------------------------------------------------------------------------
234 //-----------------------------------------------------------------------------
236 // Does the region contain the point (x,y)?
237 wxRegionContain
wxRegion::Contains(long x
, long y
) const
242 // TODO. Return wxInRegion if within region.
248 // Does the region contain the point pt?
249 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
254 Point p
= { pt
.y
, pt
.x
} ;
255 if (PtInRgn( p
, M_REGION
) )
261 // Does the region contain the rectangle (x, y, w, h)?
262 wxRegionContain
wxRegion::Contains(long x
, long y
, long w
, long h
) const
267 Rect rect
= { y
, x
, y
+ h
, x
+ w
} ;
268 if (RectInRgn( &rect
, M_REGION
) )
274 // Does the region contain the rectangle rect
275 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
284 h
= rect
.GetHeight();
285 return Contains(x
, y
, w
, h
);
288 ///////////////////////////////////////////////////////////////////////////////
290 // wxRegionIterator //
292 ///////////////////////////////////////////////////////////////////////////////
295 * Initialize empty iterator
297 wxRegionIterator::wxRegionIterator() : m_current(0), m_numRects(0), m_rects(NULL
)
301 wxRegionIterator::~wxRegionIterator()
308 * Initialize iterator for region
310 wxRegionIterator::wxRegionIterator(const wxRegion
& region
)
318 * Reset iterator for a new /e region.
320 void wxRegionIterator::Reset(const wxRegion
& region
)
330 if (m_region
.Empty())
334 // we cannot dissolve it into rects on mac
335 m_rects
= new wxRect
[1];
337 GetRegionBounds( OTHER_M_REGION( region
) , &rect
) ;
338 m_rects
[0].x
= rect
.left
;
339 m_rects
[0].y
= rect
.top
;
340 m_rects
[0].width
= rect
.right
- rect
.left
;
341 m_rects
[0].height
= rect
.bottom
- rect
.top
;
347 * Increment iterator. The rectangle returned is the one after the
350 void wxRegionIterator::operator ++ ()
352 if (m_current
< m_numRects
)
357 * Increment iterator. The rectangle returned is the one before the
360 void wxRegionIterator::operator ++ (int)
362 if (m_current
< m_numRects
)
366 long wxRegionIterator::GetX() const
368 if (m_current
< m_numRects
)
369 return m_rects
[m_current
].x
;
373 long wxRegionIterator::GetY() const
375 if (m_current
< m_numRects
)
376 return m_rects
[m_current
].y
;
380 long wxRegionIterator::GetW() const
382 if (m_current
< m_numRects
)
383 return m_rects
[m_current
].width
;
387 long wxRegionIterator::GetH() const
389 if (m_current
< m_numRects
)
390 return m_rects
[m_current
].height
;