1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/region.cpp 
   4 // Author:      Robert Roebling 
   5 // Modified:    VZ at 05.10.00: use AllocExclusive(), comparison fixed 
   7 // Copyright:   (c) 1998 Robert Roebling 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 // For compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  22 #include "wx/region.h" 
  28 #include "wx/gtk/private.h" 
  31 // ---------------------------------------------------------------------------- 
  32 // wxRegionRefData: private class containing the information about the region 
  33 // ---------------------------------------------------------------------------- 
  35 class wxRegionRefData 
: public wxObjectRefData
 
  43     wxRegionRefData(const wxRegionRefData
& refData
) 
  46         m_region 
= gdk_region_copy(refData
.m_region
); 
  49     virtual ~wxRegionRefData() 
  52             gdk_region_destroy( m_region 
); 
  58 // ---------------------------------------------------------------------------- 
  60 // ---------------------------------------------------------------------------- 
  62 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  63 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData)) 
  65 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
) 
  66 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
) 
  68 // ---------------------------------------------------------------------------- 
  69 // wxRegion construction 
  70 // ---------------------------------------------------------------------------- 
  72 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  74 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) 
  82     m_refData 
= new wxRegionRefData(); 
  84     M_REGIONDATA
->m_region 
= gdk_region_rectangle( &rect 
); 
  87 wxRegion::wxRegion( GdkRegion 
*region 
) 
  89     m_refData 
= new wxRegionRefData(); 
  90     M_REGIONDATA
->m_region 
= gdk_region_copy( region 
); 
  93 wxRegion::wxRegion( size_t n
, const wxPoint 
*points
, int fillStyle 
) 
  95     GdkPoint 
*gdkpoints 
= new GdkPoint
[n
]; 
  96     for ( size_t i 
= 0 ; i 
< n 
; i
++ ) 
  98         gdkpoints
[i
].x 
= points
[i
].x
; 
  99         gdkpoints
[i
].y 
= points
[i
].y
; 
 102     m_refData 
= new wxRegionRefData(); 
 104     GdkRegion
* reg 
= gdk_region_polygon
 
 108                         fillStyle 
== wxWINDING_RULE 
? GDK_WINDING_RULE
 
 112     M_REGIONDATA
->m_region 
= reg
; 
 117 wxRegion::~wxRegion() 
 119     // m_refData unrefed in ~wxObject 
 122 wxObjectRefData 
*wxRegion::CreateRefData() const 
 124     return new wxRegionRefData
; 
 127 wxObjectRefData 
*wxRegion::CloneRefData(const wxObjectRefData 
*data
) const 
 129     return new wxRegionRefData(*(wxRegionRefData 
*)data
); 
 132 // ---------------------------------------------------------------------------- 
 133 // wxRegion comparison 
 134 // ---------------------------------------------------------------------------- 
 136 bool wxRegion::DoIsEqual(const wxRegion
& region
) const 
 138     return gdk_region_equal(M_REGIONDATA
->m_region
, 
 139                             M_REGIONDATA_OF(region
)->m_region
); 
 142 // ---------------------------------------------------------------------------- 
 143 // wxRegion operations 
 144 // ---------------------------------------------------------------------------- 
 146 void wxRegion::Clear() 
 151 bool wxRegion::DoUnionWithRect(const wxRect
& r
) 
 153     // workaround for a strange GTK/X11 bug: taking union with an empty 
 154     // rectangle results in an empty region which is definitely not what we 
 161         InitRect(r
.x
, r
.y
, r
.width
, r
.height
); 
 170         rect
.width 
= r
.width
; 
 171         rect
.height 
= r
.height
; 
 173         gdk_region_union_with_rect( M_REGIONDATA
->m_region
, &rect 
); 
 179 bool wxRegion::DoUnionWithRegion( const wxRegion
& region 
) 
 181     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 185         m_refData 
= new wxRegionRefData(); 
 186         M_REGIONDATA
