1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/region.cpp
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"
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 class wxRegionRefData
: public wxObjectRefData
34 wxRegionRefData::wxRegionRefData()
36 m_region
= (GdkRegion
*) NULL
;
39 wxRegionRefData::~wxRegionRefData()
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( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
60 m_refData
= new wxRegionRefData();
61 GdkRegion
*reg
= gdk_region_new();
68 gdk_region_union_with_rect( reg
, &rect
);
69 M_REGIONDATA
->m_region
= reg
;
71 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
72 gdk_region_destroy( reg
);
74 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
77 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
79 m_refData
= new wxRegionRefData();
80 GdkRegion
*reg
= gdk_region_new();
84 rect
.width
= bottomRight
.x
- rect
.x
;
85 rect
.height
= bottomRight
.y
- rect
.y
;
87 gdk_region_union_with_rect( reg
, &rect
);
88 M_REGIONDATA
->m_region
= reg
;
90 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
91 gdk_region_destroy( reg
);
93 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
96 wxRegion::wxRegion( const wxRect
& rect
)
98 m_refData
= new wxRegionRefData();
99 GdkRegion
*reg
= gdk_region_new();
103 g_rect
.width
= rect
.width
;
104 g_rect
.height
= rect
.height
;
106 gdk_region_union_with_rect( reg
, &g_rect
);
107 M_REGIONDATA
->m_region
= reg
;
109 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
110 gdk_region_destroy( reg
);
112 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
119 wxRegion::~wxRegion()
123 bool wxRegion::operator == ( const wxRegion
& region
)
125 return m_refData
== region
.m_refData
;
128 bool wxRegion::operator != ( const wxRegion
& region
)
130 return m_refData
!= region
.m_refData
;
133 void wxRegion::Clear()
138 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
144 rect
.height
= height
;
147 m_refData
= new wxRegionRefData();
148 GdkRegion
*reg
= gdk_region_new();
150 gdk_region_union_with_rect( reg
, &rect
);
151 M_REGIONDATA
->m_region
= reg
;
153 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
154 gdk_region_destroy( reg
);
160 gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
162 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
163 gdk_region_destroy( M_REGIONDATA
->m_region
);
164 M_REGIONDATA
->m_region
= reg
;
168 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
173 bool wxRegion::Union( const wxRect
& rect
)
175 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
178 bool wxRegion::Union( const wxRegion
& region
)
185 m_refData
= new wxRegionRefData();
186 M_REGIONDATA
->m_region
= gdk_region_new();
190 gdk_region_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
192 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
193 gdk_region_destroy( M_REGIONDATA
->m_region
);
194 M_REGIONDATA
->m_region
= reg
;
197 wxNode
*node
= region
.GetRectList()->First();
200 wxRect
*r
= (wxRect
*)node
->Data();
201 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
208 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
212 m_refData
= new wxRegionRefData();
213 M_REGIONDATA
->m_region
= gdk_region_new();
216 wxRegion
reg( x
, y
, width
, height
);
221 bool wxRegion::Intersect( const wxRect
& rect
)
225 m_refData
= new wxRegionRefData();
226 M_REGIONDATA
->m_region
= gdk_region_new();
229 wxRegion
reg( rect
);
234 bool wxRegion::Intersect( const wxRegion
& region
)
241 m_refData
= new wxRegionRefData();
242 M_REGIONDATA
->m_region
= gdk_region_new();
247 gdk_region_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
249 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
250 gdk_region_destroy( M_REGIONDATA
->m_region
);
251 M_REGIONDATA
->m_region
= reg
;
256 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
260 m_refData
= new wxRegionRefData();
261 M_REGIONDATA
->m_region
= gdk_region_new();
264 wxRegion
reg( x
, y
, width
, height
);
269 bool wxRegion::Subtract( const wxRect
& rect
)
273 m_refData
= new wxRegionRefData();
274 M_REGIONDATA
->m_region
= gdk_region_new();
277 wxRegion
reg( rect
);
282 bool wxRegion::Subtract( const wxRegion
& region
)
289 m_refData
= new wxRegionRefData();
290 M_REGIONDATA
->m_region
= gdk_region_new();
294 gdk_region_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
296 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
297 gdk_region_destroy( M_REGIONDATA
->m_region
);
298 M_REGIONDATA
->m_region
= reg
;
303 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
307 m_refData
= new wxRegionRefData();
308 M_REGIONDATA
->m_region
= gdk_region_new();
311 wxRegion
reg( x
, y
, width
, height
);
316 bool wxRegion::Xor( const wxRect
& rect
)
320 m_refData
= new wxRegionRefData();
321 M_REGIONDATA
->m_region
= gdk_region_new();
324 wxRegion
reg( rect
);
329 bool wxRegion::Xor( const wxRegion
& region
)
336 m_refData
= new wxRegionRefData();
337 M_REGIONDATA
->m_region
= gdk_region_new();
341 gdk_region_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
343 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
344 gdk_region_destroy( M_REGIONDATA
->m_region
);
345 M_REGIONDATA
->m_region
= reg
;
348 wxNode
*node
= region
.GetRectList()->First();
351 wxRect
*r
= (wxRect
*)node
->Data();
352 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
359 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
369 gdk_region_get_clipbox( M_REGIONDATA
->m_region
, &rect
);
376 wxRect
wxRegion::GetBox() const
382 GetBox( x
, y
, w
, h
);
383 return wxRect( x
, y
, w
, h
);
386 bool wxRegion::Empty() const
391 return gdk_region_empty( M_REGIONDATA
->m_region
);
394 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
399 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
405 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
415 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
418 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
419 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
420 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
425 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
427 return Contains( pt
.x
, pt
.y
);
430 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
432 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
435 GdkRegion
*wxRegion::GetRegion() const
438 return (GdkRegion
*) NULL
;
440 return M_REGIONDATA
->m_region
;
443 wxList
*wxRegion::GetRectList() const
446 return (wxList
*) NULL
;
448 return &(M_REGIONDATA
->m_rects
);
451 //-----------------------------------------------------------------------------
453 //-----------------------------------------------------------------------------
455 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
457 wxRegionIterator::wxRegionIterator()
462 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
467 void wxRegionIterator::Reset( const wxRegion
& region
)
473 wxRegionIterator::operator bool () const
475 return m_current
< (size_t)m_region
.GetRectList()->Number();
478 bool wxRegionIterator::HaveRects() const
480 return m_current
< (size_t)m_region
.GetRectList()->Number();
483 void wxRegionIterator::operator ++ ()
485 if (m_current
< (size_t)m_region
.GetRectList()->Number()) ++m_current
;
488 void wxRegionIterator::operator ++ (int)
490 if (m_current
< (size_t)m_region
.GetRectList()->Number()) ++m_current
;
493 wxCoord
wxRegionIterator::GetX() const
495 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
497 wxRect
*r
= (wxRect
*)node
->Data();
501 wxCoord
wxRegionIterator::GetY() const
503 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
505 wxRect
*r
= (wxRect
*)node
->Data();
509 wxCoord
wxRegionIterator::GetW() const
511 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
513 wxRect
*r
= (wxRect
*)node
->Data();
517 wxCoord
wxRegionIterator::GetH() const
519 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
521 wxRect
*r
= (wxRect
*)node
->Data();