/////////////////////////////////////////////////////////////////////////////
// File: region.cpp
// Purpose: Region class
-// Author: Markus Holzem/Julian Smart
+// Author: Julian Smart
// Created: Fri Oct 24 10:46:34 MET 1997
-// RCS-ID: $Id$
-// Copyright: (c) 1997 Markus Holzem/Julian Smart
+// RCS-ID: $Id$
+// Copyright: (c) 1997 Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/region.h"
#include "wx/gdicmn.h"
+#ifdef __VMS__
+#pragma message disable nosimpint
+#endif
#include <Xm/Xm.h>
+#ifdef __VMS__
+#pragma message enable nosimpint
+#endif
// #include "wx/motif/private.h"
-#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
-#endif
+
+// ----------------------------------------------------------------------------
+// list types
+// ----------------------------------------------------------------------------
+
+#include "wx/listimpl.cpp"
+
+WX_DEFINE_LIST(wxRectList);
//-----------------------------------------------------------------------------
// wxRegionRefData implementation
wxRegionRefData()
{
m_region = XCreateRegion();
+ m_usingRects = FALSE;
+ m_rects = (wxRect*) NULL;
+ m_rectCount = 0;
}
wxRegionRefData(const wxRegionRefData& data)
{
m_region = XCreateRegion();
+ m_rects = (wxRect*) NULL;
+ m_rectCount = 0;
XUnionRegion(m_region, data.m_region, m_region);
+
+ SetRects(data.m_rectCount, data.m_rects);
}
~wxRegionRefData()
{
XDestroyRegion(m_region);
+ DeleteRects();
}
- Region m_region;
+
+ wxRect* GetRects() { return m_rects; };
+ void SetRects(const wxRectList& rectList);
+ void SetRects(int count, const wxRect* rects);
+ bool UsingRects() const { return m_usingRects; }
+ int GetRectCount() const { return m_rectCount; }
+
+ void DeleteRects();
+
+ Region m_region;
+ wxRect* m_rects;
+ int m_rectCount;
+ bool m_usingRects; // TRUE if we're using the above.
};
+void wxRegionRefData::SetRects(const wxRectList& rectList)
+{
+ DeleteRects();
+ m_usingRects = (rectList.GetCount() > 0);
+ if (m_usingRects)
+ {
+ m_rectCount = rectList.GetCount();
+ m_rects = new wxRect[m_rectCount];
+ }
+
+ wxRectList::Node* node = rectList.GetFirst();
+ int i = 0;
+ while (node) {
+ wxRect* rect = node->GetData();
+ m_rects[i] = * rect;
+ node = node->GetNext();
+ i ++;
+ }
+}
+
+void wxRegionRefData::SetRects(int count, const wxRect* rects)
+{
+ DeleteRects();
+ m_usingRects = (count > 0);
+ if (m_usingRects)
+ {
+ m_rectCount = count;
+ m_rects = new wxRect[m_rectCount];
+ int i;
+ for (i = 0; i < m_rectCount; i++)
+ m_rects[i] = rects[i];
+ }
+}
+
+void wxRegionRefData::DeleteRects()
+{
+ if (m_rects)
+ {
+ delete[] m_rects;
+ m_rects = (wxRect*) NULL;
+ }
+ m_rectCount = 0;
+ m_usingRects = FALSE;
+ }
+
#define M_REGION (((wxRegionRefData*)m_refData)->m_region)
//-----------------------------------------------------------------------------
{
}
-wxRegion::wxRegion(long x, long y, long w, long h)
+wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
{
m_refData = new wxRegionRefData;
}
//! Combine rectangle (x, y, w, h) with this.
-bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
+bool
+wxRegion::Combine(wxCoord x, wxCoord y,
+ wxCoord width, wxCoord height,
+ wxRegionOp op)
{
+ // work around for XUnionRectWithRegion() bug: taking a union with an empty
+ // rect results in an empty region (at least XFree 3.3.6 and 4.0 have this
+ // problem)
+ if ( op == wxRGN_OR && (!width || !height) )
+ return TRUE;
+
// Don't change shared data
if (!m_refData) {
m_refData = new wxRegionRefData();
//-----------------------------------------------------------------------------
// Outer bounds of region
-void wxRegion::GetBox(long& x, long& y, long&w, long &h) const
+void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
{
if (m_refData) {
XRectangle rect;
wxRect wxRegion::GetBox() const
{
- long x, y, w, h;
+ wxCoord x, y, w, h;
GetBox(x, y, w, h);
return wxRect(x, y, w, h);
}
//-----------------------------------------------------------------------------
// Does the region contain the point (x,y)?
-wxRegionContain wxRegion::Contains(long WXUNUSED(x), long WXUNUSED(y)) const
+wxRegionContain wxRegion::Contains(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const
{
if (!m_refData)
return wxOutRegion;
}
// Does the region contain the rectangle (x, y, w, h)?
-wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
+wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const
{
if (!m_refData)
return wxOutRegion;
if (!m_refData)
return wxOutRegion;
- long x, y, w, h;
+ wxCoord x, y, w, h;
x = rect.x;
y = rect.y;
w = rect.GetWidth();
return Contains(x, y, w, h);
}
+bool wxRegion::UsingRects() const
+{
+ return ((wxRegionRefData*)m_refData)->UsingRects();
+}
+
+/*
+wxRectList& wxRegion::GetRectList()
+{
+ return ((wxRegionRefData*)m_refData)->GetRectList();
+}
+*/
+
+wxRect* wxRegion::GetRects()
+{
+ return ((wxRegionRefData*)m_refData)->GetRects();
+}
+
+int wxRegion::GetRectCount() const
+{
+ return ((wxRegionRefData*)m_refData)->GetRectCount();
+}
+
+void wxRegion::SetRects(const wxRectList& rectList)
+{
+ ((wxRegionRefData*)m_refData)->SetRects(rectList);
+}
+
+void wxRegion::SetRects(int count, const wxRect* rects)
+{
+ ((wxRegionRefData*)m_refData)->SetRects(count, rects);
+}
+
///////////////////////////////////////////////////////////////////////////////
// //
// wxRegionIterator //
m_numRects = 0;
else
{
- // TODO create m_rects and fill with rectangles for this region
-
- // For now, fudge by getting the whole bounding box.
- m_rects = new wxRect[1];
- m_numRects = 1;
- m_rects[0] = m_region.GetBox();
+ // Create m_rects and fill with rectangles for this region.
+ // Since we can't find the rectangles in a region, we cheat
+ // by retrieving the rectangles explicitly set in wxPaintDC::wxPaintDC
+ // (dcclient.cpp).
+ if (m_region.UsingRects())
+ {
+ wxRect* rects = m_region.GetRects();
+ int count = m_region.GetRectCount();
+ m_numRects = count;
+ m_rects = new wxRect[m_numRects];
+
+ for (size_t i = 0; i < m_numRects; i++)
+ m_rects[i] = rects[i];
+
+ /*
+ int i = 0;
+ wxRectList::Node* node = rectList.GetFirst();
+ while (node) {
+ wxRect* rect = node->GetData();
+ m_rects[i] = * rect;
+ node = node->GetNext();
+ i ++;
+ }
+ */
+ }
+ else
+ {
+ // For now, fudge by getting the whole bounding box.
+ m_rects = new wxRect[1];
+ m_numRects = 1;
+ m_rects[0] = m_region.GetBox();
+ }
}
}
++m_current;
}
-long wxRegionIterator::GetX() const
+wxCoord wxRegionIterator::GetX() const
{
if (m_current < m_numRects)
return m_rects[m_current].x;
return 0;
}
-long wxRegionIterator::GetY() const
+wxCoord wxRegionIterator::GetY() const
{
if (m_current < m_numRects)
return m_rects[m_current].y;
return 0;
}
-long wxRegionIterator::GetW() const
+wxCoord wxRegionIterator::GetW() const
{
if (m_current < m_numRects)
return m_rects[m_current].width ;
return 0;
}
-long wxRegionIterator::GetH() const
+wxCoord wxRegionIterator::GetH() const
{
if (m_current < m_numRects)
return m_rects[m_current].height;