]>
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::operator==( const wxRegion
& region
) const
134 if (m_refData
== region
.m_refData
) return true;
136 if (!m_refData
|| !region
.m_refData
) return false;
138 // compare the regions themselves, not the pointers to ref data!
139 return XEqualRegion( M_REGIONDATA
->m_region
,
140 M_REGIONDATA_OF(region
)->m_region
) == True
;
143 // ----------------------------------------------------------------------------
144 // wxRegion operations
145 // ----------------------------------------------------------------------------
147 void wxRegion::Clear()
152 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
154 // work around for XUnionRectWithRegion() bug: taking a union with an empty
155 // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
157 if ( !width
|| !height
)
163 rect
.width
= (unsigned short)width
;
164 rect
.height
= (unsigned short)height
;
168 m_refData
= new wxRegionRefData();
169 M_REGIONDATA
->m_region
= XCreateRegion();
170 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
176 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
182 bool wxRegion::Union( const wxRect
& rect
)
184 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
187 bool wxRegion::Union( const wxRegion
& region
)
194 m_refData
= new wxRegionRefData();
195 M_REGIONDATA
->m_region
= XCreateRegion();
202 XUnionRegion( M_REGIONDATA
->m_region
,
203 M_REGIONDATA_OF(region
)->m_region
,
204 M_REGIONDATA
->m_region
);
209 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
211 wxRegion
reg( x
, y
, width
, height
);
213 return Intersect( reg
);
216 bool wxRegion::Intersect( const wxRect
& rect
)
218 wxRegion
reg( rect
);
220 return Intersect( reg
);
223 bool wxRegion::Intersect( const wxRegion
& region
)
230 m_refData
= new wxRegionRefData();
231 M_REGIONDATA
->m_region
= XCreateRegion();
241 XIntersectRegion( M_REGIONDATA
->m_region
,
242 M_REGIONDATA_OF(region
)->m_region
,
243 M_REGIONDATA
->m_region
);
248 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
250 wxRegion
reg( x
, y
, width
, height
);
251 return Subtract( reg
);
254 bool wxRegion::Subtract( const wxRect
& rect
)
256 wxRegion
reg( rect
);
257 return Subtract( reg
);
260 bool wxRegion::Subtract( const wxRegion
& region
)
267 m_refData
= new wxRegionRefData();
268 M_REGIONDATA
->m_region
= XCreateRegion();
275 XSubtractRegion( M_REGIONDATA
->m_region
,
276 M_REGIONDATA_OF(region
)->m_region
,
277 M_REGIONDATA
->m_region
);
282 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
284 wxRegion
reg( x
, y
, width
, height
);
288 bool wxRegion::Xor( const wxRect
& rect
)
290 wxRegion
reg( rect
);
294 bool wxRegion::Xor( const wxRegion
& region
)
301 m_refData
= new wxRegionRefData();
302 M_REGIONDATA
->m_region
= XCreateRegion();
309 XXorRegion( M_REGIONDATA
->m_region
,
310 M_REGIONDATA_OF(region
)->m_region
,
311 M_REGIONDATA
->m_region
);
316 // ----------------------------------------------------------------------------
318 // ----------------------------------------------------------------------------
320 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
325 XClipBox( M_REGIONDATA
->m_region
, &rect
);
340 wxRect
wxRegion::GetBox() const
343 GetBox( x
, y
, w
, h
);
344 return wxRect( x
, y
, w
, h
);
347 bool wxRegion::Offset( wxCoord x
, wxCoord y
)
354 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
359 bool wxRegion::Empty() const
364 return XEmptyRegion( M_REGIONDATA
->m_region
) == True
;
367 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
372 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
378 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
383 int res
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h
);
386 case RectangleIn
: return wxInRegion
;
387 case RectangleOut
: return wxOutRegion
;
388 case RectanglePart
: return wxPartRegion
;
393 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
395 return Contains( pt
.x
, pt
.y
);
398 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
400 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
403 WXRegion
*wxRegion::GetX11Region() const
406 return (WXRegion
*) NULL
;
408 return (WXRegion
*) M_REGIONDATA
->m_region
;
411 // ----------------------------------------------------------------------------
413 // ----------------------------------------------------------------------------
415 // the following structures must match the private structures
416 // in X11 region code ( xc/lib/X11/region.h )
418 // this makes the Region type transparent
419 // and we have access to the region rectangles
422 short x1
, x2
, y1
, y2
;
426 long size
, numRects
;
427 _XBox
*rects
, extents
;
430 class wxRIRefData
: public wxObjectRefData
434 wxRIRefData() : m_rects(0), m_numRects(0){}
435 virtual ~wxRIRefData();
440 void CreateRects( const wxRegion
& r
);
443 wxRIRefData::~wxRIRefData()
448 void wxRIRefData::CreateRects( const wxRegion
& region
)
456 if (region
.IsEmpty()) return;
458 Region r
= (Region
) region
.GetX11Region();
463 GrGetRegionBox(r
, & rect
);
465 m_rects
= new wxRect
[1];
466 m_rects
[0].x
= rect
.x
;
467 m_rects
[0].y
= rect
.y
;
468 m_rects
[0].width
= rect
.width
;
469 m_rects
[0].height
= rect
.height
;
471 m_numRects
= r
->numRects
;
474 m_rects
= new wxRect
[m_numRects
];
475 for (size_t i
=0; i
< m_numRects
; ++i
)
477 _XBox
&xr
= r
->rects
[i
];
478 wxRect
&wr
= m_rects
[i
];
481 wr
.width
= xr
.x2
-xr
.x1
;
482 wr
.height
= xr
.y2
-xr
.y1
;
489 wxRegionIterator::wxRegionIterator()
491 m_refData
= new wxRIRefData();
495 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
497 m_refData
= new wxRIRefData();
501 void wxRegionIterator::Reset( const wxRegion
& region
)
504 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
508 bool wxRegionIterator::HaveRects() const
510 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
513 wxRegionIterator::operator bool () const
518 void wxRegionIterator::operator ++ ()
520 if (HaveRects()) ++m_current
;
523 void wxRegionIterator::operator ++ (int)
525 if (HaveRects()) ++m_current
;
528 wxCoord
wxRegionIterator::GetX() const
530 if( !HaveRects() ) return 0;
531 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
534 wxCoord
wxRegionIterator::GetY() const
536 if( !HaveRects() ) return 0;
537 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
540 wxCoord
wxRegionIterator::GetW() const
542 if( !HaveRects() ) return -1;
543 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
546 wxCoord
wxRegionIterator::GetH() const
548 if( !HaveRects() ) return -1;
549 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
552 wxRect
wxRegionIterator::GetRect() const
556 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];