/ExtLibs/wxWidgets/src/osx/carbon/graphics.cpp
C++ | 1632 lines | 1159 code | 302 blank | 171 comment | 80 complexity | 5414cf5d79cbf3aee6e1e5b083fa8247 MD5 | raw file
- /////////////////////////////////////////////////////////////////////////////
- // Name: src/osx/carbon/graphics.cpp
- // Purpose: wxDC class
- // Author: Stefan Csomor
- // Modified by:
- // Created: 01/02/97
- // RCS-ID: $Id$
- // copyright: (c) Stefan Csomor
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- #include "wx/wxprec.h"
- #include "wx/graphics.h"
- #include "wx/private/graphics.h"
- #ifndef WX_PRECOMP
- #include "wx/dcclient.h"
- #include "wx/dcmemory.h"
- #include "wx/dcprint.h"
- #include "wx/log.h"
- #include "wx/region.h"
- #include "wx/image.h"
- #include "wx/icon.h"
- #endif
- #ifdef __MSL__
- #if __MSL__ >= 0x6000
- #include "math.h"
- // in case our functions were defined outside std, we make it known all the same
- namespace std { }
- using namespace std;
- #endif
- #endif
- #ifdef __WXMAC__
- #include "wx/osx/private.h"
- #include "wx/osx/dcprint.h"
- #include "wx/osx/dcclient.h"
- #include "wx/osx/dcmemory.h"
- #include "wx/osx/private.h"
- #else
- #include "CoreServices/CoreServices.h"
- #include "ApplicationServices/ApplicationServices.h"
- #include "wx/osx/core/cfstring.h"
- #include "wx/cocoa/dcclient.h"
- #endif
- #ifdef __WXCOCOA__
- CGColorSpaceRef wxMacGetGenericRGBColorSpace()
- {
- static wxCFRef<CGColorSpaceRef> genericRGBColorSpace;
- if (genericRGBColorSpace == NULL)
- {
- genericRGBColorSpace.reset( CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ) );
- }
- return genericRGBColorSpace;
- }
- int UMAGetSystemVersion()
- {
- return 0x1050;
- }
- #define wxOSX_USE_CORE_TEXT 1
- #endif
- #if wxOSX_USE_COCOA_OR_IPHONE
- extern CGContextRef wxOSXGetContextFromCurrentContext() ;
- #if wxOSX_USE_COCOA
- extern bool wxOSXLockFocus( WXWidget view) ;
- extern void wxOSXUnlockFocus( WXWidget view) ;
- #endif
- #endif
- #if 1 // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
- // TODO test whether this private API also works under 10.3
- // copying values from NSCompositingModes (see also webkit and cairo sources)
- typedef enum CGCompositeOperation {
- kCGCompositeOperationClear = 0,
- kCGCompositeOperationCopy = 1,
- kCGCompositeOperationSourceOver = 2,
- kCGCompositeOperationSourceIn = 3,
- kCGCompositeOperationSourceOut = 4,
- kCGCompositeOperationSourceAtop = 5,
- kCGCompositeOperationDestinationOver = 6,
- kCGCompositeOperationDestinationIn = 7,
- kCGCompositeOperationDestinationOut = 8,
- kCGCompositeOperationDestinationAtop = 9,
- kCGCompositeOperationXOR = 10,
- kCGCompositeOperationPlusDarker = 11,
- // NS only, unsupported by CG : Highlight
- kCGCompositeOperationPlusLighter = 12
- } CGCompositeOperation ;
- extern "C"
- {
- CG_EXTERN void CGContextSetCompositeOperation (CGContextRef context, int operation);
- } ;
- #endif
- //-----------------------------------------------------------------------------
- // constants
- //-----------------------------------------------------------------------------
- #if !defined( __DARWIN__ ) || defined(__MWERKS__)
- #ifndef M_PI
- const double M_PI = 3.14159265358979;
- #endif
- #endif
- static const double RAD2DEG = 180.0 / M_PI;
- //
- // Pen, Brushes and Fonts
- //
- #pragma mark -
- #pragma mark wxMacCoreGraphicsPattern, ImagePattern, HatchPattern classes
- OSStatus wxMacDrawCGImage(
- CGContextRef inContext,
- const CGRect * inBounds,
- CGImageRef inImage)
- {
- #if wxOSX_USE_CARBON
- return HIViewDrawCGImage( inContext, inBounds, inImage );
- #else
- CGContextSaveGState(inContext);
- CGContextTranslateCTM(inContext, inBounds->origin.x, inBounds->origin.y + inBounds->size.height);
- CGRect r = *inBounds;
- r.origin.x = r.origin.y = 0;
- CGContextScaleCTM(inContext, 1, -1);
- CGContextDrawImage(inContext, r, inImage );
- CGContextRestoreGState(inContext);
- return noErr;
- #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 && wxOSX_USE_CORE_TEXT
- CTFontRef wxMacCreateCTFont( const wxFont& font )
- {
- #ifdef __WXMAC__
- return wxCFRetain((CTFontRef) font.OSXGetCTFont());
- #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
- {
- public :
- wxMacCoreGraphicsPattern() {}
- // is guaranteed to be called only with a non-Null CGContextRef
- virtual void Render( CGContextRef ctxRef ) = 0;
- operator CGPatternRef() const { return m_patternRef; }
- protected :
- virtual ~wxMacCoreGraphicsPattern()
- {
- // as this is called only when the m_patternRef is been released;
- // don't release it again
- }
- static void _Render( void *info, CGContextRef ctxRef )
- {
- wxMacCoreGraphicsPattern* self = (wxMacCoreGraphicsPattern*) info;
- if ( self && ctxRef )
- self->Render( ctxRef );
- }
- static void _Dispose( void *info )
- {
- wxMacCoreGraphicsPattern* self = (wxMacCoreGraphicsPattern*) info;
- delete self;
- }
- CGPatternRef m_patternRef;
- static const CGPatternCallbacks ms_Callbacks;
- };
- const CGPatternCallbacks wxMacCoreGraphicsPattern::ms_Callbacks = { 0, &wxMacCoreGraphicsPattern::_Render, &wxMacCoreGraphicsPattern::_Dispose };
- class ImagePattern : public wxMacCoreGraphicsPattern
- {
- public :
- ImagePattern( const wxBitmap* bmp , const CGAffineTransform& transform )
- {
- wxASSERT( bmp && bmp->IsOk() );
- #ifdef __WXMAC__
- Init( (CGImageRef) bmp->CreateCGImage() , transform );
- #endif
- }
- // ImagePattern takes ownership of CGImageRef passed in
- ImagePattern( CGImageRef image , const CGAffineTransform& transform )
- {
- if ( image )
- CFRetain( image );
- Init( image , transform );
- }
- virtual void Render( CGContextRef ctxRef )
- {
- if (m_image != NULL)
- wxMacDrawCGImage( ctxRef, &m_imageBounds, m_image );
- }
- protected :
- void Init( CGImageRef image, const CGAffineTransform& transform )
- {
- m_image = image;
- if ( 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,
- kCGPatternTilingNoDistortion, true , &wxMacCoreGraphicsPattern::ms_Callbacks );
- }
- }
- virtual ~ImagePattern()
- {
- if ( m_image )
- CGImageRelease( m_image );
- }
- CGImageRef m_image;
- CGRect m_imageBounds;
- };
- class HatchPattern : public wxMacCoreGraphicsPattern
- {
- public :
- HatchPattern( int hatchstyle, const CGAffineTransform& transform )
- {
- m_hatch = hatchstyle;
- 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,
- kCGPatternTilingNoDistortion, false , &wxMacCoreGraphicsPattern::ms_Callbacks );
- }
- void StrokeLineSegments( CGContextRef ctxRef , const CGPoint pts[] , size_t count )
- {
- CGContextStrokeLineSegments( ctxRef , pts , count );
- }
- virtual void Render( CGContextRef ctxRef )
- {
- switch ( m_hatch )
- {
- case wxBDIAGONAL_HATCH :
- {
- CGPoint pts[] =
- {
- { (CGFloat) 8.0 , (CGFloat) 0.0 } , { (CGFloat) 0.0 , (CGFloat) 8.0 }
- };
- StrokeLineSegments( ctxRef , pts , 2 );
- }
- break;
- case wxCROSSDIAG_HATCH :
- {
- CGPoint pts[] =
- {
- { (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 );
- }
- break;
- case wxFDIAGONAL_HATCH :
- {
- CGPoint pts[] =
- {
- { (CGFloat) 0.0 , (CGFloat) 0.0 } , { (CGFloat) 8.0 , (CGFloat) 8.0 }
- };
- StrokeLineSegments( ctxRef , pts , 2 );
- }
- break;
- case wxCROSS_HATCH :
- {
- CGPoint pts[] =
- {
- { (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 );
- }
- break;
- case wxHORIZONTAL_HATCH :
- {
- CGPoint pts[] =
- {
- { (CGFloat) 0.0 , (CGFloat) 4.0 } , { (CGFloat) 8.0 , (CGFloat) 4.0 } ,
- };
- StrokeLineSegments( ctxRef , pts , 2 );
- }
- break;
- case wxVERTICAL_HATCH :
- {
- CGPoint pts[] =
- {
- { (CGFloat) 4.0 , (CGFloat) 0.0 } , { (CGFloat) 4.0 , (CGFloat) 8.0 } ,
- };
- StrokeLineSegments( ctxRef , pts , 2 );
- }
- break;
- default:
- break;
- }
- }
- protected :
- virtual ~HatchPattern() {}
- CGRect m_imageBounds;
- int m_hatch;
- };
- class wxMacCoreGraphicsPenData : public wxGraphicsObjectRefData
- {
- public:
- wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer, const wxPen &pen );
- ~wxMacCoreGraphicsPenData();
- void Init();
- virtual void Apply( wxGraphicsContext* context );
- virtual wxDouble GetWidth() { return m_width; }
- protected :
- CGLineCap m_cap;
- wxCFRef<CGColorRef> m_color;
- wxCFRef<CGColorSpaceRef> m_colorSpace;
- CGLineJoin m_join;
- CGFloat m_width;
- int m_count;
- const CGFloat *m_lengths;
- CGFloat *m_userLengths;
- bool m_isPattern;
- wxCFRef<CGPatternRef> m_pattern;
- CGFloat* m_patternColorComponents;
- };
- wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer, const wxPen &pen ) :
- wxGraphicsObjectRefData( renderer )
- {
- Init();
- m_color.reset( wxMacCreateCGColor( pen.GetColour() ) ) ;
- // TODO: * m_dc->m_scaleX
- m_width = pen.GetWidth();
- if (m_width <= 0.0)
- m_width = (CGFloat) 0.1;
- switch ( pen.GetCap() )
- {
- case wxCAP_ROUND :
- m_cap = kCGLineCapRound;
- break;
- case wxCAP_PROJECTING :
- m_cap = kCGLineCapSquare;
- break;
- case wxCAP_BUTT :
- m_cap = kCGLineCapButt;
- break;
- default :
- m_cap = kCGLineCapButt;
- break;
- }
- switch ( pen.GetJoin() )
- {
- case wxJOIN_BEVEL :
- m_join = kCGLineJoinBevel;
- break;
- case wxJOIN_MITER :
- m_join = kCGLineJoinMiter;
- break;
- case wxJOIN_ROUND :
- m_join = kCGLineJoinRound;
- break;
- default :
- m_join = kCGLineJoinMiter;
- break;
- }
- const CGFloat dashUnit = m_width < 1.0 ? (CGFloat) 1.0 : m_width;
- 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() )
- {
- case wxPENSTYLE_SOLID:
- break;
- case wxPENSTYLE_DOT:
- m_count = WXSIZEOF(dotted);
- m_userLengths = new CGFloat[ m_count ] ;
- memcpy( m_userLengths, dotted, sizeof(dotted) );
- m_lengths = m_userLengths;
- break;
- case wxPENSTYLE_LONG_DASH:
- m_count = WXSIZEOF(dashed);
- m_lengths = dashed;
- break;
- case wxPENSTYLE_SHORT_DASH:
- m_count = WXSIZEOF(short_dashed);
- m_lengths = short_dashed;
- break;
- case wxPENSTYLE_DOT_DASH:
- m_count = WXSIZEOF(dotted_dashed);
- m_lengths = dotted_dashed;
- break;
- case wxPENSTYLE_USER_DASH:
- wxDash *dashes;
- m_count = pen.GetDashes( &dashes );
- if ((dashes != NULL) && (m_count > 0))
- {
- m_userLengths = new CGFloat[m_count];
- for ( int i = 0; i < m_count; ++i )
- {
- m_userLengths[i] = dashes[i] * dashUnit;
- if ( i % 2 == 1 && 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;
- }
- }
- m_lengths = m_userLengths;
- break;
- case wxPENSTYLE_STIPPLE:
- {
- wxBitmap* bmp = pen.GetStipple();
- if ( bmp && bmp->IsOk() )
- {
- m_colorSpace.reset( CGColorSpaceCreatePattern( NULL ) );
- m_pattern.reset( (CGPatternRef) *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) );
- m_patternColorComponents = new CGFloat[1] ;
- m_patternColorComponents[0] = (CGFloat) 1.0;
- m_isPattern = true;
- }
- }
- break;
- default :
- {
- m_isPattern = true;
- m_colorSpace.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) );
- m_pattern.reset( (CGPatternRef) *( new HatchPattern( pen.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) );
- m_patternColorComponents = new CGFloat[4] ;
- 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;
- }
- if ((m_lengths != NULL) && (m_count > 0))
- {
- // force the line cap, otherwise we get artifacts (overlaps) and just solid lines
- m_cap = kCGLineCapButt;
- }
- }
- wxMacCoreGraphicsPenData::~wxMacCoreGraphicsPenData()
- {
- delete[] m_userLengths;
- delete[] m_patternColorComponents;
- }
- void wxMacCoreGraphicsPenData::Init()
- {
- m_lengths = NULL;
- m_userLengths = NULL;
- m_width = 0;
- m_count = 0;
- m_patternColorComponents = NULL;
- m_isPattern = false;
- }
- void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context )
- {
- CGContextRef cg = (CGContextRef) context->GetNativeContext();
- CGContextSetLineWidth( cg , m_width );
- CGContextSetLineJoin( cg , m_join );
- CGContextSetLineDash( cg , 0 , m_lengths , m_count );
- CGContextSetLineCap( cg , m_cap );
- if ( m_isPattern )
- {
- CGAffineTransform matrix = CGContextGetCTM( cg );
- CGContextSetPatternPhase( cg, CGSizeMake(matrix.tx, matrix.ty) );
- CGContextSetStrokeColorSpace( cg , m_colorSpace );
- CGContextSetStrokePattern( cg, m_pattern , m_patternColorComponents );
- }
- else
- {
- CGContextSetStrokeColorWithColor( cg , m_color );
- }
- }
- //
- // Brush
- //
- // make sure we all use one class for all conversions from wx to native colour
- class wxMacCoreGraphicsColour
- {
- public:
- wxMacCoreGraphicsColour();
- wxMacCoreGraphicsColour(const wxBrush &brush);
- ~wxMacCoreGraphicsColour();
- void Apply( CGContextRef cgContext );
- protected:
- void Init();
- wxCFRef<CGColorRef> m_color;
- wxCFRef<CGColorSpaceRef> m_colorSpace;
- bool m_isPattern;
- wxCFRef<CGPatternRef> m_pattern;
- CGFloat* m_patternColorComponents;
- } ;
- wxMacCoreGraphicsColour::~wxMacCoreGraphicsColour()
- {
- delete[] m_patternColorComponents;
- }
- void wxMacCoreGraphicsColour::Init()
- {
- m_isPattern = false;
- m_patternColorComponents = NULL;
- }
- void wxMacCoreGraphicsColour::Apply( CGContextRef cgContext )
- {
- if ( m_isPattern )
- {
- CGAffineTransform matrix = CGContextGetCTM( cgContext );
- CGContextSetPatternPhase( cgContext, CGSizeMake(matrix.tx, matrix.ty) );
- CGContextSetFillColorSpace( cgContext , m_colorSpace );
- CGContextSetFillPattern( cgContext, m_pattern , m_patternColorComponents );
- }
- else
- {
- CGContextSetFillColorWithColor( cgContext, m_color );
- }
- }
- wxMacCoreGraphicsColour::wxMacCoreGraphicsColour()
- {
- Init();
- }
- wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush &brush )
- {
- Init();
- if ( brush.GetStyle() == wxSOLID )
- {
- m_color.reset( wxMacCreateCGColor( brush.GetColour() ));
- }
- else if ( brush.IsHatch() )
- {
- m_isPattern = true;
- m_colorSpace.reset( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) );
- m_pattern.reset( (CGPatternRef) *( new HatchPattern( brush.GetStyle() , CGAffineTransformMakeScale( 1,-1 ) ) ) );
- m_patternColorComponents = new CGFloat[4] ;
- 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
- {
- // now brush is a bitmap
- wxBitmap* bmp = brush.GetStipple();
- if ( bmp && bmp->IsOk() )
- {
- m_isPattern = true;
- m_patternColorComponents = new CGFloat[1] ;
- m_patternColorComponents[0] = (CGFloat) 1.0;
- m_colorSpace.reset( CGColorSpaceCreatePattern( NULL ) );
- m_pattern.reset( (CGPatternRef) *( new ImagePattern( bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) );
- }
- }
- }
- class wxMacCoreGraphicsBrushData : public wxGraphicsObjectRefData
- {
- public:
- wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer );
- wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer, const wxBrush &brush );
- ~wxMacCoreGraphicsBrushData ();
- virtual void Apply( wxGraphicsContext* context );
- void CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
- wxDouble x2, wxDouble y2,
- const wxGraphicsGradientStops& stops);
- void CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
- wxDouble xc, wxDouble yc, wxDouble radius,
- const wxGraphicsGradientStops& stops);
- virtual bool IsShading() { return m_isShading; }
- CGShadingRef GetShading() { return m_shading; }
- protected:
- CGFunctionRef CreateGradientFunction(const wxGraphicsGradientStops& stops);
- static void CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out);
- virtual void Init();
- wxMacCoreGraphicsColour m_cgColor;
- bool m_isShading;
- CGFunctionRef m_gradientFunction;
- CGShadingRef m_shading;
- // information about a single gradient component
- struct GradientComponent
- {
- CGFloat pos;
- CGFloat red;
- CGFloat green;
- CGFloat blue;
- CGFloat alpha;
- };
- // and information about all of them
- struct GradientComponents
- {
- GradientComponents()
- {
- count = 0;
- comps = NULL;
- }
- void Init(unsigned count_)
- {
- count = count_;
- comps = new GradientComponent[count];
- }
- ~GradientComponents()
- {
- delete [] comps;
- }
- unsigned count;
- GradientComponent *comps;
- };
- GradientComponents m_gradientComponents;
- };
- wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer )
- {
- Init();
- }
- void
- wxMacCoreGraphicsBrushData::CreateLinearGradientBrush(wxDouble x1, wxDouble y1,
- wxDouble x2, wxDouble y2,
- const wxGraphicsGradientStops& stops)
- {
- m_gradientFunction = CreateGradientFunction(stops);
- m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) x1, (CGFloat) y1),
- CGPointMake((CGFloat) x2,(CGFloat) y2), m_gradientFunction, true, true ) ;
- m_isShading = true ;
- }
- void
- wxMacCoreGraphicsBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo,
- wxDouble xc, wxDouble yc,
- wxDouble radius,
- const wxGraphicsGradientStops& stops)
- {
- m_gradientFunction = CreateGradientFunction(stops);
- m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) xo,(CGFloat) yo), 0,
- CGPointMake((CGFloat) xc,(CGFloat) yc), (CGFloat) radius, m_gradientFunction, true, true ) ;
- m_isShading = true ;
- }
- wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* renderer, const wxBrush &brush) : wxGraphicsObjectRefData( renderer ),
- m_cgColor( brush )
- {
- Init();
- }
- wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData()
- {
- if ( m_shading )
- CGShadingRelease(m_shading);
- if( m_gradientFunction )
- CGFunctionRelease(m_gradientFunction);
- }
- void wxMacCoreGraphicsBrushData::Init()
- {
- m_gradientFunction = NULL;
- m_shading = NULL;
- m_isShading = false;
- }
- void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext* context )
- {
- CGContextRef cg = (CGContextRef) context->GetNativeContext();
- if ( m_isShading )
- {
- // nothing to set as shades are processed by clipping using the path and filling
- }
- else
- {
- m_cgColor.Apply( cg );
- }
- }
- void wxMacCoreGraphicsBrushData::CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out)
- {
- const GradientComponents& stops = *(GradientComponents*) info ;
- CGFloat f = *in;
- if (f <= 0.0)
- {
- // Start
- out[0] = stops.comps[0].red;
- out[1] = stops.comps[0].green;
- out[2] = stops.comps[0].blue;
- out[3] = stops.comps[0].alpha;
- }
- else if (f >= 1.0)
- {
- // end
- out[0] = stops.comps[stops.count - 1].red;
- out[1] = stops.comps[stops.count - 1].green;
- out[2] = stops.comps[stops.count - 1].blue;
- out[3] = stops.comps[stops.count - 1].alpha;
- }
- else
- {
- // Find first component with position greater than f
- unsigned i;
- for ( i = 0; i < stops.count; i++ )
- {
- if (stops.comps[i].pos > f)
- break;
- }
- // Interpolated between stops
- CGFloat diff = (f - stops.comps[i-1].pos);
- CGFloat range = (stops.comps[i].pos - stops.comps[i-1].pos);
- CGFloat fact = diff / range;
- out[0] = stops.comps[i - 1].red + (stops.comps[i].red - stops.comps[i - 1].red) * fact;
- out[1] = stops.comps[i - 1].green + (stops.comps[i].green - stops.comps[i - 1].green) * fact;
- out[2] = stops.comps[i - 1].blue + (stops.comps[i].blue - stops.comps[i - 1].blue) * fact;
- out[3] = stops.comps[i - 1].alpha + (stops.comps[i].alpha - stops.comps[i - 1].alpha) * fact;
- }
- }
- CGFunctionRef
- wxMacCoreGraphicsBrushData::CreateGradientFunction(const wxGraphicsGradientStops& stops)
- {
- static const CGFunctionCallbacks callbacks = { 0, &CalculateShadingValues, NULL };
- 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.Init(stops.GetCount());
- for ( unsigned i = 0; i < m_gradientComponents.count; i++ )
- {
- const wxGraphicsGradientStop stop = stops.Item(i);
- m_gradientComponents.comps[i].pos = stop.GetPosition();
- const wxColour col = stop.GetColour();
- m_gradientComponents.comps[i].red = (CGFloat) (col.Red() / 255.0);
- m_gradientComponents.comps[i].green = (CGFloat) (col.Green() / 255.0);
- m_gradientComponents.comps[i].blue = (CGFloat) (col.Blue() / 255.0);
- m_gradientComponents.comps[i].alpha = (CGFloat) (col.Alpha() / 255.0);
- }
- return CGFunctionCreate ( &m_gradientComponents, 1,
- input_value_range,
- 4,
- output_value_ranges,
- &callbacks);
- }
- //
- // Font
- //
- #if wxOSX_USE_IPHONE
- extern UIFont* CreateUIFont( const wxFont& font );
- extern void DrawTextInContext( CGContextRef context, CGPoint where, UIFont *font, NSString* text );
- extern CGSize MeasureTextInContext( UIFont *font, NSString* text );
- #endif
- class wxMacCoreGraphicsFontData : public wxGraphicsObjectRefData
- {
- public:
- wxMacCoreGraphicsFontData( wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col );
- ~wxMacCoreGraphicsFontData();
- #if wxOSX_USE_ATSU_TEXT
- virtual ATSUStyle GetATSUStyle() { return m_macATSUIStyle; }
- #endif
- #if wxOSX_USE_CORE_TEXT
- CTFontRef OSXGetCTFont() const { return m_ctFont ; }
- #endif
- wxColour GetColour() const { return m_colour ; }
- bool GetUnderlined() const { return m_underlined ; }
- #if wxOSX_USE_IPHONE
- UIFont* GetUIFont() const { return m_uiFont; }
- #endif
- private :
- wxColour m_colour;
- bool m_underlined;
- #if wxOSX_USE_ATSU_TEXT
- ATSUStyle m_macATSUIStyle;
- #endif
- #if wxOSX_USE_CORE_TEXT
- wxCFRef< CTFontRef > m_ctFont;
- #endif
- #if wxOSX_USE_IPHONE
- UIFont* m_uiFont;
- #endif
- };
- wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col) : wxGraphicsObjectRefData( renderer )
- {
- m_colour = col;
- m_underlined = font.GetUnderlined();
- #if wxOSX_USE_CORE_TEXT
- m_ctFont.reset( wxMacCreateCTFont( font ) );
- #endif
- #if wxOSX_USE_IPHONE
- m_uiFont = CreateUIFont(font);
- wxMacCocoaRetain( m_uiFont );
- #endif
- #if wxOSX_USE_ATSU_TEXT
- OSStatus status = noErr;
- m_macATSUIStyle = NULL;
- status = ATSUCreateAndCopyStyle( (ATSUStyle) font.MacGetATSUStyle() , &m_macATSUIStyle );
- wxASSERT_MSG( status == noErr, wxT("couldn't create ATSU style") );
- // we need the scale here ...
- Fixed atsuSize = IntToFixed( int( 1 * font.GetPointSize()) );
- RGBColor atsuColor ;
- col.GetRGBColor( &atsuColor );
- ATSUAttributeTag atsuTags[] =
- {
- kATSUSizeTag ,
- kATSUColorTag ,
- };
- ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
- {
- sizeof( Fixed ) ,
- sizeof( RGBColor ) ,
- };
- ATSUAttributeValuePtr atsuValues[WXSIZEOF(atsuTags)] =
- {
- &atsuSize ,
- &atsuColor ,
- };
- status = ::ATSUSetAttributes(
- m_macATSUIStyle, WXSIZEOF(atsuTags),
- atsuTags, atsuSizes, atsuValues);
- wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
- #endif
- }
- wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData()
- {
- #if wxOSX_USE_CORE_TEXT
- #endif
- #if wxOSX_USE_ATSU_TEXT
- if ( m_macATSUIStyle )
- {
- ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
- m_macATSUIStyle = NULL;
- }
- #endif
- #if wxOSX_USE_IPHONE
- wxMacCocoaRelease( m_uiFont );
- #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
- //
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsMatrix declaration
- //-----------------------------------------------------------------------------
- class WXDLLIMPEXP_CORE wxMacCoreGraphicsMatrixData : public wxGraphicsMatrixData
- {
- public :
- wxMacCoreGraphicsMatrixData(wxGraphicsRenderer* renderer) ;
- virtual ~wxMacCoreGraphicsMatrixData() ;
- virtual wxGraphicsObjectRefData *Clone() const ;
- // concatenates the matrix
- virtual void Concat( const wxGraphicsMatrixData *t );
- // sets the matrix to the respective values
- virtual void Set(wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0,
- wxDouble tx=0.0, wxDouble ty=0.0);
- // 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();
- // returns true if the elements of the transformation matrix are equal ?
- virtual bool IsEqual( const wxGraphicsMatrixData* t) const ;
- // return true if this is the identity matrix
- virtual bool IsIdentity() const;
- //
- // transformation
- //
- // add the translation to this matrix
- virtual void Translate( wxDouble dx , wxDouble dy );
- // add the scale to this matrix
- virtual void Scale( wxDouble xScale , wxDouble yScale );
- // add the rotation to this matrix (radians)
- virtual void Rotate( wxDouble angle );
- //
- // apply the transforms
- //
- // applies that matrix to the point
- virtual void TransformPoint( wxDouble *x, wxDouble *y ) const;
- // applies the matrix except for translations
- virtual void TransformDistance( wxDouble *dx, wxDouble *dy ) const;
- // returns the native representation
- virtual void * GetNativeMatrix() const;
- private :
- CGAffineTransform m_matrix;
- } ;
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsMatrix implementation
- //-----------------------------------------------------------------------------
- wxMacCoreGraphicsMatrixData::wxMacCoreGraphicsMatrixData(wxGraphicsRenderer* renderer) : wxGraphicsMatrixData(renderer)
- {
- }
- wxMacCoreGraphicsMatrixData::~wxMacCoreGraphicsMatrixData()
- {
- }
- wxGraphicsObjectRefData *wxMacCoreGraphicsMatrixData::Clone() const
- {
- wxMacCoreGraphicsMatrixData* m = new wxMacCoreGraphicsMatrixData(GetRenderer()) ;
- m->m_matrix = m_matrix ;
- return m;
- }
- // concatenates the matrix
- void wxMacCoreGraphicsMatrixData::Concat( const wxGraphicsMatrixData *t )
- {
- m_matrix = CGAffineTransformConcat(*((CGAffineTransform*) t->GetNativeMatrix()), m_matrix );
- }
- // sets the matrix to the respective values
- void wxMacCoreGraphicsMatrixData::Set(wxDouble a, wxDouble b, wxDouble c, wxDouble d,
- wxDouble tx, wxDouble ty)
- {
- m_matrix = CGAffineTransformMake((CGFloat) a,(CGFloat) b,(CGFloat) c,(CGFloat) d,(CGFloat) tx,(CGFloat) ty);
- }
- // gets the component valuess of the matrix
- void wxMacCoreGraphicsMatrixData::Get(wxDouble* a, wxDouble* b, wxDouble* c,
- wxDouble* d, wxDouble* tx, wxDouble* ty) const
- {
- if (a) *a = m_matrix.a;
- if (b) *b = m_matrix.b;
- if (c) *c = m_matrix.c;
- if (d) *d = m_matrix.d;
- if (tx) *tx= m_matrix.tx;
- if (ty) *ty= m_matrix.ty;
- }
- // makes this the inverse matrix
- void wxMacCoreGraphicsMatrixData::Invert()
- {
- m_matrix = CGAffineTransformInvert( m_matrix );
- }
- // returns true if the elements of the transformation matrix are equal ?
- bool wxMacCoreGraphicsMatrixData::IsEqual( const wxGraphicsMatrixData* t) const
- {
- return CGAffineTransformEqualToTransform(m_matrix, *((CGAffineTransform*) t->GetNativeMatrix()));
- }
- // return true if this is the identity matrix
- bool wxMacCoreGraphicsMatrixData::IsIdentity() const
- {
- return ( m_matrix.a == 1 && m_matrix.d == 1 &&
- m_matrix.b == 0 && m_matrix.d == 0 && m_matrix.tx == 0 && m_matrix.ty == 0);
- }
- //
- // transformation
- //
- // add the translation to this matrix
- void wxMacCoreGraphicsMatrixData::Translate( wxDouble dx , wxDouble 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, (CGFloat) xScale, (CGFloat) yScale);
- }
- // add the rotation to this matrix (radians)
- void wxMacCoreGraphicsMatrixData::Rotate( wxDouble angle )
- {
- m_matrix = CGAffineTransformRotate( m_matrix, (CGFloat) angle);
- }
- //
- // apply the transforms
- //
- // applies that matrix to the point
- void wxMacCoreGraphicsMatrixData::TransformPoint( wxDouble *x, wxDouble *y ) const
- {
- CGPoint pt = CGPointApplyAffineTransform( CGPointMake((CGFloat) *x,(CGFloat) *y), m_matrix);
- *x = pt.x;
- *y = pt.y;
- }
- // applies the matrix except for translations
- void wxMacCoreGraphicsMatrixData::TransformDistance( wxDouble *dx, wxDouble *dy ) const
- {
- CGSize sz = CGSizeApplyAffineTransform( CGSizeMake((CGFloat) *dx,(CGFloat) *dy) , m_matrix );
- *dx = sz.width;
- *dy = sz.height;
- }
- // returns the native representation
- void * wxMacCoreGraphicsMatrixData::GetNativeMatrix() const
- {
- return (void*) &m_matrix;
- }
- //
- // Graphics Path
- //
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsPath declaration
- //-----------------------------------------------------------------------------
- class WXDLLEXPORT wxMacCoreGraphicsPathData : public wxGraphicsPathData
- {
- public :
- wxMacCoreGraphicsPathData( wxGraphicsRenderer* renderer, CGMutablePathRef path = NULL);
- ~wxMacCoreGraphicsPathData();
- virtual wxGraphicsObjectRefData *Clone() const;
- // begins a new subpath at (x,y)
- virtual void MoveToPoint( wxDouble x, wxDouble y );
- // adds a straight line from the current point to (x,y)
- virtual void AddLineToPoint( wxDouble x, wxDouble y );
- // adds a cubic Bezier curve from the current point, using two control points and an end point
- virtual void AddCurveToPoint( wxDouble cx1, wxDouble cy1, wxDouble cx2, wxDouble cy2, wxDouble x, wxDouble y );
- // closes the current sub-path
- virtual void CloseSubpath();
- // gets the last point of the current path, (0,0) if not yet set
- virtual void GetCurrentPoint( wxDouble* x, wxDouble* y) const;
- // adds an arc of a circle centering at (x,y) with radius (r) from startAngle to endAngle
- virtual void AddArc( wxDouble x, wxDouble y, wxDouble r, wxDouble startAngle, wxDouble endAngle, bool clockwise );
- //
- // These are convenience functions which - if not available natively will be assembled
- // using the primitives from above
- //
- // adds a quadratic Bezier curve from the current point, using a control point and an end point
- virtual void AddQuadCurveToPoint( wxDouble cx, wxDouble cy, wxDouble x, wxDouble y );
- // appends a rectangle as a new closed subpath
- virtual void AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
- // appends a circle as a new closed subpath
- virtual void AddCircle( wxDouble x, wxDouble y, wxDouble r );
- // appends an ellipsis as a new closed subpath fitting the passed rectangle
- virtual void AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h);
- // 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)
- virtual void AddArcToPoint( wxDouble x1, wxDouble y1 , wxDouble x2, wxDouble y2, wxDouble r );
- // adds another path
- virtual void AddPath( const wxGraphicsPathData* path );
- // returns the native path
- virtual void * GetNativePath() const { return m_path; }
- // give the native path returned by GetNativePath() back (there might be some deallocations necessary)
- virtual void UnGetNativePath(void *WXUNUSED(p)) const {}
- // transforms each point of this path by the matrix
- virtual void Transform( const wxGraphicsMatrixData* matrix );
- // gets the bounding box enclosing all points (possibly including control points)
- virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const;
- virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxODDEVEN_RULE) const;
- private :
- CGMutablePathRef m_path;
- };
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsPath implementation
- //-----------------------------------------------------------------------------
- wxMacCoreGraphicsPathData::wxMacCoreGraphicsPathData( wxGraphicsRenderer* renderer, CGMutablePathRef path) : wxGraphicsPathData(renderer)
- {
- if ( path )
- m_path = path;
- else
- m_path = CGPathCreateMutable();
- }
- wxMacCoreGraphicsPathData::~wxMacCoreGraphicsPathData()
- {
- CGPathRelease( m_path );
- }
- wxGraphicsObjectRefData* wxMacCoreGraphicsPathData::Clone() const
- {
- wxMacCoreGraphicsPathData* clone = new wxMacCoreGraphicsPathData(GetRenderer(),CGPathCreateMutableCopy(m_path));
- return clone ;
- }
- // opens (starts) a new subpath
- void wxMacCoreGraphicsPathData::MoveToPoint( wxDouble x1 , wxDouble y1 )
- {
- CGPathMoveToPoint( m_path , NULL , (CGFloat) x1 , (CGFloat) y1 );
- }
- void wxMacCoreGraphicsPathData::AddLineToPoint( wxDouble x1 , wxDouble 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 , (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 , (CGFloat) cx1 , (CGFloat) cy1 , (CGFloat) x , (CGFloat) y );
- }
- void wxMacCoreGraphicsPathData::AddRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble 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 )
- {
- CGPathAddEllipseInRect( m_path, NULL, CGRectMake(x-r,y-r,2*r,2*r));
- }
- void wxMacCoreGraphicsPathData::AddEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
- {
- CGPathAddEllipseInRect( m_path, NULL, CGRectMake(x,y,w,h));
- }
- // 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 , (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 , (CGFloat) x1, (CGFloat) y1, (CGFloat) x2, (CGFloat) y2, (CGFloat) r);
- }
- void wxMacCoreGraphicsPathData::AddPath( const wxGraphicsPathData* path )
- {
- CGPathAddPath( m_path , NULL, (CGPathRef) path->GetNativePath() );
- }
- // closes the current subpath
- void wxMacCoreGraphicsPathData::CloseSubpath()
- {
- CGPathCloseSubpath( m_path );
- }
- // gets the last point of the current path, (0,0) if not yet set
- void wxMacCoreGraphicsPathData::GetCurrentPoint( wxDouble* x, wxDouble* y) const
- {
- CGPoint p = CGPathGetCurrentPoint( m_path );
- *x = p.x;
- *y = p.y;
- }
- // transforms each point of this path by the matrix
- void wxMacCoreGraphicsPathData::Transform( const wxGraphicsMatrixData* matrix )
- {
- CGMutablePathRef p = CGPathCreateMutable() ;
- CGPathAddPath( p, (CGAffineTransform*) matrix->GetNativeMatrix() , m_path );
- CGPathRelease( m_path );
- m_path = p;
- }
- // gets the bounding box enclosing all points (possibly including control points)
- void wxMacCoreGraphicsPathData::GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const
- {
- CGRect bounds = CGPathGetBoundingBox( m_path ) ;
- *x = bounds.origin.x;
- *y = bounds.origin.y;
- *w = bounds.size.width;
- *h = bounds.size.height;
- }
- bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle) const
- {
- return CGPathContainsPoint( m_path, NULL, CGPointMake((CGFloat) x,(CGFloat) y), fillStyle == wxODDEVEN_RULE );
- }
- //
- // Graphics Context
- //
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsContext declaration
- //-----------------------------------------------------------------------------
- class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext
- {
- public:
- wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 );
- #if wxOSX_USE_CARBON
- wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window );
- #endif
- wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window );
- wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer);
- wxMacCoreGraphicsContext();
- ~wxMacCoreGraphicsContext();
- void Init();
- virtual void StartPage( wxDouble width, wxDouble height );
- virtual void EndPage();
- virtual void Flush();
- // push the current state of the context, ie the transformation matrix on a stack
- virtual void PushState();
- // pops a stored state from the stack
- virtual void PopState();
- // clips drawings to the region
- virtual void Clip( const wxRegion ®ion );
- // clips drawings to the rect
- virtual void Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
- // resets the clipping to original extent
- virtual void ResetClip();
- virtual void * GetNativeContext();
- virtual bool SetAntialiasMode(wxAntialiasMode antialias);
- virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation);
-
- virtual bool SetCompositionMode(wxCompositionMode op);
- virtual void BeginLayer(wxDouble opacity);
- virtual void EndLayer();
- //
- // transformation
- //
- // translate
- virtual void Translate( wxDouble dx , wxDouble dy );
- // scale
- virtual void Scale( wxDouble xScale , wxDouble yScale );
- // rotate (radians)
- virtual void Rotate( wxDouble angle );
- // concatenates this transform with the current transform of this context
- virtual void ConcatTransform( const wxGraphicsMatrix& matrix );
- // sets the transform of this context
- virtual void SetTransform( const wxGraphicsMatrix& matrix );
- // gets the matrix of this context
- virtual wxGraphicsMatrix GetTransform() const;
- //
- // setting the paint
- //
- // strokes along a path with the current pen
- virtual void StrokePath( const wxGraphicsPath &path );
- // fills a path with the current brush
- virtual void FillPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
- // draws a path by first filling and then stroking
- virtual void DrawPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
- virtual bool ShouldOffset() const
- {
- if ( !m_enableOffset )
- return false;
-
- int penwidth = 0 ;
- if ( !m_pen.IsNull() )
- {
- penwidth = (int)((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->GetWidth();
- if ( penwidth == 0 )
- penwidth = 1;
- }
- return ( penwidth % 2 ) == 1;
- }
- //
- // text
- //
- virtual void GetTextExtent( const wxString &text, wxDouble *width, wxDouble *height,
- wxDouble *descent, wxDouble *externalLeading ) const;
- virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const;
- //
- // image support
- //
- 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 );
-
- // fast convenience methods
-
-
- virtual void DrawRectangleX( wxDouble x, wxDouble y, wxDouble w, wxDouble h );
- void SetNativeContext( CGContextRef cg );
- DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsContext)
- private:
- bool EnsureIsValid();
- virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
- virtual void DoDrawRotatedText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle );
- CGContextRef m_cgContext;
- #if wxOSX_USE_CARBON
- WindowRef m_windowRef;
- #else
- WXWidget m_view;
- #endif
- bool m_contextSynthesized;
- CGAffineTransform m_windowTransform;
- bool m_invisible;
- #if wxOSX_USE_COCOA_OR_CARBON
- wxCFRef<HIShapeRef> m_clipRgn;
- #endif
- };
- //-----------------------------------------------------------------------------
- // device context implementation
- //
- // more and more of the dc functionality should be implemented by calling
- // the appropricate wxMacCoreGraphicsContext, but we will have to do that step by step
- // also coordinate conversions should be moved to native matrix ops
- //-----------------------------------------------------------------------------
- // we always stock two context states, one at entry, to be able to preserve the
- // state we were called with, the other one after changing to HI Graphics orientation
- // (this one is used for getting back clippings etc)
- //-----------------------------------------------------------------------------
- // wxMacCoreGraphicsContext implementation
- //-----------------------------------------------------------------------------
- IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext, wxGraphicsContext)
- class wxQuartzOffsetHelper
- {
- public :
- wxQuartzOffsetHelper( CGContextRef cg , bool offset )
- {
- m_cg = cg;
- m_offset = offset;
- if ( m_offset )
- {
- m_userOffset = CGContextConvertSizeToUserSpace( m_cg, CGSizeMake( 0.5 , 0.5 ) );
- CGContextTranslateCTM( m_cg, m_userOffset.width , m_userOffset.height );
- }
- else
- {
- m_userOffset = CGSizeMake(0.0, 0.0);
- }
- }
- ~wxQuartzOffsetHelper( )
- {
- if ( m_offset )
- CGContextTranslateCTM( m_cg, -m_userOffset.width , -m_userOffset.height );
- }
- public :
- CGSize m_userOffset;
- CGContextRef m_cg;
- bool m_offset;
- } ;
- void wxMacCoreGraphicsContext::Init()
- {
- m_cgContext = NULL;
- m_contextSynthesized = false;
- m_width = 0;
- m_height = 0;
- #if wxOSX_USE_CARBON
- m_windowRef = NULL;
- #endif
- #if wxOSX_USE_COCOA_OR_IPHONE
- m_view = NULL;
- #endif
- m_invisible = false;
- m_antialias = wxANTIALIAS_DEFAULT;
- m_interpolation = wxINTERPOLATION_DEFAULT;
- }
- wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer)
- {
- Init();
- SetNativeContext(cgcontext);
- m_width = width;
- m_height = height;
- }
- #if wxOSX_USE_CARBON
- wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ): wxGraphicsContext(renderer)
- {
- Init();
- m_windowRef = window;
- m_enableOffset = true;
- }
- #endif
- wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer)
- {
- Init();
- m_enableOffset = true;
- wxSize sz = window->GetSize();
- m_width = sz.x;
- m_height = sz.y;
- #if wxOSX_USE_COCOA_OR_IPHONE
- m_view = window->GetHandle();
- #if wxOSX_USE_COCOA
- if ( ! window->GetPeer()->IsFlipped() )
- {
- m_windowTransform = CGAffineTransformMakeTranslation( 0 , m_height );
- m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 );
- }
- else
- #endif
- {
- m_windowTransform = CGAffineTransformIdentity;
- }
- #else
- int originX , originY;
- originX = originY = 0;
- Rect bounds = { 0,0,0,0 };
- m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef();
- window->MacWindowToRootWindow( &o