]>
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
6 // Copyright: (c) 1997 Julian Smart, Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // for compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
13 #include "wx/region.h"
17 #include "wx/gdicmn.h"
21 #pragma message disable nosimpint
23 #include "wx/x11/private.h"
24 #include "X11/Xutil.h"
26 #pragma message enable nosimpint
29 // ----------------------------------------------------------------------------
30 // wxRegionRefData: private class containing the information about the region
31 // ----------------------------------------------------------------------------
33 class wxRegionRefData
: public wxGDIRefData
41 wxRegionRefData(const wxRegionRefData
& refData
)
43 m_region
= XCreateRegion();
44 XUnionRegion( refData
.m_region
, m_region
, m_region
);
47 virtual ~wxRegionRefData()
50 XDestroyRegion( m_region
);
56 // ----------------------------------------------------------------------------
58 // ----------------------------------------------------------------------------
60 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
61 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))
63 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
)
64 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
)
66 // ----------------------------------------------------------------------------
67 // wxRegion construction
68 // ----------------------------------------------------------------------------
70 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
72 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
77 rect
.width
= (unsigned short)w
;
78 rect
.height
= (unsigned short)h
;
80 m_refData
= new wxRegionRefData();
82 M_REGIONDATA
->m_region
= XCreateRegion();
83 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
86 wxRegion::wxRegion( size_t WXUNUSED(n
), const wxPoint
*WXUNUSED(points
), wxPolygonFillMode
WXUNUSED(fillStyle
) )
89 XPoint
*xpoints
= new XPoint
[n
];
90 for ( size_t i
= 0 ; i
< n
; i
++ )
92 xpoints
[i
].x
= points
[i
].x
;
93 xpoints
[i
].y
= points
[i
].y
;
96 m_refData
= new wxRegionRefData();
98 Region
* reg
= gdk_region_polygon
102 fillStyle
== wxWINDING_RULE
? GDK_WINDING_RULE
106 M_REGIONDATA
->m_region
= reg
;
112 wxRegion::~wxRegion()
114 // m_refData unrefed in ~wxObject
117 wxGDIRefData
*wxRegion::CreateGDIRefData() const
119 return new wxRegionRefData
;
122 wxGDIRefData
*wxRegion::CloneGDIRefData(const wxGDIRefData
*data
) const
124 return new wxRegionRefData(*(wxRegionRefData
*)data
);
127 // ----------------------------------------------------------------------------
128 // wxRegion comparison
129 // ----------------------------------------------------------------------------
131 bool wxRegion::DoIsEqual(const wxRegion
& region
) const
133 return XEqualRegion( M_REGIONDATA
->m_region
,
134 M_REGIONDATA_OF(region
)->m_region
) == True
;
137 // ----------------------------------------------------------------------------
138 // wxRegion operations
139 // ----------------------------------------------------------------------------
141 void wxRegion::Clear()
146 bool wxRegion::DoUnionWithRect(const wxRect
& r
)
148 // work around for XUnionRectWithRegion() bug: taking a union with an empty
149 // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
157 rect
.width
= (unsigned short)r
.width
;
158 rect
.height
= (unsigned short)r
.height
;
162 m_refData
= new wxRegionRefData();
163 M_REGIONDATA
->m_region
= XCreateRegion();
170 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
175 bool wxRegion::DoUnionWithRegion( const wxRegion
& region
)
177 wxCHECK_MSG( region
.IsOk(), false, wxT("invalid region") );
181 m_refData
= new wxRegionRefData();
182 M_REGIONDATA
->m_region
= XCreateRegion();
189 XUnionRegion( M_REGIONDATA
->m_region
,
190 M_REGIONDATA_OF(region
)->m_region
,
191 M_REGIONDATA
->m_region
);
196 bool wxRegion::DoIntersect( const wxRegion
& region
)
198 wxCHECK_MSG( region
.IsOk(), false, wxT("invalid region") );
202 m_refData
= new wxRegionRefData();
203 M_REGIONDATA
->m_region
= XCreateRegion();
213 XIntersectRegion( M_REGIONDATA
->m_region
,
214 M_REGIONDATA_OF(region
)->m_region
,
215 M_REGIONDATA
->m_region
);
220 bool wxRegion::DoSubtract( const wxRegion
& region
)
222 wxCHECK_MSG( region
.IsOk(), false, wxT("invalid region") );
226 m_refData
= new wxRegionRefData();
227 M_REGIONDATA
->m_region
= XCreateRegion();
234 XSubtractRegion( M_REGIONDATA
->m_region
,
235 M_REGIONDATA_OF(region
)->m_region
,
236 M_REGIONDATA
->m_region
);
241 bool wxRegion::DoXor( const wxRegion
& region
)
243 wxCHECK_MSG( region
.IsOk(), false, wxT("invalid region") );
247 m_refData
= new wxRegionRefData();
248 M_REGIONDATA
->m_region
= XCreateRegion();
255 XXorRegion( M_REGIONDATA
->m_region
,
256 M_REGIONDATA_OF(region
)->m_region
,
257 M_REGIONDATA
->m_region
);
262 // ----------------------------------------------------------------------------
264 // ----------------------------------------------------------------------------
266 bool wxRegion::DoGetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
271 XClipBox( M_REGIONDATA
->m_region
, &rect
);
290 bool wxRegion::DoOffset( wxCoord x
, wxCoord y
)
297 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
302 bool wxRegion::IsEmpty() const
307 return XEmptyRegion( M_REGIONDATA
->m_region
) == True
;
310 wxRegionContain
wxRegion::DoContainsPoint( wxCoord x
, wxCoord y
) const
315 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
321 wxRegionContain
wxRegion::DoContainsRect(const wxRect
& r
) const
326 int res
= XRectInRegion(M_REGIONDATA
->m_region
, r
.x
, r
.y
, r
.width
, r
.height
);
329 case RectangleIn
: return wxInRegion
;
330 case RectangleOut
: return wxOutRegion
;
331 case RectanglePart
: return wxPartRegion
;
336 WXRegion
*wxRegion::GetX11Region() const
341 return (WXRegion
*) M_REGIONDATA
->m_region
;
344 // ----------------------------------------------------------------------------
346 // ----------------------------------------------------------------------------
348 // the following structures must match the private structures
349 // in X11 region code ( xc/lib/X11/region.h )
351 // this makes the Region type transparent
352 // and we have access to the region rectangles
355 short x1
, x2
, y1
, y2
;
359 long size
, numRects
;
360 _XBox
*rects
, extents
;
363 class wxRIRefData
: public wxGDIRefData
367 wxRIRefData() : m_rects(0), m_numRects(0){}
368 virtual ~wxRIRefData();
373 void CreateRects( const wxRegion
& r
);
376 wxRIRefData::~wxRIRefData()
381 void wxRIRefData::CreateRects( const wxRegion
& region
)
389 if (region
.IsEmpty()) return;
391 Region r
= (Region
) region
.GetX11Region();
396 GrGetRegionBox(r
, & rect
);
398 m_rects
= new wxRect
[1];
399 m_rects
[0].x
= rect
.x
;
400 m_rects
[0].y
= rect
.y
;
401 m_rects
[0].width
= rect
.width
;
402 m_rects
[0].height
= rect
.height
;
404 m_numRects
= r
->numRects
;
407 m_rects
= new wxRect
[m_numRects
];
408 for (size_t i
=0; i
< m_numRects
; ++i
)
410 _XBox
&xr
= r
->rects
[i
];
411 wxRect
&wr
= m_rects
[i
];
414 wr
.width
= xr
.x2
-xr
.x1
;
415 wr
.height
= xr
.y2
-xr
.y1
;
422 wxRegionIterator::wxRegionIterator()
424 m_refData
= new wxRIRefData();
428 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
430 m_refData
= new wxRIRefData();
434 void wxRegionIterator::Reset( const wxRegion
& region
)
437 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
441 bool wxRegionIterator::HaveRects() const
443 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
446 wxRegionIterator::operator bool () const
451 void wxRegionIterator::operator ++ ()
453 if (HaveRects()) ++m_current
;
456 void wxRegionIterator::operator ++ (int)
458 if (HaveRects()) ++m_current
;
461 wxCoord
wxRegionIterator::GetX() const
463 if( !HaveRects() ) return 0;
464 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
467 wxCoord
wxRegionIterator::GetY() const
469 if( !HaveRects() ) return 0;
470 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
473 wxCoord
wxRegionIterator::GetW() const
475 if( !HaveRects() ) return -1;
476 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
479 wxCoord
wxRegionIterator::GetH() const
481 if( !HaveRects() ) return -1;
482 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
485 wxRect
wxRegionIterator::GetRect() const
489 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];