initial (not yet working) code for DirectFB port
[wxWidgets.git] / src / dfb / region.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/region.cpp
3 // Purpose: Region handling for wxWidgets/DFB
4 // Author: Vaclav Slavik
5 // Created: 2006-08-08
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #include "wx/region.h"
19
20 IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
21 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
22
23 //-----------------------------------------------------------------------------
24 // wxRegionRefData
25 //-----------------------------------------------------------------------------
26
27 class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
28 {
29 public:
30 wxRegionRefData() {}
31 wxRegionRefData(const wxRect& rect) : m_rect(rect) {}
32 wxRegionRefData(const wxRegionRefData& data) : m_rect(data.m_rect) {}
33
34 ~wxRegionRefData() {}
35
36 wxRect m_rect;
37 };
38
39 #define M_REGION_OF(r) ((wxRegionRefData*)((r).m_refData))
40 #define M_REGION M_REGION_OF(*this)
41
42 //-----------------------------------------------------------------------------
43 // wxRegion
44 //-----------------------------------------------------------------------------
45
46 wxObjectRefData *wxRegion::CreateRefData() const
47 {
48 return new wxRegionRefData;
49 }
50
51 wxObjectRefData *wxRegion::CloneRefData(const wxObjectRefData *data) const
52 {
53 return new wxRegionRefData(*(wxRegionRefData *)data);
54 }
55
56 wxRegion::wxRegion()
57 {
58 m_refData = NULL;
59 }
60
61 wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
62 {
63 m_refData = new wxRegionRefData(wxRect(x, y, w, h));
64 }
65
66 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
67 {
68 m_refData = new wxRegionRefData(wxRect(topLeft, bottomRight));
69 }
70
71 wxRegion::wxRegion(const wxRect& r)
72 {
73 m_refData = new wxRegionRefData(r);
74 }
75
76 wxRegion::~wxRegion()
77 {
78 // m_refData unrefed in ~wxObject
79 }
80
81 bool wxRegion::operator==(const wxRegion& region) const
82 {
83 if ( m_refData != region.m_refData )
84 return false;
85
86 if ( !Ok() )
87 return true; // both invalid
88
89 return M_REGION->m_rect == M_REGION_OF(region)->m_rect;
90 }
91
92 //-----------------------------------------------------------------------------
93 // Information about the region
94 //-----------------------------------------------------------------------------
95
96 void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
97 {
98 wxRect r = GetBox();
99 x = r.GetX();
100 y = r.GetY();
101 w = r.GetWidth();
102 h = r.GetHeight();
103 }
104
105 wxRect wxRegion::GetBox() const
106 {
107 if (m_refData)
108 return M_REGION->m_rect;
109 else
110 return wxRect();
111 }
112
113 bool wxRegion::Empty() const
114 {
115 if (!m_refData)
116 return true;
117
118 return M_REGION->m_rect.IsEmpty();
119 }
120
121 //-----------------------------------------------------------------------------
122 // Modifications
123 //-----------------------------------------------------------------------------
124
125 void wxRegion::Clear()
126 {
127 UnRef();
128 }
129
130 bool wxRegion::Offset(wxCoord x, wxCoord y)
131 {
132 AllocExclusive();
133 M_REGION->m_rect.Offset(x, y);
134 return true;
135 }
136
137 bool wxRegion::Union(const wxRect& rect)
138 {
139 AllocExclusive();
140
141 if ( M_REGION->m_rect.Inside(rect) )
142 {
143 return true;
144 }
145 else if ( rect.Inside(M_REGION->m_rect) )
146 {
147 M_REGION->m_rect = rect;
148 return true;
149 }
150 else
151 {
152 wxFAIL_MSG( _T("only rectangular regions are supported") );
153 return false;
154 }
155 }
156
157 bool wxRegion::Union(const wxRegion& region)
158 {
159 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
160 return Union(M_REGION_OF(region)->m_rect);
161 }
162
163 bool wxRegion::Intersect(const wxRect& rect)
164 {
165 AllocExclusive();
166 M_REGION->m_rect.Intersect(rect);
167 return true;
168 }
169
170 bool wxRegion::Intersect(const wxRegion& region)
171 {
172 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
173 return Intersect(M_REGION_OF(region)->m_rect);
174 }
175
176 bool wxRegion::Subtract(const wxRect& rect)
177 {
178 wxCHECK_MSG( Ok(), false, _T("invalid region") );
179
180 if ( rect.Inside(M_REGION->m_rect) )
181 {
182 // subtracted rectangle contains this one, so the result is empty
183 // rectangle
184 M_REGION->m_rect = wxRect();
185 return true;
186 }
187 else if ( !M_REGION->m_rect.Intersects(rect) )
188 {
189 // the rectangles are disjoint, so substracting has no effect
190 return true;
191 }
192 else
193 {
194 wxFAIL_MSG( _T("only rectangular regions implemented") );
195 return false;
196 }
197 }
198
199 bool wxRegion::Subtract(const wxRegion& region)
200 {
201 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
202 return Subtract(M_REGION_OF(region)->m_rect);
203 }
204
205 bool wxRegion::Xor(const wxRect& rect)
206 {
207 wxFAIL_MSG( _T("Xor not implemented") );
208 return false;
209 }
210
211 bool wxRegion::Xor(const wxRegion& region)
212 {
213 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
214 return Xor(M_REGION_OF(region)->m_rect);
215 }
216
217
218 //-----------------------------------------------------------------------------
219 // Tests
220 //-----------------------------------------------------------------------------
221
222 wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const
223 {
224 wxCHECK_MSG( Ok(), wxOutRegion, _T("invalid region") );
225
226 if (M_REGION->m_rect.Inside(x, y))
227 return wxInRegion;
228 else
229 return wxOutRegion;
230 }
231
232 wxRegionContain wxRegion::Contains(const wxRect& rect) const
233 {
234 wxCHECK_MSG( Ok(), wxOutRegion, _T("invalid region") );
235
236 // 1) is the rectangle entirely covered by the region?
237 if (M_REGION->m_rect.Inside(rect))
238 return wxInRegion;
239
240 // 2) is the rectangle completely outside the region?
241 if (!M_REGION->m_rect.Intersects(rect))
242 return wxOutRegion;
243
244 // 3) neither case happened => it is partially covered:
245 return wxPartRegion;
246 }
247
248 //-----------------------------------------------------------------------------
249 // wxRegionIterator
250 //-----------------------------------------------------------------------------
251
252 void wxRegionIterator::Reset(const wxRegion& region)
253 {
254 wxRegionRefData *d = M_REGION_OF(region);
255 m_rect = d ? d->m_rect : wxRect();
256 }
257
258 wxRegionIterator& wxRegionIterator::operator++()
259 {
260 // there's only one rectangle in the iterator, so iterating always
261 // reaches the end:
262 Reset();
263 return *this;
264 }
265
266 wxRegionIterator wxRegionIterator::operator++(int)
267 {
268 wxRegionIterator tmp = *this;
269
270 // there's only one rectangle in the iterator, so iterating always
271 // reaches the end:
272 Reset();
273
274 return tmp;
275 }