]> git.saurik.com Git - wxWidgets.git/blame - src/dfb/region.cpp
Avoid crash if user aborts the print
[wxWidgets.git] / src / dfb / region.cpp
CommitLineData
b3c86150
VS
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
44dcb12f
VS
36 // default assignment and comparision operators are OK
37
b3c86150
VS
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
b3c86150
VS
83//-----------------------------------------------------------------------------
84// Information about the region
85//-----------------------------------------------------------------------------
86
8a16d737
VZ
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
b3c86150 93{
8a16d737
VZ
94 if ( !m_refData )
95 return false;
96
97 const wxRect& r = M_REGION->m_rect;
b3c86150
VS
98 x = r.GetX();
99 y = r.GetY();
100 w = r.GetWidth();
101 h = r.GetHeight();
b3c86150 102
8a16d737 103 return true;
b3c86150
VS
104}
105
8a16d737 106bool wxRegion::IsEmpty() const
b3c86150
VS
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
8a16d737 123bool wxRegion::DoOffset(wxCoord x, wxCoord y)
b3c86150
VS
124{
125 AllocExclusive();
126 M_REGION->m_rect.Offset(x, y);
127 return true;
128}
129
8a16d737 130bool wxRegion::DoUnionWithRect(const wxRect& rect)
b3c86150
VS
131{
132 AllocExclusive();
133
19883268 134 if ( M_REGION->m_rect.Contains(rect) )
b3c86150
VS
135 {
136 return true;
137 }
19883268 138 else if ( rect.Contains(M_REGION->m_rect) )
b3c86150
VS
139 {
140 M_REGION->m_rect = rect;
141 return true;
142 }
143 else
144 {
a5001e93 145 wxFAIL_MSG( "only rectangular regions are supported" );
b3c86150
VS
146 return false;
147 }
148}
149
8a16d737 150bool wxRegion::DoUnionWithRegion(const wxRegion& region)
b3c86150 151{
a5001e93 152 wxCHECK_MSG( region.Ok(), false, "invalid region" );
8a16d737 153 return DoUnionWithRect(M_REGION_OF(region)->m_rect);
b3c86150
VS
154}
155
8a16d737 156bool wxRegion::DoIntersect(const wxRegion& region)
b3c86150 157{
a5001e93 158 wxCHECK_MSG( region.Ok(), false, "invalid region" );
8a16d737 159
b3c86150 160 AllocExclusive();
8a16d737 161 M_REGION->m_rect.Intersect(M_REGION_OF(region)->m_rect);
b3c86150
VS
162 return true;
163}
164
8a16d737 165bool wxRegion::DoSubtract(const wxRegion& region)
b3c86150 166{
a5001e93
VS
167 wxCHECK_MSG( region.Ok(), false, "invalid region" );
168 wxCHECK_MSG( Ok(), false, "invalid region" );
b3c86150 169
8a16d737
VZ
170 const wxRect& rect = M_REGION_OF(region)->m_rect;
171
19883268 172 if ( rect.Contains(M_REGION->m_rect) )
b3c86150
VS
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 {
a5001e93 186 wxFAIL_MSG( "only rectangular regions implemented" );
b3c86150
VS
187 return false;
188 }
189}
190
8a16d737 191bool wxRegion::DoXor(const wxRegion& region)
b3c86150 192{
a5001e93
VS
193 wxCHECK_MSG( region.Ok(), false, "invalid region" );
194 wxFAIL_MSG( "Xor not implemented" );
b3c86150
VS
195 return false;
196}
197
b3c86150
VS
198
199//-----------------------------------------------------------------------------
200// Tests
201//-----------------------------------------------------------------------------
202
8a16d737 203wxRegionContain wxRegion::DoContainsPoint(wxCoord x, wxCoord y) const
b3c86150 204{
a5001e93 205 wxCHECK_MSG( Ok(), wxOutRegion, "invalid region" );
b3c86150 206
19883268 207 if (M_REGION->m_rect.Contains(x, y))
b3c86150
VS
208 return wxInRegion;
209 else
210 return wxOutRegion;
211}
212
8a16d737 213wxRegionContain wxRegion::DoContainsRect(const wxRect& rect) const
b3c86150 214{
a5001e93 215 wxCHECK_MSG( Ok(), wxOutRegion, "invalid region" );
b3c86150
VS
216
217 // 1) is the rectangle entirely covered by the region?
19883268 218 if (M_REGION->m_rect.Contains(rect))
b3c86150
VS
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}