X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c871c71b9ba09ca9c43685dd454ec68e9bd9af58..f3b2e2d7196297adadd899fe56e7aeffde605f0f:/src/mac/carbon/region.cpp diff --git a/src/mac/carbon/region.cpp b/src/mac/carbon/region.cpp index aefaa80693..737d67bff5 100644 --- a/src/mac/carbon/region.cpp +++ b/src/mac/carbon/region.cpp @@ -8,18 +8,14 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "region.h" -#endif +#include "wx/wxprec.h" #include "wx/region.h" #include "wx/gdicmn.h" #include "wx/mac/uma.h" -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) - IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) -#endif +IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) +IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) //----------------------------------------------------------------------------- // wxRegionRefData implementation @@ -89,25 +85,41 @@ wxRegion::wxRegion(size_t n, const wxPoint *points, int WXUNUSED(fillStyle)) { m_refData = new wxRegionRefData; - OpenRgn(); - - wxCoord x1, x2 , y1 , y2 ; - x2 = x1 = points[0].x ; - y2 = y1 = points[0].y ; - ::MoveTo(x1,y1); - for (size_t i = 1; i < n; i++) - { - x2 = points[i].x ; - y2 = points[i].y ; - ::LineTo(x2, y2); - } - // close the polyline if necessary - if ( x1 != x2 || y1 != y2 ) + // OS X somehow does not collect the region invisibly as before, so sometimes things + // get drawn on screen instead of just being combined into a region, therefore we allocate a temp gworld now + + GWorldPtr gWorld = NULL; + GWorldPtr oldWorld; + GDHandle oldGDHandle; + OSStatus err ; + Rect destRect = {0,0,1,1}; + + ::GetGWorld( &oldWorld, &oldGDHandle ); + err = ::NewGWorld( &gWorld, 32, &destRect, nil, nil, 0 ); + if ( err == noErr ) { - ::LineTo(x1,y1 ) ; + ::SetGWorld( gWorld, GetGDevice() ); + + OpenRgn(); + + wxCoord x1, x2 , y1 , y2 ; + x2 = x1 = points[0].x ; + y2 = y1 = points[0].y ; + ::MoveTo(x1,y1); + for (size_t i = 1; i < n; i++) + { + x2 = points[i].x ; + y2 = points[i].y ; + ::LineTo(x2, y2); + } + // close the polyline if necessary + if ( x1 != x2 || y1 != y2 ) + { + ::LineTo(x1,y1 ) ; + } + CloseRgn( M_REGION ) ; + ::SetGWorld( oldWorld, oldGDHandle ); } - ClosePoly(); - CloseRgn( M_REGION ) ; } /*! @@ -397,6 +409,40 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) /*! * Reset iterator for a new /e region. */ + +OSStatus wxMacRegionToRectsCounterCallback ( + UInt16 message, RgnHandle region, const Rect *rect, void *data) +{ + long *m_numRects = (long*) data ; + if ( message == kQDRegionToRectsMsgInit ) + { + (*m_numRects) = 0 ; + } + else if (message == kQDRegionToRectsMsgParse) + { + (*m_numRects) += 1 ; + } + return noErr; +} + +class RegionToRectsCallbackData +{ +public : + wxRect* m_rects ; + long m_current ; +} ; + +OSStatus wxMacRegionToRectsSetterCallback ( + UInt16 message, RgnHandle region, const Rect *rect, void *data) +{ + if (message == kQDRegionToRectsMsgParse) + { + RegionToRectsCallbackData *cb = (RegionToRectsCallbackData*) data ; + cb->m_rects[cb->m_current++] = wxRect( rect->left , rect->top , rect->right - rect->left , rect->bottom - rect->top ) ; + } + return noErr; +} + void wxRegionIterator::Reset(const wxRegion& region) { m_current = 0; @@ -411,15 +457,25 @@ void wxRegionIterator::Reset(const wxRegion& region) m_numRects = 0; else { - // we cannot dissolve it into rects on mac - m_rects = new wxRect[1]; - Rect rect ; - GetRegionBounds( OTHER_M_REGION( region ) , &rect ) ; - m_rects[0].x = rect.left; - m_rects[0].y = rect.top; - m_rects[0].width = rect.right - rect.left; - m_rects[0].height = rect.bottom - rect.top; - m_numRects = 1; + RegionToRectsUPP proc = NewRegionToRectsUPP (wxMacRegionToRectsCounterCallback); + + OSStatus err = noErr; + err = QDRegionToRects (OTHER_M_REGION( region ) , kQDParseRegionFromTopLeft, proc, (void*)&m_numRects); + if (err == noErr) + { + DisposeRegionToRectsUPP (proc); + proc = NewRegionToRectsUPP (wxMacRegionToRectsSetterCallback); + m_rects = new wxRect[m_numRects]; + RegionToRectsCallbackData data ; + data.m_rects = m_rects ; + data.m_current = 0 ; + QDRegionToRects (OTHER_M_REGION( region ) , kQDParseRegionFromTopLeft, proc, (void*)&data); + } + else + { + m_numRects = 0 ; + } + DisposeRegionToRectsUPP (proc); } }