1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "region.h"
16 #include "wx/region.h"
18 //-----------------------------------------------------------------------------
20 //-----------------------------------------------------------------------------
22 class wxRegionRefData
: public wxObjectRefData
26 wxRegionRefData(void);
27 ~wxRegionRefData(void);
35 wxRegionRefData::wxRegionRefData(void)
37 m_region
= (GdkRegion
*) NULL
;
40 wxRegionRefData::~wxRegionRefData(void)
42 if (m_region
) gdk_region_destroy( m_region
);
44 wxNode
*node
= m_rects
.First();
47 wxRect
*r
= (wxRect
*)node
->Data();
53 //-----------------------------------------------------------------------------
55 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
57 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
59 wxRegion::wxRegion( long x
, long y
, long w
, long h
)
61 m_refData
= new wxRegionRefData();
62 GdkRegion
*reg
= gdk_region_new();
68 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
69 gdk_region_destroy( reg
);
70 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
73 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
75 m_refData
= new wxRegionRefData();
76 GdkRegion
*reg
= gdk_region_new();
80 rect
.width
= bottomRight
.x
- rect
.x
;
81 rect
.height
= bottomRight
.y
- rect
.y
;
82 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
83 gdk_region_destroy( reg
);
84 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
87 wxRegion::wxRegion( const wxRect
& rect
)
89 m_refData
= new wxRegionRefData();
90 GdkRegion
*reg
= gdk_region_new();
94 g_rect
.width
= rect
.width
;
95 g_rect
.height
= rect
.height
;
96 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
97 gdk_region_destroy( reg
);
99 wxNode
*node
= M_REGIONDATA
->m_rects
.First();
102 wxRect
*r
= (wxRect
*)node
->Data();
103 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
108 wxRegion::wxRegion(void)
110 m_refData
= new wxRegionRefData();
111 M_REGIONDATA
->m_region
= gdk_region_new();
114 wxRegion::~wxRegion(void)
118 void wxRegion::Clear(void)
121 m_refData
= new wxRegionRefData();
122 M_REGIONDATA
->m_region
= gdk_region_new();
125 bool wxRegion::Union( long x
, long y
, long width
, long height
)
131 rect
.height
= height
;
132 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
133 gdk_region_destroy( M_REGIONDATA
->m_region
);
134 M_REGIONDATA
->m_region
= reg
;
135 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
139 bool wxRegion::Union( const wxRect
& rect
)
144 g_rect
.width
= rect
.width
;
145 g_rect
.height
= rect
.height
;
146 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect
);
147 gdk_region_destroy( M_REGIONDATA
->m_region
);
148 M_REGIONDATA
->m_region
= reg
;
149 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
153 bool wxRegion::Union( const wxRegion
& region
)
155 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
156 gdk_region_destroy( M_REGIONDATA
->m_region
);
157 M_REGIONDATA
->m_region
= reg
;
159 wxNode
*node
= region
.GetRectList()->First();
162 wxRect
*r
= (wxRect
*)node
->Data();
163 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
170 bool wxRegion::Intersect( long x
, long y
, long width
, long height
)
172 wxRegion
reg( x
, y
, width
, height
);
177 bool wxRegion::Intersect( const wxRect
& rect
)
179 wxRegion
reg( rect
);
184 bool wxRegion::Intersect( const wxRegion
& region
)
186 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
187 gdk_region_destroy( M_REGIONDATA
->m_region
);
188 M_REGIONDATA
->m_region
= reg
;
192 bool wxRegion::Subtract( long x
, long y
, long width
, long height
)
194 wxRegion
reg( x
, y
, width
, height
);
199 bool wxRegion::Subtract( const wxRect
& rect
)
201 wxRegion
reg( rect
);
206 bool wxRegion::Subtract( const wxRegion
& region
)
208 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
209 gdk_region_destroy( M_REGIONDATA
->m_region
);
210 M_REGIONDATA
->m_region
= reg
;
214 bool wxRegion::Xor( long x
, long y
, long width
, long height
)
216 wxRegion
reg( x
, y
, width
, height
);
221 bool wxRegion::Xor( const wxRect
& rect
)
223 wxRegion
reg( rect
);
228 bool wxRegion::Xor( const wxRegion
& region
)
230 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
231 gdk_region_destroy( M_REGIONDATA
->m_region
);
232 M_REGIONDATA
->m_region
= reg
;
234 wxNode
*node
= region
.GetRectList()->First();
237 wxRect
*r
= (wxRect
*)node
->Data();
238 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
245 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h
) const
251 wxNode
*node
= GetRectList()->First();
254 wxRect
*r
= (wxRect
*)node
->Data();
255 if (node
== GetRectList()->First())
274 if (r
->width
+r
->x
> x
+w
)
276 w
= r
->x
+ r
->width
- x
;
278 if (r
->height
+r
->y
> y
+h
)
280 h
= r
->y
+ r
->height
- y
;
287 wxRect
wxRegion::GetBox(void) const
293 GetBox( x
, y
, w
, h
);
294 return wxRect( x
, y
, w
, h
);
297 bool wxRegion::Empty(void) const
299 return gdk_region_empty( M_REGIONDATA
->m_region
);
302 wxRegionContain
wxRegion::Contains( long x
, long y
) const
304 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
310 wxRegionContain
wxRegion::Contains( long x
, long y
, long w
, long h
) const
317 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
320 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
321 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
322 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
327 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
329 return Contains( pt
.x
, pt
.y
);
332 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
334 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
337 GdkRegion
*wxRegion::GetRegion(void) const
339 return M_REGIONDATA
->m_region
;
342 wxList
*wxRegion::GetRectList() const
344 return &(M_REGIONDATA
->m_rects
);
347 //-----------------------------------------------------------------------------
349 //-----------------------------------------------------------------------------
351 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
353 wxRegionIterator::wxRegionIterator(void)
358 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
364 void wxRegionIterator::Reset( const wxRegion
& region
)
370 wxRegionIterator::operator bool (void) const
372 return m_current
< m_region
.GetRectList()->Number();
375 bool wxRegionIterator::HaveRects(void) const
377 return m_current
< m_region
.GetRectList()->Number();
380 void wxRegionIterator::operator ++ (void)
382 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
385 void wxRegionIterator::operator ++ (int)
387 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
390 long wxRegionIterator::GetX(void) const
392 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
394 wxRect
*r
= (wxRect
*)node
->Data();
398 long wxRegionIterator::GetY(void) const
400 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
402 wxRect
*r
= (wxRect
*)node
->Data();
406 long wxRegionIterator::GetW(void) const
408 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
410 wxRect
*r
= (wxRect
*)node
->Data();
414 long wxRegionIterator::GetH(void) const
416 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
418 wxRect
*r
= (wxRect
*)node
->Data();