1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mgl/region.cpp
3 // Purpose: Region handling for wxWidgets/MGL
4 // Author: Vaclav Slavik
6 // Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com)
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #include "wx/region.h"
20 #include "wx/gdicmn.h"
21 #include "wx/module.h"
24 #include "wx/thread.h"
28 #include "wx/listimpl.cpp"
29 WX_DEFINE_LIST(wxRegionRectList
)
31 IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
)
32 IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
, wxObject
)
34 //-----------------------------------------------------------------------------
35 // wxRegionRefData implementation
36 //-----------------------------------------------------------------------------
38 class WXDLLEXPORT wxRegionRefData
: public wxGDIRefData
43 wxRegionRefData(const wxRegionRefData
& data
)
45 m_region
= data
.m_region
;
48 virtual ~wxRegionRefData() {}
53 #define M_REGION (((wxRegionRefData*)m_refData)->m_region)
54 #define M_REGION_OF(r) (((wxRegionRefData*)(r.m_refData))->m_region)
56 //-----------------------------------------------------------------------------
58 //-----------------------------------------------------------------------------
60 wxGDIRefData
*wxRegion::CreateGDIRefData() const
62 return new wxRegionRefData
;
65 wxGDIRefData
*wxRegion::CloneGDIRefData(const wxGDIRefData
*data
) const
67 return new wxRegionRefData(*(wxRegionRefData
*)data
);
71 * Create an empty region.
78 wxRegion::wxRegion(wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
80 m_refData
= new wxRegionRefData
;
81 MGLRect
rect(x
, y
, x
+ w
, y
+ h
);
85 wxRegion::wxRegion(const wxPoint
& topLeft
, const wxPoint
& bottomRight
)
87 m_refData
= new wxRegionRefData
;
88 MGLRect
rect(topLeft
.x
, topLeft
.y
, bottomRight
.x
+1, bottomRight
.y
+1);
92 wxRegion::wxRegion(const wxRect
& r
)
94 m_refData
= new wxRegionRefData
;
95 MGLRect
rect(r
.GetLeft(), r
.GetTop(), r
.GetRight()+1, r
.GetBottom()+1);
99 wxRegion::wxRegion(const MGLRegion
& region
)
101 m_refData
= new wxRegionRefData
;
105 wxRegion::wxRegion(size_t n
, const wxPoint
*points
, int WXUNUSED(fillStyle
))
107 m_refData
= new wxRegionRefData
;
108 point_t
*pts
= new point_t
[n
];
110 for (size_t i
= 0; i
< n
; i
++)
112 pts
[i
].x
= points
[i
].x
;
113 pts
[i
].y
= points
[i
].y
;
116 region_t
* rgn
= MGL_rgnPolygon(n
, pts
, 1, 0, 0);
123 wxRegion::~wxRegion()
125 // m_refData unrefed in ~wxObject
128 const MGLRegion
& wxRegion::GetMGLRegion() const
133 //-----------------------------------------------------------------------------
135 //-----------------------------------------------------------------------------
137 // Clear current region
138 void wxRegion::Clear()
144 //-----------------------------------------------------------------------------
145 // Information on region
146 //-----------------------------------------------------------------------------
148 bool wxRegion::DoIsEqual(const wxRegion
& WXUNUSED(region
)) const
150 wxFAIL_MSG( wxT("not implemented") );
155 // Outer bounds of region
156 bool wxRegion::DoGetBox(wxCoord
& x
, wxCoord
& y
, wxCoord
&w
, wxCoord
&h
) const
161 rect
= M_REGION
.getBounds();
164 w
= rect
.right
- rect
.left
;
165 h
= rect
.bottom
- rect
.top
;
177 bool wxRegion::IsEmpty() const
182 return (bool)(M_REGION
.isEmpty());
185 //-----------------------------------------------------------------------------
187 //-----------------------------------------------------------------------------
189 bool wxRegion::DoOffset(wxCoord x
, wxCoord y
)
192 M_REGION
.offset(x
, y
);
196 // Union rectangle or region with this.
197 bool wxRegion::DoUnionWithRect(const wxRect
& r
)
200 M_REGION
+= MGLRect(r
.x
, r
.y
, r
.GetRight() + 1, r
.GetHeight() + 1);
204 bool wxRegion::DoUnionWithRegion(const wxRegion
& region
)
207 M_REGION
+= M_REGION_OF(region
);
211 bool wxRegion::DoIntersect(const wxRegion
& region
)
214 M_REGION
&= M_REGION_OF(region
);
218 bool wxRegion::DoSubtract(const wxRegion
& region
)
221 M_REGION
-= M_REGION_OF(region
);
225 bool wxRegion::DoXor(const wxRegion
& region
)
228 MGLRegion rg1
= M_REGION
+ M_REGION_OF(region
),
229 rg2
= M_REGION
& M_REGION_OF(region
);
230 M_REGION
= rg1
- rg2
;
235 //-----------------------------------------------------------------------------
237 //-----------------------------------------------------------------------------
239 // Does the region contain the point (x,y)?
240 wxRegionContain
wxRegion::DoContainsPoint(wxCoord x
, wxCoord y
) const
245 if (M_REGION
.includes((int)x
, (int)y
))
251 // Does the region contain the rectangle (x, y, w, h)?
252 wxRegionContain
wxRegion::DoContainsRect(const wxRect
& r
) const
257 MGLRect
rect(r
.x
, r
.y
, r
.GetRight() + 1, r
.GetBottom() + 1);
260 // 1) is the rectangle entirely covered by the region?
261 rg
= MGLRegion(rect
) - M_REGION
;
265 // 2) is the rectangle completely outside the region?
266 rg
= M_REGION
& rect
; // intersection
270 // 3) neither case happened => it is partially covered:
274 ///////////////////////////////////////////////////////////////////////////////
275 // wxRegionIterator //
276 ///////////////////////////////////////////////////////////////////////////////
279 static wxMutex
*gs_mutexIterator
;
281 class wxMglRegionModule
: public wxModule
284 virtual bool OnInit()
286 gs_mutexIterator
= new wxMutex();
289 virtual void OnExit()
291 wxDELETE(gs_mutexIterator
);
294 DECLARE_DYNAMIC_CLASS(wxMglRegionModule
)
296 IMPLEMENT_DYNAMIC_CLASS(wxMglRegionModule
, wxModule
)
300 * Initialize empty iterator
302 wxRegionIterator::wxRegionIterator() : m_currentNode(NULL
)
304 m_rects
.DeleteContents(true);
307 wxRegionIterator::~wxRegionIterator()
312 * Initialize iterator for region
314 wxRegionIterator::wxRegionIterator(const wxRegion
& region
)
316 m_rects
.DeleteContents(true);
321 * Reset iterator for a new /e region.
325 static wxRegionRectList
*gs_rectList
;
327 static void MGLAPI
wxMGL_region_callback(const rect_t
*r
)
329 gs_rectList
->Append(new wxRect(r
->left
, r
->top
,
330 r
->right
- r
->left
, r
->bottom
- r
->top
));
333 void wxRegionIterator::Reset(const wxRegion
& region
)
335 m_currentNode
= NULL
;
341 wxMutexLocker
lock(*gs_mutexIterator
);
343 gs_rectList
= &m_rects
;
344 M_REGION_OF(region
).traverse(wxMGL_region_callback
);
345 m_currentNode
= m_rects
.GetFirst();
350 * Increment iterator. The rectangle returned is the one after the
353 void wxRegionIterator::operator ++ ()
356 m_currentNode
= m_currentNode
->GetNext();
360 * Increment iterator. The rectangle returned is the one before the
363 void wxRegionIterator::operator ++ (int)
366 m_currentNode
= m_currentNode
->GetNext();
369 wxCoord
wxRegionIterator::GetX() const
372 return m_currentNode
->GetData()->x
;
377 wxCoord
wxRegionIterator::GetY() const
380 return m_currentNode
->GetData()->y
;
385 wxCoord
wxRegionIterator::GetW() const
388 return m_currentNode
->GetData()->width
;
393 wxCoord
wxRegionIterator::GetH() const
396 return m_currentNode
->GetData()->height
;