->m_region 
= gdk_region_new(); 
 193     gdk_region_union( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 198 bool wxRegion::DoIntersect( const wxRegion
& region 
) 
 200     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 204         // intersecting with invalid region doesn't make sense 
 210     gdk_region_intersect( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 215 bool wxRegion::DoSubtract( const wxRegion
& region 
) 
 217     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 221         // subtracting from an invalid region doesn't make sense 
 227     gdk_region_subtract( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 232 bool wxRegion::DoXor( const wxRegion
& region 
) 
 234     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 243     gdk_region_xor( M_REGIONDATA
->m_region
, region
.GetRegion() ); 
 248 bool wxRegion::DoOffset( wxCoord x
, wxCoord y 
) 
 255     gdk_region_offset( M_REGIONDATA
->m_region
, x
, y 
); 
 260 // ---------------------------------------------------------------------------- 
 262 // ---------------------------------------------------------------------------- 
 264 bool wxRegion::DoGetBox( wxCoord 
&x
, wxCoord 
&y
, wxCoord 
&w
, wxCoord 
&h 
) const 
 269         gdk_region_get_clipbox( M_REGIONDATA
->m_region
, &rect 
); 
 288 bool wxRegion::IsEmpty() const 
 293     return gdk_region_empty( M_REGIONDATA
->m_region 
); 
 296 wxRegionContain 
wxRegion::DoContainsPoint( wxCoord x
, wxCoord y 
) const 
 301     if (gdk_region_point_in( M_REGIONDATA
->m_region
, x
, y 
)) 
 307 wxRegionContain 
wxRegion::DoContainsRect(const wxRect
& r
) const 
 315     rect
.width 
= r
.width
; 
 316     rect
.height 
= r
.height
; 
 317     GdkOverlapType res 
= gdk_region_rect_in( M_REGIONDATA
->m_region
, &rect 
); 
 320         case GDK_OVERLAP_RECTANGLE_IN
:   return wxInRegion
; 
 321         case GDK_OVERLAP_RECTANGLE_OUT
:  return wxOutRegion
; 
 322         case GDK_OVERLAP_RECTANGLE_PART
: return wxPartRegion
; 
 327 GdkRegion 
*wxRegion::GetRegion() const 
 330         return (GdkRegion
*) NULL
; 
 332     return M_REGIONDATA
->m_region
; 
 335 // ---------------------------------------------------------------------------- 
 337 // ---------------------------------------------------------------------------- 
 339 wxRegionIterator::wxRegionIterator() 
 345 wxRegionIterator::wxRegionIterator( const wxRegion
& region 
) 
 351 void wxRegionIterator::Init() 
 357 wxRegionIterator::~wxRegionIterator() 
 362 void wxRegionIterator::CreateRects( const wxRegion
& region 
) 
 367     GdkRegion 
*gdkregion 
= region
.GetRegion(); 
 371     GdkRectangle 
*gdkrects 
= NULL
; 
 373     gdk_region_get_rectangles( gdkregion
, &gdkrects
, &numRects 
); 
 375     m_numRects 
= numRects
; 
 378         m_rects 
= new wxRect
[m_numRects
]; 
 379         for (size_t i
=0; i 
< m_numRects
; ++i
) 
 381             GdkRectangle 
&gr 
= gdkrects
[i
]; 
 382             wxRect 
&wr 
= m_rects
[i
]; 
 386             wr
.height 
= gr
.height
; 
 392 void wxRegionIterator::Reset( const wxRegion
& region 
) 
 399 bool wxRegionIterator::HaveRects() const 
 401     return m_current 
< m_numRects
; 
 404 wxRegionIterator
& wxRegionIterator::operator ++ () 
 412 wxRegionIterator 
wxRegionIterator::operator ++ (int) 
 414     wxRegionIterator tmp 
= *this; 
 422 wxCoord 
wxRegionIterator::GetX() const 
 424     wxCHECK_MSG( HaveRects(), 0, _T("invalid wxRegionIterator") ); 
 426     return m_rects
[m_current
].x
; 
 429 wxCoord 
wxRegionIterator::GetY() const 
 431     wxCHECK_MSG( HaveRects(), 0, _T("invalid wxRegionIterator") ); 
 433     return m_rects
[m_current
].y
; 
 436 wxCoord 
wxRegionIterator::GetW() const 
 438     wxCHECK_MSG( HaveRects(), 0, _T("invalid wxRegionIterator") ); 
 440     return m_rects
[m_current
].width
; 
 443 wxCoord 
wxRegionIterator::GetH() const 
 445     wxCHECK_MSG( HaveRects(), 0, _T("invalid wxRegionIterator") ); 
 447     return m_rects
[m_current
].height
; 
 450 wxRect 
wxRegionIterator::GetRect() const 
 454         r 
= m_rects
[m_current
]; 
 459 wxRegionIterator
& wxRegionIterator::operator=(const wxRegionIterator
& ri
) 
 463     m_current 
= ri
.m_current
; 
 464     m_numRects 
= ri
.m_numRects
; 
 467         m_rects 
= new wxRect
[m_numRects
]; 
 468         for ( unsigned int n 
= 0; n 
< m_numRects
; n
++ ) 
 469             m_rects
[n
] = ri
.m_rects
[n
];