on demand creation of native CGContexts , so that pure text measuring contexts don't need a native counterpart
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42248 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -38,13 +38,24 @@
|
||||
typedef float CGFloat;
|
||||
#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;
|
||||
|
||||
//
|
||||
// Graphics Path
|
||||
//
|
||||
|
||||
class WXDLLEXPORT wxMacCoreGraphicsPath : public wxGraphicsPath
|
||||
{
|
||||
DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsPath)
|
||||
public :
|
||||
wxMacCoreGraphicsPath();
|
||||
~wxMacCoreGraphicsPath();
|
||||
@@ -84,11 +95,24 @@ public :
|
||||
// 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 );
|
||||
|
||||
CGPathRef GetPath() const;
|
||||
// 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 *p) {}
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsPath)
|
||||
DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsPath)
|
||||
private :
|
||||
CGMutablePathRef m_path;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxGraphicsPath implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsPath, wxGraphicsPath)
|
||||
|
||||
wxMacCoreGraphicsPath::wxMacCoreGraphicsPath()
|
||||
{
|
||||
m_path = CGPathCreateMutable();
|
||||
@@ -149,11 +173,6 @@ void wxMacCoreGraphicsPath::CloseSubpath()
|
||||
CGPathCloseSubpath( m_path );
|
||||
}
|
||||
|
||||
CGPathRef wxMacCoreGraphicsPath::GetPath() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
// gets the last point of the current path, (0,0) if not yet set
|
||||
void wxMacCoreGraphicsPath::GetCurrentPoint( wxDouble& x, wxDouble&y)
|
||||
{
|
||||
@@ -168,13 +187,13 @@ void wxMacCoreGraphicsPath::GetCurrentPoint( wxDouble& x, wxDouble&y)
|
||||
|
||||
class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext
|
||||
{
|
||||
DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext)
|
||||
|
||||
public:
|
||||
wxMacCoreGraphicsContext( CGContextRef cgcontext );
|
||||
|
||||
wxMacCoreGraphicsContext( WindowRef window );
|
||||
|
||||
wxMacCoreGraphicsContext( wxWindow* window );
|
||||
|
||||
wxMacCoreGraphicsContext();
|
||||
|
||||
~wxMacCoreGraphicsContext();
|
||||
@@ -272,9 +291,17 @@ public:
|
||||
void SetNativeContext( CGContextRef cg );
|
||||
CGPathDrawingMode GetDrawingMode() const { return m_mode; }
|
||||
|
||||
DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext)
|
||||
DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsContext)
|
||||
|
||||
private:
|
||||
void EnsureIsValid();
|
||||
|
||||
CGContextRef m_cgContext;
|
||||
WindowRef m_windowRef;
|
||||
int m_originX;
|
||||
int m_originY;
|
||||
wxMacCFRefHolder<HIShapeRef> m_clipRgn;
|
||||
bool m_releaseContext;
|
||||
CGPathDrawingMode m_mode;
|
||||
ATSUStyle m_macATSUIStyle;
|
||||
@@ -284,18 +311,6 @@ private:
|
||||
wxColor m_textForegroundColor;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// device context implementation
|
||||
//
|
||||
@@ -308,20 +323,19 @@ static const double RAD2DEG = 180.0 / M_PI;
|
||||
// state we were called with, the other one after changing to HI Graphics orientation
|
||||
// (this one is used for getting back clippings etc)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxGraphicsPath implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// wxGraphicsContext implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext, wxGraphicsContext)
|
||||
|
||||
void wxMacCoreGraphicsContext::Init()
|
||||
{
|
||||
m_cgContext = NULL;
|
||||
m_mode = kCGPathFill;
|
||||
m_macATSUIStyle = NULL;
|
||||
m_releaseContext = false;
|
||||
m_clipRgn.Set(HIShapeCreateEmpty());
|
||||
}
|
||||
|
||||
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( CGContextRef cgcontext )
|
||||
@@ -336,15 +350,14 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( WindowRef window )
|
||||
{
|
||||
Init();
|
||||
m_windowRef = window;
|
||||
OSStatus status = QDBeginCGContext( GetWindowPort( window ) , &m_cgContext );
|
||||
wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") );
|
||||
Rect bounds;
|
||||
GetWindowBounds( window, kWindowContentRgn, &bounds );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top );
|
||||
CGContextScaleCTM( m_cgContext , 1 , -1 );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
m_releaseContext = true;
|
||||
}
|
||||
|
||||
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxWindow* window )
|
||||
{
|
||||
Init();
|
||||
m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef();
|
||||
m_originX = m_originY = 0;
|
||||
window->MacWindowToRootWindow( &m_originX , &m_originY );
|
||||
}
|
||||
|
||||
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext()
|
||||
@@ -356,7 +369,7 @@ wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
|
||||
{
|
||||
if ( m_cgContext )
|
||||
{
|
||||
CGContextSynchronize( m_cgContext );
|
||||
// TODO : when is this necessary - should we add a Flush() method ? CGContextSynchronize( m_cgContext );
|
||||
CGContextRestoreGState( m_cgContext );
|
||||
CGContextRestoreGState( m_cgContext );
|
||||
}
|
||||
@@ -365,31 +378,76 @@ wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
|
||||
QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext);
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::EnsureIsValid()
|
||||
{
|
||||
if ( !m_cgContext )
|
||||
{
|
||||
OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
|
||||
wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") );
|
||||
Rect bounds;
|
||||
GetWindowBounds( m_windowRef, kWindowContentRgn, &bounds );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top );
|
||||
CGContextScaleCTM( m_cgContext , 1 , -1 );
|
||||
CGContextTranslateCTM( m_cgContext, m_originX, m_originY );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
m_releaseContext = true;
|
||||
if ( !HIShapeIsEmpty(m_clipRgn) )
|
||||
{
|
||||
HIShapeReplacePathInCGContext( m_clipRgn, m_cgContext );
|
||||
CGContextClip( m_cgContext );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion )
|
||||
{
|
||||
HIShapeRef shape = HIShapeCreateWithQDRgn( (RgnHandle) region.GetWXHRGN() );
|
||||
HIShapeReplacePathInCGContext( shape, m_cgContext );
|
||||
CGContextClip( m_cgContext );
|
||||
CFRelease( shape );
|
||||
if( m_cgContext )
|
||||
{
|
||||
HIShapeRef shape = HIShapeCreateWithQDRgn( (RgnHandle) region.GetWXHRGN() );
|
||||
HIShapeReplacePathInCGContext( shape, m_cgContext );
|
||||
CGContextClip( m_cgContext );
|
||||
CFRelease( shape );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clipRgn.Set(HIShapeCreateWithQDRgn( (RgnHandle) region.GetWXHRGN() ));
|
||||
}
|
||||
}
|
||||
|
||||
// clips drawings to the rect
|
||||
void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
|
||||
{
|
||||
HIRect r = CGRectMake( x , y , w , h );
|
||||
CGContextClipToRect( m_cgContext, r );
|
||||
HIRect r = CGRectMake( x , y , w , h );
|
||||
if ( m_cgContext )
|
||||
{
|
||||
CGContextClipToRect( m_cgContext, r );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clipRgn.Set(HIShapeCreateWithRect(&r));
|
||||
}
|
||||
}
|
||||
|
||||
// resets the clipping to original extent
|
||||
void wxMacCoreGraphicsContext::ResetClip()
|
||||
{
|
||||
CGContextRestoreGState( m_cgContext );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
if ( m_cgContext )
|
||||
{
|
||||
CGContextRestoreGState( m_cgContext );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clipRgn.Set(HIShapeCreateEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath *p )
|
||||
void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath *path )
|
||||
{
|
||||
const wxMacCoreGraphicsPath* path = dynamic_cast< const wxMacCoreGraphicsPath*>( p );
|
||||
EnsureIsValid();
|
||||
|
||||
int width = m_pen.GetWidth();
|
||||
if ( width == 0 )
|
||||
width = 1 ;
|
||||
@@ -401,16 +459,17 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath *p )
|
||||
if ( offset )
|
||||
CGContextTranslateCTM( m_cgContext, 0.5, 0.5 );
|
||||
|
||||
CGContextAddPath( m_cgContext , path->GetPath() );
|
||||
CGContextAddPath( m_cgContext , (CGPathRef) path->GetNativePath() );
|
||||
CGContextStrokePath( m_cgContext );
|
||||
|
||||
if ( offset )
|
||||
CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath *p , int fillStyle )
|
||||
void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath *path , int fillStyle )
|
||||
{
|
||||
const wxMacCoreGraphicsPath* path = dynamic_cast< const wxMacCoreGraphicsPath*>( p );
|
||||
EnsureIsValid();
|
||||
|
||||
CGPathDrawingMode mode = m_mode;
|
||||
|
||||
if ( fillStyle == wxODDEVEN_RULE )
|
||||
@@ -432,18 +491,18 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath *p , int fillStyle
|
||||
if ( offset )
|
||||
CGContextTranslateCTM( m_cgContext, 0.5, 0.5 );
|
||||
|
||||
CGContextAddPath( m_cgContext , path->GetPath() );
|
||||
CGContextAddPath( m_cgContext , (CGPathRef) path->GetNativePath() );
|
||||
CGContextDrawPath( m_cgContext , mode );
|
||||
|
||||
if ( offset )
|
||||
CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath *p , int fillStyle )
|
||||
void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath *path , int fillStyle )
|
||||
{
|
||||
const wxMacCoreGraphicsPath* path = dynamic_cast< const wxMacCoreGraphicsPath*>( p );
|
||||
|
||||
CGContextAddPath( m_cgContext , path->GetPath() );
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextAddPath( m_cgContext , (CGPathRef) path->GetNativePath() );
|
||||
if ( fillStyle == wxODDEVEN_RULE )
|
||||
CGContextEOFillPath( m_cgContext );
|
||||
else
|
||||
@@ -467,21 +526,29 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
|
||||
|
||||
void wxMacCoreGraphicsContext::Translate( wxDouble dx , wxDouble dy )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextTranslateCTM( m_cgContext, dx, dy );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::Scale( wxDouble xScale , wxDouble yScale )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextScaleCTM( m_cgContext , xScale , yScale );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::Rotate( wxDouble angle )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextRotateCTM( m_cgContext , angle );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGImageRef image = (CGImageRef)( bmp.CGImageCreate() );
|
||||
HIRect r = CGRectMake( x , y , w , h );
|
||||
HIViewDrawCGImage( m_cgContext , &r , image );
|
||||
@@ -490,6 +557,8 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDo
|
||||
|
||||
void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGRect r = CGRectMake( 00 , 00 , w , h );
|
||||
CGContextSaveGState( m_cgContext );
|
||||
CGContextTranslateCTM( m_cgContext, x , y + h );
|
||||
@@ -501,11 +570,15 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl
|
||||
|
||||
void wxMacCoreGraphicsContext::PushState()
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextSaveGState( m_cgContext );
|
||||
}
|
||||
|
||||
void wxMacCoreGraphicsContext::PopState()
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
CGContextRestoreGState( m_cgContext );
|
||||
}
|
||||
|
||||
@@ -979,6 +1052,8 @@ void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDoub
|
||||
|
||||
void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle )
|
||||
{
|
||||
EnsureIsValid();
|
||||
|
||||
OSStatus status = noErr;
|
||||
ATSUTextLayout atsuLayout;
|
||||
UniCharCount chars = str.length();
|
||||
@@ -1276,16 +1351,7 @@ wxGraphicsContext* wxGraphicsContext::Create( const wxWindowDC &dc )
|
||||
|
||||
wxGraphicsContext* wxGraphicsContext::Create( wxWindow * window )
|
||||
{
|
||||
wxGraphicsContext* ctx = new wxMacCoreGraphicsContext( (WindowRef) window->MacGetTopLevelWindowRef() );
|
||||
CGContextRef cg = (CGContextRef) ctx->GetNativeContext() ;
|
||||
CGContextRestoreGState( cg );
|
||||
int x , y;
|
||||
x = y = 0;
|
||||
window->MacWindowToRootWindow( &x , &y );
|
||||
CGContextTranslateCTM( cg, x, y );
|
||||
CGContextSaveGState( cg );
|
||||
return ctx;
|
||||
|
||||
return new wxMacCoreGraphicsContext( window );
|
||||
}
|
||||
|
||||
wxGraphicsContext* wxGraphicsContext::CreateFromNative( void * context )
|
||||
|
Reference in New Issue
Block a user