]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/region.cpp
1945421 applied
[wxWidgets.git] / src / mac / carbon / region.cpp
index 8bbc439e8e602beeab09782dda9f821d4fde2c9f..d08fd4984c25b88208ffa5c7bd77738258a6bd85 100644 (file)
@@ -29,19 +29,33 @@ class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
 {
 public:
     wxRegionRefData()
-    { m_macRgn = NewRgn(); }
+    {
+        m_macRgn.reset( HIShapeCreateMutable() );
+    }
+
+    wxRegionRefData(wxCFRef<HIShapeRef> &region)
+    {
+        m_macRgn.reset( HIShapeCreateMutableCopy(region) );
+    }
+
+    wxRegionRefData(long x, long y, long w, long h)
+    {
+        CGRect r = CGRectMake(x,y,w,h);
+        wxCFRef<HIShapeRef> rect(HIShapeCreateWithRect(&r));
+        m_macRgn.reset( HIShapeCreateMutableCopy(rect) );
+    }
 
     wxRegionRefData(const wxRegionRefData& data)
         : wxGDIRefData()
     {
-        m_macRgn = NewRgn();
-        CopyRgn( data.m_macRgn , m_macRgn );
+        m_macRgn.reset( HIShapeCreateMutableCopy(data.m_macRgn) );
     }
 
     virtual ~wxRegionRefData()
-    { DisposeRgn( m_macRgn ); }
+    {
+    }
 
-    RgnHandle    m_macRgn;
+    wxCFRef<HIMutableShapeRef> m_macRgn;
 };
 
 #define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn)
@@ -56,37 +70,40 @@ public:
  */
 wxRegion::wxRegion()
 {
-    m_refData = new wxRegionRefData;
+    m_refData = new wxRegionRefData();
 }
 
 wxRegion::wxRegion(WXHRGN hRegion )
 {
-    m_refData = new wxRegionRefData;
-    CopyRgn( (RgnHandle) hRegion , (RgnHandle) M_REGION ) ;
+    wxCFRef< HIShapeRef > shape( (HIShapeRef) hRegion );
+    m_refData = new wxRegionRefData(shape);
 }
 
 wxRegion::wxRegion(long x, long y, long w, long h)
 {
-    m_refData = new wxRegionRefData;
-    SetRectRgn( (RgnHandle) M_REGION , x , y , x + w , y + h ) ;
+    m_refData = new wxRegionRefData(x , y , w , h );
 }
 
 wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
 {
-    m_refData = new wxRegionRefData;
-    SetRectRgn( (RgnHandle) M_REGION , topLeft.x , topLeft.y , bottomRight.x , bottomRight.y ) ;
+    m_refData = new wxRegionRefData(topLeft.x , topLeft.y ,
+                                    topLeft.x - bottomRight.x ,
+                                    topLeft.y - bottomRight.y);
 }
 
 wxRegion::wxRegion(const wxRect& rect)
 {
-    m_refData = new wxRegionRefData;
-    SetRectRgn( (RgnHandle) M_REGION , rect.x , rect.y , rect.x + rect.width , rect.y + rect.height ) ;
+    m_refData = new wxRegionRefData(rect.x , rect.y , rect.width , rect.height);
 }
 
 wxRegion::wxRegion(size_t n, const wxPoint *points, int WXUNUSED(fillStyle))
 {
-    m_refData = new wxRegionRefData;
+    wxUnusedVar(n);
+    wxUnusedVar(points);
 
+#ifndef __LP64__
+
+    // TODO : any APIs ?
     // 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
 
@@ -120,10 +137,22 @@ wxRegion::wxRegion(size_t n, const wxPoint *points, int WXUNUSED(fillStyle))
         if ( x1 != x2 || y1 != y2 )
             ::LineTo( x1, y1 ) ;
 
-        CloseRgn( M_REGION ) ;
-
+        RgnHandle tempRgn = NewRgn();
+        CloseRgn( tempRgn ) ;
         ::SetGWorld( oldWorld, oldGDHandle );
+        wxCFRef<HIShapeRef> tempShape( HIShapeCreateWithQDRgn(tempRgn ) );
+        m_refData = new wxRegionRefData(tempShape);
+        DisposeRgn( tempRgn );
+    }
+    else
+    {
+        m_refData = new wxRegionRefData;
     }
