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 //-----------------------------------------------------------------------------
84 // Information about the region
85 //-----------------------------------------------------------------------------
87 bool wxRegion::DoIsEqual(const wxRegion
& region
) const
89 return M_REGION
->m_rect
== M_REGION_OF(region
)->m_rect
;
92 bool wxRegion::DoGetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
&w
, wxCoord
&h
) const
97 const wxRect
& r
= M_REGION
->m_rect
;
106 bool wxRegion::IsEmpty() const
111 return M_REGION
->m_rect
.IsEmpty();
114 //-----------------------------------------------------------------------------
116 //-----------------------------------------------------------------------------
118 void wxRegion::Clear()
123 bool wxRegion::DoOffset(wxCoord x
, wxCoord y
)
126 M_REGION
->m_rect
.Offset(x
, y
);
130 bool wxRegion::DoUnionWithRect(const wxRect
& rect
)
134 if ( M_REGION
->m_rect
.Contains(rect
) )
138 else if ( rect
.Contains(M_REGION
->m_rect
) )
140 M_REGION
->m_rect
= rect
;
145 wxFAIL_MSG( "only rectangular regions are supported" );
150 bool wxRegion::DoUnionWithRegion(const wxRegion
& region
)
152 wxCHECK_MSG( region
.Ok(), false, "invalid region" );
153 return DoUnionWithRect(M_REGION_OF(region
)->m_rect
);
156 bool wxRegion::DoIntersect(const wxRegion
& region
)
158 wxCHECK_MSG( region
.Ok(), false, "invalid region" );
161 M_REGION
->m_rect
.Intersect(M_REGION_OF(region
)->m_rect
);
165 bool wxRegion::DoSubtract(const wxRegion
& region
)
167 wxCHECK_MSG( region
.Ok(), false, "invalid region" );
168 wxCHECK_MSG( Ok(), false, "invalid region" );
170 const wxRect
& rect
= M_REGION_OF(region
)->m_rect
;
172 if ( rect
.Contains(M_REGION
->m_rect
) )
174 // subtracted rectangle contains this one, so the result is empty
176 M_REGION
->m_rect
= wxRect();
179 else if ( !M_REGION
->m_rect
.Intersects(rect
) )
181 // the rectangles are disjoint, so substracting has no effect
186 wxFAIL_MSG( "only rectangular regions implemented" );
191 bool wxRegion::DoXor(const wxRegion
& region
)
193 wxCHECK_MSG( region
.Ok(), false, "invalid region" );
194 wxFAIL_MSG( "Xor not implemented" );
199 //-----------------------------------------------------------------------------
201 //-----------------------------------------------------------------------------
203 wxRegionContain
wxRegion::DoContainsPoint(wxCoord x
, wxCoord y
) const
205 wxCHECK_MSG( Ok(), wxOutRegion
, "invalid region" );
207 if (M_REGION
->m_rect
.Contains(x
, y
))
213 wxRegionContain
wxRegion::DoContainsRect(const wxRect
& rect
) const
215 wxCHECK_MSG( Ok(), wxOutRegion
, "invalid region" );
217 // 1) is the rectangle entirely covered by the region?
218 if (M_REGION
->m_rect
.Contains(rect
))
221 // 2) is the rectangle completely outside the region?
222 if (!M_REGION
->m_rect
.Intersects(rect
))
225 // 3) neither case happened => it is partially covered:
229 //-----------------------------------------------------------------------------
231 //-----------------------------------------------------------------------------
233 void wxRegionIterator::Reset(const wxRegion
& region
)
235 wxRegionRefData
*d
= M_REGION_OF(region
);
236 m_rect
= d
? d
->m_rect
: wxRect();
239 wxRegionIterator
& wxRegionIterator::operator++()
241 // there's only one rectangle in the iterator, so iterating always
247 wxRegionIterator
wxRegionIterator::operator++(int)
249 wxRegionIterator tmp
= *this;
251 // there's only one rectangle in the iterator, so iterating always