]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/region.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  12 #pragma implementation "region.h" 
  15 #include "wx/region.h" 
  16 #include "wx/gdicmn.h" 
  20 #pragma message disable nosimpint 
  22 #include "wx/x11/private.h" 
  23 #include "X11/Xutil.h" 
  25 #pragma message enable nosimpint 
  28 // ---------------------------------------------------------------------------- 
  29 // wxRegionRefData: private class containing the information about the region 
  30 // ---------------------------------------------------------------------------- 
  32 class wxRegionRefData 
: public wxObjectRefData
 
  40     wxRegionRefData(const wxRegionRefData
& refData
) 
  42         m_region 
= XCreateRegion(); 
  43         XUnionRegion( refData
.m_region
, m_region
, m_region 
); 
  49             XDestroyRegion( m_region 
); 
  55 // ---------------------------------------------------------------------------- 
  57 // ---------------------------------------------------------------------------- 
  59 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  60 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData)) 
  62 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
); 
  63 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
); 
  65 // ---------------------------------------------------------------------------- 
  66 // wxRegion construction 
  67 // ---------------------------------------------------------------------------- 
  69 #define M_REGIONDATA ((wxRegionRefData *)m_refData) 
  71 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) 
  79     m_refData 
= new wxRegionRefData(); 
  81     M_REGIONDATA
->m_region 
= XCreateRegion(); 
  82     XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region 
); 
  85 wxRegion::wxRegion( size_t n
, const wxPoint 
*points
, int fillStyle 
) 
  88     XPoint 
*xpoints 
= new XPoint
[n
]; 
  89     for ( size_t i 
= 0 ; i 
< n 
; i
++ ) 
  91         xpoints
[i
].x 
= points
[i
].x
; 
  92         xpoints
[i
].y 
= points
[i
].y
; 
  95     m_refData 
= new wxRegionRefData(); 
  97     Region
* reg 
= gdk_region_polygon
 
 101                         fillStyle 
== wxWINDING_RULE 
? GDK_WINDING_RULE
 
 105     M_REGIONDATA
->m_region 
= reg
; 
 111 wxRegion::~wxRegion() 
 113     // m_refData unrefed in ~wxObject 
 116 wxObjectRefData 
*wxRegion::CreateRefData() const 
 118     return new wxRegionRefData
; 
 121 wxObjectRefData 
*wxRegion::CloneRefData(const wxObjectRefData 
*data
) const 
 123     return new wxRegionRefData(*(wxRegionRefData 
*)data
); 
 126 // ---------------------------------------------------------------------------- 
 127 // wxRegion comparison 
 128 // ---------------------------------------------------------------------------- 
 130 bool wxRegion::operator==( const wxRegion
& region 
) 
 132     if (m_refData 
== region
.m_refData
) return TRUE
; 
 134     if (!m_refData 
|| !region
.m_refData
) return FALSE
; 
 136     // compare the regions themselves, not the pointers to ref data! 
 137     return XEqualRegion( M_REGIONDATA
->m_region
, 
 138                          M_REGIONDATA_OF(region
)->m_region 
); 
 141 // ---------------------------------------------------------------------------- 
 142 // wxRegion operations 
 143 // ---------------------------------------------------------------------------- 
 145 void wxRegion::Clear() 
 150 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 152     // work around for XUnionRectWithRegion() bug: taking a union with an empty 
 153     // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this 
 155     if ( !width 
|| !height 
) 
 162     rect
.height 
= height
; 
 166         m_refData 
= new wxRegionRefData(); 
 167         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 168         XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region 
); 
 174         XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region 
); 
 180 bool wxRegion::Union( const wxRect
& rect 
) 
 182     return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 185 bool wxRegion::Union( const wxRegion
& region 
) 
 192         m_refData 
= new wxRegionRefData(); 
 193         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 200     XUnionRegion( M_REGIONDATA
->m_region
, 
 201                   M_REGIONDATA_OF(region
)->m_region
, 
 202                   M_REGIONDATA
->m_region 
); 
 207 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 209     wxRegion 
reg( x
, y
, width
, height 
); 
 211     return Intersect( reg 
); 
 214 bool wxRegion::Intersect( const wxRect
& rect 
) 
 216     wxRegion 
reg( rect 
); 
 218     return Intersect( reg 
); 
 221 bool wxRegion::Intersect( const wxRegion
& region 
) 
 228         m_refData 
= new wxRegionRefData(); 
 229         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 239     XIntersectRegion( M_REGIONDATA
->m_region
, 
 240                       M_REGIONDATA_OF(region
)->m_region
, 
 241                       M_REGIONDATA
->m_region 
); 
 246 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 248     wxRegion 
reg( x
, y
, width
, height 
); 
 249     return Subtract( reg 
); 
 252 bool wxRegion::Subtract( const wxRect
& rect 
) 
 254     wxRegion 
reg( rect 
); 
 255     return Subtract( reg 
); 
 258 bool wxRegion::Subtract( const wxRegion
& region 
) 
 265         m_refData 
= new wxRegionRefData(); 
 266         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 273     XSubtractRegion( M_REGIONDATA
->m_region
, 
 274                      M_REGIONDATA_OF(region
)->m_region
, 
 275                      M_REGIONDATA
->m_region 
); 
 280 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height 
) 
 282     wxRegion 
reg( x
, y
, width
, height 
); 
 286 bool wxRegion::Xor( const wxRect
& rect 
) 
 288     wxRegion 