+#else
+    wxFAIL_MSG( "not implemented" );
+    m_refData = NULL;
+#endif
 }
 
 wxRegion::~wxRegion()
@@ -131,6 +160,16 @@ wxRegion::~wxRegion()
     // m_refData unrefed in ~wxObject
 }
 
+wxGDIRefData *wxRegion::CreateGDIRefData() const
+{
+    return new wxRegionRefData;
+}
+
+wxGDIRefData *wxRegion::CloneGDIRefData(const wxGDIRefData *data) const
+{
+    return new wxRegionRefData(*wx_static_cast(const wxRegionRefData *, data));
+}
+
 //-----------------------------------------------------------------------------
 //# Modify region
 //-----------------------------------------------------------------------------
@@ -150,7 +189,7 @@ bool wxRegion::DoOffset(wxCoord x, wxCoord y)
         // nothing to do
         return true;
 
-    OffsetRgn( M_REGION , x , y ) ;
+    verify_noerr( HIShapeOffset( M_REGION , x , y ) ) ;
 
     return true ;
 }
@@ -176,24 +215,29 @@ bool wxRegion::DoCombine(const wxRegion& region, wxRegionOp op)
     switch (op)
     {
         case wxRGN_AND:
-            SectRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+            verify_noerr( HIShapeIntersect( M_REGION , OTHER_M_REGION(region) , M_REGION ) );
             break ;
 
         case wxRGN_OR:
-            UnionRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+            verify_noerr( HIShapeUnion( M_REGION , OTHER_M_REGION(region) , M_REGION ) );
             break ;
 
         case wxRGN_XOR:
-             XorRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+            {
+                // XOR is defined as the difference between union and intersection
+                wxCFRef< HIShapeRef > unionshape( HIShapeCreateUnion( M_REGION , OTHER_M_REGION(region) ) );
+                wxCFRef< HIShapeRef > intersectionshape( HIShapeCreateIntersection( M_REGION , OTHER_M_REGION(region) ) );
+                verify_noerr( HIShapeDifference( unionshape, intersectionshape, M_REGION ) );
+            }
             break ;
 
         case wxRGN_DIFF:
-            DiffRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+            verify_noerr( HIShapeDifference( M_REGION , OTHER_M_REGION(region) , M_REGION ) ) ;
             break ;
 
         case wxRGN_COPY:
         default:
-            CopyRgn( OTHER_M_REGION(region) , M_REGION ) ;
+            M_REGION.reset( HIShapeCreateMutableCopy( OTHER_M_REGION(region) ) );
             break ;
     }
 
@@ -204,7 +248,7 @@ bool wxRegion::DoCombine(const wxRegion& region, wxRegionOp op)
 //# Information on region
 //-----------------------------------------------------------------------------
 
