X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8d854fa93f8f5a48e383395060063a7931bf0207..04fa04d8067d235ab45b5bc05b65f0679634b541:/src/os2/region.cpp diff --git a/src/os2/region.cpp b/src/os2/region.cpp index 112fccc32f..90c7306c8d 100644 --- a/src/os2/region.cpp +++ b/src/os2/region.cpp @@ -1,25 +1,29 @@ ///////////////////////////////////////////////////////////////////////////// -// File: region.cpp +// File: src/os2/region.cpp // Purpose: Region class // Author: David Webster // Modified by: // Created: 10/15/99 -// RCS-ID: $Id$ -// Copyright: (c) Davdi Webster +// RCS-ID: $Id$ +// Copyright: (c) David Webster // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/window.h" + #include "wx/gdicmn.h" +#endif + #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 @@ -30,6 +34,7 @@ public: wxRegionRefData() { m_hRegion = 0; + m_hPS = 0; } wxRegionRefData(const wxRegionRefData& rData) @@ -37,6 +42,7 @@ public: 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 @@ -64,7 +70,7 @@ public: } } - ~wxRegionRefData() + virtual ~wxRegionRefData() { ::GpiDestroyRegion(m_hPS, m_hRegion); } @@ -74,11 +80,19 @@ public: }; #define M_REGION (((wxRegionRefData*)m_refData)->m_hRegion) +#define M_REGION_OF(rgn) (((wxRegionRefData*)(rgn.m_refData))->m_hRegion) //----------------------------------------------------------------------------- // wxRegion //----------------------------------------------------------------------------- +// General remark: +// wxRegion is always basically stored in wx coordinates. However, since +// OS/2's internal functions rely on "top > bottom", the values of top and +// bottom values of a region need to be interchanged, as compared to wx. +// This needs to be taken into account when feeding any rectangle to wx _or_ +// when accessing the region data via GetBox, wxRegionIterator or otherwise. + /*! * Create an empty region. */ @@ -88,11 +102,13 @@ wxRegion::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( @@ -135,10 +151,8 @@ wxRegion::wxRegion( ); } // end of wxRegion::wxRegion -wxRegion::wxRegion( - const wxPoint& rTopLeft -, const wxPoint& rBottomRight -) +wxRegion::wxRegion(const wxPoint& rTopLeft, + const wxPoint& rBottomRight) { RECTL vRect; SIZEL vSize = {0, 0}; @@ -153,8 +167,8 @@ wxRegion::wxRegion( vRect.xLeft = rTopLeft.x; vRect.xRight = rBottomRight.x; - vRect.yBottom = rBottomRight.y; - vRect.yTop = rTopLeft.y; + vRect.yBottom = rTopLeft.y; + vRect.yTop = rBottomRight.y; m_refData = new wxRegionRefData; @@ -172,9 +186,7 @@ wxRegion::wxRegion( ); } // end of wxRegion::wxRegion -wxRegion::wxRegion( - const wxRect& rRect -) +wxRegion::wxRegion(const wxRect& rRect) { RECTL vRect; SIZEL vSize = {0, 0}; @@ -209,6 +221,11 @@ wxRegion::wxRegion( ); } // end of wxRegion::wxRegion +wxRegion::wxRegion(size_t n, const wxPoint *points, wxPolygonFillMode WXUNUSED(fillStyle)) +{ + // TO DO +} + // // Destroy the region. // @@ -216,176 +233,130 @@ wxRegion::~wxRegion() { } // end of wxRegion::~wxRegion +wxGDIRefData *wxRegion::CreateGDIRefData() const +{ + return new wxRegionRefData; +} + +wxGDIRefData *wxRegion::CloneGDIRefData(const wxGDIRefData *data) const +{ + return new wxRegionRefData(*(wxRegionRefData *)data); +} + //----------------------------------------------------------------------------- //# Modify region //----------------------------------------------------------------------------- -// -// Clear current region -// -void wxRegion::Clear() -{ - UnRef(); -} // end of wxRegion::Clear - -// -// Combine rectangle (x, y, w, h) with this. -// -bool wxRegion::Combine( - wxCoord x -, wxCoord y -, wxCoord vWidth -, wxCoord vHeight -, wxRegionOp eOp -) +bool wxRegion::DoOffset( wxCoord x, wxCoord y ) { - // - // Don't change shared data - // - if (!m_refData) + if ( !x && !y ) { - m_refData = new wxRegionRefData(); + // nothing to do + return true; } - 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; + AllocExclusive(); - switch (eOp) +#if 0 + if ( ::OffsetRgn(GetHrgn(), x, y) == ERROR ) { - 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; + wxLogLastError(wxT("OffsetRgn")); + + return false; } - bool bSuccess = ::GpiCombineRegion( ((wxRegionRefData*)m_refData)->m_hPS - ,M_REGION - ,M_REGION - ,hRgn - ,lMode - ); - ::GpiDestroyRegion ( ((wxRegionRefData*)m_refData)->m_hPS - ,hRgn - ); - - return bSuccess; -} // end of wxRegion::Combine +#endif + return true; +} // -// Union region with this. +// Clear current region // -bool wxRegion::Combine( - const wxRegion& rRegion -, wxRegionOp eOp -) +void wxRegion::Clear() { - if (rRegion.Empty()) - return FALSE; + UnRef(); +} // end of wxRegion::Clear +// +// Union region with this. +// +bool wxRegion::DoCombine( const wxRegion& rRegion, wxRegionOp eOp ) +{ // - // 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( wxT("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); -} // end of wxRegion::Combine - -bool wxRegion::Combine( - const wxRect& rRect -, wxRegionOp eOp -) -{ - return Combine( rRect.GetLeft() - ,rRect.GetTop() - ,rRect.GetWidth() - ,rRect.GetHeight() - ,eOp - ); + return true; } // end of wxRegion::Combine //----------------------------------------------------------------------------- //# Information on region //----------------------------------------------------------------------------- +bool wxRegion::DoIsEqual(const wxRegion& WXUNUSED(region)) const +{ + return false; +} + // // Outer bounds of region // -void wxRegion::GetBox( +bool wxRegion::DoGetBox( wxCoord& x , wxCoord& y , wxCoord& vWidth @@ -395,41 +366,37 @@ void wxRegion::GetBox( 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 true; } else { x = y = vWidth = vHeight = 0L; + return false; } } // end of wxRegion::GetBox -wxRect wxRegion::GetBox() const -{ - wxCoord x, y, w, h; - GetBox(x, y, w, h); - return wxRect(x, y, w, h); -} - // // Is region empty? // -bool wxRegion::Empty() const +bool wxRegion::IsEmpty() const { - wxCoord x; - wxCoord y; - wxCoord vWidth; - wxCoord vHeight; + wxCoord x; + wxCoord y; + wxCoord vWidth; + wxCoord vHeight; if (M_REGION == 0) - return TRUE; + return true; GetBox( x ,y @@ -437,53 +404,25 @@ bool wxRegion::Empty() const ,vHeight ); return ((vWidth == 0) && (vHeight == 0)); -} // end of wxRegion::Empty +} // end of wxRegion::IsEmpty //----------------------------------------------------------------------------- // Tests //----------------------------------------------------------------------------- - -// -// Does the region contain the point (x,y)? -wxRegionContain wxRegion::Contains( - wxCoord x -, wxCoord y -) const -{ - bool bOK = FALSE; - POINTL vPoint; - - vPoint.x = x; - vPoint.y = y; - - if (!m_refData) - return wxOutRegion; - - LONG lInside = ::GpiPtInRegion( ((wxRegionRefData*)m_refData)->m_hPS - ,M_REGION - ,&vPoint - ); - if (lInside == PRGN_INSIDE) - return wxInRegion; - return wxOutRegion; -} // end of wxRegion::Contains - // // Does the region contain the point pt? // -wxRegionContain wxRegion::Contains( - const wxPoint& rPoint -) const +wxRegionContain wxRegion::DoContainsPoint( wxCoord x, wxCoord y ) const { - POINTL vPoint = { rPoint.x, rPoint.y }; + POINTL vPoint = { x, y }; if (!m_refData) return wxOutRegion; - LONG lInside = ::GpiPtInRegion( ((wxRegionRefData*)m_refData)->m_hPS - ,M_REGION - ,&vPoint - ); + LONG lInside = ::GpiPtInRegion( ((wxRegionRefData*)m_refData)->m_hPS, + M_REGION, + &vPoint + ); if (lInside == PRGN_INSIDE) return wxInRegion; else @@ -493,56 +432,29 @@ wxRegionContain wxRegion::Contains( // // Does the region contain the rectangle (x, y, w, h)? // -wxRegionContain wxRegion::Contains( - wxCoord x -, wxCoord y -, wxCoord vWidth -, wxCoord vHeight -) const +wxRegionContain wxRegion::DoContainsRect(const wxRect& rect) const { - RECTL vRect; - if (!m_refData) return wxOutRegion; - vRect.xLeft = x; - vRect.yTop = y; - vRect.xRight = x + vWidth; - vRect.yBottom = y + vHeight; - - if (PRGN_INSIDE == ::GpiRectInRegion( ((wxRegionRefData*)m_refData)->m_hPS - ,M_REGION - ,&vRect - )) - return wxInRegion; - else - return wxOutRegion; -} // end of wxRegion::Contains - -// -// Does the region contain the rectangle rect -// -wxRegionContain wxRegion::Contains( - const wxRect& rRect -) const -{ - if (!m_refData) - return wxOutRegion; + RECTL vRect; + vRect.xLeft = rect.x; + vRect.xRight = rect.x + rect.width; + vRect.yTop = rect.y + rect.height; + vRect.yBottom = rect.y; + + LONG lInside = ::GpiRectInRegion( ((wxRegionRefData*)m_refData)->m_hPS, + M_REGION, + &vRect + ); + switch (lInside) + { + case RRGN_INSIDE : return wxInRegion; + case RRGN_PARTIAL : return wxPartRegion; + case RRGN_ERROR : + default : return wxOutRegion; + } - wxCoord x; - wxCoord y; - wxCoord vWidth; - wxCoord vHeight; - - x = rRect.x; - y = rRect.y; - vWidth = rRect.GetWidth(); - vHeight = rRect.GetHeight(); - return Contains( x - ,y - ,vWidth - ,vHeight - ); } // end of wxRegion::Contains // @@ -555,6 +467,52 @@ WXHRGN wxRegion::GetHRGN() const 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 // @@ -596,6 +554,7 @@ void wxRegionIterator::Reset( ) { m_lCurrent = 0; + m_lNumRects = 0; m_vRegion = rRegion; if (m_pRects) @@ -610,6 +569,7 @@ void wxRegionIterator::Reset( 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 @@ -629,10 +589,12 @@ void wxRegionIterator::Reset( ,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; @@ -640,7 +602,9 @@ void wxRegionIterator::Reset( 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 } } } @@ -693,4 +657,3 @@ wxCoord wxRegionIterator::GetH() const return m_pRects[m_lCurrent].height; return 0L; } // end of wxRegionIterator::GetH -