]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/region.cpp
1 /////////////////////////////////////////////////////////////////////////////
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 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "region.h"
15 #include "wx/region.h"
16 #include "wx/gdicmn.h"
20 #pragma message disable nosimpint
22 #include "wx/x11/private.h"
23 #include "X11/Xutil.h"
25 #pragma message enable nosimpint
28 // ----------------------------------------------------------------------------
29 // wxRegionRefData: private class containing the information about the region
30 // ----------------------------------------------------------------------------
32 class wxRegionRefData
: public wxObjectRefData
40 wxRegionRefData(const wxRegionRefData
& refData
)
42 m_region
= XCreateRegion();
43 XUnionRegion( refData
.m_region
, m_region
, m_region
);
49 XDestroyRegion( m_region
);
55 // ----------------------------------------------------------------------------
57 // ----------------------------------------------------------------------------
59 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
60 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))
62 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
);
63 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
65 // ----------------------------------------------------------------------------
66 // wxRegion construction
67 // ----------------------------------------------------------------------------
69 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
71 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
79 m_refData
= new wxRegionRefData();
81 M_REGIONDATA
->m_region
= XCreateRegion();
82 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
85 wxRegion::wxRegion( size_t n
, const wxPoint
*points
, int fillStyle
)
88 XPoint
*xpoints
= new XPoint
[n
];
89 for ( size_t i
= 0 ; i
< n
; i
++ )
91 xpoints
[i
].x
= points
[i
].x
;
92 xpoints
[i
].y
= points
[i
].y
;
95 m_refData
= new wxRegionRefData();
97 Region
* reg
= gdk_region_polygon
101 fillStyle
== wxWINDING_RULE
? GDK_WINDING_RULE
105 M_REGIONDATA
->m_region
= reg
;
111 wxRegion::~wxRegion()
113 // m_refData unrefed in ~wxObject
116 wxObjectRefData
*wxRegion::CreateRefData() const
118 return new wxRegionRefData
;
121 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
123 return new wxRegionRefData(*(wxRegionRefData
*)data
);
126 // ----------------------------------------------------------------------------
127 // wxRegion comparison
128 // ----------------------------------------------------------------------------
130 bool wxRegion::operator==( const wxRegion
& region
)
132 if (m_refData
== region
.m_refData
) return TRUE
;
134 if (!m_refData
|| !region
.m_refData
) return FALSE
;
136 // compare the regions themselves, not the pointers to ref data!
137 return XEqualRegion( M_REGIONDATA
->m_region
,
138 M_REGIONDATA_OF(region
)->m_region
);
141 // ----------------------------------------------------------------------------
142 // wxRegion operations
143 // ----------------------------------------------------------------------------
145 void wxRegion::Clear()
150 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
152 // work around for XUnionRectWithRegion() bug: taking a union with an empty
153 // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
155 if ( !width
|| !height
)
162 rect
.height
= height
;
166 m_refData
= new wxRegionRefData();
167 M_REGIONDATA
->m_region
= XCreateRegion();
168 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
174 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
180 bool wxRegion::Union( const wxRect
& rect
)
182 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
185 bool wxRegion::Union( const wxRegion
& region
)
192 m_refData
= new wxRegionRefData();
193 M_REGIONDATA
->m_region
= XCreateRegion();
200 XUnionRegion( M_REGIONDATA
->m_region
,
201 M_REGIONDATA_OF(region
)->m_region
,
202 M_REGIONDATA
->m_region
);
207 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
209 wxRegion
reg( x
, y
, width
, height
);
211 return Intersect( reg
);
214 bool wxRegion::Intersect( const wxRect
& rect
)
216 wxRegion
reg( rect
);
218 return Intersect( reg
);
221 bool wxRegion::Intersect( const wxRegion
& region
)
228 m_refData
= new wxRegionRefData();
229 M_REGIONDATA
->m_region
= XCreateRegion();
239 XIntersectRegion( M_REGIONDATA
->m_region
,
240 M_REGIONDATA_OF(region
)->m_region
,
241 M_REGIONDATA
->m_region
);
246 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
248 wxRegion
reg( x
, y
, width
, height
);
249 return Subtract( reg
);
252 bool wxRegion::Subtract( const wxRect
& rect
)
254 wxRegion
reg( rect
);
255 return Subtract( reg
);
258 bool wxRegion::Subtract( const wxRegion
& region
)
265 m_refData
= new wxRegionRefData();
266 M_REGIONDATA
->m_region
= XCreateRegion();
273 XSubtractRegion( M_REGIONDATA
->m_region
,
274 M_REGIONDATA_OF(region
)->m_region
,
275 M_REGIONDATA
->m_region
);
280 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
282 wxRegion
reg( x
, y
, width
, height
);
286 bool wxRegion::Xor( const wxRect
& rect
)
288 wxRegion
reg( rect
);
292 bool wxRegion::Xor( const wxRegion
& region
)
299 m_refData
= new wxRegionRefData();
300 M_REGIONDATA
->m_region
= XCreateRegion();
307 XXorRegion( M_REGIONDATA
->m_region
,
308 M_REGIONDATA_OF(region
)->m_region
,
309 M_REGIONDATA
->m_region
);
314 // ----------------------------------------------------------------------------
316 // ----------------------------------------------------------------------------
318 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
323 XClipBox( M_REGIONDATA
->m_region
, &rect
);
338 wxRect
wxRegion::GetBox() const
341 GetBox( x
, y
, w
, h
);
342 return wxRect( x
, y
, w
, h
);
345 bool wxRegion::Offset( wxCoord x
, wxCoord y
)
352 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
357 bool wxRegion::Empty() const
362 return XEmptyRegion( M_REGIONDATA
->m_region
);
365 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
370 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
376 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
381 int res
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h
);
384 case RectangleIn
: return wxInRegion
;
385 case RectangleOut
: return wxOutRegion
;
386 case RectanglePart
: return wxPartRegion
;
391 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
393 return Contains( pt
.x
, pt
.y
);
396 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
398 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
401 WXRegion
*wxRegion::GetX11Region() const
404 return (WXRegion
*) NULL
;
406 return (WXRegion
*) M_REGIONDATA
->m_region
;
409 // ----------------------------------------------------------------------------
411 // ----------------------------------------------------------------------------
413 // the following structures must match the private structures
414 // in X11 region code ( xc/lib/X11/region.h )
416 // this makes the Region type transparent
417 // and we have access to the region rectangles
420 short x1
, x2
, y1
, y2
;
424 long size
, numRects
;
425 _XBox
*rects
, extents
;
428 class wxRIRefData
: public wxObjectRefData
432 wxRIRefData() : m_rects(0), m_numRects(0){}
438 void CreateRects( const wxRegion
& r
);
441 wxRIRefData::~wxRIRefData()
446 void wxRIRefData::CreateRects( const wxRegion
& region
)
454 if (region
.IsEmpty()) return;
456 Region r
= (Region
) region
.GetX11Region();
461 GrGetRegionBox(r
, & rect
);
463 m_rects
= new wxRect
[1];
464 m_rects
[0].x
= rect
.x
;
465 m_rects
[0].y
= rect
.y
;
466 m_rects
[0].width
= rect
.width
;
467 m_rects
[0].height
= rect
.height
;
469 m_numRects
= r
->numRects
;
472 m_rects
= new wxRect
[m_numRects
];
473 for (size_t i
=0; i
< m_numRects
; ++i
)
475 _XBox
&xr
= r
->rects
[i
];
476 wxRect
&wr
= m_rects
[i
];
479 wr
.width
= xr
.x2
-xr
.x1
;
480 wr
.height
= xr
.y2
-xr
.y1
;
487 wxRegionIterator::wxRegionIterator()
489 m_refData
= new wxRIRefData();
493 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
495 m_refData
= new wxRIRefData();
499 void wxRegionIterator::Reset( const wxRegion
& region
)
502 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
506 bool wxRegionIterator::HaveRects() const
508 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
511 wxRegionIterator::operator bool () const
516 void wxRegionIterator::operator ++ ()
518 if (HaveRects()) ++m_current
;
521 void wxRegionIterator::operator ++ (int)
523 if (HaveRects()) ++m_current
;
526 wxCoord
wxRegionIterator::GetX() const
528 if( !HaveRects() ) return 0;
529 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
532 wxCoord
wxRegionIterator::GetY() const
534 if( !HaveRects() ) return 0;
535 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
538 wxCoord
wxRegionIterator::GetW() const
540 if( !HaveRects() ) return -1;
541 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
544 wxCoord
wxRegionIterator::GetH() const
546 if( !HaveRects() ) return -1;
547 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
550 wxRect
wxRegionIterator::GetRect() const
554 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];