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 #include "wx/graphics.h" 
  15 #include "wx/private/graphics.h" 
  18     #include "wx/dcclient.h" 
  19     #include "wx/dcmemory.h" 
  21     #include "wx/region.h" 
  26 #include "wx/mac/uma.h" 
  31         // in case our functions were defined outside std, we make it known all the same 
  37 #include "wx/mac/private.h" 
  39 //----------------------------------------------------------------------------- 
  41 //----------------------------------------------------------------------------- 
  43 #if !defined( __DARWIN__ ) || defined(__MWERKS__) 
  45 const double M_PI 
= 3.14159265358979; 
  49 static const double RAD2DEG 
= 180.0 / M_PI
; 
  52 // Pen, Brushes and Fonts 
  56 #pragma mark wxMacCoreGraphicsPattern, ImagePattern, HatchPattern classes 
  58 OSStatus 
wxMacDrawCGImage( 
  59                   CGContextRef    inContext
, 
  60                   const HIRect 
*  inBounds
, 
  65     CGContextDrawImage(inContext
, *inBounds
, inImage 
); 
  68     return HIViewDrawCGImage( inContext
, inBounds
, inImage 
); 
  72 // CGPattern wrapper class: always allocate on heap, never call destructor 
  74 class wxMacCoreGraphicsPattern
 
  77     wxMacCoreGraphicsPattern() {} 
  79     // is guaranteed to be called only with a non-Null CGContextRef 
  80     virtual void Render( CGContextRef ctxRef 
) = 0; 
  82     operator CGPatternRef() const { return m_patternRef
; } 
  85     virtual ~wxMacCoreGraphicsPattern() 
  87         // as this is called only when the m_patternRef is been released; 
  88         // don't release it again 
  91     static void _Render( void *info
, CGContextRef ctxRef 
) 
  93         wxMacCoreGraphicsPattern
* self 
= (wxMacCoreGraphicsPattern
*) info
; 
  95             self
->Render( ctxRef 
); 
  98     static void _Dispose( void *info 
) 
 100         wxMacCoreGraphicsPattern
* self 
= (wxMacCoreGraphicsPattern
*) info
; 
 104     CGPatternRef m_patternRef
; 
 106     static const CGPatternCallbacks ms_Callbacks
; 
 109 const CGPatternCallbacks 
wxMacCoreGraphicsPattern::ms_Callbacks 
= { 0, &wxMacCoreGraphicsPattern::_Render
, &wxMacCoreGraphicsPattern::_Dispose 
}; 
 111 class ImagePattern 
: public wxMacCoreGraphicsPattern
 
 114     ImagePattern( const wxBitmap
* bmp 
, const CGAffineTransform
& transform 
) 
 116         wxASSERT( bmp 
&& bmp
->Ok() ); 
 118         Init( (CGImageRef
) bmp
->CreateCGImage() , transform 
); 
 121     // ImagePattern takes ownership of CGImageRef passed in 
 122     ImagePattern( CGImageRef image 
, const CGAffineTransform
& transform 
) 
 127         Init( image 
, transform 
); 
 130     virtual void Render( CGContextRef ctxRef 
) 
 133             wxMacDrawCGImage( ctxRef
, &m_imageBounds
, m_image 
); 
 137     void Init( CGImageRef image
, const CGAffineTransform
& transform 
) 
 142             m_imageBounds 
= CGRectMake( 0.0, 0.0, (CGFloat
)CGImageGetWidth( m_image 
), (CGFloat
)CGImageGetHeight( m_image 
) ); 
 143             m_patternRef 
= CGPatternCreate( 
 144                 this , m_imageBounds
, transform 
, 
 145                 m_imageBounds
.size
.width
, m_imageBounds
.size
.height
, 
 146                 kCGPatternTilingNoDistortion
, true , &wxMacCoreGraphicsPattern::ms_Callbacks 
); 
 150     virtual ~ImagePattern() 
 153             CGImageRelease( m_image 
); 
 157     CGRect m_imageBounds
; 
 160 class HatchPattern 
: public wxMacCoreGraphicsPattern
 
 163     HatchPattern( int hatchstyle
, const CGAffineTransform
& transform 
) 
 165         m_hatch 
= hatchstyle
; 
 166         m_imageBounds 
= CGRectMake( 0.0, 0.0, 8.0 , 8.0 ); 
 167         m_patternRef 
= CGPatternCreate( 
 168             this , m_imageBounds
, transform 
, 
 169             m_imageBounds
.size
.width
, m_imageBounds
.size
.height
, 
 170             kCGPatternTilingNoDistortion
, false , &wxMacCoreGraphicsPattern::ms_Callbacks 
); 
 173     void StrokeLineSegments( CGContextRef ctxRef 
, const CGPoint pts
[] , size_t count 
) 
 175         CGContextStrokeLineSegments( ctxRef 
, pts 
, count 
); 
 178     virtual void Render( CGContextRef ctxRef 
) 
 182             case wxBDIAGONAL_HATCH 
: 
 186                     { 8.0 , 0.0 } , { 0.0 , 8.0 } 
 188                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 192             case wxCROSSDIAG_HATCH 
: 
 196                         { 0.0 , 0.0 } , { 8.0 , 8.0 } , 
 197                         { 8.0 , 0.0 } , { 0.0 , 8.0 } 
 199                     StrokeLineSegments( ctxRef 
, pts 
, 4 ); 
 203             case wxFDIAGONAL_HATCH 
: 
 207                     { 0.0 , 0.0 } , { 8.0 , 8.0 } 
 209                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 217                     { 0.0 , 4.0 } , { 8.0 , 4.0 } , 
 218                     { 4.0 , 0.0 } , { 4.0 , 8.0 } , 
 220                     StrokeLineSegments( ctxRef 
, pts 
, 4 ); 
 224             case wxHORIZONTAL_HATCH 
: 
 228                     { 0.0 , 4.0 } , { 8.0 , 4.0 } , 
 230                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 234             case wxVERTICAL_HATCH 
: 
 238                     { 4.0 , 0.0 } , { 4.0 , 8.0 } , 
 240                     StrokeLineSegments( ctxRef 
, pts 
, 2 ); 
 250     virtual ~HatchPattern() {} 
 252     CGRect      m_imageBounds
; 
 256 class wxMacCoreGraphicsPenData 
: public wxGraphicsObjectRefData
 
 259     wxMacCoreGraphicsPenData( wxGraphicsRenderer
* renderer
, const wxPen 
&pen 
); 
 260     ~wxMacCoreGraphicsPenData(); 
 263     virtual void Apply( wxGraphicsContext
* context 
); 
 264     virtual wxDouble 
GetWidth() { return m_width
; } 
 268     wxCFRef
<CGColorRef
> m_color
; 
 269     wxCFRef
<CGColorSpaceRef
> m_colorSpace
; 
 275     const CGFloat 
*m_lengths
; 
 276     CGFloat 
*m_userLengths
; 
 280     wxCFRef
<CGPatternRef
> m_pattern
; 
 281     CGFloat
* m_patternColorComponents
; 
 284 wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer
* renderer
, const wxPen 
&pen 
) : 
 285     wxGraphicsObjectRefData( renderer 
) 
 289     m_color
.reset( pen
.GetColour().CreateCGColor() ) ; 
 291     // TODO: * m_dc->m_scaleX 
 292     m_width 
= pen
.GetWidth(); 
 296     switch ( pen
.GetCap() ) 
 299             m_cap 
= kCGLineCapRound
; 
 302         case wxCAP_PROJECTING 
: 
 303             m_cap 
= kCGLineCapSquare
; 
 307             m_cap 
= kCGLineCapButt
; 
 311             m_cap 
= kCGLineCapButt
; 
 315     switch ( pen
.GetJoin() ) 
 318             m_join 
= kCGLineJoinBevel
; 
 322             m_join 
= kCGLineJoinMiter
; 
 326             m_join 
= kCGLineJoinRound
; 
 330             m_join 
= kCGLineJoinMiter
; 
 334     const CGFloat dashUnit 
= m_width 
< 1.0 ? 1.0 : m_width
; 
 336     const CGFloat dotted
[] = { dashUnit 
, dashUnit 
+ 2.0 }; 
 337     static const CGFloat short_dashed
[] = { 9.0 , 6.0 }; 
 338     static const CGFloat dashed
[] = { 19.0 , 9.0 }; 
 339     static const CGFloat dotted_dashed
[] = { 9.0 , 6.0 , 3.0 , 3.0 }; 
 341     switch ( pen
.GetStyle() ) 
 347             m_count 
= WXSIZEOF(dotted
); 
 348             m_userLengths 
= new CGFloat
[ m_count 
] ; 
 349             memcpy( m_userLengths
, dotted
, sizeof(dotted
) ); 
 350             m_lengths 
= m_userLengths
; 
 354             m_count 
= WXSIZEOF(dashed
); 
 359             m_count 
= WXSIZEOF(short_dashed
); 
 360             m_lengths 
= short_dashed
; 
 364             m_count 
= WXSIZEOF(dotted_dashed
); 
 365             m_lengths 
= dotted_dashed
; 
 370             m_count 
= pen
.GetDashes( &dashes 
); 
 371             if ((dashes 
!= NULL
) && (m_count 
> 0)) 
 373                 m_userLengths 
= new CGFloat
[m_count
]; 
 374                 for ( int i 
= 0; i 
< m_count
; ++i 
) 
 376                     m_userLengths
[i
] = dashes
[i
] * dashUnit
; 
 378                     if ( i 
% 2 == 1 && m_userLengths
[i
] < dashUnit 
+ 2.0 ) 
 379                         m_userLengths
[i
] = dashUnit 
+ 2.0; 
 380                     else if ( i 
% 2 == 0 && m_userLengths
[i
] < dashUnit 
) 
 381                         m_userLengths
