]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/dccg.cpp
Unified flags for orienting wxBookCtrls (with backward compatibility). Centralised...
[wxWidgets.git] / src / mac / carbon / dccg.cpp
index 15342cf75c6d7d5c6cf3f0de494aacf3f634c968..eaaa2f179cfdb301401f576d28e515cefff7d064 100755 (executable)
@@ -9,10 +9,6 @@
 // Licence:       wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "dc.h"
-#endif
-
 #include "wx/wxprec.h"
 
 #include "wx/dc.h"
 #include "wx/log.h"
 
 
-#if __MSL__ >= 0x6000
-#include "math.h"
-using namespace std ;
+#ifdef __MSL__
+    #if __MSL__ >= 0x6000
+        #include "math.h"
+        using namespace std ;
+    #endif
 #endif
 
 #include "wx/mac/private.h"
-#include <ATSUnicode.h>
-#include <TextCommon.h>
-#include <TextEncodingConverter.h>
-#include <FixMath.h>
-#include <CGContext.h>
 
-#if !USE_SHARED_LIBRARY
 IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
-#endif
 
 //-----------------------------------------------------------------------------
 // constants
@@ -72,12 +63,16 @@ wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) :
     
     if ( win )
     {
-        int x = 0 , y = 0;
-        win->MacWindowToRootWindow( &x,&y ) ;
-        // get area including focus rect
-        CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ;
-        if ( !EmptyRgn( m_newClip ) )
-            OffsetRgn( m_newClip , x , y ) ;
+        // guard against half constructed objects, this just leads to a empty clip
+        if( win->GetPeer() )
+        {
+            int x = 0 , y = 0;
+            win->MacWindowToRootWindow( &x,&y ) ;
+            // get area including focus rect
+            CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ;
+            if ( !EmptyRgn( m_newClip ) )
+                OffsetRgn( m_newClip , x , y ) ;
+        }
 
         SetClip( m_newClip ) ;
     }
@@ -105,6 +100,20 @@ wxMacWindowStateSaver::~wxMacWindowStateSaver()
     SetThemeDrawingState( m_themeDrawingState , true ) ;
 }
 
+// minimal implementation only used for appearance drawing < 10.3
+
+wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) :
+    m_ph( (GrafPtr) dc->m_macPort )
+{
+    wxASSERT( dc->Ok() ) ;
+    m_dc = dc ;
+//    dc->MacSetupPort(&m_ph) ;
+}
+wxMacPortSetter::~wxMacPortSetter()
+{
+//    m_dc->MacCleanupPort(&m_ph) ;
+}
+
 //-----------------------------------------------------------------------------
 // Local functions
 //-----------------------------------------------------------------------------
@@ -121,6 +130,10 @@ static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
 // also coordinate conversions should be moved to native matrix ops
 //-----------------------------------------------------------------------------
 
+// we always stock two context states, one at entry, to be able to preserve the
+// state we were called with, the other one after changing to HI Graphics orientation
+// (this one is used for getting back clippings etc)
+
 wxMacCGPath::wxMacCGPath()
 {
     m_path = CGPathCreateMutable() ;
@@ -142,6 +155,11 @@ void wxMacCGPath::AddLineToPoint( wxCoord x1 , wxCoord y1 )
     CGPathAddLineToPoint( m_path , NULL , x1 , y1 ) ;
 }
 
+void wxMacCGPath::AddQuadCurveToPoint( wxCoord cx1, wxCoord cy1, wxCoord x1, wxCoord y1 )
+{
+    CGPathAddQuadCurveToPoint( m_path , NULL , cx1 , cy1 , x1 , y1 );
+}
+
 void wxMacCGPath::AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
 {
     CGRect cgRect = { { x , y } , { w , h } } ;
@@ -164,9 +182,6 @@ CGPathRef wxMacCGPath::GetPath() const
     return m_path ;
 }
 
-// we always stock two context states, one at entry, the other one after 
-// changing to HI Graphics orientation (this one is used for getting back clippings etc)
-
 wxMacCGContext::wxMacCGContext( CGrafPtr port ) 
 {
     m_qdPort = port ;
@@ -191,11 +206,12 @@ wxMacCGContext::~wxMacCGContext()
 {
     if ( m_cgContext )
     {
+        CGContextSynchronize( m_cgContext ) ;
         CGContextRestoreGState( m_cgContext ) ;
         CGContextRestoreGState( m_cgContext ) ;
     }
     if ( m_qdPort )
-        QDEndCGContext( m_qdPort , &m_cgContext ) ;
+        CGContextRelease( m_cgContext ) ;
 }
 
 
@@ -207,9 +223,7 @@ void wxMacCGContext::Clip( const wxRegion &region )
 void wxMacCGContext::StrokePath( const wxGraphicPath *p ) 
 {
     const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ;
-    CGContextBeginPath( m_cgContext ) ;
     CGContextAddPath( m_cgContext , path->GetPath() ) ;
-    CGContextClosePath( m_cgContext ) ;
     CGContextStrokePath( m_cgContext ) ;
 }
 
@@ -224,9 +238,7 @@ void wxMacCGContext::DrawPath( const wxGraphicPath *p , int fillStyle )
         else if ( mode == kCGPathFillStroke )
             mode = kCGPathEOFillStroke ;
     }
-    CGContextBeginPath( m_cgContext ) ;
     CGContextAddPath( m_cgContext , path->GetPath() ) ;
-    CGContextClosePath( m_cgContext ) ;
     CGContextDrawPath( m_cgContext , mode ) ;
 }
 
@@ -254,6 +266,8 @@ wxGraphicPath* wxMacCGContext::CreatePath()
 { 
     // make sure that we now have a real cgref, before doing
     // anything with paths
+    CGContextRef cg = GetNativeContext() ;
+    cg = NULL ;
     return new wxMacCGPath() ; 
 }
 
