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
;