+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() ;
+}
+
+// in case we only got a QDPort only create a cgref now
+
+CGContextRef wxMacCGContext::GetNativeContext()
+{
+ if( m_cgContext == NULL )
+ {
+ Rect bounds ;
+ GetPortBounds( (CGrafPtr) m_qdPort , &bounds ) ;
+ OSStatus status = CreateCGContextForPort((CGrafPtr) m_qdPort , &m_cgContext) ;
+ CGContextSaveGState( m_cgContext ) ;
+
+ wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ;
+ CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top ) ;
+ CGContextScaleCTM( m_cgContext , 1 , -1 ) ;
+
+ CGContextSaveGState( m_cgContext ) ;
+ SetPen( m_pen ) ;
+ SetBrush( m_brush ) ;
+ }
+ return m_cgContext ;
+}
+
+void wxMacCGContext::SetNativeContext( CGContextRef cg )
+{
+ // we allow either setting or clearing but not replacing
+ wxASSERT( m_cgContext == NULL || cg == NULL ) ;
+ if ( cg )
+ CGContextSaveGState( cg ) ;
+ m_cgContext = cg ;
+}
+
+#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;