@@ -265,7 +279,7 @@ CGContextRef wxMacCGContext::GetNativeContext()
     {
         Rect bounds ;
         GetPortBounds( (CGrafPtr) m_qdPort , &bounds ) ;
-        OSStatus status = QDBeginCGContext( (CGrafPtr) m_qdPort , &m_cgContext ) ;
+        OSStatus status = CreateCGContextForPort((CGrafPtr) m_qdPort , &m_cgContext) ;
         CGContextSaveGState( m_cgContext ) ;
 
         wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ;
@@ -281,11 +295,217 @@ CGContextRef wxMacCGContext::GetNativeContext()
 
 void wxMacCGContext::SetNativeContext( CGContextRef cg ) 
 { 
-    wxASSERT( m_cgContext == NULL ) ;
+    // we allow either setting or clearing but not replacing
+    wxASSERT( m_cgContext == NULL || cg == NULL ) ;
+    if ( cg )
+        CGContextSaveGState( cg ) ;
     m_cgContext = cg ; 
-    CGContextSaveGState( m_cgContext ) ;
 }
 
+#pragma mark -
+
+// Experimental support for dashes and patterned brushes
+// uncomment the following lines to enable it
+
+// #define _NEW_GC_DASHES_
+// #define _NEW_GC_SUPPORT_
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+#define kCGColorSpaceGenericRGB   CFSTR("kCGColorSpaceGenericRGB")
+#endif
+
+void EstablishPatternColorSpace(
+       CGContextRef            ctxRef,
+       bool                            useMultibit,
+       bool                            useFill )
+{
+       CGColorSpaceRef baseSpace, patternSpace;
+
+       if (ctxRef == NULL)
+               return;
+
+       baseSpace = NULL;
+       patternSpace = NULL;
+
+       if (useMultibit)
+       {
+               patternSpace = CGColorSpaceCreatePattern( NULL );
+
+               if (useFill)
+                       CGContextSetFillColorSpace( ctxRef, patternSpace );
+               else
+                       CGContextSetStrokeColorSpace( ctxRef, patternSpace );
+       }
+       else
+       {
+               baseSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB );
+               patternSpace = CGColorSpaceCreatePattern( baseSpace );
+
+               if (useFill)
+                       CGContextSetFillColorSpace( ctxRef, patternSpace );
+               else
+                       CGContextSetStrokeColorSpace( ctxRef, patternSpace );
+       }
+
+       // NB: the context owns these now, and this code is finished with them
+       if (patternSpace != NULL)
+               CGColorSpaceRelease( patternSpace );
+       if (baseSpace != NULL)
+               CGColorSpaceRelease( baseSpace );
+}
+
+void ImagePatternRender(
+       void                    *info,
+       CGContextRef    ctxRef )
+{
+       if (ctxRef == NULL)
+               return;
+
+       CGImageRef      imageRef = (CGImageRef)info;
+       if (imageRef != NULL)
+       {
+               CGRect  boundsR = CGRectMake( 0.0, 0.0, (float)CGImageGetWidth( imageRef ), (float)CGImageGetHeight( imageRef ) );
+               CGContextDrawImage( ctxRef, boundsR, imageRef );
+       }
+}
+
+void ImagePatternDispose(
+       void            *info )
+{
+       CGImageRef      imageRef = (CGImageRef)info;
+       if (imageRef != NULL)
+               CGImageRelease( imageRef );
+}
+
+// specifies the struct version value and the callback functions for draw and release
+static const CGPatternCallbacks sImagePatternCallback = { 0, &ImagePatternRender, &ImagePatternDispose };
+
+long CreatePatternFromBitmap(
+       CGPatternRef            *patternRef,
+       const wxBitmap  *rasterInfo,
+       bool                            useMultibit )
+{
+       CGRect          boundsR;
+       CGImageRef      imageRef;
+       long                    errorStatus, widthV, heightV, depthV;
+
+       if (patternRef == NULL)
+               return (-1);
+
+       *patternRef = NULL;
+       imageRef = NULL;
+       errorStatus = 0;
+
+       if ((rasterInfo == NULL) || !rasterInfo->Ok())
+               errorStatus = (-2);
+
+       if (errorStatus == 0)
+       {
+               // build a usable bounding CGRect from the wxBitmap's bounds wxRect
+               widthV = rasterInfo->GetWidth();
+               heightV = rasterInfo->GetHeight();
+               if ((widthV <= 0) || (heightV <= 0))
+                       errorStatus = (-3);
+       }
+
+       if (errorStatus == 0)
+       {
+               depthV = rasterInfo->GetDepth();
+//             isColored = (depthV > 1);
+
+               // FIXME: this is often <= 0 - why???
+//             if (depthV <= 1)
+//                     errorStatus = (-4);
+       }
+
+       if (errorStatus == 0)
+       {
+               imageRef = (CGImageRef)(rasterInfo->CGImageCreate());
+               if (imageRef == NULL)
+                       errorStatus = (-5);
+       }
+
+       if (errorStatus == 0)
+       {
+               // FIXME: switch when this routine belongs to a DC class...
+               boundsR = CGRectMake( 0.0, 0.0, (float)widthV, (float)heightV );
+//             boundsR = CGRectMake( 0.0, 0.0, (float)XLOG2DEVREL( widthV ), (float)XLOG2DEVREL( heightV ) );
+
+               *patternRef = CGPatternCreate(
+                       (void*)imageRef,
+                       boundsR,
+                       CGAffineTransformIdentity,
+                       boundsR.size.width,
+                       boundsR.size.height,
+                       kCGPatternTilingNoDistortion,
+                       (int)useMultibit,
+                       &sImagePatternCallback );
+
+               if (*patternRef == (CGPatternRef)NULL)
+                       errorStatus = (-6);
+       }
+
+       return errorStatus;
+}
+
+long CreatePatternFromDashes(
+       CGPatternRef    *patternRef,
+       const wxDash    *sourceDash,
+       int                     count,
+       bool                    useMultibit )
+{
+       long            errorStatus;
+
+       if (patternRef == NULL)
+               return (-1);
+
+       *patternRef = NULL;
+       if ((sourceDash == NULL) || (count <= 0))
+               return (-2);
+
+       wxBitmap                dashBits( (char*)sourceDash, 8, count, 1 );
+       errorStatus = CreatePatternFromBitmap( patternRef, &dashBits, useMultibit );
+
+       return errorStatus;
+}
+
+long CreatePatternFromBrush(
+       CGPatternRef    *patternRef,
+       const wxBrush   &sourceBrush,
+       bool                    useMultibit )
+{
+       long            errorStatus;
+
+       if (patternRef == NULL)
+               return (-1);
+
+       *patternRef = NULL;
+       errorStatus = CreatePatternFromBitmap( patternRef, sourceBrush.GetStipple(), useMultibit );
+
+       return errorStatus;
+}
+
+long CreatePatternFromPen(
+       CGPatternRef    *patternRef,
+       const wxPen     &sourcePen,
+       bool                    useMultibit )
+{
+       long            errorStatus;
+
+       if (patternRef == NULL)
+               return (-1);
+
+       *patternRef = NULL;
+       errorStatus = CreatePatternFromBitmap( patternRef, sourcePen.GetStipple(), useMultibit );
+
+       return errorStatus;
+}
+
+// ------------
+#pragma mark -
+
+// FIXME: the NEW_GC_SUPPORT part this routine is unfinished and needs lots of work !!
+//
 void wxMacCGContext::SetPen( const wxPen &pen )
 {
     m_pen = pen ;
@@ -309,8 +529,55 @@ void wxMacCGContext::SetPen( const wxPen &pen )
         }
         if ( stroke )
         {
+#if defined(_NEW_GC_SUPPORT_)
+            // new candidate
+            {
+                CGPatternRef  patternRef;
+                float  alphaArray[1];
+                long  result;
+                bool  hasSetPattern, useMultibit;
+
+                hasSetPattern = false;
+                useMultibit = true;
+                result = CreatePatternFromPen( &patternRef, pen, useMultibit );
+                if (result == 0)
+                {
+                    EstablishPatternColorSpace( m_cgContext, useMultibit, false );
+
+                    alphaArray[0] = 1.0;
+                    CGContextSetStrokePattern( m_cgContext, patternRef, alphaArray );
+                    CGPatternRelease( patternRef );
+
+                    hasSetPattern = true;
+
+//wxLogDebug( wxT("CreatePatternFromPen succeeded!") );
+                }
+
+                // NB: the (-2) result is from wxPen instances that don't have a stipple wxBitmap
+                if (result < (-2))
+                    wxLogDebug( wxT("CreatePatternFromPen failed: result [%ld]"), result );
+
+                if (!hasSetPattern)
+                {
+                    RGBColor col;
+
+#if 1
+                    col = MAC_WXCOLORREF( pen.GetColour().GetPixel() );
+#else
+                    GetThemeBrushAsColor( pen.MacGetTheme(), 32, true, &col );
+#endif
+
+                    CGContextSetRGBStrokeColor(
+                        m_cgContext, (float) col.red / 65536.0,
+                        (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
+                }
+            }
+
+#else
+            // original implementation
             RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ;
             CGContextSetRGBStrokeColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+#endif
             
             CGLineCap cap ;
             switch( pen.GetCap() )
@@ -348,10 +615,83 @@ void wxMacCGContext::SetPen( const wxPen &pen )
             }
             CGContextSetLineJoin( m_cgContext , join ) ;
 
-            CGContextSetLineWidth( m_cgContext , pen.GetWidth() == 0 ? 0.1 :  pen.GetWidth() /* TODO * m_dc->m_scaleX */ ) ; 
+            /* TODO * m_dc->m_scaleX */
+            float penWidth = pen.GetWidth();
+            if (penWidth <= 0.0)
+                penWidth = 0.1;
+            CGContextSetLineWidth( m_cgContext , penWidth ) ; 
 
             m_mode = kCGPathStroke ;
             int count = 0 ;
+
+#if defined(_NEW_GC_DASHES_)
+            const char *dashData = NULL ;
+            char *userDashData = NULL ;
+            float  alphaArray[1];
+
+            const char dotted[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 };
+            const char dashed[] = { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 };
+            const char short_dashed[] = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 };
+            const char dotted_dashed[] = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00 };
+
+            switch (pen.GetStyle())
+            {
+                case wxSOLID:
+                    // default, undashed pen
+                    break;
+
+                case wxDOT:
+                    dashData = dotted;
+                    count = WXSIZEOF(dotted);
+                    break;
+                case wxLONG_DASH:
+                    dashData = dashed;
+                    count = WXSIZEOF(dashed);
+                    break;
+                case wxSHORT_DASH:
+                    dashData = short_dashed;
+                    count = WXSIZEOF(short_dashed);
+                    break;
+                case wxDOT_DASH:
+                    dashData = dotted_dashed;
+                    count = WXSIZEOF(dotted_dashed);
+                    break;
+                case wxUSER_DASH:
+                    count = pen.GetDashes( (wxDash**)&userDashData );
+                    dashData = userDashData;
+                    break;
+
+                default :
+                    break; 
+            }
+
+            if ((dashData != NULL) && (count > 0))
+            {
+                CGPatternRef  patternRef;
+                RGBColor col;
+                long  result;
+                bool  useMultibit;
+
+                    useMultibit = true;
+                    result = CreatePatternFromDashes( &patternRef, (const wxDash*)dashData, count, useMultibit );
+                    if (result == 0)
+                    {
+                        col = MAC_WXCOLORREF( pen.GetColour().GetPixel() );
+                        CGContextSetRGBStrokeColor(
+                            m_cgContext, (float) col.red / 65536.0,
+                            (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
+
+                        EstablishPatternColorSpace( m_cgContext, useMultibit, false );
+
+                        alphaArray[0] = 1.0;
+                        CGContextSetStrokePattern( m_cgContext, patternRef, alphaArray );
+                        CGPatternRelease( patternRef );
+                    }
+                if (result != 0)
+                    wxLogDebug( wxT("CreatePatternFromDashes failed: result [%ld]"), result );
+           }
+#else
             const float *lengths = NULL ;
             float *userLengths = NULL ;
             
@@ -383,11 +723,18 @@ void wxMacCGContext::SetPen( const wxPen &pen )
                 case wxUSER_DASH :
                     wxDash *dashes ;
                     count = pen.GetDashes( &dashes ) ;
-                    if ( count >0 )
+                    if ((dashes != NULL) && (count > 0))
                     {
                         userLengths = new float[count] ;
                         for( int i = 0 ; i < count ; ++i )
-                            userLengths[i] = dashes[i] ;
+                        {
+                            userLengths[i] = (float)dashes[i] ;
+                            if (userLengths[i] <= 0.0)
+                            {
+                                userLengths[i] = 1.0;
+//                                wxLogDebug( wxT("wxMacCGContext::SetPen - bad dash length[%d] [%.2f]"), i, (float)dashes[i] );
+                            }
+                        }
                     }
                     lengths = userLengths ;
                     break ;
@@ -395,20 +742,28 @@ void wxMacCGContext::SetPen( const wxPen &pen )
                     break ; 
             }
 
-            CGContextSetLineDash( m_cgContext , 0 , lengths , count ) ;
-            delete[] userLengths ;
-            // we need to change the cap, otherwise everything overlaps
-            // and we get solid lines
-            if ( count > 0 )
+            if ((lengths != NULL) && (count > 0))
+            {
+                // we need to change the cap, otherwise everything overlaps
+                // and we get solid lines
+                CGContextSetLineDash( m_cgContext , 0 , lengths , count ) ;
                 CGContextSetLineCap( m_cgContext , kCGLineCapButt ) ;
+            }
+            else 
+            {
+               CGContextSetLineDash( m_cgContext , 0 , NULL , 0 ) ;
+            }
+
+            delete[] userLengths ;
+#endif
         }
         if ( fill && stroke )
         {
             m_mode = kCGPathFillStroke ;
         }
