1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/dccg.cpp 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #if wxUSE_GRAPHICS_CONTEXT && wxMAC_USE_CORE_GRAPHICS 
  16 #include "wx/graphics.h" 
  19     #include "wx/dcclient.h" 
  20     #include "wx/dcmemory.h" 
  22     #include "wx/region.h" 
  25 #include "wx/mac/uma.h" 
  30         // in case our functions were defined outside std, we make it known all the same 
  36 #include "wx/mac/private.h" 
  38 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 
  39 typedef float CGFloat
; 
  41 #ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 
  42 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
  43     #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 1 
  45     #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0 
  49 //----------------------------------------------------------------------------- 
  51 //----------------------------------------------------------------------------- 
  53 #if !defined( __DARWIN__ ) || defined(__MWERKS__) 
  55 const double M_PI 
= 3.14159265358979; 
  59 static const double RAD2DEG 
= 180.0 / M_PI
; 
  62 // Pen, Brushes and Fonts 
  66 #pragma mark wxMacCoreGraphicsPattern, ImagePattern, HatchPattern classes 
  68 // CGPattern wrapper class: always allocate on heap, never call destructor 
  70 class wxMacCoreGraphicsPattern
 
  73     wxMacCoreGraphicsPattern() {} 
  75     // is guaranteed to be called only with a non-Null CGContextRef 
  76     virtual void Render( CGContextRef ctxRef 
) = 0; 
  78     operator CGPatternRef() const { return m_patternRef
; } 
  81     virtual ~wxMacCoreGraphicsPattern() 
  83         // as this is called only when the m_patternRef is been released; 
  84         // don't release it again 
  87     static void _Render( void *info
, CGContextRef ctxRef 
) 
  89         wxMacCoreGraphicsPattern
* self 
= (wxMacCoreGraphicsPattern
*) info
; 
  91             self
->Render( ctxRef 
); 
  94     static void _Dispose( void *info 
) 
  96         wxMacCoreGraphicsPattern
* self 
= (wxMacCoreGraphicsPattern
*) info
; 
 100     CGPatternRef m_patternRef
; 
 102     static const CGPatternCallbacks ms_Callbacks
; 
 105 const CGPatternCallbacks 
wxMacCoreGraphicsPattern::ms_Callbacks 
= { 0, &wxMacCoreGraphicsPattern::_Render
, &wxMacCoreGraphicsPattern::_Dispose 
}; 
 107 class ImagePattern 
: public wxMacCoreGraphicsPattern
 
 110     ImagePattern( const wxBitmap
* bmp 
, const CGAffineTransform
& transform 
) 
 112         wxASSERT( bmp 
&& bmp
->Ok() ); 
 114         Init( (CGImageRef
) bmp
->CGImageCreate() , transform 
); 
 117     // ImagePattern takes ownership of CGImageRef passed in 
 118     ImagePattern( CGImageRef image 
, const CGAffineTransform
& transform 
) 
 123         Init( image 
, transform 
); 
 126     virtual void Render( CGContextRef ctxRef 
) 
 129             HIViewDrawCGImage( ctxRef
, &m_imageBounds
, m_image 
); 
 133     void Init( CGImageRef image
, const CGAffineTransform
& transform 
) 
 138             m_imageBounds 
= CGRectMake( 0.0, 0.0, (CGFloat
)CGImageGetWidth( m_image 
), (CGFloat
)CGImageGetHeight( m_image 
) ); 
 139             m_patternRef 
= CGPatternCreate( 
 140                 this , m_imageBounds
, transform 
, 
 141                 m_imageBounds
.size
.width
, m_imageBounds
.size
.height
, 
 142                 kCGPatternTilingNoDistortion
, true , &wxMacCoreGraphicsPattern::ms_Callbacks 
); 
 146     virtual ~ImagePattern() 
 149             CGImageRelease( m_image 
); 
 153     CGRect m_imageBounds
; 
 156 class HatchPattern 
: public wxMacCoreGraphicsPattern
 
 159     HatchPattern( int hatchstyle
, const CGAffineTransform
& transform 
) 
 161         m_hatch 
= hatchstyle
; 
 162         m_imageBounds 
= CGRectMake( 0.0, 0.0, 8.0 , 8.0 ); 
 163         m_patternRef 
= CGPatternCreate( 
 164             this , m_imageBounds
, transform 
, 
 165             m_imageBounds
.size
.width
, m_imageBounds
.size
.height
, 
 166             kCGPatternTilingNoDistortion
, false , &wxMacCoreGraphicsPattern::ms_Callbacks 
); 
 169     void StrokeLineSegments( CGContextRef ctxRef 
, const CGPoint pts
[] , size_t count 
) 
 171 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 172         if ( CGContextStrokeLineSegments
!=NULL  
) 
 174             CGContextStrokeLineSegments( ctxRef 
, pts 
, count 
); 
 179             CGContextBeginPath( ctxRef 
); 
 180             for (size_t i 
= 0; i 
< count
; i 
+= 2) 
 182                 CGContextMoveToPoint(ctxRef
, pts
[i
].x
, pts
[i
].y
); 
 183                 CGContextAddLineToPoint(ctxRef
, pts
[i
+1].x
, pts
[i
+1].y
); 
 185             CGContextStrokePath(ctxRef
); 
 189     virtual void Render( CGContextRef ctxRef 
) 
 193             case wxBDIAGONAL_HATCH 
: 
 197                     { 8.0 , 0.0 } , { 0.0 , 8.0 } 
 199                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 203             case wxCROSSDIAG_HATCH 
: 
 207                         { 0.0 , 0.0 } , { 8.0 , 8.0 } , 
 208                         { 8.0 , 0.0 } , { 0.0 , 8.0 } 
 210                     StrokeLineSegments( ctxRef 
, pts 
, 4 ); 
 214             case wxFDIAGONAL_HATCH 
: 
 218                     { 0.0 , 0.0 } , { 8.0 , 8.0 } 
 220                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 228                     { 0.0 , 4.0 } , { 8.0 , 4.0 } , 
 229                     { 4.0 , 0.0 } , { 4.0 , 8.0 } , 
 231                     StrokeLineSegments( ctxRef 
, pts 
, 4 ); 
 235             case wxHORIZONTAL_HATCH 
: 
 239                     { 0.0 , 4.0 } , { 8.0 , 4.0 } , 
 241                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 245             case wxVERTICAL_HATCH 
: 
 249                     { 4.0 , 0.0 } , { 4.0 , 8.0 } , 
 251                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 261     virtual ~HatchPattern() {} 
 263     CGRect      m_imageBounds
; 
 267 class wxMacCoreGraphicsPenData 
: public wxGraphicsObjectRefData
 
 270     wxMacCoreGraphicsPenData( wxGraphicsRenderer
* renderer
, const wxPen 
&pen 
); 
 271     ~wxMacCoreGraphicsPenData(); 
 274     virtual void Apply( wxGraphicsContext
* context 
); 
 275     virtual wxDouble 
GetWidth() { return m_width
; } 
 279     wxMacCFRefHolder
<CGColorRef
> m_color
; 
 280     wxMacCFRefHolder
<CGColorSpaceRef
> m_colorSpace
; 
 286     const CGFloat 
*m_lengths
; 
 287     CGFloat 
*m_userLengths
; 
 291     wxMacCFRefHolder
<CGPatternRef
> m_pattern
; 
 292     CGFloat
* m_patternColorComponents
; 
 295 wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer
* renderer
, const wxPen 
&pen 
) : 
 296     wxGraphicsObjectRefData( renderer 
) 
 300     float components
[4] = { pen
.GetColour().Red() / 255.0 , pen
.GetColour().Green() / 255.0 , 
 301             pen
.GetColour().Blue() / 255.0 , pen
.GetColour().Alpha() / 255.0 } ; 
 302     m_color
.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components 
) ) ; 
 304     // TODO: * m_dc->m_scaleX 
 305     m_width 
= pen
.GetWidth(); 
 309     switch ( pen
.GetCap() ) 
 312             m_cap 
= kCGLineCapRound
; 
 315         case wxCAP_PROJECTING 
: 
 316             m_cap 
= kCGLineCapSquare
; 
 320             m_cap 
= kCGLineCapButt
; 
 324             m_cap 
= kCGLineCapButt
; 
 328     switch ( pen
.GetJoin() ) 
 331             m_join 
= kCGLineJoinBevel
; 
 335             m_join 
= kCGLineJoinMiter
; 
 339             m_join 
= kCGLineJoinRound
; 
 343             m_join 
= kCGLineJoinMiter
; 
 347     const CGFloat dashUnit 
= m_width 
< 1.0 ? 1.0 : m_width
; 
 349     const CGFloat dotted
[] = { dashUnit 
, dashUnit 
+ 2.0 }; 
 350     static const CGFloat short_dashed
[] = { 9.0 , 6.0 }; 
 351     static const CGFloat dashed
