]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/region.cpp
Bit fiddling.
[wxWidgets.git] / src / gtk1 / region.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: region.cpp
3// Purpose:
4// Author: Robert Roebling
f96aa4d9
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
c801d85f
KB
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation "region.h"
13#endif
14
15#include "wx/region.h"
16
17//-----------------------------------------------------------------------------
18// wxRegion
19//-----------------------------------------------------------------------------
20
21class wxRegionRefData: public wxObjectRefData
22{
23 public:
24
25 wxRegionRefData(void);
26 ~wxRegionRefData(void);
27
28 public:
29
30 GdkRegion *m_region;
8429bec1 31 wxList m_rects;
c801d85f
KB
32};
33
34wxRegionRefData::wxRegionRefData(void)
35{
c67daf87 36 m_region = (GdkRegion *) NULL;
ff7b1510 37}
c801d85f
KB
38
39wxRegionRefData::~wxRegionRefData(void)
40{
41 if (m_region) gdk_region_destroy( m_region );
8429bec1
RR
42
43 wxNode *node = m_rects.First();
44 while (node)
45 {
46 wxRect *r = (wxRect*)node->Data();
47 delete r;
48 node = node->Next();
49 }
ff7b1510 50}
c801d85f
KB
51
52//-----------------------------------------------------------------------------
53
54#define M_REGIONDATA ((wxRegionRefData *)m_refData)
55
56IMPLEMENT_DYNAMIC_CLASS(wxRegion,wxGDIObject);
57
58wxRegion::wxRegion( long x, long y, long w, long h )
59{
60 m_refData = new wxRegionRefData();
61 GdkRegion *reg = gdk_region_new();
62 GdkRectangle rect;
63 rect.x = x;
64 rect.y = y;
65 rect.width = w;
66 rect.height = h;
67 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
68 gdk_region_destroy( reg );
8429bec1 69 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,w,h) );
ff7b1510 70}
c801d85f
KB
71
72wxRegion::wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight )
73{
74 m_refData = new wxRegionRefData();
75 GdkRegion *reg = gdk_region_new();
76 GdkRectangle rect;
77 rect.x = topLeft.x;
78 rect.y = topLeft.y;
79 rect.width = bottomRight.x - rect.x;
80 rect.height = bottomRight.y - rect.y;
81 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
82 gdk_region_destroy( reg );
8429bec1 83 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(topLeft,bottomRight) );
ff7b1510 84}
c801d85f
KB
85
86wxRegion::wxRegion( const wxRect& rect )
87{
88 m_refData = new wxRegionRefData();
89 GdkRegion *reg = gdk_region_new();
90 GdkRectangle g_rect;
91 g_rect.x = rect.x;
92 g_rect.y = rect.y;
93 g_rect.width = rect.width;
94 g_rect.height = rect.height;
95 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &g_rect );
96 gdk_region_destroy( reg );
8429bec1
RR
97
98 wxNode *node = M_REGIONDATA->m_rects.First();
99 while (node)
100 {
101 wxRect *r = (wxRect*)node->Data();
102 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
103 node = node->Next();
104 }
ff7b1510 105}
c801d85f
KB
106
107wxRegion::wxRegion(void)
108{
109 m_refData = new wxRegionRefData();
110 M_REGIONDATA->m_region = gdk_region_new();
ff7b1510 111}
c801d85f
KB
112
113wxRegion::~wxRegion(void)
114{
ff7b1510 115}
c801d85f
KB
116
117void wxRegion::Clear(void)
118{
119 UnRef();
120 m_refData = new wxRegionRefData();
121 M_REGIONDATA->m_region = gdk_region_new();
ff7b1510 122}
c801d85f
KB
123
124bool wxRegion::Union( long x, long y, long width, long height )
125{
126 GdkRectangle rect;
127 rect.x = x;
128 rect.y = y;
129 rect.width = width;
130 rect.height = height;
131 GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
132 gdk_region_destroy( M_REGIONDATA->m_region );
133 M_REGIONDATA->m_region = reg;
8429bec1 134 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) );
c801d85f 135 return TRUE;
ff7b1510 136}
c801d85f
KB
137
138bool wxRegion::Union( const wxRect& rect )
139{
140 GdkRectangle g_rect;
141 g_rect.x = rect.x;
142 g_rect.y = rect.y;
143 g_rect.width = rect.width;
144 g_rect.height = rect.height;
145 GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &g_rect );
146 gdk_region_destroy( M_REGIONDATA->m_region );
147 M_REGIONDATA->m_region = reg;
8429bec1 148 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
c801d85f 149 return TRUE;
ff7b1510 150}
c801d85f
KB
151
152bool wxRegion::Union( const wxRegion& region )
153{
154 GdkRegion *reg = gdk_regions_union( M_REGIONDATA->m_region, region.GetRegion() );
155 gdk_region_destroy( M_REGIONDATA->m_region );
156 M_REGIONDATA->m_region = reg;
8429bec1
RR
157
158 wxNode *node = region.GetRectList()->First();
159 while (node)
160 {
161 wxRect *r = (wxRect*)node->Data();
162 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
163 node = node->Next();
164 }
165
c801d85f 166 return TRUE;
ff7b1510 167}
c801d85f
KB
168
169bool wxRegion::Intersect( long x, long y, long width, long height )
170{
171 wxRegion reg( x, y, width, height );
172 Intersect( reg );
173 return TRUE;
ff7b1510 174}
c801d85f
KB
175
176bool wxRegion::Intersect( const wxRect& rect )
177{
178 wxRegion reg( rect );
179 Intersect( reg );
180 return TRUE;
ff7b1510 181}
c801d85f
KB
182
183bool wxRegion::Intersect( const wxRegion& region )
184{
185 GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
186 gdk_region_destroy( M_REGIONDATA->m_region );
187 M_REGIONDATA->m_region = reg;
188 return TRUE;
ff7b1510 189}
c801d85f
KB
190
191bool wxRegion::Subtract( long x, long y, long width, long height )
192{
193 wxRegion reg( x, y, width, height );
194 Subtract( reg );
195 return TRUE;
ff7b1510 196}
c801d85f
KB
197
198bool wxRegion::Subtract( const wxRect& rect )
199{
200 wxRegion reg( rect );
201 Subtract( reg );
202 return TRUE;
ff7b1510 203}
c801d85f
KB
204
205bool wxRegion::Subtract( const wxRegion& region )
206{
207 GdkRegion *reg = gdk_regions_subtract( M_REGIONDATA->m_region, region.GetRegion() );
208 gdk_region_destroy( M_REGIONDATA->m_region );
209 M_REGIONDATA->m_region = reg;
210 return TRUE;
ff7b1510 211}
c801d85f
KB
212
213bool wxRegion::Xor( long x, long y, long width, long height )
214{
215 wxRegion reg( x, y, width, height );
216 Xor( reg );
217 return TRUE;
ff7b1510 218}
c801d85f
KB
219
220bool wxRegion::Xor( const wxRect& rect )
221{
222 wxRegion reg( rect );
223 Xor( reg );
224 return TRUE;
ff7b1510 225}
c801d85f
KB
226
227bool wxRegion::Xor( const wxRegion& region )
228{
229 GdkRegion *reg = gdk_regions_xor( M_REGIONDATA->m_region, region.GetRegion() );
230 gdk_region_destroy( M_REGIONDATA->m_region );
231 M_REGIONDATA->m_region = reg;
8429bec1
RR
232
233 wxNode *node = region.GetRectList()->First();
234 while (node)
235 {
236 wxRect *r = (wxRect*)node->Data();
237 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
238 node = node->Next();
239 }
240
c801d85f 241 return TRUE;
ff7b1510 242}
c801d85f
KB
243
244void wxRegion::GetBox( long& x, long& y, long&w, long &h ) const
245{
246 x = 0;
247 y = 0;
248 w = -1;
249 h = -1;
8429bec1
RR
250 wxNode *node = GetRectList()->First();
251 while (node)
252 {
253 wxRect *r = (wxRect*)node->Data();
254 if (node == GetRectList()->First())
255 {
256 x = r->x;
257 y = r->y;
258 w = r->width;
259 h = r->height;
260 }
261 else
262 {
263 if (r->x < x)
264 {
265 x = r->x;
266 w += x - r->x;
267 }
268 if (r->y < y)
269 {
270 y = r->y;
271 h += y - r->y;
272 }
273 if (r->width+r->x > x+w)
274 {
275 w = r->x + r->width - x;
276 }
277 if (r->height+r->y > y+h)
278 {
279 h = r->y + r->height - y;
280 }
281 }
282 node = node->Next();
283 }
ff7b1510 284}
c801d85f
KB
285
286wxRect wxRegion::GetBox(void) const
287{
8429bec1
RR
288 long x = 0;
289 long y = 0;
290 long w = -1;
291 long h = -1;
292 GetBox( x, y, w, h );
293 return wxRect( x, y, w, h );
ff7b1510 294}
c801d85f
KB
295
296bool wxRegion::Empty(void) const
297{
298 return gdk_region_empty( M_REGIONDATA->m_region );
ff7b1510 299}
c801d85f
KB
300
301wxRegionContain wxRegion::Contains( long x, long y ) const
302{
303 if (gdk_region_point_in( M_REGIONDATA->m_region, x, y ))
304 return wxInRegion;
305 else
306 return wxOutRegion;
ff7b1510 307}
c801d85f
KB
308
309wxRegionContain wxRegion::Contains( long x, long y, long w, long h ) const
310{
311 GdkRectangle rect;
312 rect.x = x;
313 rect.y = y;
314 rect.width = w;
315 rect.height = h;
316 GdkOverlapType res = gdk_region_rect_in( M_REGIONDATA->m_region, &rect );
317 switch (res)
318 {
319 case GDK_OVERLAP_RECTANGLE_IN: return wxInRegion;
320 case GDK_OVERLAP_RECTANGLE_OUT: return wxOutRegion;
321 case GDK_OVERLAP_RECTANGLE_PART: return wxPartRegion;
ff7b1510 322 }
c801d85f 323 return wxOutRegion;
ff7b1510 324}
c801d85f 325
8429bec1
RR
326wxRegionContain wxRegion::Contains(const wxPoint& pt) const
327{
328 return Contains( pt.x, pt.y );
329}
330
331wxRegionContain wxRegion::Contains(const wxRect& rect) const
332{
333 return Contains( rect.x, rect.y, rect.width, rect.height );
334}
335
c801d85f
KB
336GdkRegion *wxRegion::GetRegion(void) const
337{
338 return M_REGIONDATA->m_region;
ff7b1510 339}
c801d85f 340
8429bec1
RR
341wxList *wxRegion::GetRectList() const
342{
343 return &(M_REGIONDATA->m_rects);
344}
345
346//-----------------------------------------------------------------------------
347// wxRegion
348//-----------------------------------------------------------------------------
349
350IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
351
352wxRegionIterator::wxRegionIterator(void)
353{
354 m_current = 0;
355}
356
357wxRegionIterator::wxRegionIterator( const wxRegion& region )
358{
359 m_region = region;
360 m_current = 0;
361}
362
363void wxRegionIterator::Reset( const wxRegion& region )
364{
365 m_region = region;
366 m_current = 0;
367}
368
369wxRegionIterator::operator bool (void) const
370{
371 return m_current < m_region.GetRectList()->Number();
372}
373
374bool wxRegionIterator::HaveRects(void) const
375{
376 return m_current < m_region.GetRectList()->Number();
377}
378
379void wxRegionIterator::operator ++ (void)
380{
381 if (m_current < m_region.GetRectList()->Number()) ++m_current;
382}
383
384void wxRegionIterator::operator ++ (int)
385{
386 if (m_current < m_region.GetRectList()->Number()) ++m_current;
387}
388
389long wxRegionIterator::GetX(void) const
390{
391 wxNode *node = m_region.GetRectList()->Nth( m_current );
392 if (!node) return 0;
393 wxRect *r = (wxRect*)node->Data();
394 return r->x;
395}
396
397long wxRegionIterator::GetY(void) const
398{
399 wxNode *node = m_region.GetRectList()->Nth( m_current );
400 if (!node) return 0;
401 wxRect *r = (wxRect*)node->Data();
402 return r->y;
403}
404
405long wxRegionIterator::GetW(void) const
406{
407 wxNode *node = m_region.GetRectList()->Nth( m_current );
408 if (!node) return 0;
409 wxRect *r = (wxRect*)node->Data();
410 return r->width;
411}
412
413long wxRegionIterator::GetH(void) const
414{
415 wxNode *node = m_region.GetRectList()->Nth( m_current );
416 if (!node) return 0;
417 wxRect *r = (wxRect*)node->Data();
418 return r->height;
419}
420
421