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"
17 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
21 class wxRegionRefData
: public wxObjectRefData
25 wxRegionRefData(void);
26 ~wxRegionRefData(void);
34 wxRegionRefData::wxRegionRefData(void)
36 m_region
= (GdkRegion
*) NULL
;
39 wxRegionRefData::~wxRegionRefData(void)
41 if (m_region
) gdk_region_destroy( m_region
);
43 wxNode
*node
= m_rects
.First();
46 wxRect
*r
= (wxRect
*)node
->Data();
52 //-----------------------------------------------------------------------------
54 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
56 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
58 wxRegion::wxRegion( long x
, long y
, long w
, long h
)
60 m_refData
= new wxRegionRefData();
61 GdkRegion
*reg
= gdk_region_new();
67 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
68 gdk_region_destroy( reg
);
69 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
72 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
74 m_refData
= new wxRegionRefData();
75 GdkRegion
*reg
= gdk_region_new();
79 rect
.width
= bottomRight
.x
- rect
.x
;
80 rect
.height
= bottomRight
.y
- rect
.y
;
81 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
82 gdk_region_destroy( reg
);
83 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
86 wxRegion::wxRegion( const wxRect
& rect
)
88 m_refData
= new wxRegionRefData();
89 GdkRegion
*reg
= gdk_region_new();
93 g_rect
.width
= rect
.width
;
94 g_rect
.height
= rect
.height
;
95 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
96 gdk_region_destroy( reg
);
98 wxNode
*node
= M_REGIONDATA
->m_rects
.First();
101 wxRect
*r
= (wxRect
*)node
->Data();
102 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
107 wxRegion::wxRegion(void)
109 m_refData
= new wxRegionRefData();
110 M_REGIONDATA
->m_region
= gdk_region_new();
113 wxRegion::~wxRegion(void)
117 bool wxRegion::operator == ( const wxRegion
& region
)
119 return m_refData
== region
.m_refData
;
122 bool wxRegion::operator != ( const wxRegion
& region
)
124 return m_refData
!= region
.m_refData
;
127 void wxRegion::Clear(void)
130 m_refData
= new wxRegionRefData();
131 M_REGIONDATA
->m_region
= gdk_region_new();
134 bool wxRegion::Union( long x
, long y
, long width
, long height
)
140 rect
.height
= height
;
141 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
142 gdk_region_destroy( M_REGIONDATA
->m_region
);
143 M_REGIONDATA
->m_region
= reg
;
144 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
148 bool wxRegion::Union( const wxRect
& rect
)
153 g_rect
.width
= rect
.width
;
154 g_rect
.height
= rect
.height
;
155 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect
);
156 gdk_region_destroy( M_REGIONDATA
->m_region
);
157 M_REGIONDATA
->m_region
= reg
;
158 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
162 bool wxRegion::Union( const wxRegion
& region
)
164 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
165 gdk_region_destroy( M_REGIONDATA
->m_region
);
166 M_REGIONDATA
->m_region
= reg
;
168 wxNode
*node
= region
.GetRectList()->First();
171 wxRect
*r
= (wxRect
*)node
->Data();
172 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
179 bool wxRegion::Intersect( long x
, long y
, long width
, long height
)
181 wxRegion
reg( x
, y
, width
, height
);
186 bool wxRegion::Intersect( const wxRect
& rect
)
188 wxRegion
reg( rect
);
193 bool wxRegion::Intersect( const wxRegion
& region
)
195 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
196 gdk_region_destroy( M_REGIONDATA
->m_region
);
197 M_REGIONDATA
->m_region
= reg
;
201 bool wxRegion::Subtract( long x
, long y
, long width
, long height
)
203 wxRegion
reg( x
, y
, width
, height
);
208 bool wxRegion::Subtract( const wxRect
& rect
)
210 wxRegion
reg( rect
);
215 bool wxRegion::Subtract( const wxRegion
& region
)
217 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
218 gdk_region_destroy( M_REGIONDATA
->m_region
);
219 M_REGIONDATA
->m_region
= reg
;
223 bool wxRegion::Xor( long x
, long y
, long width
, long height
)
225 wxRegion
reg( x
, y
, width
, height
);
230 bool wxRegion::Xor( const wxRect
& rect
)
232 wxRegion
reg( rect
);
237 bool wxRegion::Xor( const wxRegion
& region
)
239 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
240 gdk_region_destroy( M_REGIONDATA
->m_region
);
241 M_REGIONDATA
->m_region
= reg
;
243 wxNode
*node
= region
.GetRectList()->First();
246 wxRect
*r
= (wxRect
*)node
->Data();
247 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
254 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h
) const
260 wxNode
*node
= GetRectList()->First();
263 wxRect
*r
= (wxRect
*)node
->Data();
264 if (node
== GetRectList()->First())
283 if (r
->width
+r
->x
> x
+w
)
285 w
= r
->x
+ r
->width
- x
;
287 if (r
->height
+r
->y
> y
+h
)
289 h
= r
->y
+ r
->height
- y
;
296 wxRect
wxRegion::GetBox(void) const
302 GetBox( x
, y
, w
, h
);
303 return wxRect( x
, y
, w
, h
);
306 bool wxRegion::Empty(void) const
308 return gdk_region_empty( M_REGIONDATA
->m_region
);
311 wxRegionContain
wxRegion::Contains( long x
, long y
) const
313 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
319 wxRegionContain
wxRegion::Contains( long x
, long y
, long w
, long h
) const
326 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
329 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
330 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
331 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
336 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
338 return Contains( pt
.x
, pt
.y
);
341 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
343 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
346 GdkRegion
*wxRegion::GetRegion(void) const
348 return M_REGIONDATA
->m_region
;
351 wxList
*wxRegion::GetRectList() const
353 return &(M_REGIONDATA
->m_rects
);
356 //-----------------------------------------------------------------------------
358 //-----------------------------------------------------------------------------
360 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
362 wxRegionIterator::wxRegionIterator(void)
367 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
373 void wxRegionIterator::Reset( const wxRegion
& region
)
379 wxRegionIterator::operator bool (void) const
381 return m_current
< m_region
.GetRectList()->Number();
384 bool wxRegionIterator::HaveRects(void) const
386 return m_current
< m_region
.GetRectList()->Number();
389 void wxRegionIterator::operator ++ (void)
391 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
394 void wxRegionIterator::operator ++ (int)
396 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
399 long wxRegionIterator::GetX(void) const
401 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
403 wxRect
*r
= (wxRect
*)node
->Data();
407 long wxRegionIterator::GetY(void) const
409 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
411 wxRect
*r
= (wxRect
*)node
->Data();
415 long wxRegionIterator::GetW(void) const
417 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
419 wxRect
*r
= (wxRect
*)node
->Data();
423 long wxRegionIterator::GetH(void) const
425 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
427 wxRect
*r
= (wxRect
*)node
->Data();