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