X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c07e1e2c855d4b8b9a138773c7ef7cd5c0b71418..f7d2128f3c89b2d00fbac0d8c9798409ae23b408:/src/mac/carbon/graphics.cpp diff --git a/src/mac/carbon/graphics.cpp b/src/mac/carbon/graphics.cpp index e4b9212d91..708282f7a3 100644 --- a/src/mac/carbon/graphics.cpp +++ b/src/mac/carbon/graphics.cpp @@ -12,6 +12,7 @@ #include "wx/wxprec.h" #include "wx/graphics.h" +#include "wx/private/graphics.h" #ifndef WX_PRECOMP #include "wx/dcclient.h" @@ -22,7 +23,6 @@ #include "wx/icon.h" #endif -#include "wx/mac/uma.h" #ifdef __MSL__ #if __MSL__ >= 0x6000 @@ -33,7 +33,39 @@ #endif #endif -#include "wx/mac/private.h" +#ifdef __WXMAC__ + #include "wx/mac/uma.h" + #include "wx/mac/dcprint.h" +#else + #include "CoreServices/CoreServices.h" + #include "ApplicationServices/ApplicationServices.h" + #include "wx/mac/corefoundation/cfstring.h" + #include "wx/cocoa/dcclient.h" +#endif + +#ifdef __WXCOCOA__ + +CGColorSpaceRef wxMacGetGenericRGBColorSpace() +{ + static wxCFRef genericRGBColorSpace; + + if (genericRGBColorSpace == NULL) + { + genericRGBColorSpace.reset( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) ); + } + + return genericRGBColorSpace; +} + +int UMAGetSystemVersion() +{ + return 0x1050; +} + + +#define wxMAC_USE_CORE_TEXT 1 + +#endif //----------------------------------------------------------------------------- // constants @@ -56,10 +88,10 @@ static const double RAD2DEG = 180.0 / M_PI; OSStatus wxMacDrawCGImage( CGContextRef inContext, - const HIRect * inBounds, - CGImageRef inImage) + const CGRect * inBounds, + CGImageRef inImage) { -#ifdef __LP64__ +#if defined( __LP64__ ) || defined(__WXCOCOA__) // todo flip CGContextDrawImage(inContext, *inBounds, inImage ); return noErr; @@ -68,6 +100,40 @@ OSStatus wxMacDrawCGImage( #endif } +CGColorRef wxMacCreateCGColor( const wxColour& col ) +{ + CGColorRef retval = 0; +#ifdef __WXMAC__ + retval = col.CreateCGColor(); +#else +// TODO add conversion NSColor - CGColorRef (obj-c) +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( CGColorCreateGenericRGB ) + retval = CGColorCreateGenericRGB( col.Red() / 255.0 , col.Green() / 255.0, col.Blue() / 255.0, col.Alpha() / 255.0 ); + else +#endif + { + CGFloat components[4] = { col.Red() / 255.0, col.Green() / 255.0, col.Blue() / 255.0, col.Alpha() / 255.0 } ; + retval = CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ; + } + +#endif + return retval; +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && defined(wxMAC_USE_CORE_TEXT) + +CTFontRef wxMacCreateCTFont( const wxFont& font ) +{ +#ifdef __WXMAC__ + return wxCFRetain((CTFontRef) font.MacGetCTFont()); +#else + return CTFontCreateWithName( wxCFStringRef( font.GetFaceName(), wxLocale::GetSystemEncoding() ) , font.GetPointSize() , NULL ); +#endif +} + +#endif + // CGPattern wrapper class: always allocate on heap, never call destructor class wxMacCoreGraphicsPattern @@ -113,8 +179,9 @@ public : ImagePattern( const wxBitmap* bmp , const CGAffineTransform& transform ) { wxASSERT( bmp && bmp->Ok() ); - +#ifdef __WXMAC__ Init( (CGImageRef) bmp->CreateCGImage() , transform ); +#endif } // ImagePattern takes ownership of CGImageRef passed in @@ -138,7 +205,7 @@ protected : m_image = image; if ( m_image ) { - m_imageBounds = CGRectMake( 0.0, 0.0, (CGFloat)CGImageGetWidth( m_image ), (CGFloat)CGImageGetHeight( m_image ) ); + m_imageBounds = CGRectMake( (CGFloat) 0.0, (CGFloat) 0.0, (CGFloat)CGImageGetWidth( m_image ), (CGFloat)CGImageGetHeight( m_image ) ); m_patternRef = CGPatternCreate( this , m_imageBounds, transform , m_imageBounds.size.width, m_imageBounds.size.height, @@ -162,7 +229,7 @@ public : HatchPattern( int hatchstyle, const CGAffineTransform& transform ) { m_hatch = hatchstyle; - m_imageBounds = CGRectMake( 0.0, 0.0, 8.0 , 8.0 ); + m_imageBounds = CGRectMake( (CGFloat) 0.0, (CGFloat) 0.0, (CGFloat) 8.0 , (CGFloat) 8.0 ); m_patternRef = CGPatternCreate( this , m_imageBounds, transform , m_imageBounds.size.width, m_imageBounds.size.height, @@ -182,7 +249,7 @@ public : { CGPoint pts[] = { - { 8.0 , 0.0 } , { 0.0 , 8.0 } + { (CGFloat) 8.0 , (CGFloat) 0.0 } , { (CGFloat) 0.0 , (CGFloat) 8.0 } }; StrokeLineSegments( ctxRef , pts , 2 ); } @@ -192,8 +259,8 @@ public : { CGPoint pts[] = { - { 0.0 , 0.0 } , { 8.0 , 8.0 } , - { 8.0 , 0.0 } , { 0.0 , 8.0 } + { (CGFloat) 0.0 , (CGFloat) 0.0 } , { (CGFloat) 8.0 , (CGFloat) 8.0 } , + { (CGFloat) 8.0 , (CGFloat) 0.0 } , { (CGFloat) 0.0 , (CGFloat) 8.0 } }; StrokeLineSegments( ctxRef , pts , 4 ); } @@ -203,7 +270,7 @@ public : { CGPoint pts[] = { - { 0.0 , 0.0 } , { 8.0 , 8.0 } + { (CGFloat) 0.0 , (CGFloat) 0.0 } , { (CGFloat) 8.0 , (CGFloat) 8.0 } }; StrokeLineSegments( ctxRef , pts , 2 ); } @@ -213,8 +280,8 @@ public : { CGPoint pts[] = { - { 0.0 , 4.0 } , { 8.0 , 4.0 } , - { 4.0 , 0.0 } , { 4.0 , 8.0 } , + { (CGFloat) 0.0 , (CGFloat) 4.0 } , { (CGFloat) 8.0 , (CGFloat) 4.0 } , + { (CGFloat) 4.0 , (CGFloat) 0.0 } , { (CGFloat) 4.0 , (CGFloat) 8.0 } , }; StrokeLineSegments( ctxRef , pts , 4 ); } @@ -224,7 +291,7 @@ public : { CGPoint pts[] = { - { 0.0 , 4.0 } , { 8.0 , 4.0 } , + { (CGFloat) 0.0 , (CGFloat) 4.0 } , { (CGFloat) 8.0 , (CGFloat) 4.0 } , }; StrokeLineSegments( ctxRef , pts , 2 ); } @@ -234,7 +301,7 @@ public : { CGPoint pts[] = { - { 4.0 , 0.0 } , { 4.0 , 8.0 } , + { (CGFloat) 4.0 , (CGFloat) 0.0 } , { (CGFloat) 4.0 , (CGFloat) 8.0 } , }; StrokeLineSegments( ctxRef , pts , 2 ); } @@ -264,8 +331,8 @@ public: protected : CGLineCap m_cap; - wxMacCFRefHolder m_color; - wxMacCFRefHolder m_colorSpace; + wxCFRef m_color; + wxCFRef m_colorSpace; CGLineJoin m_join; CGFloat m_width; @@ -276,7 +343,7 @@ protected : bool m_isPattern; - wxMacCFRefHolder m_pattern; + wxCFRef m_pattern; CGFloat* m_patternColorComponents; }; @@ -285,14 +352,12 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer { Init(); - CGFloat components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 , - pen.GetColour().Blue() / 255.0 , pen.GetColour().Alpha() / 255.0 } ; - m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ; + m_color.reset( wxMacCreateCGColor( pen.GetColour() ) ) ; // TODO: * m_dc->m_scaleX m_width = pen.GetWidth(); if (m_width <= 0.0) - m_width = 0.1; + m_width = (CGFloat) 0.1; switch ( pen.GetCap() ) { @@ -332,12 +397,12 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer break; } - const CGFloat dashUnit = m_width < 1.0 ? 1.0 : m_width; + const CGFloat dashUnit = m_width < 1.0 ? (CGFloat) 1.0 : m_width; - const CGFloat dotted[] = { dashUnit , dashUnit + 2.0 }; - static const CGFloat short_dashed[] = { 9.0 , 6.0 }; - static const CGFloat dashed[] = { 19.0 , 9.0 }; - static const CGFloat dotted_dashed[] = { 9.0 , 6.0 , 3.0 , 3.0 }; + const CGFloat dotted[] = { (CGFloat) dashUnit , (CGFloat) (dashUnit + 2.0) }; + static const CGFloat short_dashed[] = { (CGFloat) 9.0 , (CGFloat) 6.0 }; + static const CGFloat dashed[] = { (CGFloat) 19.0 , (CGFloat) 9.0 }; + static const CGFloat dotted_dashed[] = { (CGFloat) 9.0 , (CGFloat) 6.0 , (CGFloat) 3.0 , (CGFloat) 3.0 }; switch ( pen.GetStyle() ) { @@ -377,7 +442,7 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer m_userLengths[i] = dashes[i] * dashUnit; if ( i % 2 == 1 && m_userLengths[i] < dashUnit + 2.0 ) - m_userLengths[i] = dashUnit + 2.0; + m_userLengths[i] = (CGFloat) (dashUnit + 2.0); else if ( i % 2 == 0 && m_userLengths[i] < dashUnit ) m_userLengths[i] = dashUnit; } @@ -390,10 +455,10 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer wxBitmap* bmp = pen.GetStipple(); if ( bmp && bmp->Ok() ) { - m_colorSpace.Set( CGColorSpaceCreatePattern( NULL ) ); - m_pattern.Set( *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); + m_colorSpace.reset( CGColorSpaceCreatePattern( NULL ) ); + m_pattern.reset( (CGPatternRef) *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); m_patternColorComponents = new CGFloat[1] ; - m_patternColorComponents[0] = 1.0; + m_patternColorComponents[0] = (CGFloat) 1.0; m_isPattern = true; } } @@ -402,13 +467,13 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer default : { m_isPattern = true; - m_colorSpace.Set( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); - m_pattern.Set( *( new HatchPattern( pen.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); + m_colorSpace.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); + m_pattern.reset( (CGPatternRef) *( new HatchPattern( pen.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); m_patternColorComponents = new CGFloat[4] ; - m_patternColorComponents[0] = pen.GetColour().Red() / 255.0; - m_patternColorComponents[1] = pen.GetColour().Green() / 255.0; - m_patternColorComponents[2] = pen.GetColour().Blue() / 255.0; - m_patternColorComponents[3] = pen.GetColour().Alpha() / 255.0; + m_patternColorComponents[0] = (CGFloat) (pen.GetColour().Red() / 255.0); + m_patternColorComponents[1] = (CGFloat) (pen.GetColour().Green() / 255.0); + m_patternColorComponents[2] = (CGFloat) (pen.GetColour().Blue() / 255.0); + m_patternColorComponents[3] = (CGFloat) (pen.GetColour().Alpha() / 255.0); } break; } @@ -455,7 +520,7 @@ void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context ) { if ( context->GetLogicalFunction() == wxINVERT || context->GetLogicalFunction() == wxXOR ) { - CGContextSetRGBStrokeColor( cg , 1.0, 1.0 , 1.0, 1.0 ); + CGContextSetRGBStrokeColor( cg , (CGFloat) 1.0,(CGFloat) 1.0 , (CGFloat) 1.0, (CGFloat) 1.0 ); } else CGContextSetStrokeColorWithColor( cg , m_color ); @@ -488,15 +553,15 @@ class wxMacCoreGraphicsColour wxMacCoreGraphicsColour(); wxMacCoreGraphicsColour(const wxBrush &brush); ~wxMacCoreGraphicsColour(); - + void Apply( CGContextRef cgContext ); protected: void Init(); - wxMacCFRefHolder m_color; - wxMacCFRefHolder m_colorSpace; - + wxCFRef m_color; + wxCFRef m_colorSpace; + bool m_isPattern; - wxMacCFRefHolder m_pattern; + wxCFRef m_pattern; CGFloat* m_patternColorComponents; } ; @@ -526,7 +591,7 @@ void wxMacCoreGraphicsColour::Apply( CGContextRef cgContext ) } } -wxMacCoreGraphicsColour::wxMacCoreGraphicsColour() +wxMacCoreGraphicsColour::wxMacCoreGraphicsColour() { Init(); } @@ -536,19 +601,19 @@ wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush &brush ) Init(); if ( brush.GetStyle() == wxSOLID ) { - m_color.Set( brush.GetColour().CreateCGColor() ); + m_color.reset( wxMacCreateCGColor( brush.GetColour() )); } else if ( brush.IsHatch() ) { m_isPattern = true; - m_colorSpace.Set( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); - m_pattern.Set( *( new HatchPattern( brush.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); + m_colorSpace.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ); + m_pattern.reset( (CGPatternRef) *( new HatchPattern( brush.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) ); m_patternColorComponents = new CGFloat[4] ; - m_patternColorComponents[0] = brush.GetColour().Red() / 255.0; - m_patternColorComponents[1] = brush.GetColour().Green() / 255.0; - m_patternColorComponents[2] = brush.GetColour().Blue() / 255.0; - m_patternColorComponents[3] = brush.GetColour().Alpha() / 255.0; + m_patternColorComponents[0] = (CGFloat) (brush.GetColour().Red() / 255.0); + m_patternColorComponents[1] = (CGFloat) (brush.GetColour().Green() / 255.0); + m_patternColorComponents[2] = (CGFloat) (brush.GetColour().Blue() / 255.0); + m_patternColorComponents[3] = (CGFloat) (brush.GetColour().Alpha() / 255.0); } else { @@ -558,9 +623,9 @@ wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush &brush ) { m_isPattern = true; m_patternColorComponents = new CGFloat[1] ; - m_patternColorComponents[0] = 1.0; - m_colorSpace.Set( CGColorSpaceCreatePattern( NULL ) ); - m_pattern.Set( *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); + m_patternColorComponents[0] = (CGFloat) 1.0; + m_colorSpace.reset( CGColorSpaceCreatePattern( NULL ) ); + m_pattern.reset( (CGPatternRef) *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) ); } } } @@ -602,7 +667,8 @@ void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDoubl const wxColour&c1, const wxColour&c2 ) { m_gradientFunction = CreateGradientFunction( c1, c2 ); - m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1,y1), CGPointMake(x2,y2), m_gradientFunction, true, true ) ; + m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) x1, (CGFloat) y1), + CGPointMake((CGFloat) x2,(CGFloat) y2), m_gradientFunction, true, true ) ; m_isShading = true ; } @@ -610,7 +676,8 @@ void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDoubl const wxColour &oColor, const wxColour &cColor ) { m_gradientFunction = CreateGradientFunction( oColor, cColor ); - m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo,yo), 0, CGPointMake(xc,yc), radius, m_gradientFunction, true, true ) ; + m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) xo,(CGFloat) yo), 0, + CGPointMake((CGFloat) xc,(CGFloat) yc), (CGFloat) radius, m_gradientFunction, true, true ) ; m_isShading = true ; } @@ -670,14 +737,14 @@ CGFunctionRef wxMacCoreGraphicsBrushData::CreateGradientFunction( const wxColour static const CGFloat input_value_range [2] = { 0, 1 }; static const CGFloat output_value_ranges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; m_gradientComponents = new CGFloat[8] ; - m_gradientComponents[0] = c1.Red() / 255.0; - m_gradientComponents[1] = c1.Green() / 255.0; - m_gradientComponents[2] = c1.Blue() / 255.0; - m_gradientComponents[3] = c1.Alpha() / 255.0; - m_gradientComponents[4] = c2.Red() / 255.0; - m_gradientComponents[5] = c2.Green() / 255.0; - m_gradientComponents[6] = c2.Blue() / 255.0; - m_gradientComponents[7] = c2.Alpha() / 255.0; + m_gradientComponents[0] = (CGFloat) (c1.Red() / 255.0); + m_gradientComponents[1] = (CGFloat) (c1.Green() / 255.0); + m_gradientComponents[2] = (CGFloat) (c1.Blue() / 255.0); + m_gradientComponents[3] = (CGFloat) (c1.Alpha() / 255.0); + m_gradientComponents[4] = (CGFloat) (c2.Red() / 255.0); + m_gradientComponents[5] = (CGFloat) (c2.Green() / 255.0); + m_gradientComponents[6] = (CGFloat) (c2.Blue() / 255.0); + m_gradientComponents[7] = (CGFloat) (c2.Alpha() / 255.0); return CGFunctionCreate ( m_gradientComponents, 1, input_value_range, @@ -703,7 +770,7 @@ public: CTFontRef GetCTFont() const { return m_ctFont ; } #endif wxColour GetColour() const { return m_colour ; } - + bool GetUnderlined() const { return m_underlined ; } private : wxColour m_colour; @@ -718,15 +785,15 @@ private : wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col) : wxGraphicsObjectRefData( renderer ) { - m_macATSUIStyle = NULL; - OSStatus status = noErr; m_colour = col; m_underlined = font.GetUnderlined(); #if wxMAC_USE_CORE_TEXT - m_ctFont.reset( wxCFRetain((CTFontRef) font.MacGetCTFont()) ); + m_ctFont.reset( wxMacCreateCTFont( font ) ); #endif #if wxMAC_USE_ATSU_TEXT + OSStatus status = noErr; + m_macATSUIStyle = NULL; status = ATSUCreateAndCopyStyle( (ATSUStyle) font.MacGetATSUStyle() , &m_macATSUIStyle ); @@ -759,7 +826,7 @@ wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* rendere wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT #endif } @@ -774,10 +841,33 @@ wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData() m_macATSUIStyle = NULL; } #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT #endif } +class wxMacCoreGraphicsBitmapData : public wxGraphicsObjectRefData +{ +public: + wxMacCoreGraphicsBitmapData( wxGraphicsRenderer* renderer, CGImageRef bitmap, bool monochrome ); + ~wxMacCoreGraphicsBitmapData(); + + virtual CGImageRef GetBitmap() { return m_bitmap; } + bool IsMonochrome() { return m_monochrome; } +private : + CGImageRef m_bitmap; + bool m_monochrome; +}; + +wxMacCoreGraphicsBitmapData::wxMacCoreGraphicsBitmapData( wxGraphicsRenderer* renderer, CGImageRef bitmap, bool monochrome ) : wxGraphicsObjectRefData( renderer ), + m_bitmap(bitmap), m_monochrome(monochrome) +{ +} + +wxMacCoreGraphicsBitmapData::~wxMacCoreGraphicsBitmapData() +{ + CGImageRelease( m_bitmap ); +} + // // Graphics Matrix // @@ -805,7 +895,7 @@ public : // gets the component valuess of the matrix virtual void Get(wxDouble* a=NULL, wxDouble* b=NULL, wxDouble* c=NULL, wxDouble* d=NULL, wxDouble* tx=NULL, wxDouble* ty=NULL) const; - + // makes this the inverse matrix virtual void Invert(); @@ -874,7 +964,7 @@ void wxMacCoreGraphicsMatrixData::Concat( const wxGraphicsMatrixData *t ) void wxMacCoreGraphicsMatrixData::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d, wxDouble tx, wxDouble ty) { - m_matrix = CGAffineTransformMake(a,b,c,d,tx,ty); + m_matrix = CGAffineTransformMake((CGFloat) a,(CGFloat) b,(CGFloat) c,(CGFloat) d,(CGFloat) tx,(CGFloat) ty); } // gets the component valuess of the matrix @@ -915,19 +1005,19 @@ bool wxMacCoreGraphicsMatrixData::IsIdentity() const // add the translation to this matrix void wxMacCoreGraphicsMatrixData::Translate( wxDouble dx , wxDouble dy ) { - m_matrix = CGAffineTransformTranslate( m_matrix, dx, dy); + m_matrix = CGAffineTransformTranslate( m_matrix, (CGFloat) dx, (CGFloat) dy); } // add the scale to this matrix void wxMacCoreGraphicsMatrixData::Scale( wxDouble xScale , wxDouble yScale ) { - m_matrix = CGAffineTransformScale( m_matrix, xScale, yScale); + m_matrix = CGAffineTransformScale( m_matrix, (CGFloat) xScale, (CGFloat) yScale); } // add the rotation to this matrix (radians) void wxMacCoreGraphicsMatrixData::Rotate( wxDouble angle ) { - m_matrix = CGAffineTransformRotate( m_matrix, angle); + m_matrix = CGAffineTransformRotate( m_matrix, (CGFloat) angle); } // @@ -937,7 +1027,7 @@ void wxMacCoreGraphicsMatrixData::Rotate( wxDouble angle ) // applies that matrix to the point void wxMacCoreGraphicsMatrixData::TransformPoint( wxDouble *x, wxDouble *y ) const { - CGPoint pt = CGPointApplyAffineTransform( CGPointMake(*x,*y), m_matrix); + CGPoint pt = CGPointApplyAffineTransform( CGPointMake((CGFloat) *x,(CGFloat) *y), m_matrix); *x = pt.x; *y = pt.y; @@ -946,7 +1036,7 @@ void wxMacCoreGraphicsMatrixData::TransformPoint( wxDouble *x, wxDouble *y ) con // applies the matrix except for translations void wxMacCoreGraphicsMatrixData::TransformDistance( wxDouble *dx, wxDouble *dy ) const { - CGSize sz = CGSizeApplyAffineTransform( CGSizeMake(*dx,*dy) , m_matrix ); + CGSize sz = CGSizeApplyAffineTransform( CGSizeMake((CGFloat) *dx,(CGFloat) *dy) , m_matrix ); *dx = sz.width; *dy = sz.height; } @@ -1056,45 +1146,45 @@ wxGraphicsObjectRefData* wxMacCoreGraphicsPathData::Clone() const // opens (starts) a new subpath void wxMacCoreGraphicsPathData::MoveToPoint( wxDouble x1 , wxDouble y1 ) { - CGPathMoveToPoint( m_path , NULL , x1 , y1 ); + CGPathMoveToPoint( m_path , NULL , (CGFloat) x1 , (CGFloat) y1 ); } void wxMacCoreGraphicsPathData::AddLineToPoint( wxDouble x1 , wxDouble y1 ) { - CGPathAddLineToPoint( m_path , NULL , x1 , y1 ); + CGPathAddLineToPoint( m_path , NULL , (CGFloat) x1 , (CGFloat) y1 ); } void wxMacCoreGraphicsPathData::AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y ) { - CGPathAddCurveToPoint( m_path , NULL , cx1 , cy1 , cx2, cy2, x , y ); + CGPathAddCurveToPoint( m_path , NULL , (CGFloat) cx1 , (CGFloat) cy1 , (CGFloat) cx2, (CGFloat) cy2, (CGFloat) x , (CGFloat) y ); } void wxMacCoreGraphicsPathData::AddQuadCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble x, wxDouble y ) { - CGPathAddQuadCurveToPoint( m_path , NULL , cx1 , cy1 , x , y ); + CGPathAddQuadCurveToPoint( m_path , NULL , (CGFloat) cx1 , (CGFloat) cy1 , (CGFloat) x , (CGFloat) y ); } void wxMacCoreGraphicsPathData::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - CGRect cgRect = { { x , y } , { w , h } }; + CGRect cgRect = { { (CGFloat) x , (CGFloat) y } , { (CGFloat) w , (CGFloat) h } }; CGPathAddRect( m_path , NULL , cgRect ); } void wxMacCoreGraphicsPathData::AddCircle( wxDouble x, wxDouble y , wxDouble r ) { - CGPathAddArc( m_path , NULL , x , y , r , 0.0 , 2 * M_PI , true ); + CGPathAddArc( m_path , NULL , (CGFloat) x , (CGFloat) y , (CGFloat) r , (CGFloat) 0.0 , (CGFloat) (2 * M_PI) , true ); } // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle void wxMacCoreGraphicsPathData::AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise ) { // inverse direction as we the 'normal' state is a y axis pointing down, ie mirrored to the standard core graphics setup - CGPathAddArc( m_path, NULL , x, y, r, startAngle, endAngle, !clockwise); + CGPathAddArc( m_path, NULL , (CGFloat) x, (CGFloat) y, (CGFloat) r, (CGFloat) startAngle, (CGFloat) endAngle, !clockwise); } void wxMacCoreGraphicsPathData::AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r ) { - CGPathAddArcToPoint( m_path, NULL , x1, y1, x2, y2, r); + CGPathAddArcToPoint( m_path, NULL , (CGFloat) x1, (CGFloat) y1, (CGFloat) x2, (CGFloat) y2, (CGFloat) r); } void wxMacCoreGraphicsPathData::AddPath( const wxGraphicsPathData* path ) @@ -1137,7 +1227,7 @@ void wxMacCoreGraphicsPathData::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wx bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, int fillStyle) const { - return CGPathContainsPoint( m_path, NULL, CGPointMake(x,y), fillStyle == wxODDEVEN_RULE ); + return CGPathContainsPoint( m_path, NULL, CGPointMake((CGFloat) x,(CGFloat) y), fillStyle == wxODDEVEN_RULE ); } // @@ -1169,7 +1259,7 @@ public: virtual void GetSize( wxDouble* width, wxDouble* height); virtual void StartPage( wxDouble width, wxDouble height ); - + virtual void EndPage(); virtual void Flush(); @@ -1227,7 +1317,7 @@ public: virtual void DrawPath( const wxGraphicsPath &path, int fillStyle = wxODDEVEN_RULE ); virtual bool ShouldOffset() const - { + { int penwidth = 0 ; if ( !m_pen.IsNull() ) { @@ -1256,6 +1346,8 @@ public: virtual void DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); + virtual void DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); + virtual void DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ); void SetNativeContext( CGContextRef cg ); @@ -1273,7 +1365,7 @@ private: wxDouble m_width; wxDouble m_height; - wxMacCFRefHolder m_clipRgn; + wxCFRef m_clipRgn; }; //----------------------------------------------------------------------------- @@ -1302,12 +1394,12 @@ public : m_cg = cg; m_offset = offset; if ( m_offset ) - CGContextTranslateCTM( m_cg, 0.5, 0.5 ); + CGContextTranslateCTM( m_cg, (CGFloat) 0.5, (CGFloat) 0.5 ); } ~wxQuartzOffsetHelper( ) { if ( m_offset ) - CGContextTranslateCTM( m_cg, -0.5, -0.5 ); + CGContextTranslateCTM( m_cg, (CGFloat) -0.5, (CGFloat) -0.5 ); } public : CGContextRef m_cg; @@ -1321,9 +1413,8 @@ void wxMacCoreGraphicsContext::Init() m_windowRef = NULL; m_width = 0; m_height = 0; - - HIRect r = CGRectMake(0,0,0,0); - m_clipRgn.Set(HIShapeCreateWithRect(&r)); + CGRect r = CGRectMake(0,0,0,0); + m_clipRgn.reset(HIShapeCreateWithRect(&r)); } wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer) @@ -1343,14 +1434,15 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer) { Init(); - m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef(); + int originX , originY; originX = originY = 0; - window->MacWindowToRootWindow( &originX , &originY ); Rect bounds = { 0,0,0,0 }; -#ifdef __LP64__ +#if defined( __LP64__ ) || defined(__WXCOCOA__) #else + m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef(); + window->MacWindowToRootWindow( &originX , &originY ); GetWindowBounds( m_windowRef, kWindowContentRgn, &bounds ); #endif m_windowTransform = CGAffineTransformMakeTranslation( 0 , bounds.bottom - bounds.top ); @@ -1385,15 +1477,15 @@ void wxMacCoreGraphicsContext::StartPage( wxDouble width, wxDouble height ) { CGRect r; if ( width != 0 && height != 0) - r = CGRectMake( 0 , 0 , width , height ); + r = CGRectMake( (CGFloat) 0.0 , (CGFloat) 0.0 , (CGFloat) width , (CGFloat) height ); else - r = CGRectMake( 0 , 0 , m_width , m_height ); - + r = CGRectMake( (CGFloat) 0.0 , (CGFloat) 0.0 , (CGFloat) m_width , (CGFloat) m_height ); + CGContextBeginPage(m_cgContext, &r ); // CGContextTranslateCTM( m_cgContext , 0 , height == 0 ? m_height : height ); // CGContextScaleCTM( m_cgContext , 1 , -1 ); } - + void wxMacCoreGraphicsContext::EndPage() { CGContextEndPage(m_cgContext); @@ -1408,29 +1500,31 @@ void wxMacCoreGraphicsContext::EnsureIsValid() { if ( !m_cgContext ) { - OSStatus status = -#ifndef __LP64__ + OSStatus status = +#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) ) QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); #else paramErr; #endif - wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ); + if ( status != noErr ) + { + wxFAIL_MSG("Cannot nest wxDCs on the same window"); + } CGContextConcatCTM( m_cgContext, m_windowTransform ); - CGContextSaveGState( m_cgContext ); - m_releaseContext = true; - if ( !HIShapeIsEmpty(m_clipRgn) ) - { + CGContextSaveGState( m_cgContext ); + m_releaseContext = true; + if ( !HIShapeIsEmpty(m_clipRgn) ) + { // the clip region is in device coordinates, so we convert this again to user coordinates - wxMacCFRefHolder hishape ; - hishape.Set( HIShapeCreateMutableCopy( m_clipRgn ) ); + wxCFRef hishape( HIShapeCreateMutableCopy( m_clipRgn ) ); CGPoint transformedOrigin = CGPointApplyAffineTransform( CGPointZero,m_windowTransform); HIShapeOffset( hishape, -transformedOrigin.x, -transformedOrigin.y ); - HIShapeReplacePathInCGContext( hishape, m_cgContext ); - CGContextClip( m_cgContext ); - } - CGContextSaveGState( m_cgContext ); - } + HIShapeReplacePathInCGContext( hishape, m_cgContext ); + CGContextClip( m_cgContext ); + } + CGContextSaveGState( m_cgContext ); + } } // TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes) @@ -1441,29 +1535,61 @@ bool wxMacCoreGraphicsContext::SetLogicalFunction( int function ) return true; EnsureIsValid(); - + bool retval = false; + bool shouldAntiAlias = true; + CGBlendMode mode = kCGBlendModeNormal; - if ( function == wxCOPY ) +#if defined(__WXMAC__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ) + if ( UMAGetSystemVersion() >= 0x1050 ) { retval = true; - CGContextSetBlendMode( m_cgContext, kCGBlendModeNormal ); + switch ( function ) + { + // TODO find best corresponding porter duff modes + case wxCOPY : + mode = kCGBlendModeCopy; + break; + case wxCLEAR : + mode = kCGBlendModeClear; + break; + case wxXOR : + mode = kCGBlendModeXOR; + shouldAntiAlias = false; + break; + default : + retval = false; + break; + } } - else if ( function == wxINVERT || function == wxXOR ) + else +#endif { - // change color to white - CGContextSetBlendMode( m_cgContext, kCGBlendModeExclusion ); - CGContextSetShouldAntialias( m_cgContext, false ); - retval = true; + if ( function == wxCOPY ) + { + retval = true; + } + else if ( function == wxINVERT || function == wxXOR ) + { + // change color to white + mode = kCGBlendModeExclusion; + shouldAntiAlias = false; + retval = true; + } } - + if (retval) + { m_logicalFunction = function; + CGContextSetBlendMode( m_cgContext, mode ); + CGContextSetShouldAntialias(m_cgContext, shouldAntiAlias); + } return retval ; } void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion ) { +#ifdef __WXMAC__ if( m_cgContext ) { HIShapeReplacePathInCGContext( region.GetWXHRGN() , m_cgContext ); @@ -1474,27 +1600,28 @@ void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion ) // this offsetting to device coords is not really correct, but since we cannot apply affine transforms // to regions we try at least to have correct translations HIMutableShapeRef mutableShape = HIShapeCreateMutableCopy( region.GetWXHRGN() ); - + CGPoint transformedOrigin = CGPointApplyAffineTransform( CGPointZero, m_windowTransform ); HIShapeOffset( mutableShape, transformedOrigin.x, transformedOrigin.y ); - m_clipRgn.Set(mutableShape); + m_clipRgn.reset(mutableShape); } +#endif } // clips drawings to the rect void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - HIRect r = CGRectMake( x , y , w , h ); + CGRect r = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h ); if ( m_cgContext ) { CGContextClipToRect( m_cgContext, r ); } else { - // the clipping itself must be stored as device coordinates, otherwise + // the clipping itself must be stored as device coordinates, otherwise // we cannot apply it back correctly r.origin= CGPointApplyAffineTransform( r.origin, m_windowTransform ); - m_clipRgn.Set(HIShapeCreateWithRect(&r)); + m_clipRgn.reset(HIShapeCreateWithRect(&r)); } } @@ -1515,8 +1642,8 @@ void wxMacCoreGraphicsContext::ResetClip() } else { - HIRect r = CGRectMake(0,0,0,0); - m_clipRgn.Set(HIShapeCreateWithRect(&r)); + CGRect r = CGRectMake(0,0,0,0); + m_clipRgn.reset(HIShapeCreateWithRect(&r)); } } @@ -1621,7 +1748,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) CGContextRestoreGState( m_cgContext ); if ( m_releaseContext ) { -#ifndef __LP64__ +#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) ) QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext); #endif } @@ -1643,6 +1770,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) { CGContextRetain(m_cgContext); CGContextSaveGState( m_cgContext ); + CGContextSetTextMatrix( m_cgContext, CGAffineTransformIdentity ); CGContextSaveGState( m_cgContext ); m_releaseContext = false; } @@ -1651,34 +1779,41 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) void wxMacCoreGraphicsContext::Translate( wxDouble dx , wxDouble dy ) { if ( m_cgContext ) - CGContextTranslateCTM( m_cgContext, dx, dy ); + CGContextTranslateCTM( m_cgContext, (CGFloat) dx, (CGFloat) dy ); else - m_windowTransform = CGAffineTransformTranslate(m_windowTransform,dx,dy); + m_windowTransform = CGAffineTransformTranslate(m_windowTransform, (CGFloat) dx, (CGFloat) dy); } void wxMacCoreGraphicsContext::Scale( wxDouble xScale , wxDouble yScale ) { if ( m_cgContext ) - CGContextScaleCTM( m_cgContext , xScale , yScale ); + CGContextScaleCTM( m_cgContext , (CGFloat) xScale , (CGFloat) yScale ); else - m_windowTransform = CGAffineTransformScale(m_windowTransform,xScale,yScale); + m_windowTransform = CGAffineTransformScale(m_windowTransform, (CGFloat) xScale, (CGFloat) yScale); } void wxMacCoreGraphicsContext::Rotate( wxDouble angle ) { if ( m_cgContext ) - CGContextRotateCTM( m_cgContext , angle ); + CGContextRotateCTM( m_cgContext , (CGFloat) angle ); else - m_windowTransform = CGAffineTransformRotate(m_windowTransform,angle); + m_windowTransform = CGAffineTransformRotate(m_windowTransform, (CGFloat) angle); } void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - EnsureIsValid(); + wxGraphicsBitmap bitmap = GetRenderer()->CreateBitmap(bmp); + DrawBitmap(bitmap, x, y, w, h); +} - CGImageRef image = (CGImageRef)( bmp.CreateCGImage() ); - HIRect r = CGRectMake( x , y , w , h ); - if ( bmp.GetDepth() == 1 ) +void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + EnsureIsValid(); +#ifdef __WXMAC__ + wxMacCoreGraphicsBitmapData* refdata =static_cast(bmp.GetRefData()); + CGImageRef image = refdata->GetBitmap(); + CGRect r = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h ); + if ( refdata->IsMonochrome() == 1 ) { // is is a mask, the '1' in the mask tell where to draw the current brush if ( !m_brush.IsNull() ) @@ -1705,19 +1840,21 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDo { wxMacDrawCGImage( m_cgContext , &r , image ); } - CGImageRelease( image ); +#endif } void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { EnsureIsValid(); - CGRect r = CGRectMake( 00 , 00 , w , h ); + CGRect r = CGRectMake( (CGFloat) 0.0 , (CGFloat) 0.0 , (CGFloat) w , (CGFloat) h ); CGContextSaveGState( m_cgContext ); - CGContextTranslateCTM( m_cgContext, x , y + h ); + CGContextTranslateCTM( m_cgContext,(CGFloat) x ,(CGFloat) (y + h) ); CGContextScaleCTM( m_cgContext, 1, -1 ); +#ifdef __WXMAC__ PlotIconRefInContext( m_cgContext , &r , kAlignNone , kTransformNone , NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ); +#endif CGContextRestoreGState( m_cgContext ); } @@ -1739,32 +1876,33 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub { if ( m_font.IsNull() ) return; - + EnsureIsValid(); #if wxMAC_USE_CORE_TEXT if ( UMAGetSystemVersion() >= 0x1050 ) { wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData(); - wxMacCFStringHolder text(str, wxLocale::GetSystemEncoding() ); + wxCFStringRef text(str, wxLocale::GetSystemEncoding() ); CTFontRef font = fref->GetCTFont(); - CGColorRef col = fref->GetColour().GetPixel(); + CGColorRef col = wxMacCreateCGColor( fref->GetColour() ); CTUnderlineStyle ustyle = fref->GetUnderlined() ? kCTUnderlineStyleSingle : kCTUnderlineStyleNone ; - wxCFRef underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) ); - CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName, kCTUnderlineStyleAttributeName }; + wxCFRef underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) ); + CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName, kCTUnderlineStyleAttributeName }; CFTypeRef values[] = { font, col, underlined }; - wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, + wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, WXSIZEOF( keys ), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) ); wxCFRef attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) ); wxCFRef line( CTLineCreateWithAttributedString(attrtext) ); - + y += CTFontGetAscent(font); - + CGContextSaveGState(m_cgContext); CGContextTranslateCTM(m_cgContext, x, y); CGContextScaleCTM(m_cgContext, 1, -1); CGContextSetTextPosition(m_cgContext, 0, 0); CTLineDraw( line, m_cgContext ); CGContextRestoreGState(m_cgContext); + CFRelease( col ); return; } #endif @@ -1774,7 +1912,7 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub return; } #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT // TODO core graphics text implementation here #endif } @@ -1797,41 +1935,18 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub { OSStatus status = noErr; ATSUTextLayout atsuLayout; - UniCharCount chars = str.length(); - UniChar* ubuf = NULL; - -#if SIZEOF_WCHAR_T == 4 - wxMBConvUTF16 converter; -#if wxUSE_UNICODE - size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ); -#else - const wxWCharBuffer wchar = str.wc_str( wxConvLocal ); - size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ); -#endif - chars = unicharlen / 2; -#else -#if wxUSE_UNICODE - ubuf = (UniChar*) str.wc_str(); -#else - wxWCharBuffer wchar = str.wc_str( wxConvLocal ); - chars = wxWcslen( wchar.data() ); - ubuf = (UniChar*) wchar.data(); -#endif -#endif - + wxMacUniCharBuffer unibuf( str ); + UniCharCount chars = unibuf.GetChars(); + ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); - status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , + status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); - + wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") ); - + status = ::ATSUSetTransientFontMatching( atsuLayout , true ); wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); - + int iAngle = int( angle * RAD2DEG ); if ( abs(iAngle) > 0 ) { @@ -1851,7 +1966,7 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag), atsuTags, atsuSizes, atsuValues ); } - + { ATSUAttributeTag atsuTags[] = { @@ -1868,42 +1983,39 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag), atsuTags, atsuSizes, atsuValues ); } - + ATSUTextMeasurement textBefore, textAfter; ATSUTextMeasurement ascent, descent; - + status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &ascent , &descent ); - + wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); - + Rect rect; x += (int)(sin(angle) * FixedToInt(ascent)); y += (int)(cos(angle) * FixedToInt(ascent)); - + status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(x) , IntToFixed(y) , &rect ); wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") ); - + CGContextSaveGState(m_cgContext); - CGContextTranslateCTM(m_cgContext, x, y); + CGContextTranslateCTM(m_cgContext, (CGFloat) x, (CGFloat) y); CGContextScaleCTM(m_cgContext, 1, -1); status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, IntToFixed(0) , IntToFixed(0) ); - + wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") ); - + CGContextRestoreGState(m_cgContext); - + ::ATSUDisposeTextLayout(atsuLayout); - -#if SIZEOF_WCHAR_T == 4 - free( ubuf ); -#endif + return; } #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT // default implementation takes care of rotation and calls non rotated DrawText afterwards wxGraphicsContext::DrawText( str, x, y, angle ); #endif @@ -1922,7 +2034,7 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid *descent = 0; if ( externalLeading ) *externalLeading = 0; - + if (str.empty()) return; @@ -1932,18 +2044,18 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData(); CTFontRef font = fref->GetCTFont(); - wxMacCFStringHolder text(str, wxLocale::GetSystemEncoding() ); + wxCFStringRef text(str, wxLocale::GetSystemEncoding() ); CFStringRef keys[] = { kCTFontAttributeName }; CFTypeRef values[] = { font }; - wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, + wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, WXSIZEOF( keys ), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) ); wxCFRef attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) ); wxCFRef line( CTLineCreateWithAttributedString(attrtext) ); - + CGFloat w, a, d, l; - + w = CTLineGetTypographicBounds(line, &a, &d, &l) ; - + if ( height ) *height = a+d+l; if ( descent ) @@ -1958,46 +2070,26 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid #if wxMAC_USE_ATSU_TEXT { OSStatus status = noErr; - + ATSUTextLayout atsuLayout; - UniCharCount chars = str.length(); - UniChar* ubuf = NULL; - -#if SIZEOF_WCHAR_T == 4 - wxMBConvUTF16 converter; -#if wxUSE_UNICODE - size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ); -#else - const wxWCharBuffer wchar = str.wc_str( wxConvLocal ); - size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ); -#endif - chars = unicharlen / 2; -#else -#if wxUSE_UNICODE - ubuf = (UniChar*) str.wc_str(); -#else - wxWCharBuffer wchar = str.wc_str( wxConvLocal ); - chars = wxWcslen( wchar.data() ); - ubuf = (UniChar*) wchar.data(); -#endif -#endif - + wxMacUniCharBuffer unibuf( str ); + UniCharCount chars = unibuf.GetChars(); + ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); - status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , + status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); - + wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") ); - + + status = ::ATSUSetTransientFontMatching( atsuLayout , true ); + wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); + ATSUTextMeasurement textBefore, textAfter; ATSUTextMeasurement textAscent, textDescent; - + status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd, &textBefore , &textAfter, &textAscent , &textDescent ); - + if ( height ) *height = FixedToInt(textAscent + textDescent); if ( descent ) @@ -2006,15 +2098,13 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid *externalLeading = 0; if ( width ) *width = FixedToInt(textAfter - textBefore); - + ::ATSUDisposeTextLayout(atsuLayout); -#if SIZEOF_WCHAR_T == 4 - free( ubuf ) ; -#endif + return; } #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT // TODO core graphics text implementation here #endif } @@ -2031,80 +2121,86 @@ void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString& text, wxArr { wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData(); CTFontRef font = fref->GetCTFont(); - - wxMacCFStringHolder t(text, wxLocale::GetSystemEncoding() ); + + wxCFStringRef t(text, wxLocale::GetSystemEncoding() ); CFStringRef keys[] = { kCTFontAttributeName }; CFTypeRef values[] = { font }; - wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, + wxCFRef attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values, WXSIZEOF( keys ), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) ); wxCFRef attrtext( CFAttributedStringCreate(kCFAllocatorDefault, t, attributes) ); wxCFRef line( CTLineCreateWithAttributedString(attrtext) ); - + int chars = text.length(); for ( int pos = 0; pos < (int)chars; pos ++ ) { widths[pos] = CTLineGetOffsetForStringIndex( line, pos+1 , NULL )+0.5; } - + return; } #endif #if wxMAC_USE_ATSU_TEXT { + OSStatus status = noErr; ATSUTextLayout atsuLayout; - UniCharCount chars = text.length(); - UniChar* ubuf = NULL; - -#if SIZEOF_WCHAR_T == 4 - wxMBConvUTF16 converter; -#if wxUSE_UNICODE - size_t unicharlen = converter.WC2MB( NULL , text.wc_str() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 ); -#else - const wxWCharBuffer wchar = text.wc_str( wxConvLocal ); - size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ); - ubuf = (UniChar*) malloc( unicharlen + 2 ); - converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ); -#endif - chars = unicharlen / 2; -#else -#if wxUSE_UNICODE - ubuf = (UniChar*) text.wc_str(); -#else - wxWCharBuffer wchar = text.wc_str( wxConvLocal ); - chars = wxWcslen( wchar.data() ); - ubuf = (UniChar*) wchar.data(); -#endif -#endif - + wxMacUniCharBuffer unibuf( text ); + UniCharCount chars = unibuf.GetChars(); + ATSUStyle style = (((wxMacCoreGraphicsFontData*)m_font.GetRefData())->GetATSUStyle()); - ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 , + status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 , &chars , &style , &atsuLayout ); - + + wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") ); + + status = ::ATSUSetTransientFontMatching( atsuLayout , true ); + wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") ); + +// new implementation from JS, keep old one just in case +#if 0 for ( int pos = 0; pos < (int)chars; pos ++ ) { unsigned long actualNumberOfBounds = 0; ATSTrapezoid glyphBounds; - + // We get a single bound, since the text should only require one. If it requires more, there is an issue OSStatus result; result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ); if (result != noErr || actualNumberOfBounds != 1 ) return; - + widths[pos] = FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); //unsigned char uch = s[i]; } +#else + ATSLayoutRecord *layoutRecords = NULL; + ItemCount glyphCount = 0; - ::ATSUDisposeTextLayout(atsuLayout); -#if SIZEOF_WCHAR_T == 4 - free( ubuf ) ; + // Get the glyph extents + OSStatus err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(atsuLayout, + 0, + kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, + (void **) + &layoutRecords, + &glyphCount); + wxASSERT(glyphCount == (text.length()+1)); + + if ( err == noErr && glyphCount == (text.length()+1)) + { + for ( int pos = 1; pos < (int)glyphCount ; pos ++ ) + { + widths[pos-1] = FixedToInt( layoutRecords[pos].realPos ); + } + } + + ::ATSUDirectReleaseLayoutDataArrayPtr(NULL, + kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, + (void **) &layoutRecords); #endif + ::ATSUDisposeTextLayout(atsuLayout); } #endif -#if WXMAC_USE_CG_TEXT +#if wxMAC_USE_CG_TEXT // TODO core graphics text implementation here #endif } @@ -2166,13 +2262,15 @@ public : // Context virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc); + virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc); + virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc); virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ); virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window ); virtual wxGraphicsContext * CreateContext( wxWindow* window ); - + virtual wxGraphicsContext * CreateMeasuringContext(); // Path @@ -2201,6 +2299,11 @@ public : // sets the font virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; + // create a native bitmap representation + virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) ; + + // create a native bitmap representation + virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) ; private : DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsRenderer) } ; @@ -2218,18 +2321,59 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer() return &gs_MacCoreGraphicsRenderer; } -wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc) +#ifdef __WXCOCOA__ +extern CGContextRef wxMacGetContextFromCurrentNSContext() ; +#endif + +wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc ) +{ + const wxDCImpl* impl = dc.GetImpl(); + wxWindowDCImpl *win_impl = wxDynamicCast( impl, wxWindowDCImpl ); + if (win_impl) + { + int w, h; + win_impl->GetSize( &w, &h ); + CGContextRef cgctx = 0; +#ifdef __WXMAC__ + cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef()); +#else + cgctx = wxMacGetContextFromCurrentNSContext() ; +#endif + return new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h ); + } + return NULL; +} + +wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc ) { - wxMemoryDC* mdc = wxDynamicCast(&dc, wxMemoryDC); - if ( mdc ) +#ifdef __WXMAC__ + const wxDCImpl* impl = dc.GetImpl(); + wxMemoryDCImpl *mem_impl = wxDynamicCast( impl, wxMemoryDCImpl ); + if (mem_impl) { - return new wxMacCoreGraphicsContext(this, - (CGContextRef)mdc->GetGraphicsContext()->GetNativeContext()); + int w, h; + mem_impl->GetSize( &w, &h ); + return new wxMacCoreGraphicsContext( this, + (CGContextRef)(mem_impl->GetGraphicsContext()->GetNativeContext()), (wxDouble) w, (wxDouble) h ); } - else +#endif + return NULL; +} + +wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxPrinterDC& dc ) +{ +#ifdef __WXMAC__ + const wxDCImpl* impl = dc.GetImpl(); + wxPrinterDCImpl *print_impl = wxDynamicCast( impl, wxPrinterDCImpl ); + if (print_impl) { - return new wxMacCoreGraphicsContext(this,(CGContextRef)dc.GetWindow()->MacGetCGContextRef() ); + int w, h; + print_impl->GetSize( &w, &h ); + return new wxMacCoreGraphicsContext( this, + (CGContextRef)(print_impl->GetGraphicsContext()->GetNativeContext()), (wxDouble) w, (wxDouble) h ); } +#endif + return NULL; } wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context ) @@ -2299,6 +2443,35 @@ wxGraphicsBrush wxMacCoreGraphicsRenderer::CreateBrush(const wxBrush& brush ) } } +wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmap( const wxBitmap& bmp ) +{ + if ( bmp.Ok() ) + { + wxGraphicsBitmap p; +#ifdef __WXMAC__ + p.SetRefData(new wxMacCoreGraphicsBitmapData( this , bmp.CreateCGImage(), bmp.GetDepth() == 1 ) ); +#endif + return p; + } + else + return wxNullGraphicsBitmap; +} + +wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateSubBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + wxMacCoreGraphicsBitmapData* refdata =static_cast(bmp.GetRefData()); + CGImageRef img = refdata->GetBitmap(); + if ( img ) + { + wxGraphicsBitmap p; + CGImageRef subimg = CGImageCreateWithImageInRect(img,CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h )); + p.SetRefData(new wxMacCoreGraphicsBitmapData( this , subimg, refdata->IsMonochrome() ) ); + return p; + } + else + return wxNullGraphicsBitmap; +} + // sets the brush to a linear gradient, starting at (x1,y1) with color c1 to (x2,y2) with color c2 wxGraphicsBrush wxMacCoreGraphicsRenderer::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2, const wxColour&c1, const wxColour&c2) @@ -2381,7 +2554,10 @@ CGDataConsumerRef wxMacCGDataConsumerCreateWithCFData( CFMutableDataRef data ) return CGDataConsumerCreateWithCFData( data ); } -void wxMacReleaseMemoryBufferProviderCallback(void *info, const void *data, size_t WXUNUSED(size)) +void +wxMacReleaseMemoryBufferProviderCallback(void *info, + const void * WXUNUSED_UNLESS_DEBUG(data), + size_t WXUNUSED(size)) { wxMemoryBuffer* membuf = (wxMemoryBuffer*) info ; @@ -2395,7 +2571,7 @@ CGDataProviderRef wxMacCGDataProviderCreateWithMemoryBuffer( const wxMemoryBuffe wxMemoryBuffer* b = new wxMemoryBuffer( buf ); if ( b->GetDataLen() == 0 ) return NULL; - + return CGDataProviderCreateWithData( b , (const void *) b->GetData() , b->GetDataLen() , wxMacReleaseMemoryBufferProviderCallback ); -} \ No newline at end of file +}