]>
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"
20 #include "wx/gdicmn.h"
23 #pragma message disable nosimpint
25 #include "wx/x11/private.h"
26 #include "X11/Xutil.h"
28 #pragma message enable nosimpint
31 // ----------------------------------------------------------------------------
32 // wxRegionRefData: private class containing the information about the region
33 // ----------------------------------------------------------------------------
35 class wxRegionRefData
: public wxObjectRefData
43 wxRegionRefData(const wxRegionRefData
& refData
)
45 m_region
= XCreateRegion();
46 XUnionRegion( refData
.m_region
, m_region
, m_region
);
52 XDestroyRegion( 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
)
79 rect
.width
= (unsigned short)w
;
80 rect
.height
= (unsigned short)h
;
82 m_refData
= new wxRegionRefData();
84 M_REGIONDATA
->m_region
= XCreateRegion();
85 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
88 wxRegion::wxRegion( size_t WXUNUSED(n
), const wxPoint
*WXUNUSED(points
), int WXUNUSED(fillStyle
) )
91 XPoint
*xpoints
= new XPoint
[n
];
92 for ( size_t i
= 0 ; i
< n
; i
++ )
94 xpoints
[i
].x
= points
[i
].x
;
95 xpoints
[i
].y
= points
[i
].y
;
98 m_refData
= new wxRegionRefData();
100 Region
* reg
= gdk_region_polygon
104 fillStyle
== wxWINDING_RULE
? GDK_WINDING_RULE
108 M_REGIONDATA
->m_region
= reg
;
114 wxRegion::~wxRegion()
116 // m_refData unrefed in ~wxObject
119 wxObjectRefData
*wxRegion::CreateRefData() const
121 return new wxRegionRefData
;
124 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
126 return new wxRegionRefData(*(wxRegionRefData
*)data
);
129 // ----------------------------------------------------------------------------
130 // wxRegion comparison
131 // ----------------------------------------------------------------------------
133 bool wxRegion::operator==( const wxRegion
& region
) const
135 if (m_refData
== region
.m_refData
) return true;
137 if (!m_refData
|| !region
.m_refData
) return false;
139 // compare the regions themselves, not the pointers to ref data!
140 return XEqualRegion( M_REGIONDATA
->m_region
,
141 M_REGIONDATA_OF(region
)->m_region
) == True
;
144 // ----------------------------------------------------------------------------
145 // wxRegion operations
146 // ----------------------------------------------------------------------------
148 void wxRegion::Clear()
153 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
155 // work around for XUnionRectWithRegion() bug: taking a union with an empty
156 // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
158 if ( !width
|| !height
)
164 rect
.width
= (unsigned short)width
;
165 rect
.height
= (unsigned short)height
;
169 m_refData
= new wxRegionRefData();
170 M_REGIONDATA
->m_region
= XCreateRegion();
171 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
177 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
183 bool wxRegion::Union( const wxRect
& rect
)
185 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
188 bool wxRegion::Union( const wxRegion
& region
)
195 m_refData
= new wxRegionRefData();
196 M_REGIONDATA
->m_region
= XCreateRegion();
203 XUnionRegion( M_REGIONDATA
->m_region
,
204 M_REGIONDATA_OF(region
)->m_region
,
205 M_REGIONDATA
->m_region
);
210 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
212 wxRegion
reg( x
, y
, width
, height
);
214 return Intersect( reg
);
217 bool wxRegion::Intersect( const wxRect
& rect
)
219 wxRegion
reg( rect
);
221 return Intersect( reg
);
224 bool wxRegion::Intersect( const wxRegion
& region
)
231 m_refData
= new wxRegionRefData();
232 M_REGIONDATA
->m_region
= XCreateRegion();
242 XIntersectRegion( M_REGIONDATA
->m_region
,
243 M_REGIONDATA_OF(region
)->m_region
,
244 M_REGIONDATA
->m_region
);
249 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
251 wxRegion
reg( x
, y
, width
, height
);
252 return Subtract( reg
);
255 bool wxRegion::Subtract( const wxRect
& rect
)
257 wxRegion
reg( rect
);
258 return Subtract( reg
);
261 bool wxRegion::Subtract( const wxRegion
& region
)
268 m_refData
= new wxRegionRefData();
269 M_REGIONDATA
->m_region
= XCreateRegion();
276 XSubtractRegion( M_REGIONDATA
->m_region
,
277 M_REGIONDATA_OF(region
)->m_region
,
278 M_REGIONDATA
->m_region
);
283 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
285 wxRegion
reg( x
, y
, width
, height
);
289 bool wxRegion::Xor( const wxRect
& rect
)
291 wxRegion
reg( rect
);
295 bool wxRegion::Xor( const wxRegion
& region
)
302 m_refData
= new wxRegionRefData();
303 M_REGIONDATA
->m_region
= XCreateRegion();
310 XXorRegion( M_REGIONDATA
->m_region
,
311 M_REGIONDATA_OF(region
)->m_region
,
312 M_REGIONDATA
->m_region
);
317 // ----------------------------------------------------------------------------
319 // ----------------------------------------------------------------------------
321 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
326 XClipBox( M_REGIONDATA
->m_region
, &rect
);
341 wxRect
wxRegion::GetBox() const
344 GetBox( x
, y
, w
, h
);
345 return wxRect( x
, y
, w
, h
);
348 bool wxRegion::Offset( wxCoord x
, wxCoord y
)
355 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
360 bool wxRegion::Empty() const
365 return XEmptyRegion( M_REGIONDATA
->m_region
) == True
;
368 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
373 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
379 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
384 int res
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h
);
387 case RectangleIn
: return wxInRegion
;
388 case RectangleOut
: return wxOutRegion
;
389 case RectanglePart
: return wxPartRegion
;
394 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
396 return Contains( pt
.x
, pt
.y
);
399 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
401 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
404 WXRegion
*wxRegion::GetX11Region() const
407 return (WXRegion
*) NULL
;
409 return (WXRegion
*) M_REGIONDATA
->m_region
;
412 // ----------------------------------------------------------------------------
414 // ----------------------------------------------------------------------------
416 // the following structures must match the private structures
417 // in X11 region code ( xc/lib/X11/region.h )
419 // this makes the Region type transparent
420 // and we have access to the region rectangles
423 short x1
, x2
, y1
, y2
;
427 long size
, numRects
;
428 _XBox
*rects
, extents
;
431 class wxRIRefData
: public wxObjectRefData
435 wxRIRefData() : m_rects(0), m_numRects(0){}
441 void CreateRects( const wxRegion
& r
);
444 wxRIRefData::~wxRIRefData()
449 void wxRIRefData::CreateRects( const wxRegion
& region
)
457 if (region
.IsEmpty()) return;
459 Region r
= (Region
) region
.GetX11Region();
464 GrGetRegionBox(r
, & rect
);
466 m_rects
= new wxRect
[1];
467 m_rects
[0].x
= rect
.x
;
468 m_rects
[0].y
= rect
.y
;
469 m_rects
[0].width
= rect
.width
;
470 m_rects
[0].height
= rect
.height
;
472 m_numRects
= r
->numRects
;
475 m_rects
= new wxRect
[m_numRects
];
476 for (size_t i
=0; i
< m_numRects
; ++i
)
478 _XBox
&xr
= r
->rects
[i
];
479 wxRect
&wr
= m_rects
[i
];
482 wr
.width
= xr
.x2
-xr
.x1
;
483 wr
.height
= xr
.y2
-xr
.y1
;
490 wxRegionIterator::wxRegionIterator()
492 m_refData
= new wxRIRefData();
496 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
498 m_refData
= new wxRIRefData();
502 void wxRegionIterator::Reset( const wxRegion
& region
)
505 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
509 bool wxRegionIterator::HaveRects() const
511 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
514 wxRegionIterator::operator bool () const
519 void wxRegionIterator::operator ++ ()
521 if (HaveRects()) ++m_current
;
524 void wxRegionIterator::operator ++ (int)
526 if (HaveRects()) ++m_current
;
529 wxCoord
wxRegionIterator::GetX() const
531 if( !HaveRects() ) return 0;
532 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
535 wxCoord
wxRegionIterator::GetY() const
537 if( !HaveRects() ) return 0;
538 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
541 wxCoord
wxRegionIterator::GetW() const
543 if( !HaveRects() ) return -1;
544 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
547 wxCoord
wxRegionIterator::GetH() const
549 if( !HaveRects() ) return -1;
550 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
553 wxRect
wxRegionIterator::GetRect() const
557 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];