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"
23 #define NULL ((void*)0L)
26 //-----------------------------------------------------------------------------
28 //-----------------------------------------------------------------------------
30 class wxRegionRefData
: public wxObjectRefData
43 wxRegionRefData::wxRegionRefData()
45 m_region
= (GdkRegion
*) NULL
;
48 wxRegionRefData::~wxRegionRefData()
50 if (m_region
) gdk_region_destroy( m_region
);
52 wxNode
*node
= m_rects
.First();
55 wxRect
*r
= (wxRect
*)node
->Data();
61 //-----------------------------------------------------------------------------
63 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
65 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
67 wxRegion::wxRegion( long x
, long y
, long w
, long h
)
69 m_refData
= new wxRegionRefData();
70 GdkRegion
*reg
= gdk_region_new();
76 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
77 gdk_region_destroy( reg
);
78 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
81 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
83 m_refData
= new wxRegionRefData();
84 GdkRegion
*reg
= gdk_region_new();
88 rect
.width
= bottomRight
.x
- rect
.x
;
89 rect
.height
= bottomRight
.y
- rect
.y
;
90 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
91 gdk_region_destroy( reg
);
92 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
95 wxRegion::wxRegion( const wxRect
& rect
)
97 m_refData
= new wxRegionRefData();
98 GdkRegion
*reg
= gdk_region_new();
102 g_rect
.width
= rect
.width
;
103 g_rect
.height
= rect
.height
;
104 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
105 gdk_region_destroy( reg
);
107 wxNode
*node
= M_REGIONDATA
->m_rects
.First();
110 wxRect
*r
= (wxRect
*)node
->Data();
111 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
118 m_refData
= new wxRegionRefData();
119 M_REGIONDATA
->m_region
= gdk_region_new();
122 wxRegion::~wxRegion()
126 bool wxRegion::operator == ( const wxRegion
& region
)
128 return m_refData
== region
.m_refData
;
131 bool wxRegion::operator != ( const wxRegion
& region
)
133 return m_refData
!= region
.m_refData
;
136 void wxRegion::Clear()
139 m_refData
= new wxRegionRefData();
140 M_REGIONDATA
->m_region
= gdk_region_new();
143 bool wxRegion::Union( long x
, long y
, long width
, long height
)
149 rect
.height
= height
;
150 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
151 gdk_region_destroy( M_REGIONDATA
->m_region
);
152 M_REGIONDATA
->m_region
= reg
;
153 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
157 bool wxRegion::Union( const wxRect
& rect
)
162 g_rect
.width
= rect
.width
;
163 g_rect
.height
= rect
.height
;
164 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &g_rect
);
165 gdk_region_destroy( M_REGIONDATA
->m_region
);
166 M_REGIONDATA
->m_region
= reg
;
167 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
171 bool wxRegion::Union( const wxRegion
& region
)
173 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
174 gdk_region_destroy( M_REGIONDATA
->m_region
);
175 M_REGIONDATA
->m_region
= reg
;
177 wxNode
*node
= region
.GetRectList()->First();
180 wxRect
*r
= (wxRect
*)node
->Data();
181 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
188 bool wxRegion::Intersect( long x
, long y
, long width
, long height
)
190 wxRegion
reg( x
, y
, width
, height
);
195 bool wxRegion::Intersect( const wxRect
& rect
)
197 wxRegion
reg( rect
);
202 bool wxRegion::Intersect( const wxRegion
& region
)
204 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
205 gdk_region_destroy( M_REGIONDATA
->m_region
);
206 M_REGIONDATA
->m_region
= reg
;
210 bool wxRegion::Subtract( long x
, long y
, long width
, long height
)
212 wxRegion
reg( x
, y
, width
, height
);
217 bool wxRegion::Subtract( const wxRect
& rect
)
219 wxRegion
reg( rect
);
224 bool wxRegion::Subtract( const wxRegion
& region
)
226 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
227 gdk_region_destroy( M_REGIONDATA
->m_region
);
228 M_REGIONDATA
->m_region
= reg
;
232 bool wxRegion::Xor( long x
, long y
, long width
, long height
)
234 wxRegion
reg( x
, y
, width
, height
);
239 bool wxRegion::Xor( const wxRect
& rect
)
241 wxRegion
reg( rect
);
246 bool wxRegion::Xor( const wxRegion
& region
)
248 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
249 gdk_region_destroy( M_REGIONDATA
->m_region
);
250 M_REGIONDATA
->m_region
= reg
;
252 wxNode
*node
= region
.GetRectList()->First();
255 wxRect
*r
= (wxRect
*)node
->Data();
256 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
263 void wxRegion::GetBox( long& x
, long& y
, long&w
, long &h
) const
269 wxNode
*node
= GetRectList()->First();
272 wxRect
*r
= (wxRect
*)node
->Data();
273 if (node
== GetRectList()->First())
292 if (r
->width
+r
->x
> x
+w
)
294 w
= r
->x
+ r
->width
- x
;
296 if (r
->height
+r
->y
> y
+h
)
298 h
= r
->y
+ r
->height
- y
;
305 wxRect
wxRegion::GetBox() const
311 GetBox( x
, y
, w
, h
);
312 return wxRect( x
, y
, w
, h
);
315 bool wxRegion::Empty() const
317 return gdk_region_empty( M_REGIONDATA
->m_region
);
320 wxRegionContain
wxRegion::Contains( long x
, long y
) const
322 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
328 wxRegionContain
wxRegion::Contains( long x
, long y
, long w
, long h
) const
335 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
338 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
339 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
340 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
345 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
347 return Contains( pt
.x
, pt
.y
);
350 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
352 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
355 GdkRegion
*wxRegion::GetRegion() const
357 return M_REGIONDATA
->m_region
;
360 wxList
*wxRegion::GetRectList() const
362 return &(M_REGIONDATA
->m_rects
);
365 //-----------------------------------------------------------------------------
367 //-----------------------------------------------------------------------------
369 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
371 wxRegionIterator::wxRegionIterator()
376 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
382 void wxRegionIterator::Reset( const wxRegion
& region
)
388 wxRegionIterator::operator bool () const
390 return m_current
< m_region
.GetRectList()->Number();
393 bool wxRegionIterator::HaveRects() const
395 return m_current
< m_region
.GetRectList()->Number();
398 void wxRegionIterator::operator ++ ()
400 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
403 void wxRegionIterator::operator ++ (int)
405 if (m_current
< m_region
.GetRectList()->Number()) ++m_current
;
408 wxCoord
wxRegionIterator::GetX() const
410 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
412 wxRect
*r
= (wxRect
*)node
->Data();
416 wxCoord
wxRegionIterator::GetY() const
418 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
420 wxRect
*r
= (wxRect
*)node
->Data();
424 wxCoord
wxRegionIterator::GetW() const
426 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
428 wxRect
*r
= (wxRect
*)node
->Data();
432 wxCoord
wxRegionIterator::GetH() const
434 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
436 wxRect
*r
= (wxRect
*)node
->Data();