]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/region.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // File:      src/x11/region.cpp 
   3 // Purpose:   Region class 
   4 // Author:    Julian Smart, Robert Roebling 
   5 // Created:   Fri Oct 24 10:46:34 MET 1997 
   7 // Copyright: (c) 1997 Julian Smart, Robert Roebling 
   8 // Licence:   wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // for compilers that support precompilation, includes "wx.h". 
  12 #include "wx/wxprec.h" 
  14 #include "wx/region.h" 
  18     #include "wx/gdicmn.h" 
  22 #pragma message disable nosimpint 
  24 #include "wx/x11/private.h" 
  25 #include "X11/Xutil.h" 
  27 #pragma message enable nosimpint 
  30 // ---------------------------------------------------------------------------- 
  31 // wxRegionRefData: private class containing the information about the region 
  32 // ---------------------------------------------------------------------------- 
  34 class wxRegionRefData 
: public wxObjectRefData
 
  42     wxRegionRefData(const wxRegionRefData
& refData
) 
  44         m_region 
= XCreateRegion(); 
  45         XUnionRegion( refData
.m_region
, m_region
, m_region 
); 
  48     virtual ~wxRegionRefData() 
  51             XDestroyRegion( m_region 
); 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  61 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  62 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData)) 
  64 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
) 
  65 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
) 
  67 // ---------------------------------------------------------------------------- 
  68 // wxRegion construction 
  69 // ---------------------------------------------------------------------------- 
  71 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  73 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) 
  78     rect
.width 
= (unsigned short)w
; 
  79     rect
.height 
= (unsigned short)h
; 
  81     m_refData 
= new wxRegionRefData(); 
  83     M_REGIONDATA
->m_region 
= XCreateRegion(); 
  84     XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region 
); 
  87 wxRegion::wxRegion( size_t WXUNUSED(n
), const wxPoint 
*WXUNUSED(points
), int WXUNUSED(fillStyle
) ) 
  90     XPoint 
*xpoints 
= new XPoint
[n
]; 
  91     for ( size_t i 
= 0 ; i 
< n 
; i
++ ) 
  93         xpoints
[i
].x 
= points
[i
].x
; 
  94         xpoints
[i
].y 
= points
[i
].y
; 
  97     m_refData 
= new wxRegionRefData(); 
  99     Region
* reg 
= gdk_region_polygon
 
 103                         fillStyle 
== wxWINDING_RULE 
? GDK_WINDING_RULE
 
 107     M_REGIONDATA
->m_region 
= reg
; 
 113 wxRegion::~wxRegion() 
 115     // m_refData unrefed in ~wxObject 
 118 wxObjectRefData 
*wxRegion::CreateRefData() const 
 120     return new wxRegionRefData
; 
 123 wxObjectRefData 
*wxRegion::CloneRefData(const wxObjectRefData 
*data
) const 
 125     return new wxRegionRefData(*(wxRegionRefData 
*)data
); 
 128 // ---------------------------------------------------------------------------- 
 129 // wxRegion comparison 
 130 // ---------------------------------------------------------------------------- 
 132 bool wxRegion::DoIsEqual(const wxRegion
& region
) const 
 134     return XEqualRegion( M_REGIONDATA
->m_region
, 
 135                          M_REGIONDATA_OF(region
)->m_region 
) == True
; 
 138 // ---------------------------------------------------------------------------- 
 139 // wxRegion operations 
 140 // ---------------------------------------------------------------------------- 
 142 void wxRegion::Clear() 
 147 bool wxRegion::DoUnionWithRect(const wxRect
& r
) 
 149     // work around for XUnionRectWithRegion() bug: taking a union with an empty 
 150     // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this 
 158     rect
.width 
= (unsigned short)r
.width
; 
 159     rect
.height 
= (unsigned short)r
.height
; 
 163         m_refData 
= new wxRegionRefData(); 
 164         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 171     XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region 
); 
 176 bool wxRegion::DoUnionWithRegion( const wxRegion
& region 
) 
 178     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 182         m_refData 
= new wxRegionRefData(); 
 183         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 190     XUnionRegion( M_REGIONDATA
->m_region
, 
 191                   M_REGIONDATA_OF(region
)->m_region
, 
 192                   M_REGIONDATA
->m_region 
); 
 197 bool wxRegion::DoIntersect( const wxRegion
& region 
) 
 199     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 203         m_refData 
= new wxRegionRefData(); 
 204         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 214     XIntersectRegion( M_REGIONDATA
->m_region
, 
 215                       M_REGIONDATA_OF(region
)->m_region
, 
 216                       M_REGIONDATA
->m_region 
); 
 221 bool wxRegion::DoSubtract( const wxRegion
& region 
) 
 223     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 227         m_refData 
= new wxRegionRefData(); 
 228         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 235     XSubtractRegion( M_REGIONDATA
->m_region
, 
 236                      M_REGIONDATA_OF(region
)->m_region
, 
 237                      M_REGIONDATA
->m_region 
); 
 242 bool wxRegion::DoXor( const wxRegion
& region 
) 
 244     wxCHECK_MSG( region
.Ok(), false, _T("invalid region") ); 
 248         m_refData 