-        
     }
 }
+
 void wxMacCGContext::SetBrush( const wxBrush &brush )
 {
     m_brush = brush ;
@@ -422,16 +777,64 @@ void wxMacCGContext::SetBrush( const wxBrush &brush )
     // we can benchmark performance, should go into a setting later
     CGContextSetShouldAntialias( m_cgContext , false ) ;
 #endif
+
     if ( fill | stroke )
     {
-
         // setup brushes
         m_mode = kCGPathFill ; // just a default
 
         if ( fill )
         {
+#if defined(_NEW_GC_SUPPORT_)
+            // new candidate
+            {
+                CGPatternRef  patternRef;
+                float  alphaArray[1];
+                long  result;
+                bool  hasSetPattern, useMultibit;
+
+                hasSetPattern = false;
+                useMultibit = true;
+                result = CreatePatternFromBrush( &patternRef, brush, useMultibit );
+                if (result == 0)
+                {
+                    EstablishPatternColorSpace( m_cgContext, useMultibit, true );
+
+                    alphaArray[0] = 1.0;
+                    CGContextSetFillPattern( m_cgContext, patternRef, alphaArray );
+                    CGPatternRelease( patternRef );
+
+                    hasSetPattern = true;
+
+//wxLogDebug( wxT("CreatePatternFromBrush succeeded!") );
+                }
+
+                // NB: the (-2) result is from wxBrush instances that don't have a stipple wxBitmap
+                if (result < (-2))
+                    wxLogDebug( wxT("CreatePatternFromBrush failed: result [%ld]"), result );
+
+                if (!hasSetPattern)
+                {
+                    RGBColor col;
+
+#if 1
+                    col = MAC_WXCOLORREF( brush.GetColour().GetPixel() );
+#else
+                    GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &col );
+#endif
+
+                    CGContextSetRGBFillColor(
+                        m_cgContext, (float) col.red / 65536.0,
+                        (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
+                }
+            }
+
+#else
+            // original implementation
             RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
             CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+#endif
+
             m_mode = kCGPathFill ;
         }
         if ( stroke )
@@ -442,70 +845,7 @@ void wxMacCGContext::SetBrush( const wxBrush &brush )
         {
             m_mode = kCGPathFillStroke ;
         }
-        
-    }
-}
-
-// snippets from Sketch Sample from Apple :
-
-#define        kGenericRGBProfilePathStr       "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"
-/*
-    This function locates, opens, and returns the profile reference for the calibrated 
-    Generic RGB color space. It is up to the caller to call CMCloseProfile when done
-    with the profile reference this function returns.
-*/
-CMProfileRef wxMacOpenGenericProfile(void)
-{
-    static CMProfileRef cachedRGBProfileRef = NULL;
-    
-    // we only create the profile reference once
-    if (cachedRGBProfileRef == NULL)
-    {
-               CMProfileLocation       loc;
-       
-               loc.locType = cmPathBasedProfile;
-               strcpy(loc.u.pathLoc.path, kGenericRGBProfilePathStr);
-       
-               verify_noerr( CMOpenProfile(&cachedRGBProfileRef, &loc) );
-    }
-
-    if (cachedRGBProfileRef)
-    {
-               // clone the profile reference so that the caller has their own reference, not our cached one
-               CMCloneProfileRef(cachedRGBProfileRef);   
     }
-
-    return cachedRGBProfileRef;
-}
-
-/*
-    Return the generic RGB color space. This is a 'get' function and the caller should
-    not release the returned value unless the caller retains it first. Usually callers
-    of this routine will immediately use the returned colorspace with CoreGraphics
-    so they typically do not need to retain it themselves.
-    
-    This function creates the generic RGB color space once and hangs onto it so it can
-    return it whenever this function is called.
-*/
-
-CGColorSpaceRef wxMacGetGenericRGBColorSpace()
-{
-    static CGColorSpaceRef genericRGBColorSpace = NULL;
-
-       if (genericRGBColorSpace == NULL)
-       {
-               CMProfileRef genericRGBProfile = wxMacOpenGenericProfile();
-       
-               if (genericRGBProfile)
-               {
-                       genericRGBColorSpace = CGColorSpaceCreateWithPlatformColorSpace(genericRGBProfile);
-                       wxASSERT_MSG( genericRGBColorSpace != NULL, wxT("couldn't create the generic RGB color space") ) ;
-                       
-                       // we opened the profile so it is up to us to close it
-                       CMCloseProfile(genericRGBProfile); 
-               }
-       }
-    return genericRGBColorSpace;
 }
 
 void AddEllipticArcToPath(CGContextRef c, CGPoint center, float a, float b, float fromDegree , float toDegree )
@@ -562,7 +902,7 @@ wxDC::wxDC()
     m_needComputeScaleY = FALSE;
 
     m_ok = FALSE ;
-
+    m_macPort = 0 ;
     m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
 
     m_pen = *wxBLACK_PEN;
@@ -596,7 +936,7 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
     wxCoord ww = XLOG2DEVREL(w);
     wxCoord hh = YLOG2DEVREL(h);
 
-    CGContextRef cg = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
+    CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
     CGImageRef image = (CGImageRef)( bmp.CGImageCreate() ) ;
     HIRect r = CGRectMake( xx , yy , ww , hh ) ;
     HIViewDrawCGImage( cg , &r , image ) ;
@@ -615,7 +955,7 @@ void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
     wxCoord ww = XLOG2DEVREL(w);
     wxCoord hh = YLOG2DEVREL(h);
 
-    CGContextRef cg = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
+    CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
     CGRect r = CGRectMake( 00 , 00 , ww , hh ) ;
     CGContextSaveGState(cg);    
     CGContextTranslateCTM(cg, xx , yy + hh );
@@ -634,7 +974,7 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     ww = XLOG2DEVREL(width);
     hh = YLOG2DEVREL(height);
 
-    CGContextRef cgContext = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
+    CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
     CGRect clipRect = CGRectMake( xx ,yy , ww, hh ) ;
     CGContextClipToRect( cgContext , clipRect ) ;
 
@@ -711,11 +1051,11 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region  )
 void wxDC::DestroyClippingRegion()
 {
 //    CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
-    CGContextRef cgContext = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
+    CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
     CGContextRestoreGState( cgContext );    
     CGContextSaveGState( cgContext );    
-    SetPen( m_pen ) ;
-    SetBrush( m_brush ) ;
+    m_graphicContext->SetPen( m_pen ) ;
+    m_graphicContext->SetBrush( m_brush ) ;
     m_clipping = FALSE;
 }
 
