1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/region.cpp
3 // Purpose: Region handling for wxWidgets/DFB
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #include "wx/region.h"
20 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
)
21 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
, wxObject
)
23 //-----------------------------------------------------------------------------
25 //-----------------------------------------------------------------------------
27 class WXDLLEXPORT wxRegionRefData
: public wxGDIRefData
31 wxRegionRefData(const wxRect
& rect
) : m_rect(rect
) {}
32 wxRegionRefData(const wxRegionRefData
& data
) : m_rect(data
.m_rect
) {}
36 // default assignment and comparision operators are OK
41 #define M_REGION_OF(r) ((wxRegionRefData*)((r).m_refData))
42 #define M_REGION M_REGION_OF(*this)
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 wxObjectRefData
*wxRegion::CreateRefData() const
50 return new wxRegionRefData
;
53 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
55 return new wxRegionRefData(*(wxRegionRefData
*)data
);
63 wxRegion::wxRegion(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
65 m_refData
= new wxRegionRefData(wxRect(x
, y
, w
, h
));
68 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
70 m_refData
= new wxRegionRefData(wxRect(topLeft
, bottomRight
));
73 wxRegion::wxRegion(const wxRect
& r
)
75 m_refData
= new wxRegionRefData(r
);
80 // m_refData unrefed in ~wxObject
83 bool wxRegion::operator==(const wxRegion
& region
) const
85 if ( m_refData
== region
.m_refData
)
90 // only equal if both are invalid, otherwise different
94 return M_REGION
->m_rect
== M_REGION_OF(region
)->m_rect
;
97 //-----------------------------------------------------------------------------
98 // Information about the region
99 //-----------------------------------------------------------------------------
101 void wxRegion::GetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
&w
, wxCoord
&h
) const
110 wxRect
wxRegion::GetBox() const
113 return M_REGION
->m_rect
;
118 bool wxRegion::Empty() const
123 return M_REGION
->m_rect
.IsEmpty();
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 void wxRegion::Clear()
135 bool wxRegion::Offset(wxCoord x
, wxCoord y
)
138 M_REGION
->m_rect
.Offset(x
, y
);
142 bool wxRegion::Union(const wxRect
& rect
)
146 if ( M_REGION
->m_rect
.Inside(rect
) )
150 else if ( rect
.Inside(M_REGION
->m_rect
) )
152 M_REGION
->m_rect
= rect
;
157 wxFAIL_MSG( _T("only rectangular regions are supported") );
162 bool wxRegion::Union(const wxRegion
& region
)
164 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
165 return Union(M_REGION_OF(region
)->m_rect
);
168 bool wxRegion::Intersect(const wxRect
& rect
)
171 M_REGION
->m_rect
.Intersect(rect
);
175 bool wxRegion::Intersect(const wxRegion
& region
)
177 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
178 return Intersect(M_REGION_OF(region
)->m_rect
);
181 bool wxRegion::Subtract(const wxRect
& rect
)
183 wxCHECK_MSG( Ok(), false, _T("invalid region") );
185 if ( rect
.Inside(M_REGION
->m_rect
) )
187 // subtracted rectangle contains this one, so the result is empty
189 M_REGION
->m_rect
= wxRect();
192 else if ( !M_REGION
->m_rect
.Intersects(rect
) )
194 // the rectangles are disjoint, so substracting has no effect
199 wxFAIL_MSG( _T("only rectangular regions implemented") );
204 bool wxRegion::Subtract(const wxRegion
& region
)
206 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
207 return Subtract(M_REGION_OF(region
)->m_rect
);
210 bool wxRegion::Xor(const wxRect
& rect
)
212 wxFAIL_MSG( _T("Xor not implemented") );
216 bool wxRegion::Xor(const wxRegion
& region
)
218 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
219 return Xor(M_REGION_OF(region
)->m_rect
);
223 //-----------------------------------------------------------------------------
225 //-----------------------------------------------------------------------------
227 wxRegionContain
wxRegion::Contains(wxCoord x
, wxCoord y
) const
229 wxCHECK_MSG( Ok(), wxOutRegion
, _T("invalid region") );
231 if (M_REGION
->m_rect
.Inside(x
, y
))
237 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
239 wxCHECK_MSG( Ok(), wxOutRegion
, _T("invalid region") );
241 // 1) is the rectangle entirely covered by the region?
242 if (M_REGION
->m_rect
.Inside(rect
))
245 // 2) is the rectangle completely outside the region?
246 if (!M_REGION
->m_rect
.Intersects(rect
))
249 // 3) neither case happened => it is partially covered:
253 //-----------------------------------------------------------------------------
255 //-----------------------------------------------------------------------------
257 void wxRegionIterator::Reset(const wxRegion
& region
)
259 wxRegionRefData
*d
= M_REGION_OF(region
);
260 m_rect
= d
? d
->m_rect
: wxRect();
263 wxRegionIterator
& wxRegionIterator::operator++()
265 // there's only one rectangle in the iterator, so iterating always
271 wxRegionIterator
wxRegionIterator::operator++(int)
273 wxRegionIterator tmp
= *this;
275 // there's only one rectangle in the iterator, so iterating always