-bool wxRegion::DoIsEqual(const wxRegion& region) const
+bool wxRegion::DoIsEqual(const wxRegion& WXUNUSED(region)) const
 {
     wxFAIL_MSG( _T("not implemented") );
 
@@ -216,12 +260,12 @@ bool wxRegion::DoGetBox(wxCoord& x, wxCoord& y, wxCoord& w, wxCoord& h) const
 {
     if (m_refData)
     {
-        Rect box ;
-        GetRegionBounds( M_REGION , &box ) ;
-        x = box.left ;
-        y = box.top ;
-        w = box.right - box.left ;
-        h = box.bottom - box.top ;
+        CGRect box ;
+        HIShapeGetBounds( M_REGION , &box ) ;
+        x = wx_static_cast(int, box.origin.x);
+        y = wx_static_cast(int, box.origin.y);
+        w = wx_static_cast(int, box.size.width);
+        h = wx_static_cast(int, box.size.height);
 
         return true;
     }
@@ -237,7 +281,7 @@ bool wxRegion::DoGetBox(wxCoord& x, wxCoord& y, wxCoord& w, wxCoord& h) const
 bool wxRegion::IsEmpty() const
 {
     if ( m_refData )
-        return EmptyRgn( M_REGION ) ;
+        return HIShapeIsEmpty( M_REGION ) ;
     else
         return true ;
 }
@@ -257,8 +301,8 @@ wxRegionContain wxRegion::DoContainsPoint(wxCoord x, wxCoord y) const
     if (!m_refData)
         return wxOutRegion;
 
-    Point p = { y , x } ;
-    if (PtInRgn( p , M_REGION ) )
+    CGPoint p = { y , x } ;
+    if (HIShapeContainsPoint( M_REGION , &p ) )
         return wxInRegion;
 
     return wxOutRegion;
@@ -270,11 +314,18 @@ wxRegionContain wxRegion::DoContainsRect(const wxRect& r) const
     if (!m_refData)
         return wxOutRegion;
 
-    Rect rect = { r.y , r.x , r.y + r.h , r.x + r.w } ;
-    if (RectInRgn( &rect , M_REGION ) )
+    CGRect rect = CGRectMake(r.x,r.y,r.width,r.height);
+    wxCFRef<HIShapeRef> rectshape(HIShapeCreateWithRect(&rect));
+    wxCFRef<HIShapeRef> intersect(HIShapeCreateIntersection(rectshape,M_REGION));
+    CGRect bounds;
+    HIShapeGetBounds(intersect, &bounds);
+
+    if ( HIShapeIsRectangular(intersect) && CGRectEqualToRect(rect,bounds) )
         return wxInRegion;
-    else
+    else if ( HIShapeIsEmpty( intersect ) )
         return wxOutRegion;
+    else
+        return wxPartRegion;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -354,8 +405,9 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region)
  * Reset iterator for a new /e region.
  */
 
+#ifndef __LP64__
 OSStatus wxMacRegionToRectsCounterCallback(
-    UInt16 message, RgnHandle region, const Rect *rect, void *data )
+    UInt16 message, RgnHandle WXUNUSED(region), const Rect *WXUNUSED(rect), void *data )
 {
     long *m_numRects = (long*) data ;
     if ( message == kQDRegionToRectsMsgInit )
@@ -378,7 +430,7 @@ public :
 };
 
 OSStatus wxMacRegionToRectsSetterCallback(
-    UInt16 message, RgnHandle region, const Rect *rect, void *data )
+    UInt16 message, RgnHandle WXUNUSED(region), const Rect *rect, void *data )
 {
     if (message == kQDRegionToRectsMsgParse)
     {
@@ -388,6 +440,7 @@ OSStatus wxMacRegionToRectsSetterCallback(
 
     return noErr;
 }
+#endif
 
 void wxRegionIterator::Reset(const wxRegion& region)
 {
@@ -406,26 +459,35 @@ void wxRegionIterator::Reset(const wxRegion& region)
     }
     else
     {
-        RegionToRectsUPP proc = NewRegionToRectsUPP( wxMacRegionToRectsCounterCallback );
+#ifdef __LP64__
+        // copying this to a path and dissecting the path would be an option
+        m_numRects = 1;
+        m_rects = new wxRect[m_numRects];
+        m_rects[0] = m_region.GetBox();
+
+#else
+        RegionToRectsUPP proc = (RegionToRectsUPP) wxMacRegionToRectsCounterCallback;
 
         OSStatus err = noErr;
-        err = QDRegionToRects (OTHER_M_REGION( region ) , kQDParseRegionFromTopLeft, proc, (void*)&m_numRects);
+        RgnHandle rgn = NewRgn();
+        HIShapeGetAsQDRgn(OTHER_M_REGION(region), rgn);
+
+        err = QDRegionToRects (rgn, kQDParseRegionFromTopLeft, proc, (void*)&m_numRects);
         if (err == noErr)
         {
-            DisposeRegionToRectsUPP (proc);
-            proc = NewRegionToRectsUPP (wxMacRegionToRectsSetterCallback);
+            proc = (RegionToRectsUPP) 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 );
+            QDRegionToRects( rgn , kQDParseRegionFromTopLeft, proc, (void*)&data );
         }
         else
         {
             m_numRects = 0;
         }
-
-        DisposeRegionToRectsUPP( proc );
+        DisposeRgn( rgn );
+#endif
     }
 }