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();
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
) );
109 m_refData
= new wxRegionRefData();
110 M_REGIONDATA
->m_region
= gdk_region_new();
113 wxRegion::~wxRegion()
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()
130 m_refData
= new wxRegionRefData();
131 M_REGIONDATA
->m_region
= gdk_region_new();
134 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord 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( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord 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( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord 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( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord 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( wxCoord
& x
, wxCoord
& y
, wxCoord
&w
, wxCoord
&h
) const
261 gdk_region_get_clipbox( M_REGIONDATA
->m_region
, &rect
);
268 wxRect
wxRegion::GetBox() const
274 GetBox( x
, y
, w
, h
);
275 return wxRect( x
, y
, w
, h
);
278 bool wxRegion::Empty() const
280 return gdk_region_empty( M_REGIONDATA
->m_region
);
283 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
285 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
291 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
298 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
301 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
302 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
303 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
308 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
310 return Contains( pt
.x
, pt
.y
);
313 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
315 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
318 GdkRegion
*wxRegion::GetRegion() const
320 return M_REGIONDATA
->m_region
;
323 wxList
*wxRegion::GetRectList() const
325 return &(M_REGIONDATA
->m_rects
);
328 //-----------------------------------------------------------------------------
330 //-----------------------------------------------------------------------------
332 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
334 wxRegionIterator::wxRegionIterator()
339 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
344 void wxRegionIterator::Reset( const wxRegion
& region
)
350 wxRegionIterator::operator bool () const
352 return m_current
< (size_t)m_region
.GetRectList()->Number();
355 bool wxRegionIterator::HaveRects() const
357 return m_current
< (size_t)m_region
.GetRectList()->Number();
360 void wxRegionIterator::operator ++ ()
362 if (m_current
< (size_t)m_region
.GetRectList()->Number()) ++m_current
;
365 void wxRegionIterator::operator ++ (int)
367 if (m_current
< (size_t)m_region
.GetRectList()->Number()) ++m_current
;
370 wxCoord
wxRegionIterator::GetX() const
372 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
374 wxRect
*r
= (wxRect
*)node
->Data();
378 wxCoord
wxRegionIterator::GetY() const
380 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
382 wxRect
*r
= (wxRect
*)node
->Data();
386 wxCoord
wxRegionIterator::GetW() const
388 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
390 wxRect
*r
= (wxRect
*)node
->Data();
394 wxCoord
wxRegionIterator::GetH() const
396 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
398 wxRect
*r
= (wxRect
*)node
->Data();