@@ -904,14 +1244,26 @@ bool wxDC::DoFloodFill(wxCoord x, wxCoord y,
 bool  wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
 {
     wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel  Invalid DC") );
-    wxFAIL_MSG( wxT("GetPixel not implemented on Core Graphics") ) ;
-    return false ;
+    wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel  Invalid DC") );
+    wxMacPortSaver helper((CGrafPtr)m_macPort) ;
+    RGBColor colour;
+    GetCPixel( 
+        XLOG2DEVMAC(x) + m_macLocalOriginInPort.x - m_macLocalOrigin.x, 
+        YLOG2DEVMAC(y) + m_macLocalOriginInPort.y - m_macLocalOrigin.y, &colour );
+    // Convert from Mac colour to wx
+    col->Set( colour.red   >> 8,
+        colour.green >> 8,
+        colour.blue  >> 8);
+    return true ;
 }
 
 void  wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
     
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+    
     wxCoord xx1 = XLOG2DEVMAC(x1) ;
     wxCoord yy1 = YLOG2DEVMAC(y1) ;
     wxCoord xx2 = XLOG2DEVMAC(x2) ;
@@ -932,6 +1284,8 @@ void  wxDC::DoCrossHair( wxCoord x, wxCoord y )
 {
     wxCHECK_RET( Ok(), wxT("wxDC::DoCrossHair  Invalid window dc") );
 
+    if ( m_logicalFunction != wxCOPY )
+        return ;
     
     int w = 0;
     int h = 0;
@@ -953,28 +1307,15 @@ void  wxDC::DoCrossHair( wxCoord x, wxCoord y )
     CalcBoundingBox(x+w, y+h);
 }
 
-/*
-* To draw arcs properly the angles need to be converted from the WX style:
-* Angles start on the +ve X axis and go anti-clockwise (As you would draw on
-* a normal axis on paper).
-* TO
-* the Mac style:
-* Angles start on the +ve y axis and go clockwise.
-*/
-
-static double wxConvertWXangleToMACangle(double angle)
-{
-    double newAngle = 90 - angle ;
-    if ( newAngle < 0 )
-        newAngle += 360 ;
-    return newAngle ;
-}
-
 void  wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
                       wxCoord x2, wxCoord y2,
                       wxCoord xc, wxCoord yc )
 {
     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc  Invalid DC"));
+
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCoord xx1 = XLOG2DEVMAC(x1);
     wxCoord yy1 = YLOG2DEVMAC(y1);
     wxCoord xx2 = XLOG2DEVMAC(x2);
@@ -985,32 +1326,38 @@ void  wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
     double dy = yy1 - yyc;
     double radius = sqrt((double)(dx*dx+dy*dy));
     wxCoord rad   = (wxCoord)radius;
-    double radius1, radius2;
+    double sa, ea;
     if (xx1 == xx2 && yy1 == yy2)
     {
-        radius1 = 0.0;
-        radius2 = 360.0;
+        sa = 0.0;
+        ea = 360.0;
     }
     else if (radius == 0.0)
     {
-        radius1 = radius2 = 0.0;
+        sa = ea = 0.0;
     }
     else
     {
-        radius1 = (xx1 - xxc == 0) ?
+        sa = (xx1 - xxc == 0) ?
             (yy1 - yyc < 0) ? 90.0 : -90.0 :
         -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
-        radius2 = (xx2 - xxc == 0) ?
+        ea = (xx2 - xxc == 0) ?
             (yy2 - yyc < 0) ? 90.0 : -90.0 :
         -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
     }
-    wxCoord alpha2 = wxCoord(radius2 - radius1);
-    if( (xx1 > xx2) || (yy1 > yy2) ) {
-        alpha2 *= -1;
-    }
+
+    bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
     wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
     CGContextRef ctx = mctx->GetNativeContext() ;
-    AddEllipticArcToPath( ctx , CGPointMake( xxc , yyc ) , rad , rad , 0 , 180 ) ;
+    CGContextSaveGState( ctx ) ;
+    CGContextTranslateCTM( ctx, xxc , yyc );
+    CGContextScaleCTM( ctx , 1 , -1 ) ;
+    if ( fill )
+        CGContextMoveToPoint( ctx , 0 , 0 ) ;
+    CGContextAddArc( ctx, 0, 0 , rad , DegToRad(sa), DegToRad(ea), 0);
+    if ( fill )
+        CGContextAddLineToPoint( ctx , 0 , 0 ) ;
+    CGContextRestoreGState( ctx ) ;
     CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
 }
 