[i
] = dashUnit
; 
 384             m_lengths 
= m_userLengths
; 
 389                 wxBitmap
* bmp 
= pen
.GetStipple(); 
 390                 if ( bmp 
&& bmp
->Ok() ) 
 392                     m_colorSpace
.reset( CGColorSpaceCreatePattern( NULL 
) ); 
 393                     m_pattern
.reset( (CGPatternRef
) *( new ImagePattern( bmp 
, CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 394                     m_patternColorComponents 
= new CGFloat
[1] ; 
 395                     m_patternColorComponents
[0] = 1.0; 
 404                 m_colorSpace
.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); 
 405                 m_pattern
.reset( (CGPatternRef
) *( new HatchPattern( pen
.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 406                 m_patternColorComponents 
= new CGFloat
[4] ; 
 407                 m_patternColorComponents
[0] = pen
.GetColour().Red() / 255.0; 
 408                 m_patternColorComponents
[1] = pen
.GetColour().Green() / 255.0; 
 409                 m_patternColorComponents
[2] = pen
.GetColour().Blue() / 255.0; 
 410                 m_patternColorComponents
[3] =  pen
.GetColour().Alpha() / 255.0; 
 414     if ((m_lengths 
!= NULL
) && (m_count 
> 0)) 
 416         // force the line cap, otherwise we get artifacts (overlaps) and just solid lines 
 417         m_cap 
= kCGLineCapButt
; 
 421 wxMacCoreGraphicsPenData::~wxMacCoreGraphicsPenData() 
 423     delete[] m_userLengths
; 
 424     delete[] m_patternColorComponents
; 
 427 void wxMacCoreGraphicsPenData::Init() 
 430     m_userLengths 
= NULL
; 
 433     m_patternColorComponents 
= NULL
; 
 437 void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext
* context 
) 
 439     CGContextRef cg 
= (CGContextRef
) context
->GetNativeContext(); 
 440     CGContextSetLineWidth( cg 
, m_width 
); 
 441     CGContextSetLineJoin( cg 
, m_join 
); 
 443     CGContextSetLineDash( cg 
, 0 , m_lengths 
, m_count 
); 
 444     CGContextSetLineCap( cg 
, m_cap 
); 
 448         CGAffineTransform matrix 
= CGContextGetCTM( cg 
); 
 449         CGContextSetPatternPhase( cg
, CGSizeMake(matrix
.tx
, matrix
.ty
) ); 
 450         CGContextSetStrokeColorSpace( cg 
, m_colorSpace 
); 
 451         CGContextSetStrokePattern( cg
, m_pattern 
, m_patternColorComponents 
); 
 455         if ( context
->GetLogicalFunction() == wxINVERT 
|| context
->GetLogicalFunction() == wxXOR 
) 
 457             CGContextSetRGBStrokeColor( cg 
, 1.0, 1.0 , 1.0, 1.0 ); 
 460             CGContextSetStrokeColorWithColor( cg 
, m_color 
); 
 468 static const char *gs_stripedback_xpm
[] = { 
 469 /* columns rows colors chars-per-pixel */ 
 480 wxBitmap 
gs_stripedback_bmp( wxImage( (const char* const* ) gs_stripedback_xpm  
), -1 ) ; 
 482 // make sure we all use one class for all conversions from wx to native colour 
 484 class wxMacCoreGraphicsColour
 
 487         wxMacCoreGraphicsColour(); 
 488         wxMacCoreGraphicsColour(const wxBrush 
&brush
); 
 489         ~wxMacCoreGraphicsColour(); 
 491         void Apply( CGContextRef cgContext 
); 
 494         wxCFRef
<CGColorRef
> m_color
; 
 495         wxCFRef
<CGColorSpaceRef
> m_colorSpace
; 
 498         wxCFRef
<CGPatternRef
> m_pattern
; 
 499         CGFloat
* m_patternColorComponents
; 
 502 wxMacCoreGraphicsColour::~wxMacCoreGraphicsColour() 
 504     delete[] m_patternColorComponents
; 
 507 void wxMacCoreGraphicsColour::Init() 
 510     m_patternColorComponents 
= NULL
; 
 513 void wxMacCoreGraphicsColour::Apply( CGContextRef cgContext 
) 
 517         CGAffineTransform matrix 
= CGContextGetCTM( cgContext 
); 
 518         CGContextSetPatternPhase( cgContext
, CGSizeMake(matrix
.tx
, matrix
.ty
) ); 
 519         CGContextSetFillColorSpace( cgContext 
, m_colorSpace 
); 
 520         CGContextSetFillPattern( cgContext
, m_pattern 
, m_patternColorComponents 
); 
 524         CGContextSetFillColorWithColor( cgContext
, m_color 
); 
 528 wxMacCoreGraphicsColour::wxMacCoreGraphicsColour()  
 533 wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush 
&brush 
) 
 536     if ( brush
.GetStyle() == wxSOLID 
) 
 538         m_color
.reset( brush
.GetColour().CreateCGColor() ); 
 540     else if ( brush
.IsHatch() ) 
 543         m_colorSpace
.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); 
 544         m_pattern
.reset( (CGPatternRef
) *( new HatchPattern( brush
.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 546         m_patternColorComponents 
= new CGFloat
[4] ; 
 547         m_patternColorComponents
[0] = brush
.GetColour().Red() / 255.0; 
 548         m_patternColorComponents
[1] = brush
.GetColour().Green() / 255.0; 
 549         m_patternColorComponents
[2] = brush
.GetColour().Blue() / 255.0; 
 550         m_patternColorComponents
[3] = brush
.GetColour().Alpha() / 255.0; 
 554         // now brush is a bitmap 
 555         wxBitmap
* bmp 
= brush
.GetStipple(); 
 556         if ( bmp 
&& bmp
->Ok() ) 
 559             m_patternColorComponents 
= new CGFloat
[1] ; 
 560             m_patternColorComponents
[0] = 1.0; 
 561             m_colorSpace
.reset( CGColorSpaceCreatePattern( NULL 
) ); 
 562             m_pattern
.reset( (CGPatternRef
) *( new ImagePattern( bmp 
, CGAffineTransformMakeScale( 1,-1 ) ) ) ); 
 567 class wxMacCoreGraphicsBrushData 
: public wxGraphicsObjectRefData
 
 570     wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer 
); 
 571     wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer
, const wxBrush 
&brush 
); 
 572     ~wxMacCoreGraphicsBrushData (); 
 574     virtual void Apply( wxGraphicsContext
* context 
); 
 575     void CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
 576         const wxColour
&c1
, const wxColour
&c2 
); 
 577     void CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
 578     const wxColour 
&oColor
, const wxColour 
&cColor 
); 
 580     virtual bool IsShading() { return m_isShading
; } 
 581     CGShadingRef 
GetShading() { return m_shading
; } 
 583     CGFunctionRef 
CreateGradientFunction( const wxColour
& c1
, const wxColour
& c2 
); 
 584     static void CalculateShadingValues (void *info
, const CGFloat 
*in
, CGFloat 
*out
); 
 587     wxMacCoreGraphicsColour m_cgColor
; 
 590     CGFunctionRef m_gradientFunction
; 
 591     CGShadingRef m_shading
; 
 592     CGFloat 
*m_gradientComponents
; 
 595 wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer
* renderer
) : wxGraphicsObjectRefData( renderer 
) 
 600 void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
 601         const wxColour
&c1
, const wxColour
&c2 
) 
 603     m_gradientFunction 
= CreateGradientFunction( c1
, c2 
); 
 604     m_shading 
= CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1
,y1
), CGPointMake(x2
,y2
), m_gradientFunction
, true, true ) ; 
 608 void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
 609     const wxColour 
&oColor
, const wxColour 
&cColor 
) 
 611     m_gradientFunction 
= CreateGradientFunction( oColor
, cColor 
); 
 612     m_shading 
= CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo
,yo
), 0, CGPointMake(xc
,yc
), radius
, m_gradientFunction
, true, true ) ; 
 616 wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer
* renderer
, const wxBrush 
&brush
) : wxGraphicsObjectRefData( renderer 
), 
 623 wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData() 
 626         CGShadingRelease(m_shading
); 
 628     if( m_gradientFunction 
) 
 629         CGFunctionRelease(m_gradientFunction
); 
 631     delete[] m_gradientComponents
; 
 634 void wxMacCoreGraphicsBrushData::Init() 
 636     m_gradientFunction 
= NULL
; 
 638     m_gradientComponents 
= NULL
; 
 642 void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext
* context 
) 
 644     CGContextRef cg 
= (CGContextRef
) context
->GetNativeContext(); 
 648         // nothing to set as shades are processed by clipping using the path and filling 
 652         m_cgColor
.Apply( cg 
); 
 656 void wxMacCoreGraphicsBrushData::CalculateShadingValues (void *info
, const CGFloat 
*in
, CGFloat 
*out
) 
 658     CGFloat
* colors 
= (CGFloat
*) info 
; 
 660     for( int i 
= 0 ; i 
< 4 ; ++i 
) 
 662         out
[i
] = colors
[i
] + ( colors
[4+i
] - colors
[i
] ) * f
; 
 666 CGFunctionRef 
wxMacCoreGraphicsBrushData::CreateGradientFunction( const wxColour
& c1
, const wxColour
& c2 
) 
 668     static const CGFunctionCallbacks callbacks 
= { 0, &CalculateShadingValues
, NULL 
}; 
 669     static const CGFloat input_value_range 
[2] = { 0, 1 }; 
 670     static const CGFloat output_value_ranges 