[] = { 19.0 , 9.0 }; 
 352     static const CGFloat dotted_dashed
[] = { 9.0 , 6.0 , 3.0 , 3.0 }; 
 354     switch ( pen
.GetStyle() ) 
 360             m_count 
= WXSIZEOF(dotted
); 
 361             m_userLengths 
= new CGFloat
[ m_count 
] ; 
 362             memcpy( m_userLengths
, dotted
, sizeof(dotted
) ); 
 363             m_lengths 
= m_userLengths
; 
 367             m_count 
= WXSIZEOF(dashed
); 
 372             m_count 
= WXSIZEOF(short_dashed
); 
 373             m_lengths 
= short_dashed
; 
 377             m_count 
= WXSIZEOF(dotted_dashed
); 
 378             m_lengths 
= dotted_dashed
; 
 383             m_count 
= pen
.GetDashes( &dashes 
); 
 384             if ((dashes 
!= NULL
) && (m_count 
> 0)) 
 386                 m_userLengths 
= new CGFloat
[m_count
]; 
 387                 for ( int i 
= 0; i 
< m_count
; ++i 
) 
 389                     m_userLengths
[i
] = dashes
[i
] * dashUnit
; 
 391                     if ( i 
% 2 == 1 && m_userLengths
[i
] < dashUnit 
+ 2.0 ) 
 392                         m_userLengths
[i
] = dashUnit 
+ 2.0; 
 393                     else if ( i 
% 2 == 0 && m_userLengths
[i
] < dashUnit 
) 
 394                         m_userLengths
[i
] = dashUnit
; 
 397             m_lengths 
= m_userLengths
; 
 402                 wxBitmap
* bmp 
= pen
.GetStipple(); 
 403                 if ( bmp 
&& bmp
->Ok() ) 
 405                     m_colorSpace
.Set( CGColorSpaceCreatePattern( NULL 
) ); 
 406                     m_pattern
.Set( *( new ImagePattern( bmp 
, CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 407                     m_patternColorComponents 
= new CGFloat
[1] ; 
 408                     m_patternColorComponents
[0] = 1.0; 
 417                 m_colorSpace
.Set( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); 
 418                 m_pattern
.Set( *( new HatchPattern( pen
.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 419                 m_patternColorComponents 
= new CGFloat
[4] ; 
 420                 m_patternColorComponents
[0] = pen
.GetColour().Red() / 255.0; 
 421                 m_patternColorComponents
[1] = pen
.GetColour().Green() / 255.0; 
 422                 m_patternColorComponents
[2] = pen
.GetColour().Blue() / 255.0; 
 423                 m_patternColorComponents
[3] =  pen
.GetColour().Alpha() / 255.0; 
 427     if ((m_lengths 
!= NULL
) && (m_count 
> 0)) 
 429         // force the line cap, otherwise we get artifacts (overlaps) and just solid lines 
 430         m_cap 
= kCGLineCapButt
; 
 434 wxMacCoreGraphicsPenData::~wxMacCoreGraphicsPenData() 
 436     delete[] m_userLengths
; 
 437     delete[] m_patternColorComponents
; 
 440 void wxMacCoreGraphicsPenData::Init() 
 443     m_userLengths 
= NULL
; 
 446     m_patternColorComponents 
= NULL
; 
 450 void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext
* context 
) 
 452     CGContextRef cg 
= (CGContextRef
) context
->GetNativeContext(); 
 453     CGContextSetLineWidth( cg 
, m_width 
); 
 454     CGContextSetLineJoin( cg 
, m_join 
); 
 456     CGContextSetLineDash( cg 
, 0 , m_lengths 
, m_count 
); 
 457     CGContextSetLineCap( cg 
, m_cap 
); 
 461         CGAffineTransform matrix 
= CGContextGetCTM( cg 
); 
 462         CGContextSetPatternPhase( cg
, CGSizeMake(matrix
.tx
, matrix
.ty
) ); 
 463         CGContextSetStrokeColorSpace( cg 
, m_colorSpace 
); 
 464         CGContextSetStrokePattern( cg
, m_pattern 
, m_patternColorComponents 
); 
 468         if ( context
->GetLogicalFunction() == wxINVERT 
|| context
->GetLogicalFunction() == wxXOR 
) 
 470             CGContextSetRGBStrokeColor( cg 
, 1.0, 1.0 , 1.0, 1.0 ); 
 473             CGContextSetStrokeColorWithColor( cg 
, m_color 
); 
 481 class wxMacCoreGraphicsBrushData 
: public wxGraphicsObjectRefData
 
 484     wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer 
); 
 485     wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer
, const wxBrush 
&brush 
); 
 486     ~wxMacCoreGraphicsBrushData (); 
 488     virtual void Apply( wxGraphicsContext
* context 
); 
 489     void CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
 490         const wxColour
&c1
, const wxColour
&c2 
); 
 491     void CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
 492     const wxColour 
&oColor
, const wxColour 
&cColor 
); 
 494     virtual bool IsShading() { return m_isShading
; } 
 495     CGShadingRef 
GetShading() { return m_shading
; } 
 497     CGFunctionRef 
CreateGradientFunction( const wxColour
& c1
, const wxColour
& c2 
); 
 498     static void CalculateShadingValues (void *info
, const CGFloat 
*in
, CGFloat 
*out
); 
 501     wxMacCFRefHolder
<CGColorRef
> m_color
; 
 502     wxMacCFRefHolder
<CGColorSpaceRef
> m_colorSpace
; 
 505     wxMacCFRefHolder
<CGPatternRef
> m_pattern
; 
 506     CGFloat
* m_patternColorComponents
; 
 509     CGFunctionRef m_gradientFunction
; 
 510     CGShadingRef m_shading
; 
 511     CGFloat 
*m_gradientComponents
; 
 514 wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer
) : wxGraphicsObjectRefData( renderer 
) 
 519 void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
 520         const wxColour
&c1
, const wxColour
&c2 
) 
 522     m_gradientFunction 
= CreateGradientFunction( c1
, c2 
); 
 523     m_shading 
= CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1
,y1
), CGPointMake(x2
,y2
), m_gradientFunction
, true, true ) ; 
 527 void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
 528     const wxColour 
&oColor
, const wxColour 
&cColor 
) 
 530     m_gradientFunction 
= CreateGradientFunction( oColor
, cColor 
); 
 531     m_shading 
= CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo
,yo
), 0, CGPointMake(xc
,yc
), radius
, m_gradientFunction
, true, true ) ; 
 535 wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer
* renderer
, const wxBrush 
&brush
) : wxGraphicsObjectRefData( renderer 
) 
 539     if ( brush
.GetStyle() == wxSOLID 
) 
 541         if ( brush
.MacGetBrushKind() == kwxMacBrushTheme 
) 
 543 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 544             if ( HIThemeBrushCreateCGColor 
!= 0 ) 
 547                 HIThemeBrushCreateCGColor( brush
.MacGetTheme(), &color 
); 
 548                 m_color
.Set( color 
) ; 
 553                 // as close as we can get, unfortunately < 10.4 things get difficult 
 555                 GetThemeBrushAsColor( brush
.MacGetTheme(), 32, true, &color 
); 
 556                 float components
[4] = {  (CGFloat
) color
.red 
/ 65536, 
 557                     (CGFloat
) color
.green 
/ 65536, (CGFloat
) color
.blue 
/ 65536, 1 } ; 
 558                 m_color
.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components 
) ) ; 
 563             float components
[4] = { brush
.GetColour().Red() / 255.0 , brush
.GetColour().Green() / 255.0 , 
 564                 brush
.GetColour().Blue() / 255.0 , brush
.GetColour().Alpha() / 255.0 } ; 
 565             m_color
.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components 
) ) ; 
 568     else if ( brush
.IsHatch() ) 
 571         m_colorSpace
.Set( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); 
 572         m_pattern