@@ -1019,10 +1366,9 @@ void  wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
 {
     wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc  Invalid DC"));
 
-    double angle = sa - ea;  // Order important Mac in opposite direction to wx
-    // we have to make sure that the filling is always counter-clockwise
-    if ( angle > 0 )
-        angle -= 360 ;
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCoord xx = XLOG2DEVMAC(x);
     wxCoord yy = YLOG2DEVMAC(y);
     wxCoord ww = m_signX * XLOG2DEVREL(w);
@@ -1030,11 +1376,22 @@ void  wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
     // handle -ve width and/or height
     if (ww < 0) { ww = -ww; xx = xx - ww; }
     if (hh < 0) { hh = -hh; yy = yy - hh; }
-    sa = wxConvertWXangleToMACangle(sa);
+
+    bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
+
     wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
     CGContextRef ctx = mctx->GetNativeContext() ;
-    AddEllipticArcToPath( ctx  , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , sa , angle) ;
-    CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
+
+    CGContextSaveGState( ctx ) ;
+    CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2);
+    CGContextScaleCTM( ctx , 1 * ww / 2 , -1 * hh / 2 ) ;
+    if ( fill )
+        CGContextMoveToPoint( ctx , 0 , 0 ) ;
+    CGContextAddArc( ctx, 0, 0, 1, DegToRad(sa), DegToRad(ea), 0);
+    if ( fill )
+        CGContextAddLineToPoint( ctx , 0 , 0 ) ;
+    CGContextRestoreGState( ctx ) ;
+    CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;    
 }
 
 void  wxDC::DoDrawPoint( wxCoord x, wxCoord y )
