]>
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"
15 #include "wx/gdicmn.h"
19 #pragma message disable nosimpint
21 #include "wx/x11/private.h"
22 #include "X11/Xutil.h"
24 #pragma message enable nosimpint
27 // ----------------------------------------------------------------------------
28 // wxRegionRefData: private class containing the information about the region
29 // ----------------------------------------------------------------------------
31 class wxRegionRefData
: public wxObjectRefData
39 wxRegionRefData(const wxRegionRefData
& refData
)
41 m_region
= XCreateRegion();
42 XUnionRegion( refData
.m_region
, m_region
, m_region
);
48 XDestroyRegion( m_region
);
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
59 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))
61 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
)
62 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
)
64 // ----------------------------------------------------------------------------
65 // wxRegion construction
66 // ----------------------------------------------------------------------------
68 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
70 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
75 rect
.width
= (unsigned short)w
;
76 rect
.height
= (unsigned short)h
;
78 m_refData
= new wxRegionRefData();
80 M_REGIONDATA
->m_region
= XCreateRegion();
81 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
84 wxRegion::wxRegion( size_t WXUNUSED(n
), const wxPoint
*WXUNUSED(points
), int WXUNUSED(fillStyle
) )
87 XPoint
*xpoints
= new XPoint
[n
];
88 for ( size_t i
= 0 ; i
< n
; i
++ )
90 xpoints
[i
].x
= points
[i
].x
;
91 xpoints
[i
].y
= points
[i
].y
;
94 m_refData
= new wxRegionRefData();
96 Region
* reg
= gdk_region_polygon
100 fillStyle
== wxWINDING_RULE
? GDK_WINDING_RULE
104 M_REGIONDATA
->m_region
= reg
;
110 wxRegion::~wxRegion()
112 // m_refData unrefed in ~wxObject
115 wxObjectRefData
*wxRegion::CreateRefData() const
117 return new wxRegionRefData
;
120 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
122 return new wxRegionRefData(*(wxRegionRefData
*)data
);
125 // ----------------------------------------------------------------------------
126 // wxRegion comparison
127 // ----------------------------------------------------------------------------
129 bool wxRegion::operator==( const wxRegion
& region
) const
131 if (m_refData
== region
.m_refData
) return true;
133 if (!m_refData
|| !region
.m_refData
) return false;
135 // compare the regions themselves, not the pointers to ref data!
136 return XEqualRegion( M_REGIONDATA
->m_region
,
137 M_REGIONDATA_OF(region
)->m_region
) == True
;
140 // ----------------------------------------------------------------------------
141 // wxRegion operations
142 // ----------------------------------------------------------------------------
144 void wxRegion::Clear()
149 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
151 // work around for XUnionRectWithRegion() bug: taking a union with an empty
152 // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
154 if ( !width
|| !height
)
160 rect
.width
= (unsigned short)width
;
161 rect
.height
= (unsigned short)height
;
165 m_refData
= new wxRegionRefData();
166 M_REGIONDATA
->m_region
= XCreateRegion();
167 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
173 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
179 bool wxRegion::Union( const wxRect
& rect
)
181 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
184 bool wxRegion::Union( const wxRegion
& region
)
191 m_refData
= new wxRegionRefData();
192 M_REGIONDATA
->m_region
= XCreateRegion();
199 XUnionRegion( M_REGIONDATA
->m_region
,
200 M_REGIONDATA_OF(region
)->m_region
,
201 M_REGIONDATA
->m_region
);
206 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
208 wxRegion
reg( x
, y
, width
, height
);
210 return Intersect( reg
);
213 bool wxRegion::Intersect( const wxRect
& rect
)
215 wxRegion
reg( rect
);
217 return Intersect( reg
);
220 bool wxRegion::Intersect( const wxRegion
& region
)
227 m_refData
= new wxRegionRefData();
228 M_REGIONDATA
->m_region
= XCreateRegion();
238 XIntersectRegion( M_REGIONDATA
->m_region
,
239 M_REGIONDATA_OF(region
)->m_region
,
240 M_REGIONDATA
->m_region
);
245 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
247 wxRegion
reg( x
, y
, width
, height
);
248 return Subtract( reg
);
251 bool wxRegion::Subtract( const wxRect
& rect
)
253 wxRegion
reg( rect
);
254 return Subtract( reg
);
257 bool wxRegion::Subtract( const wxRegion
& region
)
264 m_refData
= new wxRegionRefData();
265 M_REGIONDATA
->m_region
= XCreateRegion();
272 XSubtractRegion( M_REGIONDATA
->m_region
,
273 M_REGIONDATA_OF(region
)->m_region
,
274 M_REGIONDATA
->m_region
);
279 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
281 wxRegion
reg( x
, y
, width
, height
);
285 bool wxRegion::Xor( const wxRect
& rect
)
287 wxRegion
reg( rect
);
291 bool wxRegion::Xor( const wxRegion
& region
)
298 m_refData
= new wxRegionRefData();
299 M_REGIONDATA
->m_region
= XCreateRegion();
306 XXorRegion( M_REGIONDATA
->m_region
,
307 M_REGIONDATA_OF(region
)->m_region
,
308 M_REGIONDATA
->m_region
);
313 // ----------------------------------------------------------------------------
315 // ----------------------------------------------------------------------------
317 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
322 XClipBox( M_REGIONDATA
->m_region
, &rect
);
337 wxRect
wxRegion::GetBox() const
340 GetBox( x
, y
, w
, h
);
341 return wxRect( x
, y
, w
, h
);
344 bool wxRegion::Offset( wxCoord x
, wxCoord y
)
351 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
356 bool wxRegion::Empty() const
361 return XEmptyRegion( M_REGIONDATA
->m_region
) == True
;
364 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
369 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
375 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
380 int res
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h
);
383 case RectangleIn
: return wxInRegion
;
384 case RectangleOut
: return wxOutRegion
;
385 case RectanglePart
: return wxPartRegion
;
390 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
392 return Contains( pt
.x
, pt
.y
);
395 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
397 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
400 WXRegion
*wxRegion::GetX11Region() const
403 return (WXRegion
*) NULL
;
405 return (WXRegion
*) M_REGIONDATA
->m_region
;
408 // ----------------------------------------------------------------------------
410 // ----------------------------------------------------------------------------
412 // the following structures must match the private structures
413 // in X11 region code ( xc/lib/X11/region.h )
415 // this makes the Region type transparent
416 // and we have access to the region rectangles
419 short x1
, x2
, y1
, y2
;
423 long size
, numRects
;
424 _XBox
*rects
, extents
;
427 class wxRIRefData
: public wxObjectRefData
431 wxRIRefData() : m_rects(0), m_numRects(0){}
437 void CreateRects( const wxRegion
& r
);
440 wxRIRefData::~wxRIRefData()
445 void wxRIRefData::CreateRects( const wxRegion
& region
)
453 if (region
.IsEmpty()) return;
455 Region r
= (Region
) region
.GetX11Region();
460 GrGetRegionBox(r
, & rect
);
462 m_rects
= new wxRect
[1];
463 m_rects
[0].x
= rect
.x
;
464 m_rects
[0].y
= rect
.y
;
465 m_rects
[0].width
= rect
.width
;
466 m_rects
[0].height
= rect
.height
;
468 m_numRects
= r
->numRects
;
471 m_rects
= new wxRect
[m_numRects
];
472 for (size_t i
=0; i
< m_numRects
; ++i
)
474 _XBox
&xr
= r
->rects
[i
];
475 wxRect
&wr
= m_rects
[i
];
478 wr
.width
= xr
.x2
-xr
.x1
;
479 wr
.height
= xr
.y2
-xr
.y1
;
486 wxRegionIterator::wxRegionIterator()
488 m_refData
= new wxRIRefData();
492 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
494 m_refData
= new wxRIRefData();
498 void wxRegionIterator::Reset( const wxRegion
& region
)
501 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
505 bool wxRegionIterator::HaveRects() const
507 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
510 wxRegionIterator::operator bool () const
515 void wxRegionIterator::operator ++ ()
517 if (HaveRects()) ++m_current
;
520 void wxRegionIterator::operator ++ (int)
522 if (HaveRects()) ++m_current
;
525 wxCoord
wxRegionIterator::GetX() const
527 if( !HaveRects() ) return 0;
528 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
531 wxCoord
wxRegionIterator::GetY() const
533 if( !HaveRects() ) return 0;
534 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
537 wxCoord
wxRegionIterator::GetW() const
539 if( !HaveRects() ) return -1;
540 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
543 wxCoord
wxRegionIterator::GetH() const
545 if( !HaveRects() ) return -1;
546 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
549 wxRect
wxRegionIterator::GetRect() const
553 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];