reg( rect 
); 
 292 bool wxRegion::Xor( const wxRegion
& region 
) 
 299         m_refData 
= new wxRegionRefData(); 
 300         M_REGIONDATA
->m_region 
= XCreateRegion(); 
 307     XXorRegion( M_REGIONDATA
->m_region
, 
 308                 M_REGIONDATA_OF(region
)->m_region
, 
 309                 M_REGIONDATA
->m_region 
); 
 314 // ---------------------------------------------------------------------------- 
 316 // ---------------------------------------------------------------------------- 
 318 void wxRegion::GetBox( wxCoord 
&x
, wxCoord 
&y
, wxCoord 
&w
, wxCoord 
&h 
) const 
 323         XClipBox( M_REGIONDATA
->m_region
, &rect 
); 
 338 wxRect 
wxRegion::GetBox() const 
 341     GetBox( x
, y
, w
, h 
); 
 342     return wxRect( x
, y
, w
, h 
); 
 345 bool wxRegion::Offset( wxCoord x
, wxCoord y 
) 
 352     XOffsetRegion( M_REGIONDATA
->m_region
, x
, y 
); 
 357 bool wxRegion::Empty() const 
 362     return XEmptyRegion( M_REGIONDATA
->m_region 
); 
 365 wxRegionContain 
wxRegion::Contains( wxCoord x
, wxCoord y 
) const 
 370     if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y 
)) 
 376 wxRegionContain 
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h 
) const 
 381     int res 
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h 
); 
 384         case RectangleIn
:   return wxInRegion
; 
 385         case RectangleOut
:  return wxOutRegion
; 
 386         case RectanglePart
: return wxPartRegion
; 
 391 wxRegionContain 
wxRegion::Contains(const wxPoint
& pt
) const 
 393     return Contains( pt
.x
, pt
.y 
); 
 396 wxRegionContain 
wxRegion::Contains(const wxRect
& rect
) const 
 398     return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height 
); 
 401 WXRegion 
*wxRegion::GetX11Region() const 
 404         return (WXRegion
*) NULL
; 
 406     return (WXRegion
*) M_REGIONDATA
->m_region
; 
 409 // ---------------------------------------------------------------------------- 
 411 // ---------------------------------------------------------------------------- 
 413 // the following structures must match the private structures 
 414 // in X11 region code ( xc/lib/X11/region.h ) 
 416 // this makes the Region type transparent 
 417 // and we have access to the region rectangles 
 420     short x1
, x2
, y1
, y2
; 
 424     long   size 
, numRects
; 
 425     _XBox 
*rects
, extents
; 
 428 class wxRIRefData
: public wxObjectRefData
 
 432     wxRIRefData() : m_rects(0), m_numRects(0){} 
 438     void CreateRects( const wxRegion
& r 
); 
 441 wxRIRefData::~wxRIRefData() 
 446 void wxRIRefData::CreateRects( const wxRegion
& region 
) 
 454     if (region
.IsEmpty()) return; 
 456     Region r 
= (Region
) region
.GetX11Region(); 
 461         GrGetRegionBox(r
, & rect
); 
 463         m_rects 
= new wxRect
[1]; 
 464         m_rects
[0].x 
= rect
.x
; 
 465         m_rects
[0].y 
= rect
.y
; 
 466         m_rects
[0].width 
= rect
.width
; 
 467         m_rects
[0].height 
= rect
.height
; 
 469         m_numRects 
= r
->numRects
; 
 472             m_rects 
= new wxRect
[m_numRects
]; 
 473             for (size_t i
=0; i 
< m_numRects
; ++i
) 
 475                 _XBox 
&xr 
= r
->rects
[i
]; 
 476                 wxRect 
&wr 
= m_rects
[i
]; 
 479                 wr
.width 
= xr
.x2
-xr
.x1
; 
 480                 wr
.height 
= xr
.y2
-xr
.y1
; 
 487 wxRegionIterator::wxRegionIterator() 
 489     m_refData 
= new wxRIRefData(); 
 493 wxRegionIterator::wxRegionIterator( const wxRegion
& region 
) 
 495     m_refData 
= new wxRIRefData(); 
 499 void wxRegionIterator::Reset( const wxRegion
& region 
) 
 502     ((wxRIRefData
*)m_refData
)->CreateRects(region
); 
 506 bool wxRegionIterator::HaveRects() const 
 508     return m_current 
< ((wxRIRefData
*)m_refData
)->m_numRects
; 
 511 wxRegionIterator::operator bool () const 
 516 void wxRegionIterator::operator ++ () 
 518     if (HaveRects()) ++m_current
; 
 521 void wxRegionIterator::operator ++ (int) 
 523     if (HaveRects()) ++m_current
; 
 526 wxCoord 
wxRegionIterator::GetX() const 
 528     if( !HaveRects() ) return 0; 
 529     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
; 
 532 wxCoord 
wxRegionIterator::GetY() const 
 534     if( !HaveRects() ) return 0; 
 535     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
; 
 538 wxCoord 
wxRegionIterator::GetW() const 
 540     if( !HaveRects() ) return -1; 
 541     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
; 
 544 wxCoord 
wxRegionIterator::GetH() const 
 546     if( !HaveRects() ) return -1; 
 547     return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
; 
 550 wxRect 
wxRegionIterator::GetRect() const 
 554         r 
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];