@@ -1048,6 +1405,9 @@ void  wxDC::DoDrawLines(int n, wxPoint points[],
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
     
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCoord x1, x2 , y1 , y2 ;
     x1 = XLOG2DEVMAC(points[0].x + xoffset);
     y1 = YLOG2DEVMAC(points[0].y + yoffset);
@@ -1064,6 +1424,65 @@ void  wxDC::DoDrawLines(int n, wxPoint points[],
     delete path ;
 }
 
+#if wxUSE_SPLINES
+void wxDC::DoDrawSpline(wxList *points)
+{
+    wxCHECK_RET(Ok(), wxT("Invalid DC"));
+    
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+    
+    wxGraphicPath* path = m_graphicContext->CreatePath() ;
+    
+    wxList::compatibility_iterator node = points->GetFirst();
+    if (node == wxList::compatibility_iterator())
+        // empty list
+        return;
+    
+    wxPoint *p = (wxPoint *)node->GetData();
+    
+    wxCoord x1 = p->x;
+    wxCoord y1 = p->y;
+    
+    node = node->GetNext();
+    p = (wxPoint *)node->GetData();
+    
+    wxCoord x2 = p->x;
+    wxCoord y2 = p->y;
+    wxCoord cx1 = ( x1 + x2 ) / 2;
+    wxCoord cy1 = ( y1 + y2 ) / 2;
+    
+    path->MoveToPoint( XLOG2DEVMAC( x1 ) , XLOG2DEVMAC( y1 ) ) ;
+    path->AddLineToPoint( XLOG2DEVMAC( cx1 ) , XLOG2DEVMAC( cy1 ) ) ;
+    
+#if !wxUSE_STL
+    while ((node = node->GetNext()) != NULL)
+#else
+    while ((node = node->GetNext()))
+#endif // !wxUSE_STL
+    {
+        p = (wxPoint *)node->GetData();
+        x1 = x2;
+        y1 = y2;
+        x2 = p->x;
+        y2 = p->y;
+        wxCoord cx4 = (x1 + x2) / 2;
+        wxCoord cy4 = (y1 + y2) / 2;
+        
+        path->AddQuadCurveToPoint( XLOG2DEVMAC( x1 ) , XLOG2DEVMAC( y1 ) , 
+                                   XLOG2DEVMAC( cx4 ) , XLOG2DEVMAC( cy4 ) ) ;
+        
+        cx1 = cx4;
+        cy1 = cy4;
+    }
+            
+    path->AddLineToPoint( XLOG2DEVMAC( x2 ) , XLOG2DEVMAC( y2 ) ) ;
+    
+    m_graphicContext->StrokePath( path ) ;
+    delete path ;
+}
+#endif
+
 void  wxDC::DoDrawPolygon(int n, wxPoint points[],
                           wxCoord xoffset, wxCoord yoffset,
                           int fillStyle )
@@ -1073,6 +1492,9 @@ void  wxDC::DoDrawPolygon(int n, wxPoint points[],
     if ( n== 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
         return ;
         
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     x2 = x1 = XLOG2DEVMAC(points[0].x + xoffset);
     y2 = y1 = YLOG2DEVMAC(points[0].y + yoffset);
     
@@ -1097,6 +1519,10 @@ void  wxDC::DoDrawPolygon(int n, wxPoint points[],
 void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
+
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCoord xx = XLOG2DEVMAC(x);
     wxCoord yy = YLOG2DEVMAC(y);
     wxCoord ww = m_signX * XLOG2DEVREL(width);
@@ -1126,6 +1552,11 @@ void  wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
                                    double radius)
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
+
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
+
     if (radius < 0.0)
         radius = - radius * ((width < height) ? width : height);
     wxCoord xx = XLOG2DEVMAC(x);
@@ -1155,6 +1586,10 @@ void  wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
 void  wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
+
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCoord xx = XLOG2DEVMAC(x);
     wxCoord yy = YLOG2DEVMAC(y);
     wxCoord ww = m_signX * XLOG2DEVREL(width);
@@ -1176,25 +1611,12 @@ void  wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 
     wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
     CGContextRef ctx = mctx->GetNativeContext() ;
-    if ( width == height )
-    {
-        CGContextBeginPath(ctx);
-        CGContextAddArc(ctx ,
-            xx + ww / 2,
-            yy + hh / 2,
-            ww / 2,
-            0,
-            2 * M_PI,
-            0 ) ;
-        CGContextClosePath(ctx);
-
-        CGContextDrawPath( ctx , kCGPathFillStroke ) ;
-    }
-    else
-    {
-        AddEllipticArcToPath( ctx , CGPointMake( xx + ww / 2 , yy + hh / 2 ) , ww / 2 , hh / 2 , 0 , 360) ;
-        CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
-    }
+    CGContextSaveGState( ctx ) ;
+    CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2);
+    CGContextScaleCTM( ctx , ww / 2 , hh / 2 ) ;
+    CGContextAddArc( ctx, 0, 0, 1,  0 , 2*M_PI , 0);
+    CGContextRestoreGState( ctx ) ;
+    CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
 }
 
 bool  wxDC::CanDrawBitmap(void) const
@@ -1215,36 +1637,65 @@ bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
         xsrcMask = xsrc; ysrcMask = ysrc;
     }
 