= new wxRegionRefData(); 
 249         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 256     XXorRegion( M_REGIONDATA
->m_region
, 
 257                 M_REGIONDATA_OF(region
)->m_region
, 
 258                 M_REGIONDATA
->m_region 
); 
 263 // ---------------------------------------------------------------------------- 
 265 // ---------------------------------------------------------------------------- 
 267 bool wxRegion::DoGetBox( wxCoord 
&x
, wxCoord 
&y
, wxCoord 
&w
, wxCoord 
&h 
) const 
 272         XClipBox( M_REGIONDATA
->m_region
, &rect 
); 
 291 bool wxRegion::DoOffset( wxCoord x
, wxCoord y 
) 
 298     XOffsetRegion( M_REGIONDATA
->m_region
, x
, y 
); 
 303 bool wxRegion::IsEmpty() const 
 308     return XEmptyRegion( M_REGIONDATA
->m_region 
) == True
; 
 311 wxRegionContain 
wxRegion::DoContainsPoint( wxCoord x
, wxCoord y 
) const 
 316     if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y 
)) 
 322 wxRegionContain 
wxRegion::DoContainsRect(const wxRect
& r
) const 
 327     int res 
= XRectInRegion(M_REGIONDATA
->m_region
, r
.x
, r
.y
, r
.width
, r
.height
); 
 330         case RectangleIn
:   return wxInRegion
; 
 331         case RectangleOut
:  return wxOutRegion
; 
 332         case RectanglePart
: return wxPartRegion
; 
 337 WXRegion 
*wxRegion::GetX11Region() const 
 340         return (WXRegion
*) NULL
; 
 342     return (WXRegion
*) M_REGIONDATA
->m_region
; 
 345 // ---------------------------------------------------------------------------- 
 347 // ---------------------------------------------------------------------------- 
 349 // the following structures must match the private structures 
 350 // in X11 region code ( xc/lib/X11/region.h ) 
 352 // this makes the Region type transparent 
 353 // and we have access to the region rectangles 
 356     short x1
, x2
, y1
, y2
; 
 360     long   size 
, numRects
; 
 361     _XBox 
*rects
, extents
; 
 364 class wxRIRefData
: public wxObjectRefData
 
 368     wxRIRefData() : m_rects(0), m_numRects(0){} 
 369    virtual ~wxRIRefData(); 
 374     void CreateRects( const wxRegion
& r 
); 
 377 wxRIRefData::~wxRIRefData() 
 382 void wxRIRefData::CreateRects( const wxRegion
& region 
) 
 390     if (region
.IsEmpty()) return; 
 392     Region r 
= (Region
) region
.GetX11Region(); 
 397         GrGetRegionBox(r
, & rect
); 
 399         m_rects 
= new wxRect
[1]; 
 400         m_rects
[0].x 
= rect
.x
; 
 401         m_rects
[0].y 
= rect
.y
; 
 402         m_rects
[0].width 
= rect
.width
; 
 403         m_rects
[0].height 
= rect
.height
; 
 405         m_numRects 
= r
->numRects
; 
 408             m_rects 
= new wxRect
[m_numRects
]; 
 409             for (size_t i
=0; i 
< m_numRects
; ++i
) 
 411                 _XBox 
&xr 
= r
->rects
[i
]; 
 412                 wxRect 
&wr 
= m_rects
[i
]; 
 415                 wr
.width 
= xr
.x2
-xr
.x1
; 
 416                 wr
.height 
= xr
.y2
-xr
.y1
; 
 423 wxRegionIterator::wxRegionIterator() 
 425     m_refData 
= new wxRIRefData(); 
 429 wxRegionIterator::wxRegionIterator( const wxRegion
& region 
) 
 431     m_refData 
= new wxRIRefData(); 
 435 void wxRegionIterator::Reset( const wxRegion
& region 
) 
 438     ((wxRIRefData
*)m_refData
)->CreateRects(region
); 
 442 bool wxRegionIterator::HaveRects() const 
 444     return m_current 
< ((wxRIRefData
*)m_refData
)->m_numRects
; 
 447 wxRegionIterator::operator bool () const 
 452 void wxRegionIterator::operator ++ () 
 454     if (HaveRects()) ++m_current
; 
 457 void wxRegionIterator::operator ++ (int) 
 459     if (HaveRects()) ++m_current
; 
 462 wxCoord 
wxRegionIterator::GetX() const 
 464     if( !HaveRects() ) return 0; 
 465     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
; 
 468 wxCoord 
wxRegionIterator::GetY() const 
 470     if( !HaveRects() ) return 0; 
 471     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
; 
 474 wxCoord 
wxRegionIterator::GetW() const 
 476     if( !HaveRects() ) return -1; 
 477     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
; 
 480 wxCoord 
wxRegionIterator::GetH() const 
 482     if( !HaveRects() ) return -1; 
 483     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
; 
 486 wxRect 
wxRegionIterator::GetRect() const 
 490         r 
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];