.Set( *( new HatchPattern( brush
.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 574         m_patternColorComponents 
= new CGFloat
[4] ; 
 575         m_patternColorComponents
[0] = brush
.GetColour().Red() / 255.0; 
 576         m_patternColorComponents
[1] = brush
.GetColour().Green() / 255.0; 
 577         m_patternColorComponents
[2] = brush
.GetColour().Blue() / 255.0; 
 578         m_patternColorComponents
[3] = brush
.GetColour().Alpha() / 255.0; 
 582         // now brush is a bitmap 
 583         wxBitmap
* bmp 
= brush
.GetStipple(); 
 584         if ( bmp 
&& bmp
->Ok() ) 
 587             m_patternColorComponents 
= new CGFloat
[1] ; 
 588             m_patternColorComponents
[0] = 1.0; 
 589             m_colorSpace
.Set( CGColorSpaceCreatePattern( NULL 
) ); 
 590             m_pattern
.Set( *( new ImagePattern( bmp 
, CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 595 wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData() 
 598         CGShadingRelease(m_shading
); 
 600     if( m_gradientFunction 
) 
 601         CGFunctionRelease(m_gradientFunction
); 
 603     delete[] m_gradientComponents
; 
 604     delete[] m_patternColorComponents
; 
 607 void wxMacCoreGraphicsBrushData::Init() 
 609     m_patternColorComponents 
= NULL
; 
 610     m_gradientFunction 
= NULL
; 
 613     m_gradientComponents 
= NULL
; 
 617 void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext
* context 
) 
 619     CGContextRef cg 
= (CGContextRef
) context
->GetNativeContext(); 
 623         // nothing to set as shades are processed by clipping using the path and filling 
 629             CGAffineTransform matrix 
= CGContextGetCTM( cg 
); 
 630             CGContextSetPatternPhase( cg
, CGSizeMake(matrix
.tx
, matrix
.ty
) ); 
 631             CGContextSetFillColorSpace( cg 
, m_colorSpace 
); 
 632             CGContextSetFillPattern( cg
, m_pattern 
, m_patternColorComponents 
); 
 636             CGContextSetFillColorWithColor( cg
, m_color 
); 
 641 void wxMacCoreGraphicsBrushData::CalculateShadingValues (void *info
, const CGFloat 
*in
, CGFloat 
*out
) 
 643     CGFloat
* colors 
= (CGFloat
*) info 
; 
 645     for( int i 
= 0 ; i 
< 4 ; ++i 
) 
 647         out
[i
] = colors
[i
] + ( colors
[4+i
] - colors
[i
] ) * f
; 
 651 CGFunctionRef 
wxMacCoreGraphicsBrushData::CreateGradientFunction( const wxColour
& c1
, const wxColour
& c2 
) 
 653     static const CGFunctionCallbacks callbacks 
= { 0, &CalculateShadingValues
, NULL 
}; 
 654     static const CGFloat input_value_range 
[2] = { 0, 1 }; 
 655     static const CGFloat output_value_ranges 
[8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; 
 656     m_gradientComponents 
= new CGFloat
[8] ; 
 657     m_gradientComponents
[0] = c1
.Red() / 255.0; 
 658     m_gradientComponents
[1] = c1
.Green() / 255.0; 
 659     m_gradientComponents
[2] = c1
.Blue() / 255.0; 
 660     m_gradientComponents
[3] = c1
.Alpha() / 255.0; 
 661     m_gradientComponents
[4] = c2
.Red() / 255.0; 
 662     m_gradientComponents
[5] = c2
.Green() / 255.0; 
 663     m_gradientComponents
[6] = c2
.Blue() / 255.0; 
 664     m_gradientComponents
[7] = c2
.Alpha() / 255.0; 
 666     return CGFunctionCreate ( m_gradientComponents
,  1, 
 677 class wxMacCoreGraphicsFontData 
: public wxGraphicsObjectRefData
 
 680     wxMacCoreGraphicsFontData( wxGraphicsRenderer
* renderer
, const wxFont 
&font
, const wxColour
& col 
); 
 681     ~wxMacCoreGraphicsFontData(); 
 683     virtual ATSUStyle 
GetATSUStyle() { return m_macATSUIStyle
; } 
 685     ATSUStyle m_macATSUIStyle
; 
 688 wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer
* renderer
, const wxFont 
&font
, const wxColour
& col
) : wxGraphicsObjectRefData( renderer 
) 
 690     m_macATSUIStyle 
= NULL
; 
 694     status 
= ATSUCreateAndCopyStyle( (ATSUStyle
) font
.MacGetATSUStyle() , &m_macATSUIStyle 
); 
 696     wxASSERT_MSG( status 
== noErr
, wxT("couldn't create ATSU style") ); 
 698     // we need the scale here ... 
 700     Fixed atsuSize 
= IntToFixed( int( 1 * font
.MacGetFontSize()) ); 
 701     RGBColor atsuColor 
= MAC_WXCOLORREF( col
.GetPixel() ); 
 702     ATSUAttributeTag atsuTags
[] = 
 707     ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 712     ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 718     status 
= ::ATSUSetAttributes( 
 719         m_macATSUIStyle
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) , 
 720         atsuTags
, atsuSizes
, atsuValues
); 
 722     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ); 
 725 wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() 
 727     if ( m_macATSUIStyle 
) 
 729         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
); 
 730         m_macATSUIStyle 
= NULL
; 
 738 //----------------------------------------------------------------------------- 
 739 // wxMacCoreGraphicsMatrix declaration 
 740 //----------------------------------------------------------------------------- 
 742 class WXDLLIMPEXP_CORE wxMacCoreGraphicsMatrixData 
: public wxGraphicsMatrixData
 
 745     wxMacCoreGraphicsMatrixData(wxGraphicsRenderer
* renderer
) ; 
 747     virtual ~wxMacCoreGraphicsMatrixData() ; 
 749     virtual wxGraphicsObjectRefData 
*Clone() const ; 
 751     // concatenates the matrix 
 752     virtual void Concat( const wxGraphicsMatrixData 
*t 
); 
 754     // sets the matrix to the respective values 
 755     virtual void Set(wxDouble a
=1.0, wxDouble b
=0.0, wxDouble c
=0.0, wxDouble d
=1.0, 
 756         wxDouble tx
=0.0, wxDouble ty
=0.0); 
 758     // gets the component valuess of the matrix 
 759     virtual void Get(wxDouble
* a
=NULL
, wxDouble
* b
=NULL
,  wxDouble
* c
=NULL
, 
 760                      wxDouble
* d
=NULL
, wxDouble
* tx
=NULL
, wxDouble
* ty
=NULL
) const; 
 762     // makes this the inverse matrix 
 763     virtual void Invert(); 
 765     // returns true if the elements of the transformation matrix are equal ? 
 766     virtual bool IsEqual( const wxGraphicsMatrixData
* t
) const ; 
 768     // return true if this is the identity matrix 
 769     virtual bool IsIdentity() const; 
 775     // add the translation to this matrix 
 776     virtual void Translate( wxDouble dx 
, wxDouble dy 
); 
 778     // add the scale to this matrix 
 779     virtual void Scale( wxDouble xScale 
, wxDouble yScale 
); 
 781     // add the rotation to this matrix (radians) 
 782     virtual void Rotate( wxDouble angle 
); 
 785     // apply the transforms 
 788     // applies that matrix to the point 
 789     virtual void TransformPoint( wxDouble 
*x
, wxDouble 
*y 
) const; 
 791     // applies the matrix except for translations 
 792     virtual void TransformDistance( wxDouble 
*dx
, wxDouble 
*dy 
) const; 
 794     // returns the native representation 
 795     virtual void * GetNativeMatrix() const; 
 798     CGAffineTransform m_matrix
; 
 801 //----------------------------------------------------------------------------- 
 802 // wxMacCoreGraphicsMatrix implementation 
 803 //----------------------------------------------------------------------------- 
 805 wxMacCoreGraphicsMatrixData::wxMacCoreGraphicsMatrixData(wxGraphicsRenderer
* renderer
) : wxGraphicsMatrixData(renderer
) 
 809 wxMacCoreGraphicsMatrixData::~wxMacCoreGraphicsMatrixData() 
 813 wxGraphicsObjectRefData 
*wxMacCoreGraphicsMatrixData::Clone() const 
 815     wxMacCoreGraphicsMatrixData
* m 
= new wxMacCoreGraphicsMatrixData(GetRenderer()) ; 
 816     m
->m_matrix 
= m_matrix 
; 
 820 // concatenates the matrix 
 821 void wxMacCoreGraphicsMatrixData::Concat( const wxGraphicsMatrixData 
*t 
) 
 823     m_matrix 
= CGAffineTransformConcat(m_matrix
, *((CGAffineTransform
*) t
->GetNativeMatrix()) ); 
 826 // sets the matrix to the respective values 
 827 void wxMacCoreGraphicsMatrixData::Set(wxDouble a
, wxDouble b
, wxDouble c
, wxDouble d
, 
 828     wxDouble tx
, wxDouble ty
) 
 830     m_matrix 
= CGAffineTransformMake(a
,b
,c
,d
,tx
,ty
); 
 833 // gets the component valuess of the matrix 
 834 void wxMacCoreGraphicsMatrixData::Get(wxDouble
* a
, wxDouble
* b
,  wxDouble
* c
, 
 835                                       wxDouble
* d
, wxDouble
* tx
, wxDouble
* ty
) const 
 837     if (a
)  *a 
= m_matrix
.a
; 
 838     if (b
)  *b 
= m_matrix
.b
; 
 839     if (c
)  *c 
= m_matrix
.c
; 
 840     if (d
)  *d 
= m_matrix
.d
; 
 841     if (tx
) *tx
= m_matrix
.tx
; 
 842     if (ty
) *ty
= m_matrix
.ty
; 
 845 // makes this the inverse matrix 
 846 void wxMacCoreGraphicsMatrixData::Invert() 
 848     m_matrix 
= CGAffineTransformInvert( m_matrix 
); 
 851 // returns true if the elements of the transformation matrix are equal ? 
 852 bool wxMacCoreGraphicsMatrixData::IsEqual( const wxGraphicsMatrixData
* t
) const 
 854     const CGAffineTransform
* tm 
= (CGAffineTransform
*) t
->GetNativeMatrix(); 
 855 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
 856     if ( CGAffineTransformEqualToTransform
!=NULL 
) 
 858         return CGAffineTransformEqualToTransform(m_matrix
, *((CGAffineTransform
*) t
->GetNativeMatrix())); 
 864             m_matrix
.a 
== tm
->a 
&& 
 865             m_matrix
.b 
== tm
->b 
&& 
 866             m_matrix
.c 
== tm
->c 
&& 
 867             m_matrix
.d 
== tm
->d 
&& 
 868             m_matrix
.tx 
== tm
->tx 
&& 
 869             m_matrix
.ty 
== tm
->ty 
) ; 
 873 // return true if this is the identity matrix 
 874 bool wxMacCoreGraphicsMatrixData::IsIdentity() const 
 876     return ( m_matrix
.a 
== 1 && m_matrix
.d 
== 1 && 
 877         m_matrix
.b 
== 0 && m_matrix
.d 
== 0 && m_matrix
.tx 
== 0 && m_matrix
.ty 
== 0); 
 884 // add the translation to this matrix 
 885 void wxMacCoreGraphicsMatrixData::Translate( wxDouble dx 
, wxDouble dy 
) 
 887     m_matrix 
= CGAffineTransformTranslate( m_matrix
, dx
, dy
); 
 890 // add the scale to this matrix 
 891 void wxMacCoreGraphicsMatrixData::Scale( wxDouble xScale 
, wxDouble yScale 
) 
 893     m_matrix 
= CGAffineTransformScale( m_matrix
, xScale
, yScale
); 
 896 // add the rotation to this matrix (radians) 
 897 void wxMacCoreGraphicsMatrixData::Rotate( wxDouble angle 
) 
 899     m_matrix 
= CGAffineTransformRotate( m_matrix
, angle
); 
 903 // apply the transforms 
 906 // applies that matrix to the point 
 907 void wxMacCoreGraphicsMatrixData::TransformPoint( wxDouble 
*x
, wxDouble 
*y 
) const 
 909     CGPoint pt 
= CGPointApplyAffineTransform( CGPointMake(*x
,*y
), m_matrix
); 
 915 // applies the matrix except for translations 
 916 void wxMacCoreGraphicsMatrixData::TransformDistance( wxDouble 
*dx
, wxDouble 
*dy 
) const 
 918     CGSize sz 
= CGSizeApplyAffineTransform( CGSizeMake(*dx
,*dy
) , m_matrix 
); 
 923 // returns the native representation 
 924 void * wxMacCoreGraphicsMatrixData::GetNativeMatrix() const 
 926     return (void*) &m_matrix
; 
 933 //----------------------------------------------------------------------------- 
 934 // wxMacCoreGraphicsPath declaration 
 935 //----------------------------------------------------------------------------- 
 937 class WXDLLEXPORT wxMacCoreGraphicsPathData 
: public wxGraphicsPathData
 
 940     wxMacCoreGraphicsPathData( wxGraphicsRenderer
* renderer
, CGMutablePathRef path 
= NULL
); 
 942     ~wxMacCoreGraphicsPathData(); 
 944     virtual wxGraphicsObjectRefData 
*Clone() const; 
 946     // begins a new subpath at (x,y) 
 947     virtual void MoveToPoint( wxDouble x
, wxDouble y 
); 
 949     // adds a straight line from the current point to (x,y) 
 950     virtual void AddLineToPoint( wxDouble x
, wxDouble y 
); 
 952     // adds a cubic Bezier curve from the current point, using two control points and an end point 
 953     virtual void AddCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble cx2
, wxDouble cy2
, wxDouble x
, wxDouble y 
); 
 955     // closes the current sub-path 
 956     virtual void CloseSubpath(); 
 958     // gets the last point of the current path, (0,0) if not yet set 
 959     virtual void GetCurrentPoint( wxDouble
* x
, wxDouble
* y
) const; 
 961     // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle 
 962     virtual void AddArc( wxDouble x
, wxDouble y
, wxDouble r
, wxDouble startAngle
, wxDouble endAngle
, bool clockwise 
); 
 965     // These are convenience functions which - if not available natively will be assembled 
 966     // using the primitives from above 
 969     // adds a quadratic Bezier curve from the current point, using a control point and an end point 
 970     virtual void AddQuadCurveToPoint( wxDouble cx
, wxDouble cy
, wxDouble x
, wxDouble y 
); 
 972     // appends a rectangle as a new closed subpath 
 973     virtual void AddRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
 975     // appends an ellipsis as a new closed subpath fitting the passed rectangle 
 976     virtual void AddCircle( wxDouble x
, wxDouble y
, wxDouble r 
); 
 978     // draws a an arc to two tangents connecting (current) to (x1,y1) and (x1,y1) to (x2,y2), also a straight line from (current) to (x1,y1) 
 979     virtual void AddArcToPoint( wxDouble x1
, wxDouble y1 
, wxDouble x2
, wxDouble y2
, wxDouble r 
); 
 982     virtual void AddPath( const wxGraphicsPathData
* path 
); 
 984     // returns the native path 
 985     virtual void * GetNativePath() const { return m_path
; } 
 987     // give the native path returned by GetNativePath() back (there might be some deallocations necessary) 
 988     virtual void UnGetNativePath(void *p
) const {} 
 990     // transforms each point of this path by the matrix 
 991     virtual void Transform( const wxGraphicsMatrixData
* matrix 
); 
 993     // gets the bounding box enclosing all points (possibly including control points) 
 994     virtual void GetBox(wxDouble 
*x
, wxDouble 
*y
, wxDouble 
*w
, wxDouble 
*y
) const; 
 996     virtual bool Contains( wxDouble x
, wxDouble y
, int fillStyle 
= wxODDEVEN_RULE
) const; 
 998     CGMutablePathRef m_path
; 
1001 //----------------------------------------------------------------------------- 
1002 // wxMacCoreGraphicsPath implementation 
1003 //----------------------------------------------------------------------------- 
1005 wxMacCoreGraphicsPathData::wxMacCoreGraphicsPathData( wxGraphicsRenderer
* renderer
, CGMutablePathRef path
) : wxGraphicsPathData(renderer
) 
1010         m_path 
= CGPathCreateMutable(); 
1013 wxMacCoreGraphicsPathData::~wxMacCoreGraphicsPathData() 
1015     CGPathRelease( m_path 
); 
1018 wxGraphicsObjectRefData
* wxMacCoreGraphicsPathData::Clone() const 
1020     wxMacCoreGraphicsPathData
* clone 
= new wxMacCoreGraphicsPathData(GetRenderer(),CGPathCreateMutableCopy(m_path
)); 
1025 // opens (starts) a new subpath 
1026 void wxMacCoreGraphicsPathData::MoveToPoint( wxDouble x1 
, wxDouble y1 
) 
1028     CGPathMoveToPoint( m_path 
, NULL 
, x1 
, y1 
); 
1031 void wxMacCoreGraphicsPathData::AddLineToPoint( wxDouble x1 
, wxDouble y1 
) 
1033     CGPathAddLineToPoint( m_path 
, NULL 
, x1 
, y1 
); 
1036 void wxMacCoreGraphicsPathData::AddCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble cx2
, wxDouble cy2
, wxDouble x
, wxDouble y 
) 
1038     CGPathAddCurveToPoint( m_path 
, NULL 
, cx1 
, cy1 
, cx2
, cy2
, x 
, y 
); 
1041 void wxMacCoreGraphicsPathData::AddQuadCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble x
, wxDouble y 
) 
1043     CGPathAddQuadCurveToPoint( m_path 
, NULL 
, cx1 
, cy1 
, x 
, y 
); 
1046 void wxMacCoreGraphicsPathData::AddRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1048     CGRect cgRect 
= { { x 
, y 
} , { w 
, h 
} }; 
1049     CGPathAddRect( m_path 
, NULL 
, cgRect 
); 
1052 void wxMacCoreGraphicsPathData::AddCircle( wxDouble x
, wxDouble y 
, wxDouble r 
) 
1054     CGPathAddArc( m_path 
, NULL 
, x 
, y 
, r 
, 0.0 , 2 * M_PI 
, true ); 
1057 // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle 
1058 void wxMacCoreGraphicsPathData::AddArc( wxDouble x
, wxDouble y
, wxDouble r
, wxDouble startAngle
, wxDouble endAngle
, bool clockwise 
) 
1060     // inverse direction as we the 'normal' state is a y axis pointing down, ie mirrored to the standard core graphics setup 
1061     CGPathAddArc( m_path
, NULL 
, x
, y
, r
, startAngle
, endAngle
, !clockwise
); 
1064 void wxMacCoreGraphicsPathData::AddArcToPoint( wxDouble x1
, wxDouble y1 
, wxDouble x2
, wxDouble y2
, wxDouble r 
) 
1066     CGPathAddArcToPoint( m_path
, NULL 
, x1
, y1
, x2
, y2
, r
); 
1069 void wxMacCoreGraphicsPathData::AddPath( const wxGraphicsPathData
* path 
) 
1071     CGPathAddPath( m_path 
, NULL
, (CGPathRef
) path
->GetNativePath() ); 
1074 // closes the current subpath 
1075 void wxMacCoreGraphicsPathData::CloseSubpath() 
1077     CGPathCloseSubpath( m_path 
); 
1080 // gets the last point of the current path, (0,0) if not yet set 
1081 void wxMacCoreGraphicsPathData::GetCurrentPoint( wxDouble
* x
, wxDouble
* y
) const 
1083     CGPoint p 
= CGPathGetCurrentPoint( m_path 
); 
1088 // transforms each point of this path by the matrix 
1089 void wxMacCoreGraphicsPathData::Transform( const wxGraphicsMatrixData
* matrix 
) 
1091     CGMutablePathRef p 
= CGPathCreateMutable() ; 
1092     CGPathAddPath( p
, (CGAffineTransform
*) matrix
->GetNativeMatrix() , m_path 
); 
1093     CGPathRelease( m_path 
); 
1097 // gets the bounding box enclosing all points (possibly including control points) 
1098 void wxMacCoreGraphicsPathData::GetBox(wxDouble 
*x
, wxDouble 
*y
, wxDouble 
*w
, wxDouble 
*h
) const 
1100     CGRect bounds 
= CGPathGetBoundingBox( m_path 
) ; 
1101     *x 
= bounds
.origin
.x
; 
1102     *y 
= bounds
.origin
.y
; 
1103     *w 
= bounds
.size
.width
; 
1104     *h 
= bounds
.size
.height
; 
1107 bool wxMacCoreGraphicsPathData::Contains( wxDouble x
, wxDouble y
, int fillStyle
) const 
1109 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 
1110     if ( CGPathContainsPoint
!=NULL 
) 
1112         return CGPathContainsPoint( m_path
, NULL
, CGPointMake(x
,y
), fillStyle 
== wxODDEVEN_RULE 
); 
1117         // TODO : implementation for 10.3 
1118         CGRect bounds 
= CGPathGetBoundingBox( m_path 
) ; 
1119         return CGRectContainsPoint( bounds
, CGPointMake(x
,y
) ) == 1; 
1127 //----------------------------------------------------------------------------- 
1128 // wxMacCoreGraphicsContext declaration 
1129 //----------------------------------------------------------------------------- 
1131 class WXDLLEXPORT wxMacCoreGraphicsContext 
: public wxGraphicsContext
 
