1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/region.cpp
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "region.h"
14 #include "wx/region.h"
21 //-----------------------------------------------------------------------------
23 //-----------------------------------------------------------------------------
25 class wxRegionRefData
: public wxObjectRefData
37 wxRegionRefData::wxRegionRefData()
39 m_region
= (GdkRegion
*) NULL
;
42 wxRegionRefData::~wxRegionRefData()
44 if (m_region
) gdk_region_destroy( m_region
);
47 wxNode
*node
= m_rects
.First();
50 wxRect
*r
= (wxRect
*)node
->Data();
57 //-----------------------------------------------------------------------------
59 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
61 IMPLEMENT_DYNAMIC_CLASS(wxRegion
,wxGDIObject
);
63 wxRegion::wxRegion( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
65 m_refData
= new wxRegionRefData();
66 GdkRegion
*reg
= gdk_region_new();
73 gdk_region_union_with_rect( reg
, &rect
);
74 M_REGIONDATA
->m_region
= reg
;
76 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
77 gdk_region_destroy( reg
);
80 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,w
,h
) );
84 wxRegion::wxRegion( const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
86 m_refData
= new wxRegionRefData();
87 GdkRegion
*reg
= gdk_region_new();
91 rect
.width
= bottomRight
.x
- rect
.x
;
92 rect
.height
= bottomRight
.y
- rect
.y
;
94 gdk_region_union_with_rect( reg
, &rect
);
95 M_REGIONDATA
->m_region
= reg
;
97 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
98 gdk_region_destroy( reg
);
101 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(topLeft
,bottomRight
) );
105 wxRegion::wxRegion( const wxRect
& rect
)
107 m_refData
= new wxRegionRefData();
108 GdkRegion
*reg
= gdk_region_new();
112 g_rect
.width
= rect
.width
;
113 g_rect
.height
= rect
.height
;
115 gdk_region_union_with_rect( reg
, &g_rect
);
116 M_REGIONDATA
->m_region
= reg
;
118 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &g_rect
);
119 gdk_region_destroy( reg
);
122 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(rect
.x
,rect
.y
,rect
.width
,rect
.height
) );
130 wxRegion::~wxRegion()
134 bool wxRegion::operator == ( const wxRegion
& region
)
136 return m_refData
== region
.m_refData
;
139 bool wxRegion::operator != ( const wxRegion
& region
)
141 return m_refData
!= region
.m_refData
;
144 void wxRegion::Clear()
149 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
155 rect
.height
= height
;
158 m_refData
= new wxRegionRefData();
159 GdkRegion
*reg
= gdk_region_new();
161 gdk_region_union_with_rect( reg
, &rect
);
162 M_REGIONDATA
->m_region
= reg
;
164 M_REGIONDATA
->m_region
= gdk_region_union_with_rect( reg
, &rect
);
165 gdk_region_destroy( reg
);
171 gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
173 GdkRegion
*reg
= gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect
);
174 gdk_region_destroy( M_REGIONDATA
->m_region
);
175 M_REGIONDATA
->m_region
= reg
;
180 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(x
,y
,width
,height
) );
186 bool wxRegion::Union( const wxRect
& rect
)
188 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
191 bool wxRegion::Union( const wxRegion
& region
)
198 m_refData
= new wxRegionRefData();
199 M_REGIONDATA
->m_region
= gdk_region_new();
203 gdk_region_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
205 GdkRegion
*reg
= gdk_regions_union( M_REGIONDATA
->m_region
, region
.GetRegion() );
206 gdk_region_destroy( M_REGIONDATA
->m_region
);
207 M_REGIONDATA
->m_region
= reg
;
211 wxNode
*node
= region
.GetRectList()->First();
214 wxRect
*r
= (wxRect
*)node
->Data();
215 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
223 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
227 m_refData
= new wxRegionRefData();
228 M_REGIONDATA
->m_region
= gdk_region_new();
231 wxRegion
reg( x
, y
, width
, height
);
236 bool wxRegion::Intersect( const wxRect
& rect
)
240 m_refData
= new wxRegionRefData();
241 M_REGIONDATA
->m_region
= gdk_region_new();
244 wxRegion
reg( rect
);
249 bool wxRegion::Intersect( const wxRegion
& region
)
256 m_refData
= new wxRegionRefData();
257 M_REGIONDATA
->m_region
= gdk_region_new();
262 gdk_region_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
264 GdkRegion
*reg
= gdk_regions_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() );
265 gdk_region_destroy( M_REGIONDATA
->m_region
);
266 M_REGIONDATA
->m_region
= reg
;
271 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
275 m_refData
= new wxRegionRefData();
276 M_REGIONDATA
->m_region
= gdk_region_new();
279 wxRegion
reg( x
, y
, width
, height
);
284 bool wxRegion::Subtract( const wxRect
& rect
)
288 m_refData
= new wxRegionRefData();
289 M_REGIONDATA
->m_region
= gdk_region_new();
292 wxRegion
reg( rect
);
297 bool wxRegion::Subtract( const wxRegion
& region
)
304 m_refData
= new wxRegionRefData();
305 M_REGIONDATA
->m_region
= gdk_region_new();
309 gdk_region_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
311 GdkRegion
*reg
= gdk_regions_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() );
312 gdk_region_destroy( M_REGIONDATA
->m_region
);
313 M_REGIONDATA
->m_region
= reg
;
318 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
322 m_refData
= new wxRegionRefData();
323 M_REGIONDATA
->m_region
= gdk_region_new();
326 wxRegion
reg( x
, y
, width
, height
);
331 bool wxRegion::Xor( const wxRect
& rect
)
335 m_refData
= new wxRegionRefData();
336 M_REGIONDATA
->m_region
= gdk_region_new();
339 wxRegion
reg( rect
);
344 bool wxRegion::Xor( const wxRegion
& region
)
351 m_refData
= new wxRegionRefData();
352 M_REGIONDATA
->m_region
= gdk_region_new();
356 gdk_region_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
358 GdkRegion
*reg
= gdk_regions_xor( M_REGIONDATA
->m_region
, region
.GetRegion() );
359 gdk_region_destroy( M_REGIONDATA
->m_region
);
360 M_REGIONDATA
->m_region
= reg
;
364 wxNode
*node
= region
.GetRectList()->First();
367 wxRect
*r
= (wxRect
*)node
->Data();
368 M_REGIONDATA
->m_rects
.Append( (wxObject
*) new wxRect(r
->x
,r
->y
,r
->width
,r
->height
) );
376 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
386 gdk_region_get_clipbox( M_REGIONDATA
->m_region
, &rect
);
393 wxRect
wxRegion::GetBox() const
399 GetBox( x
, y
, w
, h
);
400 return wxRect( x
, y
, w
, h
);
403 bool wxRegion::Empty() const
408 return gdk_region_empty( M_REGIONDATA
->m_region
);
411 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
416 if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y
))
422 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
432 GdkOverlapType res
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect
);
435 case GDK_OVERLAP_RECTANGLE_IN
: return wxInRegion
;
436 case GDK_OVERLAP_RECTANGLE_OUT
: return wxOutRegion
;
437 case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
;
442 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
444 return Contains( pt
.x
, pt
.y
);
447 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
449 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
452 GdkRegion
*wxRegion::GetRegion() const
455 return (GdkRegion
*) NULL
;
457 return M_REGIONDATA
->m_region
;
460 wxList
*wxRegion::GetRectList() const
464 return (wxList
*) NULL
;
466 return &(M_REGIONDATA
->m_rects
);
468 return (wxList
*) NULL
;
472 //-----------------------------------------------------------------------------
474 //-----------------------------------------------------------------------------
478 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
480 wxRegionIterator::wxRegionIterator()
485 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
490 void wxRegionIterator::Reset( const wxRegion
& region
)
496 wxRegionIterator::operator bool () const
498 return m_region
.GetRectList() && m_current
< (size_t)m_region
.GetRectList()->Number();
501 bool wxRegionIterator::HaveRects() const
503 return m_region
.GetRectList() && m_current
< (size_t)m_region
.GetRectList()->Number();
506 void wxRegionIterator::operator ++ ()
508 if (HaveRects()) ++m_current
;
511 void wxRegionIterator::operator ++ (int)
513 if (HaveRects()) ++m_current
;
516 wxCoord
wxRegionIterator::GetX() const
518 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
520 wxRect
*r
= (wxRect
*)node
->Data();
524 wxCoord
wxRegionIterator::GetY() const
526 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
528 wxRect
*r
= (wxRect
*)node
->Data();
532 wxCoord
wxRegionIterator::GetW() const
534 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
536 wxRect
*r
= (wxRect
*)node
->Data();
540 wxCoord
wxRegionIterator::GetH() const
542 wxNode
*node
= m_region
.GetRectList()->Nth( m_current
);
544 wxRect
*r
= (wxRect
*)node
->Data();
550 // the following structures must match the private structures
551 // in X11 region code ( xc/lib/X11/region.h )
553 // this makes the Region type transparent
554 // and we have access to the region rectangles
557 short x1
, x2
, y1
, y2
;
561 long size
, numRects
;
562 _XBox
*rects
, extents
;
565 class wxRIRefData
: public wxObjectRefData
569 wxRIRefData() : m_rects(0), m_numRects(0){}
575 void CreateRects( const wxRegion
& r
);
578 wxRIRefData::~wxRIRefData()
583 #include <gdk/gdkprivate.h>
585 void wxRIRefData::CreateRects( const wxRegion
& region
)
591 GdkRegion
*gdkregion
= region
.GetRegion();
593 Region r
= ((GdkRegionPrivate
*)gdkregion
)->xregion
;
595 m_numRects
= r
->numRects
;
598 m_rects
= new wxRect
[m_numRects
];
599 for( size_t i
=0; i
<m_numRects
; ++i
)
601 _XBox
&xr
= r
->rects
[i
];
602 wxRect
&wr
= m_rects
[i
];
605 wr
.width
= xr
.x2
-xr
.x1
;
606 wr
.height
= xr
.y2
-xr
.y1
;
613 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
615 wxRegionIterator::wxRegionIterator()
617 m_refData
= new wxRIRefData();
621 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
623 m_refData
= new wxRIRefData();
627 void wxRegionIterator::Reset( const wxRegion
& region
)
630 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
634 bool wxRegionIterator::HaveRects() const
636 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
639 wxRegionIterator::operator bool () const
644 void wxRegionIterator::operator ++ ()
646 if (HaveRects()) ++m_current
;
649 void wxRegionIterator::operator ++ (int)
651 if (HaveRects()) ++m_current
;
654 wxCoord
wxRegionIterator::GetX() const
656 if( !HaveRects() ) return 0;
657 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
660 wxCoord
wxRegionIterator::GetY() const
662 if( !HaveRects() ) return 0;
663 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
666 wxCoord
wxRegionIterator::GetW() const
668 if( !HaveRects() ) return -1;
669 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
672 wxCoord
wxRegionIterator::GetH() const
674 if( !HaveRects() ) return -1;
675 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;