// Author: David Webster
// Modified by:
// Created: 10/15/99
-// RCS-ID: $Id$
+// RCS-ID: $Id$
// Copyright: (c) Davdi Webster
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
+#include "wx/app.h"
#include "wx/os2/region.h"
#include "wx/gdicmn.h"
#include "wx/window.h"
#include "wx/os2/private.h"
- IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
- IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
+ IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
+ IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
//-----------------------------------------------------------------------------
// wxRegionRefData implementation
wxRegionRefData()
{
m_hRegion = 0;
+ m_hPS = 0;
}
wxRegionRefData(const wxRegionRefData& rData)
RGNRECT vRgnData;
PRECTL pRect = NULL;
+ vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
if (::GpiQueryRegionRects( rData.m_hPS // Pres space
,rData.m_hRegion // Handle of region to query
,NULL // Return all RECTs
};
#define M_REGION (((wxRegionRefData*)m_refData)->m_hRegion)
+#define M_REGION_OF(rgn) (((wxRegionRefData*)(rgn.m_refData))->m_hRegion)
//-----------------------------------------------------------------------------
// wxRegion
} // end of wxRegion::wxRegion
wxRegion::wxRegion(
- WXHRGN hRegion
+ WXHRGN hRegion,
+ WXHDC hPS
)
{
m_refData = new wxRegionRefData;
M_REGION = (HRGN) hRegion;
+ (((wxRegionRefData*)m_refData)->m_hPS) = hPS;
} // end of wxRegion::wxRegion
wxRegion::wxRegion(
{
} // end of wxRegion::~wxRegion
+wxObjectRefData *wxRegion::CreateData() const
+{
+ return new wxRegionRefData;
+}
+
+wxObjectRefData *wxRegion::CloneData(const wxObjectRefData *data) const
+{
+ return new wxRegionRefData(*(wxRegionRefData *)data);
+}
+
//-----------------------------------------------------------------------------
//# Modify region
//-----------------------------------------------------------------------------
+bool wxRegion::Offset(
+ wxCoord x
+, wxCoord y
+)
+{
+ if ( !x && !y )
+ {
+ // nothing to do
+ return TRUE;
+ }
+
+ AllocExclusive();
+
+#if 0
+ if ( ::OffsetRgn(GetHrgn(), x, y) == ERROR )
+ {
+ wxLogLastError(_T("OffsetRgn"));
+
+ return FALSE;
+ }
+#endif
+ return TRUE;
+}
+
//
// Clear current region
//
, wxRegionOp eOp
)
{
- //
- // Don't change shared data
- //
- if (!m_refData)
- {
- m_refData = new wxRegionRefData();
- }
- else if (m_refData->GetRefCount() > 1)
- {
- wxRegionRefData* pRef = (wxRegionRefData*)m_refData;
-
- UnRef();
- m_refData = new wxRegionRefData(*pRef);
- }
-
- //
- // If ref count is 1, that means it's 'ours' anyway so no action.
- //
- RECTL vRect;
-
- vRect.xLeft = x;
- vRect.xRight = x + vWidth;
- vRect.yBottom = y;
- vRect.yTop = y + vHeight;
-
- HRGN hRgn = ::GpiCreateRegion( ((wxRegionRefData*)m_refData)->m_hPS
- ,1
- ,&vRect
- );
- LONG lMode = 0L;
-
- switch (eOp)
- {
- case wxRGN_AND:
- lMode = CRGN_AND;
- break;
-
- case wxRGN_OR:
- lMode = CRGN_OR;
- break;
-
- case wxRGN_XOR:
- lMode = CRGN_XOR;
- break;
-
- case wxRGN_DIFF:
- lMode = CRGN_DIFF;
- break;
-
- case wxRGN_COPY:
- default:
- lMode = CRGN_COPY;
- break;
- }
- bool bSuccess = ::GpiCombineRegion( ((wxRegionRefData*)m_refData)->m_hPS
- ,M_REGION
- ,M_REGION
- ,hRgn
- ,lMode
- );
- ::GpiDestroyRegion ( ((wxRegionRefData*)m_refData)->m_hPS
- ,hRgn
- );
-
- return bSuccess;
+ return Combine(wxRegion(x, y, vWidth, vHeight), eOp);
} // end of wxRegion::Combine
//
, wxRegionOp eOp
)
{
- if (rRegion.Empty())
- return FALSE;
-
//
- // Don't change shared data
+ // We can't use the API functions if we don't have a valid region handle
//
if (!m_refData)
{
- m_refData = new wxRegionRefData();
+ // combining with an empty/invalid region works differently depending
+ // on the operation
+ switch (eOp)
+ {
+ case wxRGN_COPY:
+ case wxRGN_OR:
+ case wxRGN_XOR:
+ *this = rRegion;
+ break;
+
+ default:
+ wxFAIL_MSG( _T("unknown region operation") );
+ // fall through
+
+ case wxRGN_AND:
+ case wxRGN_DIFF:
+ // leave empty/invalid
+ return FALSE;
+ }
}
- else if (m_refData->GetRefCount() > 1)
+ else // we have a valid region
{
- wxRegionRefData* pRef = (wxRegionRefData*)m_refData;
-
- UnRef();
- m_refData = new wxRegionRefData(*pRef);
- }
- LONG lMode = 0;
+ LONG lMode = 0;
- switch (eOp)
- {
- case wxRGN_AND:
- lMode = CRGN_AND;
- break;
-
- case wxRGN_OR:
- lMode = CRGN_OR;
- break;
-
- case wxRGN_XOR:
- lMode = CRGN_XOR;
- break;
-
- case wxRGN_DIFF:
- lMode = CRGN_DIFF;
- break;
-
- case wxRGN_COPY:
- default:
- lMode = CRGN_COPY;
- break;
+ switch (eOp)
+ {
+ case wxRGN_AND:
+ lMode = CRGN_AND;
+ break;
+
+ case wxRGN_OR:
+ lMode = CRGN_OR;
+ break;
+
+ case wxRGN_XOR:
+ lMode = CRGN_XOR;
+ break;
+
+ case wxRGN_DIFF:
+ lMode = CRGN_DIFF;
+ break;
+
+ case wxRGN_COPY:
+ default:
+ lMode = CRGN_COPY;
+ break;
+ }
+ return (::GpiCombineRegion( ((wxRegionRefData*)rRegion.m_refData)->m_hPS
+ ,M_REGION
+ ,M_REGION
+ ,((wxRegionRefData*)rRegion.m_refData)->m_hRegion
+ ,lMode
+ ) != RGN_ERROR);
}
- return (::GpiCombineRegion( ((wxRegionRefData*)rRegion.m_refData)->m_hPS
- ,M_REGION
- ,M_REGION
- ,((wxRegionRefData*)rRegion.m_refData)->m_hRegion
- ,lMode
- ) != RGN_ERROR);
+ return TRUE;
} // end of wxRegion::Combine
bool wxRegion::Combine(
if (m_refData)
{
RECTL vRect;
+ APIRET rc;
- ::GpiQueryRegionBox( ((wxRegionRefData*)m_refData)->m_hPS
+ rc = ::GpiQueryRegionBox( ((wxRegionRefData*)m_refData)->m_hPS
,M_REGION
,&vRect
);
x = vRect.xLeft;
- y = vRect.yTop;
+ y = vRect.yBottom;
vWidth = vRect.xRight - vRect.xLeft;
vHeight = vRect.yTop - vRect.yBottom;
}
return (WXHRGN) M_REGION;
}
+//
+// Set a new PS, this means we have to recreate the old region in the new
+// PS
+//
+void wxRegion::SetPS(
+ HPS hPS
+)
+{
+ RGNRECT vRgnData;
+ PRECTL pRect = NULL;
+
+ vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
+ if (::GpiQueryRegionRects( ((wxRegionRefData*)m_refData)->m_hPS
+ ,((wxRegionRefData*)m_refData)->m_hRegion
+ ,NULL
+ ,&vRgnData
+ ,NULL
+ ))
+ {
+ pRect = new RECTL[vRgnData.crcReturned];
+ vRgnData.crc = vRgnData.crcReturned;
+ vRgnData.ircStart = 1;
+ if (::GpiQueryRegionRects( ((wxRegionRefData*)m_refData)->m_hPS
+ ,((wxRegionRefData*)m_refData)->m_hRegion
+ ,NULL
+ ,&vRgnData
+ ,pRect
+ ))
+ {
+ //
+ // First destroy the region out of the old PS
+ // and then create it in the new and set the new to current
+ //
+ ::GpiDestroyRegion( ((wxRegionRefData*)m_refData)->m_hPS
+ ,M_REGION
+ );
+ ((wxRegionRefData*)m_refData)->m_hRegion = ::GpiCreateRegion( hPS
+ ,vRgnData.crcReturned
+ ,pRect
+ );
+ ((wxRegionRefData*)m_refData)->m_hPS = hPS;
+ }
+ delete [] pRect;
+ }
+} // end of wxRegion::SetPS
+
///////////////////////////////////////////////////////////////////////////////
// //
// wxRegionIterator //
)
{
m_lCurrent = 0;
+ m_lNumRects = 0;
m_vRegion = rRegion;
if (m_pRects)
RGNRECT vRgnData;
PRECTL pRect;
+ vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
if (::GpiQueryRegionRects( ((wxRegionRefData*)rRegion.m_refData)->m_hPS // Pres space
,((wxRegionRefData*)rRegion.m_refData)->m_hRegion // Handle of region to query
,NULL // Return all RECTs
,pRect // Will contain the actual RECTS
))
{
+#if 0
M_REGION = ::GpiCreateRegion( ((wxRegionRefData*)rRegion.m_refData)->m_hPS
,vRgnData.crcReturned
,pRect
);
+#endif
for( LONG i = 0; i < m_lNumRects; i++)
{
m_pRects[i].x = pRect[i].xLeft;
m_pRects[i].y = pRect[i].yBottom;
m_pRects[i].height = pRect[i].yTop - pRect[i].yBottom;
}
+#if 0
((wxRegionRefData*)m_refData)->m_hPS = ((wxRegionRefData*)rRegion.m_refData)->m_hPS;
+#endif
}
}
}