]> git.saurik.com Git - wxWidgets.git/blame - src/mac/classic/region.cpp
Include wx/region.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / mac / classic / region.cpp
CommitLineData
2646f485 1/////////////////////////////////////////////////////////////////////////////
b3a44e05 2// File: src/mac/classic/region.cpp
2646f485
SC
3// Purpose: Region class
4// Author: Stefan Csomor
5// Created: Fri Oct 24 10:46:34 MET 1997
6// RCS-ID: $Id$
7// Copyright: (c) 1997 Stefan Csomor
65571936 8// Licence: wxWindows licence
2646f485
SC
9/////////////////////////////////////////////////////////////////////////////
10
b3a44e05
WS
11#include "wx/wxprec.h"
12
2646f485 13#include "wx/region.h"
b3a44e05 14
2646f485
SC
15#include "wx/gdicmn.h"
16#include "wx/mac/uma.h"
17
62f864c3
VZ
18IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
19IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
2646f485
SC
20
21//-----------------------------------------------------------------------------
22// wxRegionRefData implementation
23//-----------------------------------------------------------------------------
24
25class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
26public:
27 wxRegionRefData()
28 {
29 m_macRgn = NewRgn() ;
30 }
31
32 wxRegionRefData(const wxRegionRefData& data)
33 : wxGDIRefData()
34 {
35 m_macRgn = NewRgn() ;
36 CopyRgn( data.m_macRgn , m_macRgn ) ;
37 }
38
39 ~wxRegionRefData()
40 {
41 DisposeRgn( m_macRgn ) ;
42 }
43 RgnHandle m_macRgn ;
44};
45
46#define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn)
47#define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn)
48
49//-----------------------------------------------------------------------------
50// wxRegion
51//-----------------------------------------------------------------------------
52
53/*!
54 * Create an empty region.
55 */
56wxRegion::wxRegion()
57{
58 m_refData = new wxRegionRefData;
59}
60
61wxRegion::wxRegion(WXHRGN hRegion )
62{
63 m_refData = new wxRegionRefData;
64 CopyRgn( (RgnHandle) hRegion , (RgnHandle) M_REGION ) ;
65}
66
67wxRegion::wxRegion(long x, long y, long w, long h)
68{
69 m_refData = new wxRegionRefData;
70 SetRectRgn( (RgnHandle) M_REGION , x , y , x+w , y+h ) ;
71}
72
73wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
74{
75 m_refData = new wxRegionRefData;
76 SetRectRgn( (RgnHandle) M_REGION , topLeft.x , topLeft.y , bottomRight.x , bottomRight.y ) ;
77}
78
79wxRegion::wxRegion(const wxRect& rect)
80{
81 m_refData = new wxRegionRefData;
82 SetRectRgn( (RgnHandle) M_REGION , rect.x , rect.y , rect.x+rect.width , rect.y+rect.height ) ;
83}
84
85/*!
86 * Destroy the region.
87 */
88wxRegion::~wxRegion()
89{
90 // m_refData unrefed in ~wxObject
91}
92
93//-----------------------------------------------------------------------------
94//# Modify region
95//-----------------------------------------------------------------------------
96
97//! Clear current region
98void wxRegion::Clear()
99{
100 UnRef();
101}
102
103//! Combine rectangle (x, y, w, h) with this.
104bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
105{
106 // Don't change shared data
b3a44e05 107 if (!m_refData)
2646f485
SC
108 {
109 m_refData = new wxRegionRefData();
b3a44e05
WS
110 }
111 else if (m_refData->GetRefCount() > 1)
2646f485
SC
112 {
113 wxRegionRefData* ref = (wxRegionRefData*)m_refData;
114 UnRef();
115 m_refData = new wxRegionRefData(*ref);
116 }
117 RgnHandle rgn = NewRgn() ;
118 SetRectRgn( rgn , x , y, x+width,y + height ) ;
b3a44e05 119
2646f485
SC
120 switch (op)
121 {
122 case wxRGN_AND:
123 SectRgn( M_REGION , rgn , M_REGION ) ;
124 break ;
125 case wxRGN_OR:
126 UnionRgn( M_REGION , rgn , M_REGION ) ;
127 break ;
128 case wxRGN_XOR:
129 XorRgn( M_REGION , rgn , M_REGION ) ;
130 break ;
131 case wxRGN_DIFF:
132 DiffRgn( M_REGION , rgn , M_REGION ) ;
133 break ;
134 case wxRGN_COPY:
135 default:
136 CopyRgn( rgn ,M_REGION ) ;
137 break ;
138 }
139
140 DisposeRgn( rgn ) ;
141
b3a44e05 142 return true;
2646f485
SC
143}
144
145//! Union /e region with this.
146bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
147{
148 if (region.Empty())
b3a44e05 149 return false;
2646f485
SC
150
151 // Don't change shared data
152 if (!m_refData) {
153 m_refData = new wxRegionRefData();
b3a44e05
WS
154 }
155 else if (m_refData->GetRefCount() > 1)
2646f485
SC
156 {
157 wxRegionRefData* ref = (wxRegionRefData*)m_refData;
158 UnRef();
159 m_refData = new wxRegionRefData(*ref);
160 }
161
162 switch (op)
163 {
164 case wxRGN_AND:
165 SectRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
166 break ;
167 case wxRGN_OR:
168 UnionRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
169 break ;
170 case wxRGN_XOR:
171 XorRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
172 break ;
173 case wxRGN_DIFF:
174 DiffRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
175 break ;
176 case wxRGN_COPY:
177 default:
178 CopyRgn( OTHER_M_REGION(region) ,M_REGION ) ;
179 break ;
180 }
181
b3a44e05 182 return true;
2646f485
SC
183}
184
185bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
186{
187 return Combine(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), op);
188}
189
190//-----------------------------------------------------------------------------
191//# Information on region
192//-----------------------------------------------------------------------------
193
194// Outer bounds of region
195void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord& w, wxCoord& h) const
196{
b3a44e05 197 if (m_refData)
2646f485
SC
198 {
199 Rect box ;
200 GetRegionBounds( M_REGION , &box ) ;
201 x = box.left ;
202 y = box.top ;
203 w = box.right - box.left ;
204 h = box.bottom - box.top ;
b3a44e05
WS
205 }
206 else
2646f485
SC
207 {
208 x = y = w = h = 0;
209 }
210}
211
212wxRect wxRegion::GetBox() const
213{
214 wxCoord x, y, w, h;
215 GetBox(x, y, w, h);
216 return wxRect(x, y, w, h);
217}
218
219// Is region empty?
220bool wxRegion::Empty() const
221{
222 return EmptyRgn( M_REGION ) ;
223}
224
225const WXHRGN wxRegion::GetWXHRGN() const
226{
227 return M_REGION ;
228}
229
230//-----------------------------------------------------------------------------
231//# Tests
232//-----------------------------------------------------------------------------
233
234// Does the region contain the point (x,y)?
235wxRegionContain wxRegion::Contains(long x, long y) const
236{
237 if (!m_refData)
238 return wxOutRegion;
239
240 // TODO. Return wxInRegion if within region.
241 if (0)
242 return wxInRegion;
243 return wxOutRegion;
244}
245
246// Does the region contain the point pt?
247wxRegionContain wxRegion::Contains(const wxPoint& pt) const
248{
249 if (!m_refData)
250 return wxOutRegion;
251
252 Point p = { pt.y , pt.x } ;
253 if (PtInRgn( p , M_REGION ) )
254 return wxInRegion;
b3a44e05 255
2646f485
SC
256 return wxOutRegion;
257}
258
259// Does the region contain the rectangle (x, y, w, h)?
260wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
261{
262 if (!m_refData)
263 return wxOutRegion;
264
265 Rect rect = { y , x , y + h , x + w } ;
266 if (RectInRgn( &rect , M_REGION ) )
267 return wxInRegion;
268 else
269 return wxOutRegion;
270}
271
272// Does the region contain the rectangle rect
273wxRegionContain wxRegion::Contains(const wxRect& rect) const
274{
275 if (!m_refData)
276 return wxOutRegion;
277
278 long x, y, w, h;
279 x = rect.x;
280 y = rect.y;
281 w = rect.GetWidth();
282 h = rect.GetHeight();
283 return Contains(x, y, w, h);
284}
285
286///////////////////////////////////////////////////////////////////////////////
287// //
288// wxRegionIterator //
289// //
290///////////////////////////////////////////////////////////////////////////////
291
292/*!
293 * Initialize empty iterator
294 */
295wxRegionIterator::wxRegionIterator()
296 : m_current(0), m_numRects(0), m_rects(NULL)
297{
298}
299
300wxRegionIterator::~wxRegionIterator()
301{
302 if (m_rects) {
303 delete[] m_rects;
304 m_rects = NULL;
305 }
306}
307
308wxRegionIterator::wxRegionIterator(const wxRegionIterator& iterator)
309 : wxObject()
310 , m_current(iterator.m_current)
311 , m_numRects(0)
312 , m_rects(NULL)
313{
314 SetRects(iterator.m_numRects, iterator.m_rects);
315}
316
317wxRegionIterator& wxRegionIterator::operator=(const wxRegionIterator& iterator)
318{
319 m_current = iterator.m_current;
320 SetRects(iterator.m_numRects, iterator.m_rects);
321 return *this;
322}
323
324/*!
325 * Set iterator rects for region
326 */
327void wxRegionIterator::SetRects(long numRects, wxRect *rects)
328{
329 if (m_rects) {
330 delete[] m_rects;
331 m_rects = NULL;
332 }
333 if (rects)
334 {
335 int i;
336 m_rects = new wxRect[numRects];
337 for (i = 0; i < numRects; i++)
338 m_rects[i] = rects[i];
339 }
340 m_numRects = numRects;
341}
342
343/*!
344 * Initialize iterator for region
345 */
346wxRegionIterator::wxRegionIterator(const wxRegion& region)
347{
348 m_rects = NULL;
349
350 Reset(region);
351}
352
353/*!
354 * Reset iterator for a new /e region.
355 */
356void wxRegionIterator::Reset(const wxRegion& region)
357{
358 m_current = 0;
359 m_region = region;
360
361 if (m_rects) {
362 delete[] m_rects;
363 m_rects = NULL;
364 }
365
366 if (m_region.Empty())
367 m_numRects = 0;
368 else
369 {
370 // we cannot dissolve it into rects on mac
371 m_rects = new wxRect[1];
372 Rect rect ;
373 GetRegionBounds( OTHER_M_REGION( region ) , &rect ) ;
374 m_rects[0].x = rect.left;
375 m_rects[0].y = rect.top;
376 m_rects[0].width = rect.right - rect.left;
377 m_rects[0].height = rect.bottom - rect.top;
378 m_numRects = 1;
379 }
380}
381
382/*!
383 * Increment iterator. The rectangle returned is the one after the
384 * incrementation.
385 */
386wxRegionIterator& wxRegionIterator::operator ++ ()
387{
388 if (m_current < m_numRects)
389 ++m_current;
390 return *this;
391}
392
393/*!
394 * Increment iterator. The rectangle returned is the one before the
395 * incrementation.
396 */
397wxRegionIterator wxRegionIterator::operator ++ (int)
398{
399 wxRegionIterator previous(*this);
400
401 if (m_current < m_numRects)
402 ++m_current;
403
404 return previous;
405}
406
407long wxRegionIterator::GetX() const
408{
409 if (m_current < m_numRects)
410 return m_rects[m_current].x;
411 return 0;
412}
413
414long wxRegionIterator::GetY() const
415{
416 if (m_current < m_numRects)
417 return m_rects[m_current].y;
418 return 0;
419}
420
421long wxRegionIterator::GetW() const
422{
423 if (m_current < m_numRects)
424 return m_rects[m_current].width ;
425 return 0;
426}
427
428long wxRegionIterator::GetH() const
429{
430 if (m_current < m_numRects)
431 return m_rects[m_current].height;
432 return 0;
433}