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
) {}
39 #define M_REGION_OF(r) ((wxRegionRefData*)((r).m_refData))
40 #define M_REGION M_REGION_OF(*this)
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 wxObjectRefData
*wxRegion::CreateRefData() const
48 return new wxRegionRefData
;
51 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
53 return new wxRegionRefData(*(wxRegionRefData
*)data
);
61 wxRegion::wxRegion(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
63 m_refData
= new wxRegionRefData(wxRect(x
, y
, w
, h
));
66 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
68 m_refData
= new wxRegionRefData(wxRect(topLeft
, bottomRight
));
71 wxRegion::wxRegion(const wxRect
& r
)
73 m_refData
= new wxRegionRefData(r
);
78 // m_refData unrefed in ~wxObject
81 bool wxRegion::operator==(const wxRegion
& region
) const
83 if ( m_refData
!= region
.m_refData
)
87 return true; // both invalid
89 return M_REGION
->m_rect
== M_REGION_OF(region
)->m_rect
;
92 //-----------------------------------------------------------------------------
93 // Information about the region
94 //-----------------------------------------------------------------------------
96 void wxRegion::GetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
&w
, wxCoord
&h
) const
105 wxRect
wxRegion::GetBox() const
108 return M_REGION
->m_rect
;
113 bool wxRegion::Empty() const
118 return M_REGION
->m_rect
.IsEmpty();
121 //-----------------------------------------------------------------------------
123 //-----------------------------------------------------------------------------
125 void wxRegion::Clear()
130 bool wxRegion::Offset(wxCoord x
, wxCoord y
)
133 M_REGION
->m_rect
.Offset(x
, y
);
137 bool wxRegion::Union(const wxRect
& rect
)
141 if ( M_REGION
->m_rect
.Inside(rect
) )
145 else if ( rect
.Inside(M_REGION
->m_rect
) )
147 M_REGION
->m_rect
= rect
;
152 wxFAIL_MSG( _T("only rectangular regions are supported") );
157 bool wxRegion::Union(const wxRegion
& region
)
159 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
160 return Union(M_REGION_OF(region
)->m_rect
);
163 bool wxRegion::Intersect(const wxRect
& rect
)
166 M_REGION
->m_rect
.Intersect(rect
);
170 bool wxRegion::Intersect(const wxRegion
& region
)
172 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
173 return Intersect(M_REGION_OF(region
)->m_rect
);
176 bool wxRegion::Subtract(const wxRect
& rect
)
178 wxCHECK_MSG( Ok(), false, _T("invalid region") );
180 if ( rect
.Inside(M_REGION
->m_rect
) )
182 // subtracted rectangle contains this one, so the result is empty
184 M_REGION
->m_rect
= wxRect();
187 else if ( !M_REGION
->m_rect
.Intersects(rect
) )
189 // the rectangles are disjoint, so substracting has no effect
194 wxFAIL_MSG( _T("only rectangular regions implemented") );
199 bool wxRegion::Subtract(const wxRegion
& region
)
201 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
202 return Subtract(M_REGION_OF(region
)->m_rect
);
205 bool wxRegion::Xor(const wxRect
& rect
)
207 wxFAIL_MSG( _T("Xor not implemented") );
211 bool wxRegion::Xor(const wxRegion
& region
)
213 wxCHECK_MSG( region
.Ok(), false, _T("invalid region") );
214 return Xor(M_REGION_OF(region
)->m_rect
);
218 //-----------------------------------------------------------------------------
220 //-----------------------------------------------------------------------------
222 wxRegionContain
wxRegion::Contains(wxCoord x
, wxCoord y
) const
224 wxCHECK_MSG( Ok(), wxOutRegion
, _T("invalid region") );
226 if (M_REGION
->m_rect
.Inside(x
, y
))
232 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
234 wxCHECK_MSG( Ok(), wxOutRegion
, _T("invalid region") );
236 // 1) is the rectangle entirely covered by the region?
237 if (M_REGION
->m_rect
.Inside(rect
))
240 // 2) is the rectangle completely outside the region?
241 if (!M_REGION
->m_rect
.Intersects(rect
))
244 // 3) neither case happened => it is partially covered:
248 //-----------------------------------------------------------------------------
250 //-----------------------------------------------------------------------------
252 void wxRegionIterator::Reset(const wxRegion
& region
)
254 wxRegionRefData
*d
= M_REGION_OF(region
);
255 m_rect
= d
? d
->m_rect
: wxRect();
258 wxRegionIterator
& wxRegionIterator::operator++()
260 // there's only one rectangle in the iterator, so iterating always
266 wxRegionIterator
wxRegionIterator::operator++(int)
268 wxRegionIterator tmp
= *this;
270 // there's only one rectangle in the iterator, so iterating always