+    wxCoord yysrc = source->YLOG2DEVMAC(ysrc) ;
+    wxCoord xxsrc = source->XLOG2DEVMAC(xsrc)  ;
+    wxCoord wwsrc = source->XLOG2DEVREL(width ) ;
+    wxCoord hhsrc = source->YLOG2DEVREL(height) ;
+    
+    wxCoord yydest = YLOG2DEVMAC(ydest) ;
+    wxCoord xxdest = XLOG2DEVMAC(xdest) ;
+    wxCoord wwdest = XLOG2DEVREL(width ) ;
+    wxCoord hhdest = YLOG2DEVREL(height) ;
+    
     wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ;
-    if ( memdc )
+    if ( memdc && logical_func == wxCOPY )
     {
         wxBitmap blit = memdc->GetSelectedObject() ;
         wxASSERT_MSG( blit.Ok() , wxT("Invalid bitmap for blitting") ) ;
 
-        wxCoord xxdest = XLOG2DEVMAC(xdest);
-        wxCoord yydest = YLOG2DEVMAC(ydest);
-        wxCoord ww = XLOG2DEVREL(width);
-        wxCoord hh = YLOG2DEVREL(height);
-
         wxCoord bmpwidth = blit.GetWidth();
         wxCoord bmpheight = blit.GetHeight();
         
-        if ( xsrc != 0 || ysrc != 0 || bmpwidth != width || bmpheight != height )
+        if ( xxsrc != 0 || yysrc != 0 || bmpwidth != wwsrc || bmpheight != hhsrc )
         {
-            wxRect subrect( xsrc, ysrc, width , height ) ;
-            blit = blit.GetSubBitmap( subrect ) ;
+            wwsrc = wxMin( wwsrc , bmpwidth - xxsrc ) ;
+            hhsrc = wxMin( hhsrc , bmpheight - yysrc ) ;
+            if ( wwsrc > 0 && hhsrc > 0 )
+            {
+                if ( xxsrc >= 0 && yysrc >= 0 )
+                {
+                    wxRect subrect( xxsrc, yysrc, wwsrc , hhsrc ) ;
+                    blit = blit.GetSubBitmap( subrect ) ;
+                }
+                else
+                {
+                    // in this case we'd probably have to adjust the different coordinates, but
+                    // we have to find out proper contract first
+                    blit = wxNullBitmap ;
+                }
+            }
+            else
+            {
+                blit = wxNullBitmap ;
+            }
+        }
+        if ( blit.Ok() )
+        {
+            CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
+            CGImageRef image = (CGImageRef)( blit.CGImageCreate() ) ;
+            HIRect r = CGRectMake( xxdest , yydest , wwdest , hhdest ) ;
+            HIViewDrawCGImage( cg , &r , image ) ;
+            CGImageRelease( image ) ;
         }
-        
-        CGContextRef cg = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
-        CGImageRef image = (CGImageRef)( blit.CGImageCreate() ) ;
-        HIRect r = CGRectMake( xxdest , yydest , ww , hh ) ;
-        HIViewDrawCGImage( cg , &r , image ) ;
-        CGImageRelease( image ) ;
            
     }
     else
     {
-        wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
+    /*
+        CGContextRef cg = (wxMacCGContext*)(source->GetGraphicContext())->GetNativeContext() ;
+        void *data = CGBitmapContextGetData( cg ) ;
+    */
+        return FALSE ; // wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
     }
     return TRUE;
 }
@@ -1257,6 +1708,9 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
     if ( str.Length() == 0 )
         return ;
     
+    if ( m_logicalFunction != wxCOPY )
+        return ;
+
     wxCHECK_RET( m_macATSUIStyle != NULL , wxT("No valid font set") ) ;
     
     OSStatus status = noErr ;
@@ -1264,7 +1718,7 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
     UniCharCount chars = str.Length() ;
     UniChar* ubuf = NULL ;
 #if SIZEOF_WCHAR_T == 4
-       wxMBConvUTF16BE converter ;
+       wxMBConvUTF16 converter ;
 #if wxUSE_UNICODE
        size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
        ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
@@ -1293,10 +1747,11 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
         &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
 
     wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") );
-    int iAngle = int( angle );
     
-
+    status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ;
+    wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") );
     
+    int iAngle = int( angle );
     if ( abs(iAngle) > 0 )
     {
         Fixed atsuAngle = IntToFixed( iAngle ) ;
@@ -1316,7 +1771,7 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
             atsuTags, atsuSizes, atsuValues ) ;
     }
     {
-        CGContextRef cgContext = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
+        CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
         ATSUAttributeTag atsuTags[] =
         {
             kATSUCGContextTag ,
@@ -1371,13 +1826,13 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
         IntToFixed(drawX) , IntToFixed(drawY) , &rect );
     wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );
 
-    CGContextSaveGState(dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext());    
-    CGContextTranslateCTM(dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext(), drawX, drawY);
-    CGContextScaleCTM(dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext(), 1, -1);
+    CGContextSaveGState(((wxMacCGContext*)(m_graphicContext))->GetNativeContext());    
+    CGContextTranslateCTM(((wxMacCGContext*)(m_graphicContext))->GetNativeContext(), drawX, drawY);
+    CGContextScaleCTM(((wxMacCGContext*)(m_graphicContext))->GetNativeContext(), 1, -1);
     status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
         IntToFixed(0) , IntToFixed(0) );
     wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") );
-    CGContextRestoreGState( dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ) ;
+    CGContextRestoreGState( ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ) ;
 
     CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) );
     CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) );
@@ -1423,7 +1878,7 @@ void  wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *heigh
     UniCharCount chars = str.Length() ;
     UniChar* ubuf = NULL ;
 #if SIZEOF_WCHAR_T == 4
-       wxMBConvUTF16BE converter ;
+       wxMBConvUTF16 converter ;
 #if wxUSE_UNICODE
        size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
        ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
@@ -1491,9 +1946,54 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con
     if (text.Length() == 0)
         return false;
     
