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"
19 //-----------------------------------------------------------------------------
21 //-----------------------------------------------------------------------------
23 class wxRegionRefData
: public wxObjectRefData
36 wxRegionRefData::wxRegionRefData()
38 m_region
= (GdkRegion
*) NULL
;
41 wxRegionRefData::~wxRegionRefData()
43 if (m_region
) gdk_region_destroy( m_region
);
45 wxNode
*node
= m_rects
.First();
48 wxRect
*r
= (wxRect
*)node
->Data();
54 //-----------------------------------------------------------------------------
56 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
58 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
60 wxRegion::wxRegion( long x
, long y
, long w
, long h
)
62 m_refData
= new wxRegionRefData();
63 GdkRegion
*reg
= gdk_region_new();
69 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
70 gdk_region_destroy( reg
);
71 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
74 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
76 m_refData
= new wxRegionRefData();
77 GdkRegion
*reg
= gdk_region_new();
81 rect
.width
= bottomRight
.x
- rect
.x
;
82 rect
.height
= bottomRight
.y
- rect
.y
;
83 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
84 gdk_region_destroy( reg
);
85 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
88 wxRegion::wxRegion( const wxRect
& rect
)
90 m_refData
= new wxRegionRefData();
91 GdkRegion
*reg
= gdk_region_new();
95 g_rect
.width
= rect
.width
;
96 g_rect
.height
= rect
.height
;
97 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
98 gdk_region_destroy( reg
);
100 wxNode
*node
= M_REGIONDATA
->m_rects
.First();
103 wxRect
*r
= (wxRect
*)node
->Data();
104 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
111 m_refData
= new wxRegionRefData();
112 M_REGIONDATA
->m_region
= gdk_region_new();
115 wxRegion::~wxRegion()
119 bool wxRegion::operator == ( const wxRegion
& region
)
121 return m_refData
== region
.m_refData
;
124 bool wxRegion::operator != ( const wxRegion
& region
)
126 return m_refData
!= region
.m_refData
;
129 void wxRegion::Clear()
132 m_refData
= new wxRegionRefData();
133 M_REGIONDATA
->m_region
= gdk_region_new();
136 bool wxRegion::Union( long x
, long y
, long width
, long height
)
142 rect
.height
= height
;
143 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
144 gdk_region_destroy( M_REGIONDATA
->m_region
);
145 M_REGIONDATA
->m_region
= reg
;
146 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
150 bool wxRegion::Union( const wxRect
& rect
)
155 g_rect
.width
= rect
.width
;
156 g_rect
.height
= rect
.height
;
157 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect
);
158 gdk_region_destroy( M_REGIONDATA
->m_region
);
159 M_REGIONDATA
->m_region
= reg
;
160 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
164 bool wxRegion::Union( const wxRegion
& region
)
166 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
167 gdk_region_destroy( M_REGIONDATA
->m_region
);
168 M_REGIONDATA
->m_region
= reg
;
170 wxNode
*node
= region
.GetRectList()->First();
173 wxRect
*r
= (wxRect
*)node
->Data();
174 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
181 bool wxRegion::Intersect( long x
, long y
, long width
, long height
)
183 wxRegion
reg( x
, y
, width
, height
);
188 bool wxRegion::Intersect( const wxRect
& rect
)
190 wxRegion
reg( rect
);
195 bool wxRegion::Intersect( const wxRegion
& region
)
197 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
198 gdk_region_destroy( M_REGIONDATA
->m_region
);
199 M_REGIONDATA
->m_region
= reg
;
203 bool wxRegion::Subtract( long x
, long y
, long width
, long height
)
205 wxRegion
reg( x
, y
, width
, height
);
210 bool wxRegion::Subtract( const wxRect
& rect
)
212 wxRegion
reg( rect
);
217 bool wxRegion::Subtract( const wxRegion
& region
)
219 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
220 gdk_region_destroy( M_REGIONDATA
->m_region
);
221 M_REGIONDATA
->m_region
= reg
;
225 bool wxRegion::Xor( long x
, long y
, long width
, long height
)
227 wxRegion
reg( x
, y
, width
, height
);
232 bool wxRegion::Xor( const wxRect
& rect
)
234 wxRegion
reg( rect
);
239 bool wxRegion::Xor( const wxRegion
& region
)
241 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
242 gdk_region_destroy( M_REGIONDATA
->m_region
);
243 M_REGIONDATA
->m_region
= reg
;
245 wxNode
*node
= region
.GetRectList()->First();
248 wxRect
*r
= (wxRect
*)node
->Data();
249 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
256 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h
) const
262 wxNode
*node
= GetRectList()->First();
265 wxRect
*r
= (wxRect
*)node
->Data();
266 if (node
== GetRectList()->First())
285 if (r
->width
+r
->x
> x
+w
)
287 w
= r
->x
+ r
->width
- x
;
289 if (r
->height
+r
->y
> y
+h
)
291 h
= r
->y
+ r
->height
- y
;
298 wxRect
wxRegion::GetBox() const
304 GetBox( x
, y
, w
, h
);
305 return wxRect( x
, y
, w
, h
);
308 bool wxRegion::Empty() const
310 return gdk_region_empty( M_REGIONDATA
->m_region
);
313 wxRegionContain
wxRegion::Contains( long x
, long y
) const
315 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
321 wxRegionContain
wxRegion::Contains( long x
, long y
, long w
, long h
) const
328 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
331 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
332 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
333 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
338 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
340 return Contains( pt
.x
, pt
.y
);
343 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
345 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
348 GdkRegion
*wxRegion::GetRegion() const
350 return M_REGIONDATA
->m_region
;
353 wxList
*wxRegion::GetRectList() const
355 return &(M_REGIONDATA
->m_rects
);
358 //-----------------------------------------------------------------------------
360 //-----------------------------------------------------------------------------
362 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
364 wxRegionIterator::wxRegionIterator()
369 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
375 void wxRegionIterator::Reset( const wxRegion
& region
)
381 wxRegionIterator::operator bool () const
383 return m_current
< m_region
.GetRectList()->Number();
386 bool wxRegionIterator::HaveRects() const
388 return m_current
< m_region
.GetRectList()->Number();
391 void wxRegionIterator::operator ++ ()
393 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
396 void wxRegionIterator::operator ++ (int)
398 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
401 wxCoord
wxRegionIterator::GetX() const
403 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
405 wxRect
*r
= (wxRect
*)node
->Data();
409 wxCoord
wxRegionIterator::GetY() const
411 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
413 wxRect
*r
= (wxRect
*)node
->Data();
417 wxCoord
wxRegionIterator::GetW() const
419 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
421 wxRect
*r
= (wxRect
*)node
->Data();
425 wxCoord
wxRegionIterator::GetH() const
427 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
429 wxRect
*r
= (wxRect
*)node
->Data();