1134     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, CGContextRef cgcontext 
); 
1136     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, WindowRef window 
); 
1138     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, wxWindow
* window 
); 
1140     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
); 
1142     wxMacCoreGraphicsContext(); 
1144     ~wxMacCoreGraphicsContext(); 
1148     // push the current state of the context, ie the transformation matrix on a stack 
1149     virtual void PushState(); 
1151     // pops a stored state from the stack 
1152     virtual void PopState(); 
1154     // clips drawings to the region 
1155     virtual void Clip( const wxRegion 
®ion 
); 
1157     // clips drawings to the rect 
1158     virtual void Clip( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1160     // resets the clipping to original extent 
1161     virtual void ResetClip(); 
1163     virtual void * GetNativeContext(); 
1165     bool SetLogicalFunction( int function 
); 
1171     virtual void Translate( wxDouble dx 
, wxDouble dy 
); 
1174     virtual void Scale( wxDouble xScale 
, wxDouble yScale 
); 
1177     virtual void Rotate( wxDouble angle 
); 
1179     // concatenates this transform with the current transform of this context 
1180     virtual void ConcatTransform( const wxGraphicsMatrix
& matrix 
); 
1182     // sets the transform of this context 
1183     virtual void SetTransform( const wxGraphicsMatrix
& matrix 
); 
1185     // gets the matrix of this context 
1186     virtual wxGraphicsMatrix 
GetTransform() const; 
1188     // setting the paint 
1191     // strokes along a path with the current pen 
1192     virtual void StrokePath( const wxGraphicsPath 
&path 
); 
1194     // fills a path with the current brush 
1195     virtual void FillPath( const wxGraphicsPath 
&path
, int fillStyle 
= wxODDEVEN_RULE 
); 
1197     // draws a path by first filling and then stroking 
1198     virtual void DrawPath( const wxGraphicsPath 
&path
, int fillStyle 
= wxODDEVEN_RULE 
); 
1200     virtual bool ShouldOffset() const 
1203         if ( !m_pen
.IsNull() ) 
1205             penwidth 
= (int)((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->GetWidth(); 
1206             if ( penwidth 
== 0 ) 
1209         return ( penwidth 
% 2 ) == 1; 
1215     virtual void DrawText( const wxString 
&str
, wxDouble x
, wxDouble y 
); 
1217     virtual void DrawText( const wxString 
&str
, wxDouble x
, wxDouble y
, wxDouble angle 
); 
1219     virtual void GetTextExtent( const wxString 
&text
, wxDouble 
*width
, wxDouble 
*height
, 
1220         wxDouble 
*descent
, wxDouble 
*externalLeading 
) const; 
1222     virtual void GetPartialTextExtents(const wxString
& text
, wxArrayDouble
& widths
) const; 
1228     virtual void DrawBitmap( const wxBitmap 
&bmp
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1230     virtual void DrawIcon( const wxIcon 
&icon
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1232     void SetNativeContext( CGContextRef cg 
); 
1234     DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext
) 
1235     DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsContext
) 
1238     void EnsureIsValid(); 
1240     CGContextRef m_cgContext
; 
1241     WindowRef m_windowRef
; 
1242     bool m_releaseContext
; 
1243     CGAffineTransform m_windowTransform
; 
1245     wxMacCFRefHolder
<HIShapeRef
> m_clipRgn
; 
1248 //----------------------------------------------------------------------------- 
1249 // device context implementation 
1251 // more and more of the dc functionality should be implemented by calling 
1252 // the appropricate wxMacCoreGraphicsContext, but we will have to do that step by step 
1253 // also coordinate conversions should be moved to native matrix ops 
1254 //----------------------------------------------------------------------------- 
1256 // we always stock two context states, one at entry, to be able to preserve the 
1257 // state we were called with, the other one after changing to HI Graphics orientation 
1258 // (this one is used for getting back clippings etc) 
1260 //----------------------------------------------------------------------------- 
1261 // wxMacCoreGraphicsContext implementation 
1262 //----------------------------------------------------------------------------- 
1264 IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext
, wxGraphicsContext
) 
1266 void wxMacCoreGraphicsContext::Init() 
1269     m_releaseContext 
= false; 
1272     HIRect r 
= CGRectMake(0,0,0,0); 
1273     m_clipRgn
.Set(HIShapeCreateWithRect(&r
)); 
1276 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, CGContextRef cgcontext 
) : wxGraphicsContext(renderer
) 
1279     SetNativeContext(cgcontext
); 
1282 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, WindowRef window 
): wxGraphicsContext(renderer
) 
1285     m_windowRef 
= window
; 
1288 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, wxWindow
* window 
): wxGraphicsContext(renderer
) 
1291     m_windowRef 
= (WindowRef
) window
->MacGetTopLevelWindowRef(); 
1292     int originX 
, originY
; 
1293     originX 
= originY 
= 0; 
1294     window
->MacWindowToRootWindow( &originX 
, &originY 
); 
1296     GetWindowBounds( m_windowRef
, kWindowContentRgn
, &bounds 
); 
1298     m_windowTransform 
= CGAffineTransformMakeTranslation( 0 , bounds
.bottom 
- bounds
.top 
); 
1299     m_windowTransform 
= CGAffineTransformScale( m_windowTransform 
, 1 , -1 ); 
1300     m_windowTransform 
= CGAffineTransformTranslate( m_windowTransform
, originX
, originY 
) ; 
1303 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext(wxGraphicsRenderer
* renderer
) : wxGraphicsContext(renderer
) 
1308 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext() : wxGraphicsContext(NULL
) 
1311     wxLogDebug(wxT("Illegal Constructor called")); 
1314 wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext() 
1316     SetNativeContext(NULL
); 
1319 void wxMacCoreGraphicsContext::EnsureIsValid() 
1323         OSStatus status 
= QDBeginCGContext( GetWindowPort( m_windowRef 
) , &m_cgContext 
); 
1324         wxASSERT_MSG( status 
== noErr 
, wxT("Cannot nest wxDCs on the same window") ); 
1326         CGContextConcatCTM( m_cgContext
, m_windowTransform 
); 
1327                 CGContextSaveGState( m_cgContext 
); 
1328                 m_releaseContext 
= true; 
1329                 if ( !HIShapeIsEmpty(m_clipRgn
) ) 
1331             // the clip region is in device coordinates, so we convert this again to user coordinates 
1332             wxMacCFRefHolder
<HIMutableShapeRef
> hishape 
; 
1333             hishape
.Set( HIShapeCreateMutableCopy( m_clipRgn 
) ); 
1334             CGPoint transformedOrigin 
= CGPointApplyAffineTransform( CGPointZero
,m_windowTransform
); 
1335             HIShapeOffset( hishape
, -transformedOrigin
.x
, -transformedOrigin
.y 
); 
1336                         HIShapeReplacePathInCGContext( hishape
, m_cgContext 
); 
1337                         CGContextClip( m_cgContext 
); 
1339                 CGContextSaveGState( m_cgContext 
); 
1343 bool wxMacCoreGraphicsContext::SetLogicalFunction( int function 
) 
1345     if (m_logicalFunction 
== function
) 
1350     bool retval 
= false; 
1352     if ( function 
== wxCOPY 
) 
1355 #if wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 
1356         if ( CGContextSetBlendMode 
!= NULL 
) 
1358             CGContextSetBlendMode( m_cgContext
, kCGBlendModeNormal 
); 
1359             CGContextSetShouldAntialias( m_cgContext
, true ); 
1363     else if ( function 
== wxINVERT 
|| function 
== wxXOR 
) 
1365 #if wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 
1366         if ( CGContextSetBlendMode 
!= NULL 
) 
1368             // change color to white 
1369             CGContextSetBlendMode( m_cgContext
, kCGBlendModeExclusion 
); 
1370             CGContextSetShouldAntialias( m_cgContext
, false ); 
1377         m_logicalFunction 
= function
; 
1381 void wxMacCoreGraphicsContext::Clip( const wxRegion 
®ion 
) 
1385         HIShapeRef shape 
= HIShapeCreateWithQDRgn( (RgnHandle
) region
.GetWXHRGN() ); 
1386         HIShapeReplacePathInCGContext( shape
, m_cgContext 
); 
1387         CGContextClip( m_cgContext 
); 
1392         // this offsetting to device coords is not really correct, but since we cannot apply affine transforms 
1393         // to regions we try at least to have correct translations 
1394         wxMacCFRefHolder
<HIShapeRef
> hishape 
; 
1395         hishape
.Set( HIShapeCreateWithQDRgn( (RgnHandle
) region
.GetWXHRGN() )); 
1396         HIMutableShapeRef mutableShape 
= HIShapeCreateMutableCopy( hishape 
); 
1398         CGPoint transformedOrigin 
= CGPointApplyAffineTransform( CGPointZero
, m_windowTransform 
); 
1399         HIShapeOffset( mutableShape
, transformedOrigin
.x
, transformedOrigin
.y 
); 
1400         m_clipRgn
.Set(mutableShape
); 
1404 // clips drawings to the rect 
1405 void wxMacCoreGraphicsContext::Clip( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1407     HIRect r 
= CGRectMake( x 
, y 
, w 
, h 
); 
1410         CGContextClipToRect( m_cgContext
, r 
); 
1414         // the clipping itself must be stored as device coordinates, otherwise  
1415         // we cannot apply it back correctly 
1416         r
.origin
= CGPointApplyAffineTransform( r
.origin
, m_windowTransform 
); 
1417         m_clipRgn
.Set(HIShapeCreateWithRect(&r
)); 
1421     // resets the clipping to original extent 
1422 void wxMacCoreGraphicsContext::ResetClip() 
1426         // there is no way for clearing the clip, we can only revert to the stored 
1427         // state, but then we have to make sure everything else is NOT restored 
1428         CGAffineTransform transform 
= CGContextGetCTM( m_cgContext 
); 
1429         CGContextRestoreGState( m_cgContext 
); 
1430         CGContextSaveGState( m_cgContext 
); 
1431         CGAffineTransform transformNew 
= CGContextGetCTM( m_cgContext 
); 
1432         transformNew 
= CGAffineTransformInvert( transformNew 
) ; 
1433         CGContextConcatCTM( m_cgContext
, transformNew
); 
1434         CGContextConcatCTM( m_cgContext
, transform
); 
1438         HIRect r 
= CGRectMake(0,0,0,0); 
1439         m_clipRgn
.Set(HIShapeCreateWithRect(&r
)); 
1443 void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath 
&path 
) 
1445     if ( m_pen
.IsNull() ) 
1450     bool offset 
= ShouldOffset(); 
1452         CGContextTranslateCTM( m_cgContext
, 0.5, 0.5 ); 
1454     ((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->Apply(this); 
1455     CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1456     CGContextStrokePath( m_cgContext 
); 
1459         CGContextTranslateCTM( m_cgContext
, -0.5, -0.5 ); 
1462 void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath 
&path 
, int fillStyle 
) 
1464     if ( !m_brush
.IsNull() && ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1466         // when using shading, we cannot draw pen and brush at the same time 
1467         // revert to the base implementation of first filling and then stroking 
1468         wxGraphicsContext::DrawPath( path
, fillStyle 
); 
1472     CGPathDrawingMode mode 
= kCGPathFill 
; 
1473     if ( m_brush
.IsNull() ) 
1475         if ( m_pen
.IsNull() ) 
1478             mode 
= kCGPathStroke
; 
1482         if ( m_pen
.IsNull() ) 
1484             if ( fillStyle 
== wxODDEVEN_RULE 
) 
1485                 mode 
= kCGPathEOFill
; 
1491             if ( fillStyle 
== wxODDEVEN_RULE 
) 
1492                 mode 
= kCGPathEOFillStroke
; 
1494                 mode 
= kCGPathFillStroke
; 
1500     if ( !m_brush
.IsNull() ) 
1501         ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1502     if ( !m_pen
.IsNull() ) 
1503         ((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->Apply(this); 
1505     bool offset 
= ShouldOffset(); 
1508         CGContextTranslateCTM( m_cgContext
, 0.5, 0.5 ); 
1510     CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1511     CGContextDrawPath( m_cgContext 
, mode 
); 
1514         CGContextTranslateCTM( m_cgContext
, -0.5, -0.5 ); 
1517 void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath 
&path 
, int fillStyle 
) 
1519     if ( m_brush
.IsNull() ) 
1524     if ( ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1526         CGContextSaveGState( m_cgContext 
); 
1527         CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1528         CGContextClip( m_cgContext 
); 
1529         CGContextDrawShading( m_cgContext
, ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->GetShading() ); 
1530         CGContextRestoreGState( m_cgContext
); 
1534         ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1535         CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1536         if ( fillStyle 
== wxODDEVEN_RULE 
) 
1537             CGContextEOFillPath( m_cgContext 
); 
1539             CGContextFillPath( m_cgContext 
); 
1543 void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg 
) 
1545     // we allow either setting or clearing but not replacing 
1546     wxASSERT( m_cgContext 
== NULL 
|| cg 
== NULL 
); 
1550         // TODO : when is this necessary - should we add a Flush() method ? CGContextSynchronize( m_cgContext ); 
1551         CGContextRestoreGState( m_cgContext 
); 
1552         CGContextRestoreGState( m_cgContext 
); 
1553         if ( m_releaseContext 
) 
1554             QDEndCGContext( GetWindowPort( m_windowRef 
) , &m_cgContext
); 
1556             CGContextRelease(m_cgContext
); 
1562     // FIXME: This check is needed because currently we need to use a DC/GraphicsContext 
1563     // in order to get font properties, like wxFont::GetPixelSize, but since we don't have 
1564     // a native window attached to use, I create a wxGraphicsContext with a NULL CGContextRef 
1565     // for this one operation. 
1567     // When wxFont::GetPixelSize on Mac no longer needs a graphics context, this check 
1571         CGContextRetain(m_cgContext
); 
1572         CGContextSaveGState( m_cgContext 
); 
1573         CGContextSaveGState( m_cgContext 
); 
1574         m_releaseContext 
= false; 
1578 void wxMacCoreGraphicsContext::Translate( wxDouble dx 
, wxDouble dy 
) 
1581         CGContextTranslateCTM( m_cgContext
, dx
, dy 
); 
1583         m_windowTransform 
= CGAffineTransformTranslate(m_windowTransform
,dx
,dy
); 
1586 void wxMacCoreGraphicsContext::Scale( wxDouble xScale 
, wxDouble yScale 
) 
1589         CGContextScaleCTM( m_cgContext 
, xScale 
, yScale 
); 
1591         m_windowTransform 
= CGAffineTransformScale(m_windowTransform
,xScale
,yScale
); 
1594 void wxMacCoreGraphicsContext::Rotate( wxDouble angle 
) 
1597         CGContextRotateCTM( m_cgContext 
, angle 
); 
1599         m_windowTransform 
= CGAffineTransformRotate(m_windowTransform
,angle
); 
1602 void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap 
&bmp
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1606     CGImageRef image 
= (CGImageRef
)( bmp
.CGImageCreate() ); 
1607     HIRect r 
= CGRectMake( x 
, y 
, w 
, h 
); 
1608     if ( bmp
.GetDepth() == 1 ) 
1610         // is is a mask, the '1' in the mask tell where to draw the current brush 
1611         if (  !m_brush
.IsNull() ) 
1613             if ( ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1615                 // TODO clip to mask 
1617                 CGContextSaveGState( m_cgContext ); 
1618                 CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); 
1619                 CGContextClip( m_cgContext ); 
1620                 CGContextDrawShading( m_cgContext, ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->GetShading() ); 
1621                 CGContextRestoreGState( m_cgContext); 
1626                 ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1627                 HIViewDrawCGImage( m_cgContext 
, &r 
, image 
); 
1633         HIViewDrawCGImage( m_cgContext 
, &r 
, image 
); 
1635     CGImageRelease( image 
); 
1638 void wxMacCoreGraphicsContext::DrawIcon( const wxIcon 
&icon
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1642     CGRect r 
= CGRectMake( 00 , 00 , w 
, h 
); 
1643     CGContextSaveGState( m_cgContext 
); 
1644     CGContextTranslateCTM( m_cgContext
, x 
, y 
+ h 
); 
1645     CGContextScaleCTM( m_cgContext
, 1, -1 ); 
1646     PlotIconRefInContext( m_cgContext 
, &r 
, kAlignNone 
, kTransformNone 
, 
1647         NULL 
, kPlotIconRefNormalFlags 
, MAC_WXHICON( icon
.GetHICON() ) ); 
1648     CGContextRestoreGState( m_cgContext 
); 
1651 void wxMacCoreGraphicsContext::PushState() 
1655     CGContextSaveGState( m_cgContext 
); 
1658 void wxMacCoreGraphicsContext::PopState() 
1662     CGContextRestoreGState( m_cgContext 
); 
1665 void wxMacCoreGraphicsContext::DrawText( const wxString 
&str
, wxDouble x
, wxDouble y 
) 
1667     DrawText(str
, x
, y
, 0.0); 
1670 void wxMacCoreGraphicsContext::DrawText( const wxString 
&str
, wxDouble x
, wxDouble y
, wxDouble angle 
) 
1672     if ( m_font
.IsNull() ) 
1677     OSStatus status 
= noErr
; 
1678     ATSUTextLayout atsuLayout
; 
1679     UniCharCount chars 
= str
.length(); 
1680     UniChar
* ubuf 
= NULL
; 
1682 #if SIZEOF_WCHAR_T == 4 
1683     wxMBConvUTF16 converter
; 
1685     size_t unicharlen 
= converter
.WC2MB( NULL 
, str
.wc_str() , 0 ); 
1686     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1687     converter
.WC2MB( (char*) ubuf 
, str
.wc_str(), unicharlen 
+ 2 ); 
1689     const wxWCharBuffer wchar 
= str
.wc_str( wxConvLocal 
); 
1690     size_t unicharlen 
= converter
.WC2MB( NULL 
, wchar
.data() , 0 ); 
1691     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1692     converter
.WC2MB( (char*) ubuf 
, wchar
.data() , unicharlen 
+ 2 ); 
1694     chars 
= unicharlen 
/ 2; 
1697     ubuf 
= (UniChar
*) str
.wc_str(); 
1699     wxWCharBuffer wchar 
= str
.wc_str( wxConvLocal 
); 
1700     chars 
= wxWcslen( wchar
.data() ); 
1701     ubuf 
= (UniChar
*) wchar
.data(); 
1705     ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
1706     status 
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf 
, 0 , chars 
, chars 
, 1 , 
1707         &chars 
, &style 
, &atsuLayout 
); 
1709     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the rotated text") ); 
1711     status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ); 
1712     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1714     int iAngle 
= int( angle 
* RAD2DEG 
); 
1715     if ( abs(iAngle
) > 0 ) 
1717         Fixed atsuAngle 
= IntToFixed( iAngle 
); 
1718         ATSUAttributeTag atsuTags
[] = 
1720             kATSULineRotationTag 
, 
1722         ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1726         ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1730         status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
), 
1731             atsuTags
, atsuSizes
, atsuValues 
); 
1735         ATSUAttributeTag atsuTags
[] = 
1739         ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1741             sizeof( CGContextRef 
) , 
1743         ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1747         status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
), 
1748             atsuTags
, atsuSizes
, atsuValues 
); 
1751     ATSUTextMeasurement textBefore
, textAfter
; 
1752     ATSUTextMeasurement ascent
, descent
; 
1754     status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1755         &textBefore 
, &textAfter
, &ascent 
, &descent 
); 
1757     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1760     x 
+= (int)(sin(angle
) * FixedToInt(ascent
)); 
1761     y 
+= (int)(cos(angle
) * FixedToInt(ascent
)); 
1763     status 
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1764         IntToFixed(x
) , IntToFixed(y
) , &rect 
); 
1765     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1767     CGContextSaveGState(m_cgContext
); 
1768     CGContextTranslateCTM(m_cgContext
, x
, y
); 
1769     CGContextScaleCTM(m_cgContext
, 1, -1); 
1770     status 
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1771         IntToFixed(0) , IntToFixed(0) ); 
1773     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't draw the rotated text") ); 
1775     CGContextRestoreGState(m_cgContext
); 
1777     ::ATSUDisposeTextLayout(atsuLayout
); 
1779 #if SIZEOF_WCHAR_T == 4 
1784 void wxMacCoreGraphicsContext::GetTextExtent( const wxString 
&str
, wxDouble 
*width
, wxDouble 
*height
, 
1785                             wxDouble 
*descent
, wxDouble 
*externalLeading 
) const 
1787     wxCHECK_RET( !m_font
.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ); 
1789     OSStatus status 
= noErr
; 
1791     ATSUTextLayout atsuLayout
; 
1792     UniCharCount chars 
= str
.length(); 
1793     UniChar
* ubuf 
= NULL
; 
1795 #if SIZEOF_WCHAR_T == 4 
1796     wxMBConvUTF16 converter
; 
1798     size_t unicharlen 
= converter
.WC2MB( NULL 
, str
.wc_str() , 0 ); 
1799     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1800     converter
.WC2MB( (char*) ubuf 
, str
.wc_str(), unicharlen 
+ 2 ); 
1802     const wxWCharBuffer wchar 
= str
.wc_str( wxConvLocal 
); 
1803     size_t unicharlen 
= converter
.WC2MB( NULL 
, wchar
.data() , 0 ); 
1804     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1805     converter
.WC2MB( (char*) ubuf 
, wchar
.data() , unicharlen 
+ 2 ); 
1807     chars 
= unicharlen 
/ 2; 
1810     ubuf 
= (UniChar
*) str
.wc_str(); 
1812     wxWCharBuffer wchar 
= str
.wc_str( wxConvLocal 
); 
1813     chars 
= wxWcslen( wchar
.data() ); 
1814     ubuf 
= (UniChar
*) wchar
.data(); 
1818     ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
1819     status 
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf 
, 0 , chars 
, chars 
, 1 , 
1820         &chars 
, &style 
, &atsuLayout 
); 
1822     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1824     ATSUTextMeasurement textBefore
, textAfter
; 
1825     ATSUTextMeasurement textAscent
, textDescent
; 
1827     status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1828         &textBefore 
, &textAfter
, &textAscent 
, &textDescent 
); 
1831         *height 
= FixedToInt(textAscent 
+ textDescent
); 
1833         *descent 
= FixedToInt(textDescent
); 
1834     if ( externalLeading 
) 
1835         *externalLeading 
= 0; 
1837         *width 
= FixedToInt(textAfter 
- textBefore
); 
1839     ::ATSUDisposeTextLayout(atsuLayout
); 
1840 #if SIZEOF_WCHAR_T == 4 
1845 void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString
& text
, wxArrayDouble
& widths
) const 
1848     widths
.Add(0, text
.length()); 
1853     ATSUTextLayout atsuLayout
; 
1854     UniCharCount chars 
= text
.length(); 
1855     UniChar
* ubuf 
= NULL
; 
1857 #if SIZEOF_WCHAR_T == 4 
1858     wxMBConvUTF16 converter
; 
1860     size_t unicharlen 
= converter
.WC2MB( NULL 
, text
.wc_str() , 0 ); 
1861     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1862     converter
.WC2MB( (char*) ubuf 
, text
.wc_str(), unicharlen 
+ 2 ); 
1864     const wxWCharBuffer wchar 
= text
.wc_str( wxConvLocal 
); 
1865     size_t unicharlen 
= converter
.WC2MB( NULL 
, wchar
.data() , 0 ); 
1866     ubuf 
= (UniChar
*) malloc( unicharlen 
+ 2 ); 
1867     converter
.WC2MB( (char*) ubuf 
, wchar
.data() , unicharlen 
+ 2 ); 
1869     chars 
= unicharlen 
/ 2; 
1872     ubuf 
= (UniChar
*) text
.wc_str(); 
1874     wxWCharBuffer wchar 
= text
.wc_str( wxConvLocal 
); 
1875     chars 
= wxWcslen( wchar
.data() ); 
1876     ubuf 
= (UniChar
*) wchar
.data(); 
1880     ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
1881     ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf 
, 0 , chars 
, chars 
, 1 , 
1882         &chars 
, &style 
, &atsuLayout 
); 
1884     for ( int pos 
= 0; pos 
< (int)chars
; pos 
++ ) 
1886         unsigned long actualNumberOfBounds 
= 0; 
1887         ATSTrapezoid glyphBounds
; 
1889         // We get a single bound, since the text should only require one. If it requires more, there is an issue 
1891         result 
= ATSUGetGlyphBounds( atsuLayout
, 0, 0, kATSUFromTextBeginning
, pos 
+ 1, 
1892             kATSUseDeviceOrigins
, 1, &glyphBounds
, &actualNumberOfBounds 
); 
1893         if (result 
!= noErr 
|| actualNumberOfBounds 
!= 1 ) 
1896         widths
[pos
] = FixedToInt( glyphBounds
.upperRight
.x 
- glyphBounds
.upperLeft
.x 
); 
1897         //unsigned char uch = s[i]; 
1900     ::ATSUDisposeTextLayout(atsuLayout
); 
1901 #if SIZEOF_WCHAR_T == 4 
1906 void * wxMacCoreGraphicsContext::GetNativeContext() 
1911 // concatenates this transform with the current transform of this context 
1912 void wxMacCoreGraphicsContext::ConcatTransform( const wxGraphicsMatrix
& matrix 
) 
1915         CGContextConcatCTM( m_cgContext
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
1917         m_windowTransform 
= CGAffineTransformConcat(m_windowTransform
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
1920 // sets the transform of this context 
1921 void wxMacCoreGraphicsContext::SetTransform( const wxGraphicsMatrix
& matrix 
) 
1925         CGAffineTransform transform 
= CGContextGetCTM( m_cgContext 
); 
1926         transform 
= CGAffineTransformInvert( transform 
) ; 
1927         CGContextConcatCTM( m_cgContext
, transform
); 
1928         CGContextConcatCTM( m_cgContext
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
1932         m_windowTransform 
= *(CGAffineTransform
*) matrix
.GetNativeMatrix(); 
1936 // gets the matrix of this context 
1937 wxGraphicsMatrix 
wxMacCoreGraphicsContext::GetTransform() const 
1939     wxGraphicsMatrix m 
= CreateMatrix(); 
1940     *((CGAffineTransform
*) m
.GetNativeMatrix()) = ( m_cgContext 
== NULL 
? m_windowTransform 
: 
1941         CGContextGetCTM( m_cgContext 
)); 
1949 //----------------------------------------------------------------------------- 
1950 // wxMacCoreGraphicsRenderer declaration 
1951 //----------------------------------------------------------------------------- 
1953 class WXDLLIMPEXP_CORE wxMacCoreGraphicsRenderer 
: public wxGraphicsRenderer
 
1956     wxMacCoreGraphicsRenderer() {} 
1958     virtual ~wxMacCoreGraphicsRenderer() {} 
1962     virtual wxGraphicsContext 
* CreateContext( const wxWindowDC
& dc
); 
1964     virtual wxGraphicsContext 
* CreateContextFromNativeContext( void * context 
); 
1966     virtual wxGraphicsContext 
* CreateContextFromNativeWindow( void * window 
); 
1968     virtual wxGraphicsContext 
* CreateContext( wxWindow
* window 
); 
1970     virtual wxGraphicsContext 
* CreateMeasuringContext(); 
1974     virtual wxGraphicsPath 
CreatePath(); 
1978     virtual wxGraphicsMatrix 
CreateMatrix( wxDouble a
=1.0, wxDouble b
=0.0, wxDouble c
=0.0, wxDouble d
=1.0, 
1979         wxDouble tx
=0.0, wxDouble ty
=0.0); 
1982     virtual wxGraphicsPen 
CreatePen(const wxPen
& pen
) ; 
1984     virtual wxGraphicsBrush 
CreateBrush(const wxBrush
& brush 
) ; 
1986     // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 
1987     virtual wxGraphicsBrush 
CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
1988         const wxColour
&c1
, const wxColour
&c2
) ; 
1990     // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) 
1991     // with radius r and color cColor 
1992     virtual wxGraphicsBrush 
CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
1993         const wxColour 
&oColor
, const wxColour 
&cColor
) ; 
1996     virtual wxGraphicsFont 
CreateFont( const wxFont 
&font 
, const wxColour 
&col 
= *wxBLACK 
) ; 
1999     DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer
) 
2002 //----------------------------------------------------------------------------- 
2003 // wxMacCoreGraphicsRenderer implementation 
2004 //----------------------------------------------------------------------------- 
2006 IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsRenderer
,wxGraphicsRenderer
) 
2008 static wxMacCoreGraphicsRenderer gs_MacCoreGraphicsRenderer
; 
2010 wxGraphicsRenderer
* wxGraphicsRenderer::GetDefaultRenderer() 
2012     return &gs_MacCoreGraphicsRenderer
; 
2015 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC
& dc
) 
2017     wxMemoryDC
* mdc 
= wxDynamicCast(&dc
, wxMemoryDC
); 
2020         return new wxMacCoreGraphicsContext(this,  
2021             (CGContextRef
)mdc
->GetGraphicsContext()->GetNativeContext()); 
2025         return new wxMacCoreGraphicsContext(this,(CGContextRef
)dc
.GetWindow()->MacGetCGContextRef() ); 
2029 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context 
) 
2031     return new wxMacCoreGraphicsContext(this,(CGContextRef
)context
); 
2035 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( void * window 
) 
2037     return new wxMacCoreGraphicsContext(this,(WindowRef
)window
); 
2040 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContext( wxWindow
* window 
) 
2042     return new wxMacCoreGraphicsContext(this, window 
); 
2045 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateMeasuringContext() 
2047     return new wxMacCoreGraphicsContext(this); 
2052 wxGraphicsPath 
wxMacCoreGraphicsRenderer::CreatePath() 
2055     m
.SetRefData( new wxMacCoreGraphicsPathData(this)); 
2062 wxGraphicsMatrix 
wxMacCoreGraphicsRenderer::CreateMatrix( wxDouble a
, wxDouble b
, wxDouble c
, wxDouble d
, 
2063     wxDouble tx
, wxDouble ty
) 
2066     wxMacCoreGraphicsMatrixData
* data 
= new wxMacCoreGraphicsMatrixData( this ); 
2067     data
->Set( a
,b
,c
,d
,tx
,ty 
) ; 
2072 wxGraphicsPen 
wxMacCoreGraphicsRenderer::CreatePen(const wxPen
& pen
) 
2074     if ( !pen
.Ok() || pen
.GetStyle() == wxTRANSPARENT 
) 
2075         return wxNullGraphicsPen
; 
2079         p
.SetRefData(new wxMacCoreGraphicsPenData( this, pen 
)); 
2084 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateBrush(const wxBrush
& brush 
) 
2086     if ( !brush
.Ok() || brush
.GetStyle() == wxTRANSPARENT 
) 
2087         return wxNullGraphicsBrush
; 
2091         p
.SetRefData(new wxMacCoreGraphicsBrushData( this, brush 
)); 
2096 // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 
2097 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
2098     const wxColour
&c1
, const wxColour
&c2
) 
2101     wxMacCoreGraphicsBrushData
* d 
= new wxMacCoreGraphicsBrushData( this ); 
2102     d
->CreateLinearGradientBrush(x1
, y1
, x2
, y2
, c1
, c2
); 
2107 // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) 
2108 // with radius r and color cColor 
2109 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
2110     const wxColour 
&oColor
, const wxColour 
&cColor
) 
2113     wxMacCoreGraphicsBrushData
* d 
= new wxMacCoreGraphicsBrushData( this ); 
2114     d
->CreateRadialGradientBrush(xo
,yo
,xc
,yc
,radius
,oColor
,cColor
); 
2120 wxGraphicsFont 
wxMacCoreGraphicsRenderer::CreateFont( const wxFont 
&font 
, const wxColour 
&col 
) 
2125         p
.SetRefData(new wxMacCoreGraphicsFontData( this , font
, col 
)); 
2129         return wxNullGraphicsFont
; 
2134 #endif // wxMAC_USE_CORE_GRAPHICS