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