[8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; 
 671     m_gradientComponents 
= new CGFloat
[8] ; 
 672     m_gradientComponents
[0] = c1
.Red() / 255.0; 
 673     m_gradientComponents
[1] = c1
.Green() / 255.0; 
 674     m_gradientComponents
[2] = c1
.Blue() / 255.0; 
 675     m_gradientComponents
[3] = c1
.Alpha() / 255.0; 
 676     m_gradientComponents
[4] = c2
.Red() / 255.0; 
 677     m_gradientComponents
[5] = c2
.Green() / 255.0; 
 678     m_gradientComponents
[6] = c2
.Blue() / 255.0; 
 679     m_gradientComponents
[7] = c2
.Alpha() / 255.0; 
 681     return CGFunctionCreate ( m_gradientComponents
,  1, 
 692 class wxMacCoreGraphicsFontData 
: public wxGraphicsObjectRefData
 
 695     wxMacCoreGraphicsFontData( wxGraphicsRenderer
* renderer
, const wxFont 
&font
, const wxColour
& col 
); 
 696     ~wxMacCoreGraphicsFontData(); 
 698 #if wxMAC_USE_ATSU_TEXT 
 699     virtual ATSUStyle 
GetATSUStyle() { return m_macATSUIStyle
; } 
 701 #if wxMAC_USE_CORE_TEXT 
 702     CTFontRef 
GetCTFont() const { return m_ctFont 
; } 
 704     wxColour 
GetColour() const { return m_colour 
; } 
 706     bool GetUnderlined() const { return m_underlined 
; } 
 710 #if wxMAC_USE_ATSU_TEXT 
 711     ATSUStyle m_macATSUIStyle
; 
 713 #if wxMAC_USE_CORE_TEXT 
 714     wxCFRef
< CTFontRef 
> m_ctFont
; 
 718 wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer
* renderer
, const wxFont 
&font
, const wxColour
& col
) : wxGraphicsObjectRefData( renderer 
) 
 721     m_underlined 
= font
.GetUnderlined(); 
 723 #if wxMAC_USE_CORE_TEXT 
 724     m_ctFont
.reset( wxCFRetain((CTFontRef
) font
.MacGetCTFont()) ); 
 726 #if wxMAC_USE_ATSU_TEXT 
 727     OSStatus status 
= noErr
; 
 728     m_macATSUIStyle 
= NULL
; 
 730     status 
= ATSUCreateAndCopyStyle( (ATSUStyle
) font
.MacGetATSUStyle() , &m_macATSUIStyle 
); 
 732     wxASSERT_MSG( status 
== noErr
, wxT("couldn't create ATSU style") ); 
 734     // we need the scale here ... 
 736     Fixed atsuSize 
= IntToFixed( int( 1 * font
.MacGetFontSize()) ); 
 738     col
.GetRGBColor( &atsuColor 
); 
 739     ATSUAttributeTag atsuTags
[] = 
 744     ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 749     ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 755     status 
= ::ATSUSetAttributes( 
 756         m_macATSUIStyle
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) , 
 757         atsuTags
, atsuSizes
, atsuValues
); 
 759     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ); 
 761 #if wxMAC_USE_CG_TEXT 
 765 wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() 
 767 #if wxMAC_USE_CORE_TEXT 
 769 #if wxMAC_USE_ATSU_TEXT 
 770     if ( m_macATSUIStyle 
) 
 772         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
); 
 773         m_macATSUIStyle 
= NULL
; 
 776 #if wxMAC_USE_CG_TEXT 
 784 //----------------------------------------------------------------------------- 
 785 // wxMacCoreGraphicsMatrix declaration 
 786 //----------------------------------------------------------------------------- 
 788 class WXDLLIMPEXP_CORE wxMacCoreGraphicsMatrixData 
: public wxGraphicsMatrixData
 
 791     wxMacCoreGraphicsMatrixData(wxGraphicsRenderer
* renderer
) ; 
 793     virtual ~wxMacCoreGraphicsMatrixData() ; 
 795     virtual wxGraphicsObjectRefData 
*Clone() const ; 
 797     // concatenates the matrix 
 798     virtual void Concat( const wxGraphicsMatrixData 
*t 
); 
 800     // sets the matrix to the respective values 
 801     virtual void Set(wxDouble a
=1.0, wxDouble b
=0.0, wxDouble c
=0.0, wxDouble d
=1.0, 
 802         wxDouble tx
=0.0, wxDouble ty
=0.0); 
 804     // gets the component valuess of the matrix 
 805     virtual void Get(wxDouble
* a
=NULL
, wxDouble
* b
=NULL
,  wxDouble
* c
=NULL
, 
 806                      wxDouble
* d
=NULL
, wxDouble
* tx
=NULL
, wxDouble
* ty
=NULL
) const; 
 808     // makes this the inverse matrix 
 809     virtual void Invert(); 
 811     // returns true if the elements of the transformation matrix are equal ? 
 812     virtual bool IsEqual( const wxGraphicsMatrixData
* t
) const ; 
 814     // return true if this is the identity matrix 
 815     virtual bool IsIdentity() const; 
 821     // add the translation to this matrix 
 822     virtual void Translate( wxDouble dx 
, wxDouble dy 
); 
 824     // add the scale to this matrix 
 825     virtual void Scale( wxDouble xScale 
, wxDouble yScale 
); 
 827     // add the rotation to this matrix (radians) 
 828     virtual void Rotate( wxDouble angle 
); 
 831     // apply the transforms 
 834     // applies that matrix to the point 
 835     virtual void TransformPoint( wxDouble 
*x
, wxDouble 
*y 
) const; 
 837     // applies the matrix except for translations 
 838     virtual void TransformDistance( wxDouble 
*dx
, wxDouble 
*dy 
) const; 
 840     // returns the native representation 
 841     virtual void * GetNativeMatrix() const; 
 844     CGAffineTransform m_matrix
; 
 847 //----------------------------------------------------------------------------- 
 848 // wxMacCoreGraphicsMatrix implementation 
 849 //----------------------------------------------------------------------------- 
 851 wxMacCoreGraphicsMatrixData::wxMacCoreGraphicsMatrixData(wxGraphicsRenderer
* renderer
) : wxGraphicsMatrixData(renderer
) 
 855 wxMacCoreGraphicsMatrixData::~wxMacCoreGraphicsMatrixData() 
 859 wxGraphicsObjectRefData 
*wxMacCoreGraphicsMatrixData::Clone() const 
 861     wxMacCoreGraphicsMatrixData
* m 
= new wxMacCoreGraphicsMatrixData(GetRenderer()) ; 
 862     m
->m_matrix 
= m_matrix 
; 
 866 // concatenates the matrix 
 867 void wxMacCoreGraphicsMatrixData::Concat( const wxGraphicsMatrixData 
*t 
) 
 869     m_matrix 
= CGAffineTransformConcat(m_matrix
, *((CGAffineTransform
*) t
->GetNativeMatrix()) ); 
 872 // sets the matrix to the respective values 
 873 void wxMacCoreGraphicsMatrixData::Set(wxDouble a
, wxDouble b
, wxDouble c
, wxDouble d
, 
 874     wxDouble tx
, wxDouble ty
) 
 876     m_matrix 
= CGAffineTransformMake(a
,b
,c
,d
,tx
,ty
); 
 879 // gets the component valuess of the matrix 
 880 void wxMacCoreGraphicsMatrixData::Get(wxDouble
* a
, wxDouble
* b
,  wxDouble
* c
, 
 881                                       wxDouble
* d
, wxDouble
* tx
, wxDouble
* ty
) const 
 883     if (a
)  *a 
= m_matrix
.a
; 
 884     if (b
)  *b 
= m_matrix
.b
; 
 885     if (c
)  *c 
= m_matrix
.c
; 
 886     if (d
)  *d 
= m_matrix
.d
; 
 887     if (tx
) *tx
= m_matrix
.tx
; 
 888     if (ty
) *ty
= m_matrix
.ty
; 
 891 // makes this the inverse matrix 
 892 void wxMacCoreGraphicsMatrixData::Invert() 
 894     m_matrix 
= CGAffineTransformInvert( m_matrix 
); 
 897 // returns true if the elements of the transformation matrix are equal ? 
 898 bool wxMacCoreGraphicsMatrixData::IsEqual( const wxGraphicsMatrixData
* t
) const 
 900     return CGAffineTransformEqualToTransform(m_matrix
, *((CGAffineTransform
*) t
->GetNativeMatrix())); 
 903 // return true if this is the identity matrix 
 904 bool wxMacCoreGraphicsMatrixData::IsIdentity() const 
 906     return ( m_matrix
.a 
== 1 && m_matrix
.d 
== 1 && 
 907         m_matrix
.b 
== 0 && m_matrix
.d 
== 0 && m_matrix
.tx 
== 0 && m_matrix
.ty 
== 0); 
 914 // add the translation to this matrix 
 915 void wxMacCoreGraphicsMatrixData::Translate( wxDouble dx 
, wxDouble dy 
) 
 917     m_matrix 
= CGAffineTransformTranslate( m_matrix
, dx
, dy
); 
 920 // add the scale to this matrix 
 921 void wxMacCoreGraphicsMatrixData::Scale( wxDouble xScale 
, wxDouble yScale 
) 
 923     m_matrix 
= CGAffineTransformScale( m_matrix
, xScale
, yScale
); 
 926 // add the rotation to this matrix (radians) 
 927 void wxMacCoreGraphicsMatrixData::Rotate( wxDouble angle 
) 
 929     m_matrix 
= CGAffineTransformRotate( m_matrix
, angle
); 
 933 // apply the transforms 
 936 // applies that matrix to the point 
 937 void wxMacCoreGraphicsMatrixData::TransformPoint( wxDouble 
*x
, wxDouble 
*y 
) const 
 939     CGPoint pt 
= CGPointApplyAffineTransform( CGPointMake(*x
,*y
), m_matrix
); 
 945 // applies the matrix except for translations 
 946 void wxMacCoreGraphicsMatrixData::TransformDistance( wxDouble 
*dx
, wxDouble 
*dy 
) const 
 948     CGSize sz 