-    wxFAIL_MSG( wxT("Unimplemented for Core Graphics") ) ;
-    
-    return false;
+    ATSUTextLayout atsuLayout ;
+    UniCharCount chars = text.Length() ;
+    UniChar* ubuf = NULL ;
+#if SIZEOF_WCHAR_T == 4
+    wxMBConvUTF16 converter ;
+#if wxUSE_UNICODE
+    size_t unicharlen = converter.WC2MB( NULL , text.wc_str() , 0 ) ;
+    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+    converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 ) ;
+#else
+    const wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
+    size_t unicharlen = converter.WC2MB( NULL , wchar.data()  , 0 ) ;
+    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+    converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
+#endif
+    chars = unicharlen / 2 ;
+#else
+#if wxUSE_UNICODE
+    ubuf = (UniChar*) text.wc_str() ;
+#else
+    wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
+    chars = wxWcslen( wchar.data() ) ;
+    ubuf = (UniChar*) wchar.data() ;
+#endif
+#endif
+
+       OSStatus status;
+    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
+        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+        
+       for ( int pos = 0; pos < (int)chars; pos ++ ) {
+                       unsigned long actualNumberOfBounds = 0;
+                       ATSTrapezoid glyphBounds;
+
+                       // We get a single bound, since the text should only require one. If it requires more, there is an issue
+                       OSStatus result; 
+                       result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds );
+                       if (result != noErr || actualNumberOfBounds != 1 )
+                       {
+                               return false;
+                       }
+
+                       widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
+                       //unsigned char uch = s[i];
+                       
+       }
+    ::ATSUDisposeTextLayout(atsuLayout);
+    return true;
 }
 
 wxCoord   wxDC::GetCharWidth(void) const
@@ -1517,39 +2017,64 @@ void  wxDC::Clear(void)
     if ( m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT)
     {      
         HIRect rect = CGRectMake( -10000 , -10000 , 20000 , 20000 ) ;
+        CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
         switch( m_backgroundBrush.MacGetBrushKind() )
         {
             case kwxMacBrushTheme :
                 {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+                    if ( HIThemeSetFill != 0 )
+                    {
+                        HIThemeSetFill( m_backgroundBrush.MacGetTheme(), NULL, cg, kHIThemeOrientationNormal );
+                        CGContextFillRect(cg, rect);
+
+                    }
+                    else
+#endif
+                    {
+                                       RGBColor        color;
+                        GetThemeBrushAsColor( m_backgroundBrush.MacGetTheme(), 32, true, &color );
+                        CGContextSetRGBFillColor( cg, (float) color.red / 65536,
+                                                       (float) color.green / 65536, (float) color.blue / 65536, 1 );
+                                       CGContextFillRect( cg, rect );
+                    }
+
+                    // reset to normal value
+                    RGBColor col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
+                    CGContextSetRGBFillColor( cg, col.red / 65536.0, col.green / 65536.0, col.blue / 65536.0, 1.0 );
                 }
             break ;
             case kwxMacBrushThemeBackground :
                 {
+                    wxFAIL_MSG( wxT("There shouldn't be theme backgrounds under Quartz") ) ;
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
-                    if ( HIThemeDrawBackground )
+                    if ( UMAGetSystemVersion() >= 0x1030 )
                     {
                         HIThemeBackgroundDrawInfo drawInfo ;
                         drawInfo.version = 0 ;
                         drawInfo.state = kThemeStateActive ;
                         drawInfo.kind = m_backgroundBrush.MacGetThemeBackground(NULL) ;
                         if ( drawInfo.kind == kThemeBackgroundMetal )
-                            HIThemeDrawBackground( &rect , &drawInfo, dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ,
+                            HIThemeDrawBackground( &rect , &drawInfo, cg ,
                                 kHIThemeOrientationNormal) ;
-                            HIThemeApplyBackground( &rect , &drawInfo, dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ,
+                            HIThemeApplyBackground( &rect , &drawInfo, cg ,
                                 kHIThemeOrientationNormal) ;
                     }
+                    else
 #endif
+                    {
+                    }
                 }
             break ;
             case kwxMacBrushColour :
             {
                 RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ;
-                CGContextSetRGBFillColor( dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
-                CGContextFillRect(dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext(), rect);
+                CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+                CGContextFillRect(cg, rect);
 
                 // reset to normal value
                 col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
-                CGContextSetRGBFillColor( dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+                CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
             }
             break ;
         }
@@ -1566,35 +2091,38 @@ void wxDC::MacInstallFont() const
         m_macATSUIStyle = NULL ;
     }
 
-    OSStatus status = noErr ;
-    status = ATSUCreateAndCopyStyle( (ATSUStyle) m_font.MacGetATSUStyle() , (ATSUStyle*) &m_macATSUIStyle ) ;
-    wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ;
-
-    Fixed atsuSize = IntToFixed( int(m_scaleY * m_font.MacGetFontSize()) ) ;
-    RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) ;
-    ATSUAttributeTag atsuTags[] =
+    if ( m_font.Ok() )
     {
-            kATSUSizeTag ,
-            kATSUColorTag ,
-    } ;
-    ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
-    {
-            sizeof( Fixed ) ,
-            sizeof( RGBColor ) ,
-    } ;
-//    Boolean kTrue = true ;
-//    Boolean kFalse = false ;
+        OSStatus status = noErr ;
+        status = ATSUCreateAndCopyStyle( (ATSUStyle) m_font.MacGetATSUStyle() , (ATSUStyle*) &m_macATSUIStyle ) ;
+        wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ;
 
-//    ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
-    ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
-    {
-            &atsuSize ,
-            &atsuColor ,
-    } ;
-    status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
-        atsuTags, atsuSizes, atsuValues);
+        Fixed atsuSize = IntToFixed( int(m_scaleY * m_font.MacGetFontSize()) ) ;
+        RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) ;
+        ATSUAttributeTag atsuTags[] =
+        {
+                kATSUSizeTag ,
+                kATSUColorTag ,
+        } ;
+        ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+        {
+                sizeof( Fixed ) ,
+                sizeof( RGBColor ) ,
+        } ;
+    //    Boolean kTrue = true ;
+    //    Boolean kFalse = false ;
 
-    wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ;
+    //    ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
+        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+        {
+                &atsuSize ,
+                &atsuColor ,
+        } ;
+        status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
+            atsuTags, atsuSizes, atsuValues);
+
+        wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ;
+    }
 }
 
 // ---------------------------------------------------------------------------