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