= CGSizeApplyAffineTransform( CGSizeMake(*dx
,*dy
) , m_matrix 
); 
 953 // returns the native representation 
 954 void * wxMacCoreGraphicsMatrixData::GetNativeMatrix() const 
 956     return (void*) &m_matrix
; 
 963 //----------------------------------------------------------------------------- 
 964 // wxMacCoreGraphicsPath declaration 
 965 //----------------------------------------------------------------------------- 
 967 class WXDLLEXPORT wxMacCoreGraphicsPathData 
: public wxGraphicsPathData
 
 970     wxMacCoreGraphicsPathData( wxGraphicsRenderer
* renderer
, CGMutablePathRef path 
= NULL
); 
 972     ~wxMacCoreGraphicsPathData(); 
 974     virtual wxGraphicsObjectRefData 
*Clone() const; 
 976     // begins a new subpath at (x,y) 
 977     virtual void MoveToPoint( wxDouble x
, wxDouble y 
); 
 979     // adds a straight line from the current point to (x,y) 
 980     virtual void AddLineToPoint( wxDouble x
, wxDouble y 
); 
 982     // adds a cubic Bezier curve from the current point, using two control points and an end point 
 983     virtual void AddCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble cx2
, wxDouble cy2
, wxDouble x
, wxDouble y 
); 
 985     // closes the current sub-path 
 986     virtual void CloseSubpath(); 
 988     // gets the last point of the current path, (0,0) if not yet set 
 989     virtual void GetCurrentPoint( wxDouble
* x
, wxDouble
* y
) const; 
 991     // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle 
 992     virtual void AddArc( wxDouble x
, wxDouble y
, wxDouble r
, wxDouble startAngle
, wxDouble endAngle
, bool clockwise 
); 
 995     // These are convenience functions which - if not available natively will be assembled 
 996     // using the primitives from above 
 999     // adds a quadratic Bezier curve from the current point, using a control point and an end point 
