]> git.saurik.com Git - wxWidgets.git/blob - src/dfb/region.cpp
Commit patch [ 1559950 ] fix mem leaks in wx{Dir|File}Dialog
[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 // default assignment and comparision operators are OK
37
38 wxRect m_rect;
39 };
40
41 #define M_REGION_OF(r) ((wxRegionRefData*)((r).m_refData))
42 #define M_REGION M_REGION_OF(*this)
43
44 //-----------------------------------------------------------------------------
45 // wxRegion
46 //-----------------------------------------------------------------------------
47
48 wxObjectRefData *wxRegion::CreateRefData() const
49 {
50 return new wxRegionRefData;
51 }
52
53 wxObjectRefData *wxRegion::CloneRefData(const wxObjectRefData *data) const
54 {
55 return new wxRegionRefData(*(wxRegionRefData *)data);
56 }
57
58 wxRegion::wxRegion()
59 {
60 m_refData = NULL;
61 }
62
63 wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
64 {
65 m_refData = new wxRegionRefData(wxRect(x, y, w, h));
66 }
67
68 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
69 {
70 m_refData = new wxRegionRefData(wxRect(topLeft, bottomRight));
71 }
72
73 wxRegion::wxRegion(const wxRect& r)
74 {
75 m_refData = new wxRegionRefData(r);
76 }
77
78 wxRegion::~wxRegion()
79 {
80 // m_refData unrefed in ~wxObject
81 }
82
83 bool wxRegion::operator==(const wxRegion& region) const
84 {
85 if ( m_refData == region.m_refData )
86 return true;
87
88 if ( !Ok() )
89 {
90 // only equal if both are invalid, otherwise different
91 return !region.Ok();
92 }
93
94 return M_REGION->m_rect == M_REGION_OF(region)->m_rect;
95 }
96
97 //-----------------------------------------------------------------------------
98 // Information about the region
99 //-----------------------------------------------------------------------------
100
101 void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
102 {
103 wxRect r = GetBox();
104 x = r.GetX();
105 y = r.GetY();
106 w = r.GetWidth();
107 h = r.GetHeight();
108 }
109
110 wxRect wxRegion::GetBox() const
111 {
112 if (m_refData)
113 return M_REGION->m_rect;
114 else
115 return wxRect();
116 }
117
118 bool wxRegion::Empty() const
119 {
120 if (!m_refData)
121 return true;
122
123 return M_REGION->m_rect.IsEmpty();
124 }
125
126 //-----------------------------------------------------------------------------
127 // Modifications
128 //-----------------------------------------------------------------------------
129
130 void wxRegion::Clear()
131 {
132 UnRef();
133 }
134
135 bool wxRegion::Offset(wxCoord x, wxCoord y)
136 {
137 AllocExclusive();
138 M_REGION->m_rect.Offset(x, y);
139 return true;
140 }
141
142 bool wxRegion::Union(const wxRect& rect)
143 {
144 AllocExclusive();
145
146 if ( M_REGION->m_rect.Inside(rect) )
147 {
148 return true;
149 }
150 else if ( rect.Inside(M_REGION->m_rect) )
151 {
152 M_REGION->m_rect = rect;
153 return true;
154 }
155 else
156 {
157 wxFAIL_MSG( _T("only rectangular regions are supported") );
158 return false;
159 }
160 }
161
162 bool wxRegion::Union(const wxRegion& region)
163 {
164 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
165 return Union(M_REGION_OF(region)->m_rect);
166 }
167
168 bool wxRegion::Intersect(const wxRect& rect)
169 {
170 AllocExclusive();
171 M_REGION->m_rect.Intersect(rect);
172 return true;
173 }
174
175 bool wxRegion::Intersect(const wxRegion& region)
176 {
177 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
178 return Intersect(M_REGION_OF(region)->m_rect);
179 }
180
181 bool wxRegion::Subtract(const wxRect& rect)
182 {
183 wxCHECK_MSG( Ok(), false, _T("invalid region") );
184
185 if ( rect.Inside(M_REGION->m_rect) )
186 {
187 // subtracted rectangle contains this one, so the result is empty
188 // rectangle
189 M_REGION->m_rect = wxRect();
190 return true;
191 }
192 else if ( !M_REGION->m_rect.Intersects(rect) )
193 {
194 // the rectangles are disjoint, so substracting has no effect
195 return true;
196 }
197 else
198 {
199 wxFAIL_MSG( _T("only rectangular regions implemented") );
200 return false;
201 }
202 }
203
204 bool wxRegion::Subtract(const wxRegion& region)
205 {
206 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
207 return Subtract(M_REGION_OF(region)->m_rect);
208 }
209
210 bool wxRegion::Xor(const wxRect& rect)
211 {
212 wxFAIL_MSG( _T("Xor not implemented") );
213 return false;
214 }
215
216 bool wxRegion::Xor(const wxRegion& region)
217 {
218 wxCHECK_MSG( region.Ok(), false, _T("invalid region") );
219 return Xor(M_REGION_OF(region)->m_rect);
220 }
221
222
223 //-----------------------------------------------------------------------------
224 // Tests
225 //-----------------------------------------------------------------------------
226
227 wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const
228 {
229 wxCHECK_MSG( Ok(), wxOutRegion, _T("invalid region") );
230
231 if (M_REGION->m_rect.Inside(x, y))
232 return wxInRegion;
233 else
234 return wxOutRegion;
235 }
236
237 wxRegionContain wxRegion::Contains(const wxRect& rect) const
238 {
239 wxCHECK_MSG( Ok(), wxOutRegion, _T("invalid region") );
240
241 // 1) is the rectangle entirely covered by the region?
242 if (M_REGION->m_rect.Inside(rect))
243 return wxInRegion;
244
245 // 2) is the rectangle completely outside the region?
246 if (!M_REGION->m_rect.Intersects(rect))
247 return wxOutRegion;
248
249 // 3) neither case happened => it is partially covered:
250 return wxPartRegion;
251 }
252
253 //-----------------------------------------------------------------------------
254 // wxRegionIterator
255 //-----------------------------------------------------------------------------
256
257 void wxRegionIterator::Reset(const wxRegion& region)
258 {
259 wxRegionRefData *d = M_REGION_OF(region);
260 m_rect = d ? d->m_rect : wxRect();
261 }
262
263 wxRegionIterator& wxRegionIterator::operator++()
264 {
265 // there's only one rectangle in the iterator, so iterating always
266 // reaches the end:
267 Reset();
268 return *this;
269 }
270
271 wxRegionIterator wxRegionIterator::operator++(int)
272 {
273 wxRegionIterator tmp = *this;
274
275 // there's only one rectangle in the iterator, so iterating always
276 // reaches the end:
277 Reset();
278
279 return tmp;
280 }