]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/dfb/region.cpp
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / dfb / region.cpp
... / ...
CommitLineData
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
20IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
21IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
22
23//-----------------------------------------------------------------------------
24// wxRegionRefData
25//-----------------------------------------------------------------------------
26
27class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
28{
29public:
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
48wxObjectRefData *wxRegion::CreateRefData() const
49{
50 return new wxRegionRefData;
51}
52
53wxObjectRefData *wxRegion::CloneRefData(const wxObjectRefData *data) const
54{
55 return new wxRegionRefData(*(wxRegionRefData *)data);
56}
57
58wxRegion::wxRegion()
59{
60 m_refData = NULL;
61}
62
63wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
64{
65 m_refData = new wxRegionRefData(wxRect(x, y, w, h));
66}
67
68wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
69{
70 m_refData = new wxRegionRefData(wxRect(topLeft, bottomRight));
71}
72
73wxRegion::wxRegion(const wxRect& r)
74{
75 m_refData = new wxRegionRefData(r);
76}
77
78wxRegion::~wxRegion()
79{
80 // m_refData unrefed in ~wxObject
81}
82
83//-----------------------------------------------------------------------------
84// Information about the region
85//-----------------------------------------------------------------------------
86
87bool wxRegion::DoIsEqual(const wxRegion& region) const
88{
89 return M_REGION->m_rect == M_REGION_OF(region)->m_rect;
90}
91
92bool wxRegion::DoGetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
93{
94 if ( !m_refData )
95 return false;
96
97 const wxRect& r = M_REGION->m_rect;
98 x = r.GetX();
99 y = r.GetY();
100 w = r.GetWidth();
101 h = r.GetHeight();
102
103 return true;
104}
105
106bool wxRegion::IsEmpty() const
107{
108 if (!m_refData)
109 return true;
110
111 return M_REGION->m_rect.IsEmpty();
112}
113
114//-----------------------------------------------------------------------------
115// Modifications
116//-----------------------------------------------------------------------------
117
118void wxRegion::Clear()
119{
120 UnRef();
121}
122
123bool wxRegion::DoOffset(wxCoord x, wxCoord y)
124{
125 AllocExclusive();
126 M_REGION->m_rect.Offset(x, y);
127 return true;
128}
129
130bool wxRegion::DoUnionWithRect(const wxRect& rect)
131{
132 AllocExclusive();
133
134 if ( M_REGION->m_rect.Contains(rect) )
135 {
136 return true;
137 }
138 else if ( rect.Contains(M_REGION->m_rect) )
139 {
140 M_REGION->m_rect = rect;
141 return true;
142 }
143 else
144 {
145 wxFAIL_MSG( "only rectangular regions are supported" );
146 return false;
147 }
148}
149
150bool wxRegion::DoUnionWithRegion(const wxRegion& region)
151{
152 wxCHECK_MSG( region.Ok(), false, "invalid region" );
153 return DoUnionWithRect(M_REGION_OF(region)->m_rect);
154}
155
156bool wxRegion::DoIntersect(const wxRegion& region)
157{
158 wxCHECK_MSG( region.Ok(), false, "invalid region" );
159
160 AllocExclusive();
161 M_REGION->m_rect.Intersect(M_REGION_OF(region)->m_rect);
162 return true;
163}
164
165bool wxRegion::DoSubtract(const wxRegion& region)
166{
167 wxCHECK_MSG( region.Ok(), false, "invalid region" );
168 wxCHECK_MSG( Ok(), false, "invalid region" );
169
170 const wxRect& rect = M_REGION_OF(region)->m_rect;
171
172 if ( rect.Contains(M_REGION->m_rect) )
173 {
174 // subtracted rectangle contains this one, so the result is empty
175 // rectangle
176 M_REGION->m_rect = wxRect();
177 return true;
178 }
179 else if ( !M_REGION->m_rect.Intersects(rect) )
180 {
181 // the rectangles are disjoint, so substracting has no effect
182 return true;
183 }
184 else
185 {
186 wxFAIL_MSG( "only rectangular regions implemented" );
187 return false;
188 }
189}
190
191bool wxRegion::DoXor(const wxRegion& region)
192{
193 wxCHECK_MSG( region.Ok(), false, "invalid region" );
194 wxFAIL_MSG( "Xor not implemented" );
195 return false;
196}
197
198
199//-----------------------------------------------------------------------------
200// Tests
201//-----------------------------------------------------------------------------
202
203wxRegionContain wxRegion::DoContainsPoint(wxCoord x, wxCoord y) const
204{
205 wxCHECK_MSG( Ok(), wxOutRegion, "invalid region" );
206
207 if (M_REGION->m_rect.Contains(x, y))
208 return wxInRegion;
209 else
210 return wxOutRegion;
211}
212
213wxRegionContain wxRegion::DoContainsRect(const wxRect& rect) const
214{
215 wxCHECK_MSG( Ok(), wxOutRegion, "invalid region" );
216
217 // 1) is the rectangle entirely covered by the region?
218 if (M_REGION->m_rect.Contains(rect))
219 return wxInRegion;
220
221 // 2) is the rectangle completely outside the region?
222 if (!M_REGION->m_rect.Intersects(rect))
223 return wxOutRegion;
224
225 // 3) neither case happened => it is partially covered:
226 return wxPartRegion;
227}
228
229//-----------------------------------------------------------------------------
230// wxRegionIterator
231//-----------------------------------------------------------------------------
232
233void wxRegionIterator::Reset(const wxRegion& region)
234{
235 wxRegionRefData *d = M_REGION_OF(region);
236 m_rect = d ? d->m_rect : wxRect();
237}
238
239wxRegionIterator& wxRegionIterator::operator++()
240{
241 // there's only one rectangle in the iterator, so iterating always
242 // reaches the end:
243 Reset();
244 return *this;
245}
246
247wxRegionIterator wxRegionIterator::operator++(int)
248{
249 wxRegionIterator tmp = *this;
250
251 // there's only one rectangle in the iterator, so iterating always
252 // reaches the end:
253 Reset();
254
255 return tmp;
256}