1000     virtual void AddQuadCurveToPoint( wxDouble cx
, wxDouble cy
, wxDouble x
, wxDouble y 
); 
1002     // appends a rectangle as a new closed subpath 
1003     virtual void AddRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1005     // appends an ellipsis as a new closed subpath fitting the passed rectangle 
1006     virtual void AddCircle( wxDouble x
, wxDouble y
, wxDouble r 
); 
1008     // 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) 
1009     virtual void AddArcToPoint( wxDouble x1
, wxDouble y1 
, wxDouble x2
, wxDouble y2
, wxDouble r 
); 
1011     // adds another path 
1012     virtual void AddPath( const wxGraphicsPathData
* path 
); 
1014     // returns the native path 
1015     virtual void * GetNativePath() const { return m_path
; } 
1017     // give the native path returned by GetNativePath() back (there might be some deallocations necessary) 
1018     virtual void UnGetNativePath(void *WXUNUSED(p
)) const {} 
1020     // transforms each point of this path by the matrix 
1021     virtual void Transform( const wxGraphicsMatrixData
* matrix 
); 
1023     // gets the bounding box enclosing all points (possibly including control points) 
1024     virtual void GetBox(wxDouble 
*x
, wxDouble 
*y
, wxDouble 
*w
, wxDouble 
*y
) const; 
1026     virtual bool Contains( wxDouble x
, wxDouble y
, int fillStyle 
= wxODDEVEN_RULE
) const; 
1028     CGMutablePathRef m_path
; 
1031 //----------------------------------------------------------------------------- 
1032 // wxMacCoreGraphicsPath implementation 
1033 //----------------------------------------------------------------------------- 
1035 wxMacCoreGraphicsPathData::wxMacCoreGraphicsPathData( wxGraphicsRenderer
* renderer
, CGMutablePathRef path
) : wxGraphicsPathData(renderer
) 
1040         m_path 
= CGPathCreateMutable(); 
1043 wxMacCoreGraphicsPathData::~wxMacCoreGraphicsPathData() 
1045     CGPathRelease( m_path 
); 
1048 wxGraphicsObjectRefData
* wxMacCoreGraphicsPathData::Clone() const 
1050     wxMacCoreGraphicsPathData
* clone 
= new wxMacCoreGraphicsPathData(GetRenderer(),CGPathCreateMutableCopy(m_path
)); 
1055 // opens (starts) a new subpath 
1056 void wxMacCoreGraphicsPathData::MoveToPoint( wxDouble x1 
, wxDouble y1 
) 
1058     CGPathMoveToPoint( m_path 
, NULL 
, x1 
, y1 
); 
1061 void wxMacCoreGraphicsPathData::AddLineToPoint( wxDouble x1 
, wxDouble y1 
) 
1063     CGPathAddLineToPoint( m_path 
, NULL 
, x1 
, y1 
); 
1066 void wxMacCoreGraphicsPathData::AddCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble cx2
, wxDouble cy2
, wxDouble x
, wxDouble y 
) 
1068     CGPathAddCurveToPoint( m_path 
, NULL 
, cx1 
, cy1 
, cx2
, cy2
, x 
, y 
); 
1071 void wxMacCoreGraphicsPathData::AddQuadCurveToPoint( wxDouble cx1
, wxDouble cy1
, wxDouble x
, wxDouble y 
) 
1073     CGPathAddQuadCurveToPoint( m_path 
, NULL 
, cx1 
, cy1 
, x 
, y 
); 
1076 void wxMacCoreGraphicsPathData::AddRectangle( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1078     CGRect cgRect 
= { { x 
, y 
} , { w 
, h 
} }; 
1079     CGPathAddRect( m_path 
, NULL 
, cgRect 
); 
1082 void wxMacCoreGraphicsPathData::AddCircle( wxDouble x
, wxDouble y 
, wxDouble r 
) 
1084     CGPathAddArc( m_path 
, NULL 
, x 
, y 
, r 
, 0.0 , 2 * M_PI 
, true ); 
1087 // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle 
1088 void wxMacCoreGraphicsPathData::AddArc( wxDouble x
, wxDouble y
, wxDouble r
, wxDouble startAngle
, wxDouble endAngle
, bool clockwise 
) 
1090     // inverse direction as we the 'normal' state is a y axis pointing down, ie mirrored to the standard core graphics setup 
1091     CGPathAddArc( m_path
, NULL 
, x
, y
, r
, startAngle
, endAngle
, !clockwise
); 
1094 void wxMacCoreGraphicsPathData::AddArcToPoint( wxDouble x1
, wxDouble y1 
, wxDouble x2
, wxDouble y2
, wxDouble r 
) 
1096     CGPathAddArcToPoint( m_path
, NULL 
, x1
, y1
, x2
, y2
, r
); 
1099 void wxMacCoreGraphicsPathData::AddPath( const wxGraphicsPathData
* path 
) 
1101     CGPathAddPath( m_path 
, NULL
, (CGPathRef
) path
->GetNativePath() ); 
1104 // closes the current subpath 
1105 void wxMacCoreGraphicsPathData::CloseSubpath() 
1107     CGPathCloseSubpath( m_path 
); 
1110 // gets the last point of the current path, (0,0) if not yet set 
1111 void wxMacCoreGraphicsPathData::GetCurrentPoint( wxDouble
* x
, wxDouble
* y
) const 
1113     CGPoint p 
= CGPathGetCurrentPoint( m_path 
); 
1118 // transforms each point of this path by the matrix 
1119 void wxMacCoreGraphicsPathData::Transform( const wxGraphicsMatrixData
* matrix 
) 
1121     CGMutablePathRef p 
= CGPathCreateMutable() ; 
1122     CGPathAddPath( p
, (CGAffineTransform
*) matrix
->GetNativeMatrix() , m_path 
); 
1123     CGPathRelease( m_path 
); 
1127 // gets the bounding box enclosing all points (possibly including control points) 
1128 void wxMacCoreGraphicsPathData::GetBox(wxDouble 
*x
, wxDouble 
*y
, wxDouble 
*w
, wxDouble 
*h
) const 
1130     CGRect bounds 
= CGPathGetBoundingBox( m_path 
) ; 
1131     *x 
= bounds
.origin
.x
; 
1132     *y 
= bounds
.origin
.y
; 
1133     *w 
= bounds
.size
.width
; 
1134     *h 
= bounds
.size
.height
; 
1137 bool wxMacCoreGraphicsPathData::Contains( wxDouble x
, wxDouble y
, int fillStyle
) const 
1139     return CGPathContainsPoint( m_path
, NULL
, CGPointMake(x
,y
), fillStyle 
== wxODDEVEN_RULE 
); 
1146 //----------------------------------------------------------------------------- 
1147 // wxMacCoreGraphicsContext declaration 
1148 //----------------------------------------------------------------------------- 
1150 class WXDLLEXPORT wxMacCoreGraphicsContext 
: public wxGraphicsContext
 
1153     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, CGContextRef cgcontext
, wxDouble width 
= 0, wxDouble height 
= 0 ); 
1155     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, WindowRef window 
); 
1157     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, wxWindow
* window 
); 
1159     wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
); 
1161     wxMacCoreGraphicsContext(); 
1163     ~wxMacCoreGraphicsContext(); 
1167     // returns the size of the graphics context in device coordinates 
1168     virtual void GetSize( wxDouble
* width
, wxDouble
* height
); 
1170     virtual void StartPage( wxDouble width
, wxDouble height 
); 
1172     virtual void EndPage(); 
1174     virtual void Flush(); 
1176     // push the current state of the context, ie the transformation matrix on a stack 
1177     virtual void PushState(); 
1179     // pops a stored state from the stack 
1180     virtual void PopState(); 
1182     // clips drawings to the region 
1183     virtual void Clip( const wxRegion 
®ion 
); 
1185     // clips drawings to the rect 
1186     virtual void Clip( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1188     // resets the clipping to original extent 
1189     virtual void ResetClip(); 
1191     virtual void * GetNativeContext(); 
1193     bool SetLogicalFunction( int function 
); 
1199     virtual void Translate( wxDouble dx 
, wxDouble dy 
); 
1202     virtual void Scale( wxDouble xScale 
, wxDouble yScale 
); 
1205     virtual void Rotate( wxDouble angle 
); 
1207     // concatenates this transform with the current transform of this context 
1208     virtual void ConcatTransform( const wxGraphicsMatrix
& matrix 
); 
1210     // sets the transform of this context 
1211     virtual void SetTransform( const wxGraphicsMatrix
& matrix 
); 
1213     // gets the matrix of this context 
1214     virtual wxGraphicsMatrix 
GetTransform() const; 
1216     // setting the paint 
1219     // strokes along a path with the current pen 
1220     virtual void StrokePath( const wxGraphicsPath 
&path 
); 
1222     // fills a path with the current brush 
1223     virtual void FillPath( const wxGraphicsPath 
&path
, int fillStyle 
= wxODDEVEN_RULE 
); 
1225     // draws a path by first filling and then stroking 
1226     virtual void DrawPath( const wxGraphicsPath 
&path
, int fillStyle 
= wxODDEVEN_RULE 
); 
1228     virtual bool ShouldOffset() const 
1231         if ( !m_pen
.IsNull() ) 
1233             penwidth 
= (int)((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->GetWidth(); 
1234             if ( penwidth 
== 0 ) 
1237         return ( penwidth 
% 2 ) == 1; 
1243     virtual void DrawText( const wxString 
&str
, wxDouble x
, wxDouble y 
); 
1245     virtual void DrawText( const wxString 
&str
, wxDouble x
, wxDouble y
, wxDouble angle 
); 
1247     virtual void GetTextExtent( const wxString 
&text
, wxDouble 
*width
, wxDouble 
*height
, 
1248         wxDouble 
*descent
, wxDouble 
*externalLeading 
) const; 
1250     virtual void GetPartialTextExtents(const wxString
& text
, wxArrayDouble
& widths
) const; 
1256     virtual void DrawBitmap( const wxBitmap 
&bmp
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1258     virtual void DrawIcon( const wxIcon 
&icon
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
); 
1260     void SetNativeContext( CGContextRef cg 
); 
1262     DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext
) 
1263     DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsContext
) 
1266     void EnsureIsValid(); 
1268     CGContextRef m_cgContext
; 
1269     WindowRef m_windowRef
; 
1270     bool m_releaseContext
; 
1271     CGAffineTransform m_windowTransform
; 
1275     wxCFRef
<HIShapeRef
> m_clipRgn
; 
1278 //----------------------------------------------------------------------------- 
1279 // device context implementation 
1281 // more and more of the dc functionality should be implemented by calling 
1282 // the appropricate wxMacCoreGraphicsContext, but we will have to do that step by step 
1283 // also coordinate conversions should be moved to native matrix ops 
1284 //----------------------------------------------------------------------------- 
1286 // we always stock two context states, one at entry, to be able to preserve the 
1287 // state we were called with, the other one after changing to HI Graphics orientation 
1288 // (this one is used for getting back clippings etc) 
1290 //----------------------------------------------------------------------------- 
1291 // wxMacCoreGraphicsContext implementation 
1292 //----------------------------------------------------------------------------- 
1294 IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext
, wxGraphicsContext
) 
1296 class wxQuartzOffsetHelper
 
1299     wxQuartzOffsetHelper( CGContextRef cg 
, bool offset 
) 
1304             CGContextTranslateCTM( m_cg
, 0.5, 0.5 ); 
1306     ~wxQuartzOffsetHelper( ) 
1309             CGContextTranslateCTM( m_cg
, -0.5, -0.5 ); 
1316 void wxMacCoreGraphicsContext::Init() 
1319     m_releaseContext 
= false; 
1324     HIRect r 
= CGRectMake(0,0,0,0); 
1325     m_clipRgn
.reset(HIShapeCreateWithRect(&r
)); 
1328 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, CGContextRef cgcontext
, wxDouble width
, wxDouble height 
) : wxGraphicsContext(renderer
) 
1331     SetNativeContext(cgcontext
); 
1336 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, WindowRef window 
): wxGraphicsContext(renderer
) 
1339     m_windowRef 
= window
; 
1342 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer
* renderer
, wxWindow
* window 
): wxGraphicsContext(renderer
) 
1345     m_windowRef 
= (WindowRef
) window
->MacGetTopLevelWindowRef(); 
1346     int originX 
, originY
; 
1347     originX 
= originY 
= 0; 
1348     window
->MacWindowToRootWindow( &originX 
, &originY 
); 
1350     Rect bounds 
= { 0,0,0,0 }; 
1353     GetWindowBounds( m_windowRef
, kWindowContentRgn
, &bounds 
); 
1355     m_windowTransform 
= CGAffineTransformMakeTranslation( 0 , bounds
.bottom 
- bounds
.top 
); 
1356     m_windowTransform 
= CGAffineTransformScale( m_windowTransform 
, 1 , -1 ); 
1357     m_windowTransform 
= CGAffineTransformTranslate( m_windowTransform
, originX
, originY 
) ; 
1360 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext(wxGraphicsRenderer
* renderer
) : wxGraphicsContext(renderer
) 
1365 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext() : wxGraphicsContext(NULL
) 
1368     wxLogDebug(wxT("Illegal Constructor called")); 
1371 wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext() 
1373     SetNativeContext(NULL
); 
1376 void wxMacCoreGraphicsContext::GetSize( wxDouble
* width
, wxDouble
* height
) 
1383 void wxMacCoreGraphicsContext::StartPage( wxDouble width
, wxDouble height 
) 
1386     if ( width 
!= 0 && height 
!= 0) 
1387         r 
= CGRectMake( 0 , 0 , width  
, height 
); 
1389         r 
= CGRectMake( 0 , 0 , m_width  
, m_height 
); 
1391     CGContextBeginPage(m_cgContext
,  &r 
); 
1392 //    CGContextTranslateCTM( m_cgContext , 0 ,  height == 0 ? m_height : height ); 
1393 //    CGContextScaleCTM( m_cgContext , 1 , -1 ); 
1396 void wxMacCoreGraphicsContext::EndPage() 
1398     CGContextEndPage(m_cgContext
); 
1401 void wxMacCoreGraphicsContext::Flush() 
1403     CGContextFlush(m_cgContext
); 
1406 void wxMacCoreGraphicsContext::EnsureIsValid() 
1412             QDBeginCGContext( GetWindowPort( m_windowRef 
) , &m_cgContext 
); 
1416         wxASSERT_MSG( status 
== noErr 
, wxT("Cannot nest wxDCs on the same window") ); 
1418         CGContextConcatCTM( m_cgContext
, m_windowTransform 
); 
1419                 CGContextSaveGState( m_cgContext 
); 
1420                 m_releaseContext 
= true; 
1421                 if ( !HIShapeIsEmpty(m_clipRgn
) ) 
1423             // the clip region is in device coordinates, so we convert this again to user coordinates 
1424             wxCFRef
<HIMutableShapeRef
> hishape( HIShapeCreateMutableCopy( m_clipRgn 
) ); 
1425             CGPoint transformedOrigin 
= CGPointApplyAffineTransform( CGPointZero
,m_windowTransform
); 
1426             HIShapeOffset( hishape
, -transformedOrigin
.x
, -transformedOrigin
.y 
); 
1427                         HIShapeReplacePathInCGContext( hishape
, m_cgContext 
); 
1428                         CGContextClip( m_cgContext 
); 
1430                 CGContextSaveGState( m_cgContext 
); 
1434 // TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes) 
1436 bool wxMacCoreGraphicsContext::SetLogicalFunction( int function 
) 
1438     if (m_logicalFunction 
== function
) 
1443     bool retval 
= false; 
1444     bool shouldAntiAlias 
= true; 
1445     CGBlendMode mode 
= kCGBlendModeNormal
; 
1447 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 
1448     if ( UMAGetSystemVersion() >= 0x1050 ) 
1453             // TODO find best corresponding porter duff modes 
1455                 mode 
= kCGBlendModeCopy
; 
1458                 mode 
= kCGBlendModeClear
; 
1461                 mode 
= kCGBlendModeXOR
; 
1462                 shouldAntiAlias 
= false; 
1472         if ( function 
== wxCOPY 
) 
1476         else if ( function 
== wxINVERT 
|| function 
== wxXOR 
) 
1478             // change color to white 
1479             mode 
= kCGBlendModeExclusion
; 
1480             shouldAntiAlias 
= false; 
1487         m_logicalFunction 
= function
; 
1488         CGContextSetBlendMode( m_cgContext
, mode 
); 
1489         CGContextSetShouldAntialias(m_cgContext
, shouldAntiAlias
); 
1494 void wxMacCoreGraphicsContext::Clip( const wxRegion 
®ion 
) 
1498         HIShapeReplacePathInCGContext( region
.GetWXHRGN() , m_cgContext 
); 
1499         CGContextClip( m_cgContext 
); 
1503         // this offsetting to device coords is not really correct, but since we cannot apply affine transforms 
1504         // to regions we try at least to have correct translations 
1505         HIMutableShapeRef mutableShape 
= HIShapeCreateMutableCopy( region
.GetWXHRGN() ); 
1507         CGPoint transformedOrigin 
= CGPointApplyAffineTransform( CGPointZero
, m_windowTransform 
); 
1508         HIShapeOffset( mutableShape
, transformedOrigin
.x
, transformedOrigin
.y 
); 
1509         m_clipRgn
.reset(mutableShape
); 
1513 // clips drawings to the rect 
1514 void wxMacCoreGraphicsContext::Clip( wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1516     HIRect r 
= CGRectMake( x 
, y 
, w 
, h 
); 
1519         CGContextClipToRect( m_cgContext
, r 
); 
1523         // the clipping itself must be stored as device coordinates, otherwise  
1524         // we cannot apply it back correctly 
1525         r
.origin
= CGPointApplyAffineTransform( r
.origin
, m_windowTransform 
); 
1526         m_clipRgn
.reset(HIShapeCreateWithRect(&r
)); 
1530     // resets the clipping to original extent 
1531 void wxMacCoreGraphicsContext::ResetClip() 
1535         // there is no way for clearing the clip, we can only revert to the stored 
1536         // state, but then we have to make sure everything else is NOT restored 
1537         CGAffineTransform transform 
= CGContextGetCTM( m_cgContext 
); 
1538         CGContextRestoreGState( m_cgContext 
); 
1539         CGContextSaveGState( m_cgContext 
); 
1540         CGAffineTransform transformNew 
= CGContextGetCTM( m_cgContext 
); 
1541         transformNew 
= CGAffineTransformInvert( transformNew 
) ; 
1542         CGContextConcatCTM( m_cgContext
, transformNew
); 
1543         CGContextConcatCTM( m_cgContext
, transform
); 
1547         HIRect r 
= CGRectMake(0,0,0,0); 
1548         m_clipRgn
.reset(HIShapeCreateWithRect(&r
)); 
1552 void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath 
&path 
) 
1554     if ( m_pen
.IsNull() ) 
1559     wxQuartzOffsetHelper 
helper( m_cgContext 
, ShouldOffset() ); 
1561     ((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->Apply(this); 
1562     CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1563     CGContextStrokePath( m_cgContext 
); 
1566 void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath 
&path 
, int fillStyle 
) 
1568     if ( !m_brush
.IsNull() && ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1570         // when using shading, we cannot draw pen and brush at the same time 
1571         // revert to the base implementation of first filling and then stroking 
1572         wxGraphicsContext::DrawPath( path
, fillStyle 
); 
1576     CGPathDrawingMode mode 
= kCGPathFill 
; 
1577     if ( m_brush
.IsNull() ) 
1579         if ( m_pen
.IsNull() ) 
1582             mode 
= kCGPathStroke
; 
1586         if ( m_pen
.IsNull() ) 
1588             if ( fillStyle 
== wxODDEVEN_RULE 
) 
1589                 mode 
= kCGPathEOFill
; 
1595             if ( fillStyle 
== wxODDEVEN_RULE 
) 
1596                 mode 
= kCGPathEOFillStroke
; 
1598                 mode 
= kCGPathFillStroke
; 
1604     if ( !m_brush
.IsNull() ) 
1605         ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1606     if ( !m_pen
.IsNull() ) 
1607         ((wxMacCoreGraphicsPenData
*)m_pen
.GetRefData())->Apply(this); 
1609     wxQuartzOffsetHelper 
helper( m_cgContext 
, ShouldOffset() ); 
1611     CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1612     CGContextDrawPath( m_cgContext 
, mode 
); 
1615 void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath 
&path 
, int fillStyle 
) 
1617     if ( m_brush
.IsNull() ) 
1622     if ( ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1624         CGContextSaveGState( m_cgContext 
); 
1625         CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1626         CGContextClip( m_cgContext 
); 
1627         CGContextDrawShading( m_cgContext
, ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->GetShading() ); 
1628         CGContextRestoreGState( m_cgContext
); 
1632         ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1633         CGContextAddPath( m_cgContext 
, (CGPathRef
) path
.GetNativePath() ); 
1634         if ( fillStyle 
== wxODDEVEN_RULE 
) 
1635             CGContextEOFillPath( m_cgContext 
); 
1637             CGContextFillPath( m_cgContext 
); 
1641 void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg 
) 
1643     // we allow either setting or clearing but not replacing 
1644     wxASSERT( m_cgContext 
== NULL 
|| cg 
== NULL 
); 
1648         // TODO : when is this necessary - should we add a Flush() method ? CGContextSynchronize( m_cgContext ); 
1649         CGContextRestoreGState( m_cgContext 
); 
1650         CGContextRestoreGState( m_cgContext 
); 
1651         if ( m_releaseContext 
) 
1654             QDEndCGContext( GetWindowPort( m_windowRef 
) , &m_cgContext
); 
1658             CGContextRelease(m_cgContext
); 
1664     // FIXME: This check is needed because currently we need to use a DC/GraphicsContext 
1665     // in order to get font properties, like wxFont::GetPixelSize, but since we don't have 
1666     // a native window attached to use, I create a wxGraphicsContext with a NULL CGContextRef 
1667     // for this one operation. 
1669     // When wxFont::GetPixelSize on Mac no longer needs a graphics context, this check 
1673         CGContextRetain(m_cgContext
); 
1674         CGContextSaveGState( m_cgContext 
); 
1675         CGContextSaveGState( m_cgContext 
); 
1676         m_releaseContext 
= false; 
1680 void wxMacCoreGraphicsContext::Translate( wxDouble dx 
, wxDouble dy 
) 
1683         CGContextTranslateCTM( m_cgContext
, dx
, dy 
); 
1685         m_windowTransform 
= CGAffineTransformTranslate(m_windowTransform
,dx
,dy
); 
1688 void wxMacCoreGraphicsContext::Scale( wxDouble xScale 
, wxDouble yScale 
) 
1691         CGContextScaleCTM( m_cgContext 
, xScale 
, yScale 
); 
1693         m_windowTransform 
= CGAffineTransformScale(m_windowTransform
,xScale
,yScale
); 
1696 void wxMacCoreGraphicsContext::Rotate( wxDouble angle 
) 
1699         CGContextRotateCTM( m_cgContext 
, angle 
); 
1701         m_windowTransform 
= CGAffineTransformRotate(m_windowTransform
,angle
); 
1704 void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap 
&bmp
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1708     CGImageRef image 
= (CGImageRef
)( bmp
.CreateCGImage() ); 
1709     HIRect r 
= CGRectMake( x 
, y 
, w 
, h 
); 
1710     if ( bmp
.GetDepth() == 1 ) 
1712         // is is a mask, the '1' in the mask tell where to draw the current brush 
1713         if (  !m_brush
.IsNull() ) 
1715             if ( ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->IsShading() ) 
1717                 // TODO clip to mask 
1719                 CGContextSaveGState( m_cgContext ); 
1720                 CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() ); 
1721                 CGContextClip( m_cgContext ); 
1722                 CGContextDrawShading( m_cgContext, ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->GetShading() ); 
1723                 CGContextRestoreGState( m_cgContext); 
1728                 ((wxMacCoreGraphicsBrushData
*)m_brush
.GetRefData())->Apply(this); 
1729                 wxMacDrawCGImage( m_cgContext 
, &r 
, image 
); 
1735         wxMacDrawCGImage( m_cgContext 
, &r 
, image 
); 
1737     CGImageRelease( image 
); 
1740 void wxMacCoreGraphicsContext::DrawIcon( const wxIcon 
&icon
, wxDouble x
, wxDouble y
, wxDouble w
, wxDouble h 
) 
1744     CGRect r 
= CGRectMake( 00 , 00 , w 
, h 
); 
1745     CGContextSaveGState( m_cgContext 
); 
1746     CGContextTranslateCTM( m_cgContext
, x 
, y 
+ h 
); 
1747     CGContextScaleCTM( m_cgContext
, 1, -1 ); 
1748     PlotIconRefInContext( m_cgContext 
, &r 
, kAlignNone 
, kTransformNone 
, 
1749         NULL 
, kPlotIconRefNormalFlags 
, MAC_WXHICON( icon
.GetHICON() ) ); 
1750     CGContextRestoreGState( m_cgContext 
); 
1753 void wxMacCoreGraphicsContext::PushState() 
1757     CGContextSaveGState( m_cgContext 
); 
1760 void wxMacCoreGraphicsContext::PopState() 
1764     CGContextRestoreGState( m_cgContext 
); 
1767 void wxMacCoreGraphicsContext::DrawText( const wxString 
&str
, wxDouble x
, wxDouble y 
) 
1769     if ( m_font
.IsNull() ) 
1773 #if wxMAC_USE_CORE_TEXT 
1774     if ( UMAGetSystemVersion() >= 0x1050 ) 
1776         wxMacCoreGraphicsFontData
* fref 
= (wxMacCoreGraphicsFontData
*)m_font
.GetRefData(); 
1777         wxCFStringRef 
text(str
, wxLocale::GetSystemEncoding() ); 
1778         CTFontRef font 
= fref
->GetCTFont(); 
1779         CGColorRef col 
= fref
->GetColour().GetPixel(); 
1780         CTUnderlineStyle ustyle 
= fref
->GetUnderlined() ? kCTUnderlineStyleSingle 
: kCTUnderlineStyleNone 
; 
1781         wxCFRef
<CFNumberRef
> underlined( CFNumberCreate(NULL
, kCFNumberSInt32Type
, &ustyle
) );  
1782          CFStringRef keys
[] = { kCTFontAttributeName 
, kCTForegroundColorAttributeName
, kCTUnderlineStyleAttributeName 
}; 
1783         CFTypeRef values
[] = { font
, col
, underlined 
}; 
1784         wxCFRef
<CFDictionaryRef
> attributes( CFDictionaryCreate(kCFAllocatorDefault
, (const void**) &keys
, (const void**) &values
,  
1785                                                         WXSIZEOF( keys 
), &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
) ); 
1786         wxCFRef
<CFAttributedStringRef
> attrtext( CFAttributedStringCreate(kCFAllocatorDefault
, text
, attributes
) ); 
1787         wxCFRef
<CTLineRef
> line( CTLineCreateWithAttributedString(attrtext
) ); 
1789         y 
+= CTFontGetAscent(font
); 
1791         CGContextSaveGState(m_cgContext
); 
1792         CGContextTranslateCTM(m_cgContext
, x
, y
); 
1793         CGContextScaleCTM(m_cgContext
, 1, -1); 
1794         CGContextSetTextPosition(m_cgContext
, 0, 0); 
1795         CTLineDraw( line
, m_cgContext 
); 
1796         CGContextRestoreGState(m_cgContext
); 
1800 #if wxMAC_USE_ATSU_TEXT 
1802         DrawText(str
, x
, y
, 0.0); 
1806 #if wxMAC_USE_CG_TEXT 
1807     // TODO core graphics text implementation here 
1811 void wxMacCoreGraphicsContext::DrawText( const wxString 
&str
, wxDouble x
, wxDouble y
, wxDouble angle 
) 
1813     if ( m_font
.IsNull() ) 
1817 #if wxMAC_USE_CORE_TEXT 
1818     if ( UMAGetSystemVersion() >= 0x1050 ) 
1820         // default implementation takes care of rotation and calls non rotated DrawText afterwards 
1821         wxGraphicsContext::DrawText( str
, x
, y
, angle 
); 
1825 #if wxMAC_USE_ATSU_TEXT 
1827         OSStatus status 
= noErr
; 
1828         ATSUTextLayout atsuLayout
; 
1829         wxMacUniCharBuffer 
unibuf( str 
); 
1830         UniCharCount chars 
= unibuf
.GetChars(); 
1832         ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
1833         status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1834                                                    &chars 
, &style 
, &atsuLayout 
); 
1836         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the rotated text") ); 
1838         status 
= ::ATSUSetTransientFontMatching( atsuLayout 
, true ); 
1839         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't setup transient font matching") ); 
1841         int iAngle 
= int( angle 
* RAD2DEG 
); 
1842         if ( abs(iAngle
) > 0 ) 
1844             Fixed atsuAngle 
= IntToFixed( iAngle 
); 
1845             ATSUAttributeTag atsuTags
[] = 
1847                 kATSULineRotationTag 
, 
1849             ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1853             ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1857             status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
), 
1858                                              atsuTags
, atsuSizes
, atsuValues 
); 
1862             ATSUAttributeTag atsuTags
[] = 
1866             ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1868                 sizeof( CGContextRef 
) , 
1870             ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
1874             status 
= ::ATSUSetLayoutControls(atsuLayout 
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
), 
1875                                              atsuTags
, atsuSizes
, atsuValues 
); 
1878         ATSUTextMeasurement textBefore
, textAfter
; 
1879         ATSUTextMeasurement ascent
, descent
; 
1881         status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1882                                             &textBefore 
, &textAfter
, &ascent 
, &descent 
); 
1884         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1887         x 
+= (int)(sin(angle
) * FixedToInt(ascent
)); 
1888         y 
+= (int)(cos(angle
) * FixedToInt(ascent
)); 
1890         status 
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1891                                         IntToFixed(x
) , IntToFixed(y
) , &rect 
); 
1892         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't measure the rotated text") ); 
1894         CGContextSaveGState(m_cgContext
); 
1895         CGContextTranslateCTM(m_cgContext
, x
, y
); 
1896         CGContextScaleCTM(m_cgContext
, 1, -1); 
1897         status 
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1898                                 IntToFixed(0) , IntToFixed(0) ); 
1900         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't draw the rotated text") ); 
1902         CGContextRestoreGState(m_cgContext
); 
1904         ::ATSUDisposeTextLayout(atsuLayout
); 
1909 #if wxMAC_USE_CG_TEXT 
1910     // default implementation takes care of rotation and calls non rotated DrawText afterwards 
1911     wxGraphicsContext::DrawText( str
, x
, y
, angle 
); 
1915 void wxMacCoreGraphicsContext::GetTextExtent( const wxString 
&str
, wxDouble 
*width
, wxDouble 
*height
, 
1916                             wxDouble 
*descent
, wxDouble 
*externalLeading 
) const 
1918     wxCHECK_RET( !m_font
.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ); 
1926     if ( externalLeading 
) 
1927         *externalLeading 
= 0; 
1932 #if wxMAC_USE_CORE_TEXT 
1933     if ( UMAGetSystemVersion() >= 0x1050 ) 
1935         wxMacCoreGraphicsFontData
* fref 
= (wxMacCoreGraphicsFontData
*)m_font
.GetRefData(); 
1936         CTFontRef font 
= fref
->GetCTFont(); 
1938         wxCFStringRef 
text(str
, wxLocale::GetSystemEncoding() ); 
1939         CFStringRef keys
[] = { kCTFontAttributeName  
}; 
1940         CFTypeRef values
[] = { font 
}; 
1941         wxCFRef
<CFDictionaryRef
> attributes( CFDictionaryCreate(kCFAllocatorDefault
, (const void**) &keys
, (const void**) &values
,  
1942                                                                 WXSIZEOF( keys 
), &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
) ); 
1943         wxCFRef
<CFAttributedStringRef
> attrtext( CFAttributedStringCreate(kCFAllocatorDefault
, text
, attributes
) ); 
1944         wxCFRef
<CTLineRef
> line( CTLineCreateWithAttributedString(attrtext
) ); 
1948         w 
= CTLineGetTypographicBounds(line
, &a
, &d
, &l
) ; 
1954         if ( externalLeading 
) 
1955             *externalLeading 
= l
; 
1961 #if wxMAC_USE_ATSU_TEXT 
1963         OSStatus status 
= noErr
; 
1965         ATSUTextLayout atsuLayout
; 
1966         wxMacUniCharBuffer 
unibuf( str 
); 
1967         UniCharCount chars 
= unibuf
.GetChars(); 
1969         ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
1970         status 
= ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
1971                                                    &chars 
, &style 
, &atsuLayout 
); 
1973         wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create the layout of the text") ); 
1975         ATSUTextMeasurement textBefore
, textAfter
; 
1976         ATSUTextMeasurement textAscent
, textDescent
; 
1978         status 
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
, 
1979                                             &textBefore 
, &textAfter
, &textAscent 
, &textDescent 
); 
1982             *height 
= FixedToInt(textAscent 
+ textDescent
); 
1984             *descent 
= FixedToInt(textDescent
); 
1985         if ( externalLeading 
) 
1986             *externalLeading 
= 0; 
1988             *width 
= FixedToInt(textAfter 
- textBefore
); 
1990         ::ATSUDisposeTextLayout(atsuLayout
); 
1995 #if wxMAC_USE_CG_TEXT 
1996     // TODO core graphics text implementation here 
2000 void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString
& text
, wxArrayDouble
& widths
) const 
2003     widths
.Add(0, text
.length()); 
2008 #if wxMAC_USE_CORE_TEXT 
2010         wxMacCoreGraphicsFontData
* fref 
= (wxMacCoreGraphicsFontData
*)m_font
.GetRefData(); 
2011         CTFontRef font 
= fref
->GetCTFont(); 
2013         wxCFStringRef 
t(text
, wxLocale::GetSystemEncoding() ); 
2014         CFStringRef keys
[] = { kCTFontAttributeName  
}; 
2015         CFTypeRef values
[] = { font 
}; 
2016         wxCFRef
<CFDictionaryRef
> attributes( CFDictionaryCreate(kCFAllocatorDefault
, (const void**) &keys
, (const void**) &values
,  
2017                                                                 WXSIZEOF( keys 
), &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
) ); 
2018         wxCFRef
<CFAttributedStringRef
> attrtext( CFAttributedStringCreate(kCFAllocatorDefault
, t
, attributes
) ); 
2019         wxCFRef
<CTLineRef
> line( CTLineCreateWithAttributedString(attrtext
) ); 
2021         int chars 
= text
.length(); 
2022         for ( int pos 
= 0; pos 
< (int)chars
; pos 
++ ) 
2024             widths
[pos
] = CTLineGetOffsetForStringIndex( line
, pos
+1 , NULL 
)+0.5; 
2030 #if wxMAC_USE_ATSU_TEXT 
2032         ATSUTextLayout atsuLayout
; 
2033         wxMacUniCharBuffer 
unibuf( text 
); 
2034         UniCharCount chars 
= unibuf
.GetChars(); 
2036         ATSUStyle style 
= (((wxMacCoreGraphicsFontData
*)m_font
.GetRefData())->GetATSUStyle()); 
2037         ::ATSUCreateTextLayoutWithTextPtr( unibuf
.GetBuffer() , 0 , chars 
, chars 
, 1 , 
2038                                           &chars 
, &style 
, &atsuLayout 
); 
2040         for ( int pos 
= 0; pos 
< (int)chars
; pos 
++ ) 
2042             unsigned long actualNumberOfBounds 
= 0; 
2043             ATSTrapezoid glyphBounds
; 
2045             // We get a single bound, since the text should only require one. If it requires more, there is an issue 
2047             result 
= ATSUGetGlyphBounds( atsuLayout
, 0, 0, kATSUFromTextBeginning
, pos 
+ 1, 
2048                                         kATSUseDeviceOrigins
, 1, &glyphBounds
, &actualNumberOfBounds 
); 
2049             if (result 
!= noErr 
|| actualNumberOfBounds 
!= 1 ) 
2052             widths
[pos
] = FixedToInt( glyphBounds
.upperRight
.x 
- glyphBounds
.upperLeft
.x 
); 
2053             //unsigned char uch = s[i]; 
2056         ::ATSUDisposeTextLayout(atsuLayout
); 
2059 #if wxMAC_USE_CG_TEXT 
2060     // TODO core graphics text implementation here 
2064 void * wxMacCoreGraphicsContext::GetNativeContext() 
2069 // concatenates this transform with the current transform of this context 
2070 void wxMacCoreGraphicsContext::ConcatTransform( const wxGraphicsMatrix
& matrix 
) 
2073         CGContextConcatCTM( m_cgContext
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
2075         m_windowTransform 
= CGAffineTransformConcat(m_windowTransform
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
2078 // sets the transform of this context 
2079 void wxMacCoreGraphicsContext::SetTransform( const wxGraphicsMatrix
& matrix 
) 
2083         CGAffineTransform transform 
= CGContextGetCTM( m_cgContext 
); 
2084         transform 
= CGAffineTransformInvert( transform 
) ; 
2085         CGContextConcatCTM( m_cgContext
, transform
); 
2086         CGContextConcatCTM( m_cgContext
, *(CGAffineTransform
*) matrix
.GetNativeMatrix()); 
2090         m_windowTransform 
= *(CGAffineTransform
*) matrix
.GetNativeMatrix(); 
2094 // gets the matrix of this context 
2095 wxGraphicsMatrix 
wxMacCoreGraphicsContext::GetTransform() const 
2097     wxGraphicsMatrix m 
= CreateMatrix(); 
2098     *((CGAffineTransform
*) m
.GetNativeMatrix()) = ( m_cgContext 
== NULL 
? m_windowTransform 
: 
2099         CGContextGetCTM( m_cgContext 
)); 
2107 //----------------------------------------------------------------------------- 
2108 // wxMacCoreGraphicsRenderer declaration 
2109 //----------------------------------------------------------------------------- 
2111 class WXDLLIMPEXP_CORE wxMacCoreGraphicsRenderer 
: public wxGraphicsRenderer
 
2114     wxMacCoreGraphicsRenderer() {} 
2116     virtual ~wxMacCoreGraphicsRenderer() {} 
2120     virtual wxGraphicsContext 
* CreateContext( const wxWindowDC
& dc
); 
2121     virtual wxGraphicsContext 
* CreateContext( const wxMemoryDC
& dc
); 
2123     virtual wxGraphicsContext 
* CreateContextFromNativeContext( void * context 
); 
2125     virtual wxGraphicsContext 
* CreateContextFromNativeWindow( void * window 
); 
2127     virtual wxGraphicsContext 
* CreateContext( wxWindow
* window 
); 
2129     virtual wxGraphicsContext 
* CreateMeasuringContext(); 
2133     virtual wxGraphicsPath 
CreatePath(); 
2137     virtual wxGraphicsMatrix 
CreateMatrix( wxDouble a
=1.0, wxDouble b
=0.0, wxDouble c
=0.0, wxDouble d
=1.0, 
2138         wxDouble tx
=0.0, wxDouble ty
=0.0); 
2141     virtual wxGraphicsPen 
CreatePen(const wxPen
& pen
) ; 
2143     virtual wxGraphicsBrush 
CreateBrush(const wxBrush
& brush 
) ; 
2145     // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 
2146     virtual wxGraphicsBrush 
CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
2147         const wxColour
&c1
, const wxColour
&c2
) ; 
2149     // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) 
2150     // with radius r and color cColor 
2151     virtual wxGraphicsBrush 
CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
2152         const wxColour 
&oColor
, const wxColour 
&cColor
) ; 
2155     virtual wxGraphicsFont 
CreateFont( const wxFont 
&font 
, const wxColour 
&col 
= *wxBLACK 
) ; 
2158     DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer
) 
2161 //----------------------------------------------------------------------------- 
2162 // wxMacCoreGraphicsRenderer implementation 
2163 //----------------------------------------------------------------------------- 
2165 IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsRenderer
,wxGraphicsRenderer
) 
2167 static wxMacCoreGraphicsRenderer gs_MacCoreGraphicsRenderer
; 
2169 wxGraphicsRenderer
* wxGraphicsRenderer::GetDefaultRenderer() 
2171     return &gs_MacCoreGraphicsRenderer
; 
2174 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC
& dc 
) 
2176     const wxDCImpl
* impl 
= dc
.GetImpl(); 
2177     wxWindowDCImpl 
*win_impl 
= wxDynamicCast( impl
, wxWindowDCImpl 
); 
2179         return new wxMacCoreGraphicsContext( this, 
2180            (CGContextRef
)(win_impl
->GetWindow()->MacGetCGContextRef()) ); 
2185 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC
& dc 
) 
2187     const wxDCImpl
* impl 
= dc
.GetImpl(); 
2188     wxMemoryDCImpl 
*mem_impl 
= wxDynamicCast( impl
, wxMemoryDCImpl 
); 
2190         return new wxMacCoreGraphicsContext( this,  
2191             (CGContextRef
)(mem_impl
->GetGraphicsContext()->GetNativeContext()) ); 
2196 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context 
) 
2198     return new wxMacCoreGraphicsContext(this,(CGContextRef
)context
); 
2202 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( void * window 
) 
2204     return new wxMacCoreGraphicsContext(this,(WindowRef
)window
); 
2207 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateContext( wxWindow
* window 
) 
2209     return new wxMacCoreGraphicsContext(this, window 
); 
2212 wxGraphicsContext 
* wxMacCoreGraphicsRenderer::CreateMeasuringContext() 
2214     return new wxMacCoreGraphicsContext(this); 
2219 wxGraphicsPath 
wxMacCoreGraphicsRenderer::CreatePath() 
2222     m
.SetRefData( new wxMacCoreGraphicsPathData(this)); 
2229 wxGraphicsMatrix 
wxMacCoreGraphicsRenderer::CreateMatrix( wxDouble a
, wxDouble b
, wxDouble c
, wxDouble d
, 
2230     wxDouble tx
, wxDouble ty
) 
2233     wxMacCoreGraphicsMatrixData
* data 
= new wxMacCoreGraphicsMatrixData( this ); 
2234     data
->Set( a
,b
,c
,d
,tx
,ty 
) ; 
2239 wxGraphicsPen 
wxMacCoreGraphicsRenderer::CreatePen(const wxPen
& pen
) 
2241     if ( !pen
.Ok() || pen
.GetStyle() == wxTRANSPARENT 
) 
2242         return wxNullGraphicsPen
; 
2246         p
.SetRefData(new wxMacCoreGraphicsPenData( this, pen 
)); 
2251 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateBrush(const wxBrush
& brush 
) 
2253     if ( !brush
.Ok() || brush
.GetStyle() == wxTRANSPARENT 
) 
2254         return wxNullGraphicsBrush
; 
2258         p
.SetRefData(new wxMacCoreGraphicsBrushData( this, brush 
)); 
2263 // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 
2264 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateLinearGradientBrush( wxDouble x1
, wxDouble y1
, wxDouble x2
, wxDouble y2
, 
2265     const wxColour
&c1
, const wxColour
&c2
) 
2268     wxMacCoreGraphicsBrushData
* d 
= new wxMacCoreGraphicsBrushData( this ); 
2269     d
->CreateLinearGradientBrush(x1
, y1
, x2
, y2
, c1
, c2
); 
2274 // sets the brush to a radial gradient originating at (xo,yc) with color oColor and ends on a circle around (xc,yc) 
2275 // with radius r and color cColor 
2276 wxGraphicsBrush 
wxMacCoreGraphicsRenderer::CreateRadialGradientBrush( wxDouble xo
, wxDouble yo
, wxDouble xc
, wxDouble yc
, wxDouble radius
, 
2277     const wxColour 
&oColor
, const wxColour 
&cColor
) 
2280     wxMacCoreGraphicsBrushData
* d 
= new wxMacCoreGraphicsBrushData( this ); 
2281     d
->CreateRadialGradientBrush(xo
,yo
,xc
,yc
,radius
,oColor
,cColor
); 
2287 wxGraphicsFont 
wxMacCoreGraphicsRenderer::CreateFont( const wxFont 
&font 
, const wxColour 
&col 
) 
2292         p
.SetRefData(new wxMacCoreGraphicsFontData( this , font
, col 
)); 
2296         return wxNullGraphicsFont
; 
2300 // CoreGraphics Helper Methods 
2303 // Data Providers and Consumers 
2305 size_t UMAPutBytesCFRefCallback( void *info
, const void *bytes
, size_t count 
) 
2307     CFMutableDataRef data 
= (CFMutableDataRef
) info
; 
2310         CFDataAppendBytes( data
, (const UInt8
*) bytes
, count 
); 
2315 void wxMacReleaseCFDataProviderCallback(void *info
, 
2316                                       const void *WXUNUSED(data
), 
2317                                       size_t WXUNUSED(count
)) 
2320         CFRelease( (CFDataRef
) info 
); 
2323 void wxMacReleaseCFDataConsumerCallback( void *info 
) 
2326         CFRelease( (CFDataRef
) info 
); 
2329 CGDataProviderRef 
wxMacCGDataProviderCreateWithCFData( CFDataRef data 
) 
2334     return CGDataProviderCreateWithCFData( data 
); 
2337 CGDataConsumerRef 
wxMacCGDataConsumerCreateWithCFData( CFMutableDataRef data 
) 
2342     return CGDataConsumerCreateWithCFData( data 
); 
2345 void wxMacReleaseMemoryBufferProviderCallback(void *info
, const void *data
, size_t WXUNUSED(size
)) 
2347     wxMemoryBuffer
* membuf 
= (wxMemoryBuffer
*) info 
; 
2349     wxASSERT( data 
== membuf
->GetData() ) ; 
2354 CGDataProviderRef 
wxMacCGDataProviderCreateWithMemoryBuffer( const wxMemoryBuffer
& buf 
) 
2356     wxMemoryBuffer
* b 
= new wxMemoryBuffer( buf 
); 
2357     if ( b
->GetDataLen() == 0 ) 
2360     return CGDataProviderCreateWithData( b 
, (const void *) b
->GetData() , b
->GetDataLen() , 
2361                                                  wxMacReleaseMemoryBufferProviderCallback 
);