]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/region.cpp
fix for wxBitmapType definition problem
[wxWidgets.git] / src / gtk / region.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
5fc7ede9 2// Name: gtk/region.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
1e6feb95 5// Modified: VZ at 05.10.00: use Unshare(), comparison fixed
f96aa4d9
RR
6// Id: $Id$
7// Copyright: (c) 1998 Robert Roebling
5fc7ede9 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
1e6feb95
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
c801d85f 15#ifdef __GNUG__
1e6feb95 16 #pragma implementation "region.h"
c801d85f
KB
17#endif
18
1e6feb95
VZ
19// ----------------------------------------------------------------------------
20// headers
21// ----------------------------------------------------------------------------
22
c801d85f
KB
23#include "wx/region.h"
24
aed8ac3f
RR
25#include <gdk/gdk.h>
26#include <gtk/gtk.h>
bbe0af5b 27
d52e91c9
JS
28// Unfortunately the new way of implementing the region iterator
29// doesn't work with GTK+ 2.0 or above (can't access a Region in
30// GdkPrivateRegion)
31#ifdef __WXGTK20__
32#define OLDCODE 1
33#else
3d0c4d2e 34#define OLDCODE 0
d52e91c9 35#endif
864e8bd0 36
1e6feb95
VZ
37#include "wx/log.h"
38
39// ----------------------------------------------------------------------------
40// wxRegionRefData: private class containing the information about the region
41// ----------------------------------------------------------------------------
c801d85f 42
1e6feb95 43class wxRegionRefData : public wxObjectRefData
c801d85f 44{
864e8bd0 45public:
bf57d1ad 46 wxRegionRefData();
1e6feb95
VZ
47 wxRegionRefData(const wxRegionRefData& refData);
48 virtual ~wxRegionRefData();
5fc7ede9 49
c801d85f 50 GdkRegion *m_region;
3d0c4d2e 51#if OLDCODE
8429bec1 52 wxList m_rects;
3d0c4d2e 53#endif
c801d85f
KB
54};
55
1e6feb95
VZ
56// ----------------------------------------------------------------------------
57// macros
58// ----------------------------------------------------------------------------
59
60#define M_REGIONDATA ((wxRegionRefData *)m_refData)
61#define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))
62
63IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject);
64IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator,wxObject);
65
66// ============================================================================
67// implementation
68// ============================================================================
69
70// ----------------------------------------------------------------------------
71// wxRegionRefData
72// ----------------------------------------------------------------------------
73
bf57d1ad 74wxRegionRefData::wxRegionRefData()
c801d85f 75{
bbe0af5b 76 m_region = (GdkRegion *) NULL;
ff7b1510 77}
c801d85f 78
1e6feb95
VZ
79wxRegionRefData::wxRegionRefData(const wxRegionRefData& refData)
80{
81#ifdef __WXGTK20__
82 m_region = gdk_region_copy(refData.m_region);
83#else
84 m_region = gdk_region_new();
85 GdkRegion *regCopy = gdk_regions_union(m_region, refData.m_region);
86 gdk_region_destroy(m_region);
87 m_region = regCopy;
88#endif
89
29149a64 90#if OLDCODE
1e6feb95
VZ
91 wxNode *node = refData.m_rects.First();
92 while (node)
93 {
94 wxRect *r = (wxRect*)node->Data();
95 m_rects.Append( (wxObject*) new wxRect(*r) );
96 node = node->Next();
97 }
29149a64 98#endif
1e6feb95
VZ
99}
100
bf57d1ad 101wxRegionRefData::~wxRegionRefData()
c801d85f 102{
bbe0af5b 103 if (m_region) gdk_region_destroy( m_region );
5fc7ede9 104
3d0c4d2e 105#if OLDCODE
bbe0af5b
RR
106 wxNode *node = m_rects.First();
107 while (node)
108 {
109 wxRect *r = (wxRect*)node->Data();
110 delete r;
111 node = node->Next();
112 }
3d0c4d2e 113#endif
ff7b1510 114}
c801d85f 115
1e6feb95
VZ
116// ----------------------------------------------------------------------------
117// wxRegion construction
118// ----------------------------------------------------------------------------
c801d85f
KB
119
120#define M_REGIONDATA ((wxRegionRefData *)m_refData)
121
1e6feb95
VZ
122wxRegion::wxRegion()
123{
124}
125
5fc7ede9 126wxRegion::wxRegion( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
c801d85f 127{
bbe0af5b
RR
128 m_refData = new wxRegionRefData();
129 GdkRegion *reg = gdk_region_new();
130 GdkRectangle rect;
131 rect.x = x;
132 rect.y = y;
133 rect.width = w;
134 rect.height = h;
b7c2d6ff
OK
135#ifdef __WXGTK20__
136 gdk_region_union_with_rect( reg, &rect );
137 M_REGIONDATA->m_region = reg;
138#else
bbe0af5b
RR
139 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
140 gdk_region_destroy( reg );
b7c2d6ff 141#endif
3d0c4d2e 142#if OLDCODE
bbe0af5b 143 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,w,h) );
3d0c4d2e 144#endif
ff7b1510 145}
c801d85f
KB
146
147wxRegion::wxRegion( const wxPoint& topLeft, const wxPoint& bottomRight )
148{
bbe0af5b
RR
149 m_refData = new wxRegionRefData();
150 GdkRegion *reg = gdk_region_new();
151 GdkRectangle rect;
152 rect.x = topLeft.x;
153 rect.y = topLeft.y;
154 rect.width = bottomRight.x - rect.x;
155 rect.height = bottomRight.y - rect.y;
b7c2d6ff
OK
156#ifdef __WXGTK20__
157 gdk_region_union_with_rect( reg, &rect );
158 M_REGIONDATA->m_region = reg;
159#else
bbe0af5b
RR
160 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
161 gdk_region_destroy( reg );
b7c2d6ff 162#endif
3d0c4d2e 163#if OLDCODE
bbe0af5b 164 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(topLeft,bottomRight) );
3d0c4d2e 165#endif
ff7b1510 166}
c801d85f
KB
167
168wxRegion::wxRegion( const wxRect& rect )
169{
bbe0af5b
RR
170 m_refData = new wxRegionRefData();
171 GdkRegion *reg = gdk_region_new();
172 GdkRectangle g_rect;
173 g_rect.x = rect.x;
174 g_rect.y = rect.y;
175 g_rect.width = rect.width;
176 g_rect.height = rect.height;
b7c2d6ff
OK
177#ifdef __WXGTK20__
178 gdk_region_union_with_rect( reg, &g_rect );
179 M_REGIONDATA->m_region = reg;
180#else
bbe0af5b
RR
181 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &g_rect );
182 gdk_region_destroy( reg );
b7c2d6ff 183#endif
3d0c4d2e 184#if OLDCODE
e1208c31 185 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(rect.x,rect.y,rect.width,rect.height) );
3d0c4d2e 186#endif
ff7b1510 187}
c801d85f 188
1e6feb95 189wxRegion::~wxRegion()
c801d85f 190{
ff7b1510 191}
c801d85f 192
1e6feb95 193bool wxRegion::operator==( const wxRegion& region )
c801d85f 194{
1e6feb95
VZ
195 // VZ: compare the regions themselves, not the pointers to ref data!
196 return gdk_region_equal(M_REGIONDATA->m_region,
197 M_REGIONDATA_OF(region)->m_region);
ff7b1510 198}
c801d85f 199
1e6feb95 200bool wxRegion::operator != ( const wxRegion& region )
76ed8f8d 201{
1e6feb95 202 return !(*this == region);
76ed8f8d
RR
203}
204
1e6feb95 205void wxRegion::Unshare()
76ed8f8d 206{
1e6feb95
VZ
207 if ( !m_refData )
208 {
209 m_refData = new wxRegionRefData;
210 M_REGIONDATA->m_region = gdk_region_new();
211 }
212 else if ( m_refData->GetRefCount() > 1 )
213 {
214 wxRegionRefData *refData = new wxRegionRefData(*M_REGIONDATA);
215 UnRef();
216 m_refData = refData;
217 }
218 //else: we're not shared
76ed8f8d
RR
219}
220
1e6feb95
VZ
221// ----------------------------------------------------------------------------
222// wxRegion operations
223// ----------------------------------------------------------------------------
224
bf57d1ad 225void wxRegion::Clear()
c801d85f 226{
bbe0af5b 227 UnRef();
ff7b1510 228}
c801d85f 229
5fc7ede9 230bool wxRegion::Union( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 231{
bbe0af5b
RR
232 GdkRectangle rect;
233 rect.x = x;
234 rect.y = y;
235 rect.width = width;
236 rect.height = height;
e1208c31
RR
237 if (!m_refData)
238 {
239 m_refData = new wxRegionRefData();
240 GdkRegion *reg = gdk_region_new();
b7c2d6ff
OK
241#ifdef __WXGTK20__
242 gdk_region_union_with_rect( reg, &rect );
243 M_REGIONDATA->m_region = reg;
244#else
e1208c31
RR
245 M_REGIONDATA->m_region = gdk_region_union_with_rect( reg, &rect );
246 gdk_region_destroy( reg );
b7c2d6ff 247#endif
e1208c31
RR
248 }
249 else
250 {
1e6feb95
VZ
251 Unshare();
252
b7c2d6ff
OK
253#ifdef __WXGTK20__
254 gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
255#else
e1208c31
RR
256 GdkRegion *reg = gdk_region_union_with_rect( M_REGIONDATA->m_region, &rect );
257 gdk_region_destroy( M_REGIONDATA->m_region );
258 M_REGIONDATA->m_region = reg;
b7c2d6ff 259#endif
e1208c31 260 }
1e6feb95 261
3d0c4d2e 262#if OLDCODE
bbe0af5b 263 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(x,y,width,height) );
3d0c4d2e 264#endif
e1208c31 265
bbe0af5b 266 return TRUE;
ff7b1510 267}
c801d85f
KB
268
269bool wxRegion::Union( const wxRect& rect )
270{
e1208c31 271 return Union( rect.x, rect.y, rect.width, rect.height );
ff7b1510 272}
c801d85f
KB
273
274bool wxRegion::Union( const wxRegion& region )
275{
e1208c31
RR
276 if (region.IsNull())
277 return FALSE;
278
1e6feb95 279 Unshare();
e1208c31 280
b7c2d6ff
OK
281#ifdef __WXGTK20__
282 gdk_region_union( M_REGIONDATA->m_region, region.GetRegion() );
283#else
bbe0af5b
RR
284 GdkRegion *reg = gdk_regions_union( M_REGIONDATA->m_region, region.GetRegion() );
285 gdk_region_destroy( M_REGIONDATA->m_region );
286 M_REGIONDATA->m_region = reg;
b7c2d6ff 287#endif
5fc7ede9 288
3d0c4d2e 289#if OLDCODE
bbe0af5b
RR
290 wxNode *node = region.GetRectList()->First();
291 while (node)
292 {
293 wxRect *r = (wxRect*)node->Data();
294 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
295 node = node->Next();
296 }
3d0c4d2e 297#endif
5fc7ede9 298
bbe0af5b 299 return TRUE;
ff7b1510 300}
c801d85f 301
5fc7ede9 302bool wxRegion::Intersect( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 303{
bbe0af5b 304 wxRegion reg( x, y, width, height );
1e6feb95
VZ
305
306 return Intersect( reg );
ff7b1510 307}
c801d85f
KB
308
309bool wxRegion::Intersect( const wxRect& rect )
310{
bbe0af5b 311 wxRegion reg( rect );
1e6feb95 312 return Intersect( reg );
ff7b1510 313}
c801d85f 314
1e6feb95
VZ
315// this helper function just computes the region intersection without updating
316// the list of rectangles each region maintaints: this allows us to call it
317// from Intersect() itself without going into infinite recursion as we would
318// if we called Intersect() itself recursively
319bool wxRegion::IntersectRegionOnly(const wxRegion& region)
c801d85f 320{
1e6feb95 321 Unshare();
e1208c31 322
b7c2d6ff
OK
323#ifdef __WXGTK20__
324 gdk_region_intersect( M_REGIONDATA->m_region, region.GetRegion() );
325#else
bbe0af5b
RR
326 GdkRegion *reg = gdk_regions_intersect( M_REGIONDATA->m_region, region.GetRegion() );
327 gdk_region_destroy( M_REGIONDATA->m_region );
328 M_REGIONDATA->m_region = reg;
b7c2d6ff 329#endif
1e6feb95 330
bbe0af5b 331 return TRUE;
ff7b1510 332}
c801d85f 333
1e6feb95 334bool wxRegion::Intersect( const wxRegion& region )
c801d85f 335{
1e6feb95
VZ
336 if (region.IsNull())
337 return FALSE;
338
e1208c31
RR
339 if (!m_refData)
340 {
341 m_refData = new wxRegionRefData();
342 M_REGIONDATA->m_region = gdk_region_new();
1e6feb95
VZ
343 return TRUE;
344 }
345
346 if ( !IntersectRegionOnly(region) )
347 {
348 GetRectList()->Clear();
349
350 return FALSE;
351 }
352
353 // we need to update the rect list as well
354 wxList& list = *GetRectList();
355 wxNode *node = list.First();
356 while (node)
357 {
358 wxRect *r = (wxRect*)node->Data();
359
360 wxRegion regCopy = region;
361 if ( regCopy.IntersectRegionOnly(*r) )
362 {
363 // replace the node with the intersection
364 *r = regCopy.GetBox();
365 }
366 else
367 {
368 // TODO remove the rect from the list
369 r->width = 0;
370 r->height = 0;
371 }
372
373 node = node->Next();
e1208c31
RR
374 }
375
bbe0af5b 376 return TRUE;
ff7b1510 377}
c801d85f 378
1e6feb95 379bool wxRegion::Subtract( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 380{
1e6feb95
VZ
381 wxRegion reg( x, y, width, height );
382 return Subtract( reg );
383}
e1208c31 384
1e6feb95
VZ
385bool wxRegion::Subtract( const wxRect& rect )
386{
bbe0af5b 387 wxRegion reg( rect );
1e6feb95 388 return Subtract( reg );
ff7b1510 389}
c801d85f
KB
390
391bool wxRegion::Subtract( const wxRegion& region )
392{
e1208c31
RR
393 if (region.IsNull())
394 return FALSE;
395
396 if (!m_refData)
397 {
398 m_refData = new wxRegionRefData();
399 M_REGIONDATA->m_region = gdk_region_new();
400 }
401
1e6feb95
VZ
402 Unshare();
403
b7c2d6ff
OK
404#ifdef __WXGTK20__
405 gdk_region_subtract( M_REGIONDATA->m_region, region.GetRegion() );
406#else
bbe0af5b
RR
407 GdkRegion *reg = gdk_regions_subtract( M_REGIONDATA->m_region, region.GetRegion() );
408 gdk_region_destroy( M_REGIONDATA->m_region );
409 M_REGIONDATA->m_region = reg;
b7c2d6ff 410#endif
1e6feb95 411
bbe0af5b 412 return TRUE;
ff7b1510 413}
c801d85f 414
5fc7ede9 415bool wxRegion::Xor( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
c801d85f 416{
bbe0af5b 417 wxRegion reg( x, y, width, height );
1e6feb95 418 return Xor( reg );
ff7b1510 419}
c801d85f
KB
420
421bool wxRegion::Xor( const wxRect& rect )
422{
bbe0af5b 423 wxRegion reg( rect );
1e6feb95 424 return Xor( reg );
ff7b1510 425}
c801d85f
KB
426
427bool wxRegion::Xor( const wxRegion& region )
428{
e1208c31 429 if (region.IsNull())
05a11043 430 return FALSE;
e1208c31
RR
431
432 if (!m_refData)
433 {
434 m_refData = new wxRegionRefData();
435 M_REGIONDATA->m_region = gdk_region_new();
436 }
1e6feb95
VZ
437 else
438 {
439 Unshare();
440 }
e1208c31 441
b7c2d6ff
OK
442#ifdef __WXGTK20__
443 gdk_region_xor( M_REGIONDATA->m_region, region.GetRegion() );
444#else
bbe0af5b
RR
445 GdkRegion *reg = gdk_regions_xor( M_REGIONDATA->m_region, region.GetRegion() );
446 gdk_region_destroy( M_REGIONDATA->m_region );
447 M_REGIONDATA->m_region = reg;
b7c2d6ff 448#endif
5fc7ede9 449
3d0c4d2e 450#if OLDCODE
bbe0af5b
RR
451 wxNode *node = region.GetRectList()->First();
452 while (node)
453 {
454 wxRect *r = (wxRect*)node->Data();
455 M_REGIONDATA->m_rects.Append( (wxObject*) new wxRect(r->x,r->y,r->width,r->height) );
456 node = node->Next();
457 }
3d0c4d2e 458#endif
5fc7ede9 459
bbe0af5b 460 return TRUE;
ff7b1510 461}
c801d85f 462
1e6feb95
VZ
463// ----------------------------------------------------------------------------
464// wxRegion tests
465// ----------------------------------------------------------------------------
466
e1208c31 467void wxRegion::GetBox( wxCoord &x, wxCoord &y, wxCoord &w, wxCoord &h ) const
c801d85f 468{
1e6feb95
VZ
469 if ( m_refData )
470 {
471 GdkRectangle rect;
472 gdk_region_get_clipbox( M_REGIONDATA->m_region, &rect );
473 x = rect.x;
474 y = rect.y;
475 w = rect.width;
476 h = rect.height;
477 }
478 else
479 {
480 x = 0;
481 y = 0;
482 w = -1;
483 h = -1;
484 }
ff7b1510 485}
c801d85f 486
bf57d1ad 487wxRect wxRegion::GetBox() const
c801d85f 488{
1e6feb95 489 wxCoord x, y, w, h;
bbe0af5b
RR
490 GetBox( x, y, w, h );
491 return wxRect( x, y, w, h );
ff7b1510 492}
c801d85f 493
bf57d1ad 494bool wxRegion::Empty() const
c801d85f 495{
e1208c31
RR
496 if (!m_refData)
497 return TRUE;
498
bbe0af5b 499 return gdk_region_empty( M_REGIONDATA->m_region );
ff7b1510 500}
c801d85f 501
5fc7ede9 502wxRegionContain wxRegion::Contains( wxCoord x, wxCoord y ) const
c801d85f 503{
e1208c31
RR
504 if (!m_refData)
505 return wxOutRegion;
506
bbe0af5b
RR
507 if (gdk_region_point_in( M_REGIONDATA->m_region, x, y ))
508 return wxInRegion;
509 else
510 return wxOutRegion;
ff7b1510 511}
c801d85f 512
5fc7ede9 513wxRegionContain wxRegion::Contains( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) const
c801d85f 514{
e1208c31
RR
515 if (!m_refData)
516 return wxOutRegion;
517
bbe0af5b
RR
518 GdkRectangle rect;
519 rect.x = x;
520 rect.y = y;
521 rect.width = w;
522 rect.height = h;
523 GdkOverlapType res = gdk_region_rect_in( M_REGIONDATA->m_region, &rect );
524 switch (res)
525 {
526 case GDK_OVERLAP_RECTANGLE_IN: return wxInRegion;
527 case GDK_OVERLAP_RECTANGLE_OUT: return wxOutRegion;
528 case GDK_OVERLAP_RECTANGLE_PART: return wxPartRegion;
529 }
530 return wxOutRegion;
ff7b1510 531}
c801d85f 532
8429bec1
RR
533wxRegionContain wxRegion::Contains(const wxPoint& pt) const
534{
bbe0af5b 535 return Contains( pt.x, pt.y );
8429bec1
RR
536}
537
538wxRegionContain wxRegion::Contains(const wxRect& rect) const
539{
bbe0af5b 540 return Contains( rect.x, rect.y, rect.width, rect.height );
8429bec1
RR
541}
542
bf57d1ad 543GdkRegion *wxRegion::GetRegion() const
c801d85f 544{
e1208c31
RR
545 if (!m_refData)
546 return (GdkRegion*) NULL;
547
bbe0af5b 548 return M_REGIONDATA->m_region;
ff7b1510 549}
c801d85f 550
8429bec1
RR
551wxList *wxRegion::GetRectList() const
552{
3d0c4d2e 553#if OLDCODE
e1208c31
RR
554 if (!m_refData)
555 return (wxList*) NULL;
556
bbe0af5b 557 return &(M_REGIONDATA->m_rects);
3d0c4d2e
RR
558#else
559 return (wxList*) NULL;
560#endif
8429bec1
RR
561}
562
1e6feb95 563// ----------------------------------------------------------------------------
3d0c4d2e 564// wxRegionIterator
1e6feb95 565// ----------------------------------------------------------------------------
8429bec1 566
3d0c4d2e
RR
567#if OLDCODE
568
bf57d1ad 569wxRegionIterator::wxRegionIterator()
8429bec1 570{
6f2a55e3 571 Reset();
8429bec1
RR
572}
573
574wxRegionIterator::wxRegionIterator( const wxRegion& region )
575{
6f2a55e3 576 Reset(region);
8429bec1
RR
577}
578
579void wxRegionIterator::Reset( const wxRegion& region )
580{
bbe0af5b 581 m_region = region;
6f2a55e3 582 Reset();
8429bec1
RR
583}
584
5fc7ede9
VZ
585wxRegionIterator::operator bool () const
586{
3d0c4d2e 587 return m_region.GetRectList() && m_current < (size_t)m_region.GetRectList()->Number();
8429bec1
RR
588}
589
5fc7ede9
VZ
590bool wxRegionIterator::HaveRects() const
591{
3d0c4d2e 592 return m_region.GetRectList() && m_current < (size_t)m_region.GetRectList()->Number();
8429bec1
RR
593}
594
bf57d1ad 595void wxRegionIterator::operator ++ ()
8429bec1 596{
3d0c4d2e 597 if (HaveRects()) ++m_current;
8429bec1
RR
598}
599
600void wxRegionIterator::operator ++ (int)
601{
3d0c4d2e 602 if (HaveRects()) ++m_current;
8429bec1
RR
603}
604
bf57d1ad 605wxCoord wxRegionIterator::GetX() const
8429bec1 606{
bbe0af5b
RR
607 wxNode *node = m_region.GetRectList()->Nth( m_current );
608 if (!node) return 0;
609 wxRect *r = (wxRect*)node->Data();
610 return r->x;
8429bec1
RR
611}
612
bf57d1ad 613wxCoord wxRegionIterator::GetY() const
8429bec1 614{
bbe0af5b
RR
615 wxNode *node = m_region.GetRectList()->Nth( m_current );
616 if (!node) return 0;
617 wxRect *r = (wxRect*)node->Data();
618 return r->y;
8429bec1
RR
619}
620
bf57d1ad 621wxCoord wxRegionIterator::GetW() const
8429bec1 622{
bbe0af5b
RR
623 wxNode *node = m_region.GetRectList()->Nth( m_current );
624 if (!node) return 0;
625 wxRect *r = (wxRect*)node->Data();
626 return r->width;
8429bec1
RR
627}
628
bf57d1ad 629wxCoord wxRegionIterator::GetH() const
8429bec1 630{
bbe0af5b
RR
631 wxNode *node = m_region.GetRectList()->Nth( m_current );
632 if (!node) return 0;
633 wxRect *r = (wxRect*)node->Data();
634 return r->height;
8429bec1
RR
635}
636
3d0c4d2e
RR
637#else
638
639// the following structures must match the private structures
640// in X11 region code ( xc/lib/X11/region.h )
641
642// this makes the Region type transparent
643// and we have access to the region rectangles
644
645struct _XBox {
646 short x1, x2, y1, y2;
647};
1e6feb95 648
3d0c4d2e
RR
649struct _XRegion {
650 long size , numRects;
651 _XBox *rects, extents;
652};
653
654class wxRIRefData: public wxObjectRefData
655{
656public:
657
658 wxRIRefData() : m_rects(0), m_numRects(0){}
659 ~wxRIRefData();
660
661 wxRect *m_rects;
662 size_t m_numRects;
663
664 void CreateRects( const wxRegion& r );
665};
666
667wxRIRefData::~wxRIRefData()
668{
669 delete m_rects;
670}
671
672#include <gdk/gdkprivate.h>
673
674void wxRIRefData::CreateRects( const wxRegion& region )
675{
676 if( m_rects )
677 delete m_rects;
678 m_rects = 0;
679 m_numRects= 0;
680 GdkRegion *gdkregion= region.GetRegion();
681 if( gdkregion ){
682 Region r= ((GdkRegionPrivate *)gdkregion)->xregion;
683 if( r ){
684 m_numRects= r->numRects;
685 if( m_numRects )
686 {
687 m_rects= new wxRect[m_numRects];
688 for( size_t i=0; i<m_numRects; ++i )
689 {
690 _XBox &xr= r->rects[i];
691 wxRect&wr= m_rects[i];
692 wr.x = xr.x1;
693 wr.y = xr.y1;
694 wr.width = xr.x2-xr.x1;
695 wr.height= xr.y2-xr.y1;
696 }
697 }
698 }
699 }
700}
701
3d0c4d2e
RR
702wxRegionIterator::wxRegionIterator()
703{
704 m_refData = new wxRIRefData();
705 Reset();
706}
707
708wxRegionIterator::wxRegionIterator( const wxRegion& region )
709{
710 m_refData = new wxRIRefData();
711 Reset(region);
712}
713
714void wxRegionIterator::Reset( const wxRegion& region )
715{
716 m_region = region;
717 ((wxRIRefData*)m_refData)->CreateRects(region);
718 Reset();
719}
720
721bool wxRegionIterator::HaveRects() const
722{
723 return m_current < ((wxRIRefData*)m_refData)->m_numRects;
724}
725
726wxRegionIterator::operator bool () const
727{
728 return HaveRects();
729}
730
731void wxRegionIterator::operator ++ ()
732{
733 if (HaveRects()) ++m_current;
734}
735
736void wxRegionIterator::operator ++ (int)
737{
738 if (HaveRects()) ++m_current;
739}
740
741wxCoord wxRegionIterator::GetX() const
742{
743 if( !HaveRects() ) return 0;
744 return ((wxRIRefData*)m_refData)->m_rects[m_current].x;
745}
746
747wxCoord wxRegionIterator::GetY() const
748{
749 if( !HaveRects() ) return 0;
750 return ((wxRIRefData*)m_refData)->m_rects[m_current].y;
751}
752
753wxCoord wxRegionIterator::GetW() const
754{
755 if( !HaveRects() ) return -1;
756 return ((wxRIRefData*)m_refData)->m_rects[m_current].width;
757}
758
759wxCoord wxRegionIterator::GetH() const
760{
761 if( !HaveRects() ) return -1;
762 return ((wxRIRefData*)m_refData)->m_rects[m_current].height;
763}
764
1e6feb95
VZ
765wxRect wxRegionIterator::GetRect() const
766{
767 wxRect r;
768 wxNode *node = m_region.GetRectList()->Nth( m_current );
769
770 if (node)
771 r = *((wxRect*)node->Data());
772
773 return r;
774}
775
3d0c4d2e 776#endif
8429bec1 777