]>
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 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/region.h"
12 #include "wx/gdicmn.h"
16 #pragma message disable nosimpint
18 #include "wx/x11/private.h"
19 #include "X11/Xutil.h"
21 #pragma message enable nosimpint
24 // ----------------------------------------------------------------------------
25 // wxRegionRefData: private class containing the information about the region
26 // ----------------------------------------------------------------------------
28 class wxRegionRefData
: public wxObjectRefData
36 wxRegionRefData(const wxRegionRefData
& refData
)
38 m_region
= XCreateRegion();
39 XUnionRegion( refData
.m_region
, m_region
, m_region
);
45 XDestroyRegion( m_region
);
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
56 #define M_REGIONDATA_OF(rgn) ((wxRegionRefData *)(rgn.m_refData))
58 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
);
59 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
,wxObject
);
61 // ----------------------------------------------------------------------------
62 // wxRegion construction
63 // ----------------------------------------------------------------------------
65 #define M_REGIONDATA ((wxRegionRefData *)m_refData)
67 void wxRegion::InitRect(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
75 m_refData
= new wxRegionRefData();
77 M_REGIONDATA
->m_region
= XCreateRegion();
78 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
81 wxRegion::wxRegion( size_t n
, const wxPoint
*points
, int fillStyle
)
84 XPoint
*xpoints
= new XPoint
[n
];
85 for ( size_t i
= 0 ; i
< n
; i
++ )
87 xpoints
[i
].x
= points
[i
].x
;
88 xpoints
[i
].y
= points
[i
].y
;
91 m_refData
= new wxRegionRefData();
93 Region
* reg
= gdk_region_polygon
97 fillStyle
== wxWINDING_RULE
? GDK_WINDING_RULE
101 M_REGIONDATA
->m_region
= reg
;
107 wxRegion::~wxRegion()
109 // m_refData unrefed in ~wxObject
112 wxObjectRefData
*wxRegion::CreateRefData() const
114 return new wxRegionRefData
;
117 wxObjectRefData
*wxRegion::CloneRefData(const wxObjectRefData
*data
) const
119 return new wxRegionRefData(*(wxRegionRefData
*)data
);
122 // ----------------------------------------------------------------------------
123 // wxRegion comparison
124 // ----------------------------------------------------------------------------
126 bool wxRegion::operator==( const wxRegion
& region
)
128 if (m_refData
== region
.m_refData
) return TRUE
;
130 if (!m_refData
|| !region
.m_refData
) return FALSE
;
132 // compare the regions themselves, not the pointers to ref data!
133 return XEqualRegion( M_REGIONDATA
->m_region
,
134 M_REGIONDATA_OF(region
)->m_region
);
137 // ----------------------------------------------------------------------------
138 // wxRegion operations
139 // ----------------------------------------------------------------------------
141 void wxRegion::Clear()
146 bool wxRegion::Union( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
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
151 if ( !width
|| !height
)
158 rect
.height
= height
;
162 m_refData
= new wxRegionRefData();
163 M_REGIONDATA
->m_region
= XCreateRegion();
164 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
170 XUnionRectWithRegion( &rect
, M_REGIONDATA
->m_region
, M_REGIONDATA
->m_region
);
176 bool wxRegion::Union( const wxRect
& rect
)
178 return Union( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
181 bool wxRegion::Union( const wxRegion
& region
)
188 m_refData
= new wxRegionRefData();
189 M_REGIONDATA
->m_region
= XCreateRegion();
196 XUnionRegion( M_REGIONDATA
->m_region
,
197 M_REGIONDATA_OF(region
)->m_region
,
198 M_REGIONDATA
->m_region
);
203 bool wxRegion::Intersect( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
205 wxRegion
reg( x
, y
, width
, height
);
207 return Intersect( reg
);
210 bool wxRegion::Intersect( const wxRect
& rect
)
212 wxRegion
reg( rect
);
214 return Intersect( reg
);
217 bool wxRegion::Intersect( const wxRegion
& region
)
224 m_refData
= new wxRegionRefData();
225 M_REGIONDATA
->m_region
= XCreateRegion();
235 XIntersectRegion( M_REGIONDATA
->m_region
,
236 M_REGIONDATA_OF(region
)->m_region
,
237 M_REGIONDATA
->m_region
);
242 bool wxRegion::Subtract( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
244 wxRegion
reg( x
, y
, width
, height
);
245 return Subtract( reg
);
248 bool wxRegion::Subtract( const wxRect
& rect
)
250 wxRegion
reg( rect
);
251 return Subtract( reg
);
254 bool wxRegion::Subtract( const wxRegion
& region
)
261 m_refData
= new wxRegionRefData();
262 M_REGIONDATA
->m_region
= XCreateRegion();
269 XSubtractRegion( M_REGIONDATA
->m_region
,
270 M_REGIONDATA_OF(region
)->m_region
,
271 M_REGIONDATA
->m_region
);
276 bool wxRegion::Xor( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
278 wxRegion
reg( x
, y
, width
, height
);
282 bool wxRegion::Xor( const wxRect
& rect
)
284 wxRegion
reg( rect
);
288 bool wxRegion::Xor( const wxRegion
& region
)
295 m_refData
= new wxRegionRefData();
296 M_REGIONDATA
->m_region
= XCreateRegion();
303 XXorRegion( M_REGIONDATA
->m_region
,
304 M_REGIONDATA_OF(region
)->m_region
,
305 M_REGIONDATA
->m_region
);
310 // ----------------------------------------------------------------------------
312 // ----------------------------------------------------------------------------
314 void wxRegion::GetBox( wxCoord
&x
, wxCoord
&y
, wxCoord
&w
, wxCoord
&h
) const
319 XClipBox( M_REGIONDATA
->m_region
, &rect
);
334 wxRect
wxRegion::GetBox() const
337 GetBox( x
, y
, w
, h
);
338 return wxRect( x
, y
, w
, h
);
341 bool wxRegion::Offset( wxCoord x
, wxCoord y
)
348 XOffsetRegion( M_REGIONDATA
->m_region
, x
, y
);
353 bool wxRegion::Empty() const
358 return XEmptyRegion( M_REGIONDATA
->m_region
);
361 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
) const
366 if (XPointInRegion( M_REGIONDATA
->m_region
, x
, y
))
372 wxRegionContain
wxRegion::Contains( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
) const
377 int res
= XRectInRegion( M_REGIONDATA
->m_region
, x
, y
, w
, h
);
380 case RectangleIn
: return wxInRegion
;
381 case RectangleOut
: return wxOutRegion
;
382 case RectanglePart
: return wxPartRegion
;
387 wxRegionContain
wxRegion::Contains(const wxPoint
& pt
) const
389 return Contains( pt
.x
, pt
.y
);
392 wxRegionContain
wxRegion::Contains(const wxRect
& rect
) const
394 return Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
397 WXRegion
*wxRegion::GetX11Region() const
400 return (WXRegion
*) NULL
;
402 return (WXRegion
*) M_REGIONDATA
->m_region
;
405 // ----------------------------------------------------------------------------
407 // ----------------------------------------------------------------------------
409 // the following structures must match the private structures
410 // in X11 region code ( xc/lib/X11/region.h )
412 // this makes the Region type transparent
413 // and we have access to the region rectangles
416 short x1
, x2
, y1
, y2
;
420 long size
, numRects
;
421 _XBox
*rects
, extents
;
424 class wxRIRefData
: public wxObjectRefData
428 wxRIRefData() : m_rects(0), m_numRects(0){}
434 void CreateRects( const wxRegion
& r
);
437 wxRIRefData::~wxRIRefData()
442 void wxRIRefData::CreateRects( const wxRegion
& region
)
450 if (region
.IsEmpty()) return;
452 Region r
= (Region
) region
.GetX11Region();
457 GrGetRegionBox(r
, & rect
);
459 m_rects
= new wxRect
[1];
460 m_rects
[0].x
= rect
.x
;
461 m_rects
[0].y
= rect
.y
;
462 m_rects
[0].width
= rect
.width
;
463 m_rects
[0].height
= rect
.height
;
465 m_numRects
= r
->numRects
;
468 m_rects
= new wxRect
[m_numRects
];
469 for (size_t i
=0; i
< m_numRects
; ++i
)
471 _XBox
&xr
= r
->rects
[i
];
472 wxRect
&wr
= m_rects
[i
];
475 wr
.width
= xr
.x2
-xr
.x1
;
476 wr
.height
= xr
.y2
-xr
.y1
;
483 wxRegionIterator::wxRegionIterator()
485 m_refData
= new wxRIRefData();
489 wxRegionIterator::wxRegionIterator( const wxRegion
& region
)
491 m_refData
= new wxRIRefData();
495 void wxRegionIterator::Reset( const wxRegion
& region
)
498 ((wxRIRefData
*)m_refData
)->CreateRects(region
);
502 bool wxRegionIterator::HaveRects() const
504 return m_current
< ((wxRIRefData
*)m_refData
)->m_numRects
;
507 wxRegionIterator::operator bool () const
512 void wxRegionIterator::operator ++ ()
514 if (HaveRects()) ++m_current
;
517 void wxRegionIterator::operator ++ (int)
519 if (HaveRects()) ++m_current
;
522 wxCoord
wxRegionIterator::GetX() const
524 if( !HaveRects() ) return 0;
525 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].x
;
528 wxCoord
wxRegionIterator::GetY() const
530 if( !HaveRects() ) return 0;
531 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].y
;
534 wxCoord
wxRegionIterator::GetW() const
536 if( !HaveRects() ) return -1;
537 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].width
;
540 wxCoord
wxRegionIterator::GetH() const
542 if( !HaveRects() ) return -1;
543 return ((wxRIRefData
*)m_refData
)->m_rects
[m_current
].height
;
546 wxRect
wxRegionIterator::GetRect() const
550 r
= ((wxRIRefData
*)m_refData
)->m_rects
[m_current
];