1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "region.h"
15 #include "wx/region.h"
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 class wxRegionRefData
: public wxObjectRefData
28 wxRegionRefData(void);
29 ~wxRegionRefData(void);
37 wxRegionRefData::wxRegionRefData(void)
39 m_region
= (GdkRegion
*) NULL
;
42 wxRegionRefData::~wxRegionRefData(void)
44 if (m_region
) gdk_region_destroy( m_region
);
46 wxNode
*node
= m_rects
.First();
49 wxRect
*r
= (wxRect
*)node
->Data();
55 //-----------------------------------------------------------------------------
57 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
59 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
61 wxRegion::wxRegion( long x
, long y
, long w
, long h
)
63 m_refData
= new wxRegionRefData();
64 GdkRegion
*reg
= gdk_region_new();
70 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
71 gdk_region_destroy( reg
);
72 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
75 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
77 m_refData
= new wxRegionRefData();
78 GdkRegion
*reg
= gdk_region_new();
82 rect
.width
= bottomRight
.x
- rect
.x
;
83 rect
.height
= bottomRight
.y
- rect
.y
;
84 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
85 gdk_region_destroy( reg
);
86 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
89 wxRegion::wxRegion( const wxRect
& rect
)
91 m_refData
= new wxRegionRefData();
92 GdkRegion
*reg
= gdk_region_new();
96 g_rect
.width
= rect
.width
;
97 g_rect
.height
= rect
.height
;
98 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
99 gdk_region_destroy( reg
);
101 wxNode
*node
= M_REGIONDATA
->m_rects
.First();
104 wxRect
*r
= (wxRect
*)node
->Data();
105 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
110 wxRegion::wxRegion(void)
112 m_refData
= new wxRegionRefData();
113 M_REGIONDATA
->m_region
= gdk_region_new();
116 wxRegion::~wxRegion(void)
120 bool wxRegion::operator == ( const wxRegion
& region
)
122 return m_refData
== region
.m_refData
;
125 bool wxRegion::operator != ( const wxRegion
& region
)
127 return m_refData
!= region
.m_refData
;
130 void wxRegion::Clear(void)
133 m_refData
= new wxRegionRefData();
134 M_REGIONDATA
->m_region
= gdk_region_new();
137 bool wxRegion::Union( long x
, long y
, long width
, long height
)
143 rect
.height
= height
;
144 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
145 gdk_region_destroy( M_REGIONDATA
->m_region
);
146 M_REGIONDATA
->m_region
= reg
;
147 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
151 bool wxRegion::Union( const wxRect
& rect
)
156 g_rect
.width
= rect
.width
;
157 g_rect
.height
= rect
.height
;
158 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect
);
159 gdk_region_destroy( M_REGIONDATA
->m_region
);
160 M_REGIONDATA
->m_region
= reg
;
161 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
165 bool wxRegion::Union( const wxRegion
& region
)
167 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
168 gdk_region_destroy( M_REGIONDATA
->m_region
);
169 M_REGIONDATA
->m_region
= reg
;
171 wxNode
*node
= region
.GetRectList()->First();
174 wxRect
*r
= (wxRect
*)node
->Data();
175 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
182 bool wxRegion::Intersect( long x
, long y
, long width
, long height
)
184 wxRegion
reg( x
, y
, width
, height
);
189 bool wxRegion::Intersect( const wxRect
& rect
)
191 wxRegion
reg( rect
);
196 bool wxRegion::Intersect( const wxRegion
& region
)
198 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
199 gdk_region_destroy( M_REGIONDATA
->m_region
);
200 M_REGIONDATA
->m_region
= reg
;
204 bool wxRegion::Subtract( long x
, long y
, long width
, long height
)
206 wxRegion
reg( x
, y
, width
, height
);
211 bool wxRegion::Subtract( const wxRect
& rect
)
213 wxRegion
reg( rect
);
218 bool wxRegion::Subtract( const wxRegion
& region
)
220 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
221 gdk_region_destroy( M_REGIONDATA
->m_region
);
222 M_REGIONDATA
->m_region
= reg
;
226 bool wxRegion::Xor( long x
, long y
, long width
, long height
)
228 wxRegion
reg( x
, y
, width
, height
);
233 bool wxRegion::Xor( const wxRect
& rect
)
235 wxRegion
reg( rect
);
240 bool wxRegion::Xor( const wxRegion
& region
)
242 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
243 gdk_region_destroy( M_REGIONDATA
->m_region
);
244 M_REGIONDATA
->m_region
= reg
;
246 wxNode
*node
= region
.GetRectList()->First();
249 wxRect
*r
= (wxRect
*)node
->Data();
250 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
257 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h
) const
263 wxNode
*node
= GetRectList()->First();
266 wxRect
*r
= (wxRect
*)node
->Data();
267 if (node
== GetRectList()->First())
286 if (r
->width
+r
->x
> x
+w
)
288 w
= r
->x
+ r
->width
- x
;
290 if (r
->height
+r
->y
> y
+h
)
292 h
= r
->y
+ r
->height
- y
;
299 wxRect
wxRegion::GetBox(void) const
305 GetBox( x
, y
, w
, h
);
306 return wxRect( x
, y
, w
, h
);
309 bool wxRegion::Empty(void) const
311 return gdk_region_empty( M_REGIONDATA
->m_region
);
314 wxRegionContain
wxRegion::Contains( long x
, long y
) const
316 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
322 wxRegionContain
wxRegion::Contains( long x
, long y
, long w
, long h
) const
329 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
332 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
333 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
334 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
339 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
341 return Contains( pt
.x
, pt
.y
);
344 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
346 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
349 GdkRegion
*wxRegion::GetRegion(void) const
351 return M_REGIONDATA
->m_region
;
354 wxList
*wxRegion::GetRectList() const
356 return &(M_REGIONDATA
->m_rects
);
359 //-----------------------------------------------------------------------------
361 //-----------------------------------------------------------------------------
363 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
365 wxRegionIterator::wxRegionIterator(void)
370 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
376 void wxRegionIterator::Reset( const wxRegion
& region
)
382 wxRegionIterator::operator bool (void) const
384 return m_current
< m_region
.GetRectList()->Number();
387 bool wxRegionIterator::HaveRects(void) const
389 return m_current
< m_region
.GetRectList()->Number();
392 void wxRegionIterator::operator ++ (void)
394 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
397 void wxRegionIterator::operator ++ (int)
399 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
402 long wxRegionIterator::GetX(void) const
404 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
406 wxRect
*r
= (wxRect
*)node
->Data();
410 long wxRegionIterator::GetY(void) const
412 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
414 wxRect
*r
= (wxRect
*)node
->Data();
418 long wxRegionIterator::GetW(void) const
420 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
422 wxRect
*r
= (wxRect
*)node
->Data();
426 long wxRegionIterator::GetH(void) const
428 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
430 wxRect
*r
= (wxRect
*)node
->Data();