]>
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 wxGDIRefData
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
), wxPolygonFillMode
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 wxGDIRefData
*wxRegion::CreateGDIRefData() const
120 return new wxRegionRefData
;
123 wxGDIRefData
*wxRegion::CloneGDIRefData(const wxGDIRefData
*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, wxT("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, wxT("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, wxT("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, wxT("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
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 wxGDIRefData
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
];