/////////////////////////////////////////////////////////////////////////////
-// Name: src/mac/carbon/dccg.cpp
+// Name: src/osx/carbon/dccg.cpp
// Purpose: wxDC class
// Author: Stefan Csomor
// Modified by:
// Created: 01/02/97
// RCS-ID: $Id$
-// Copyright: (c) Stefan Csomor
+// copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#endif
#ifdef __WXMAC__
- #include "wx/mac/uma.h"
- #include "wx/mac/dcprint.h"
+ #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/mac/corefoundation/cfstring.h"
+ #include "wx/osx/core/cfstring.h"
#include "wx/cocoa/dcclient.h"
#endif
}
-#define wxMAC_USE_CORE_TEXT 1
+#define wxOSX_USE_CORE_TEXT 1
+
+#endif
+
+#if wxOSX_USE_COCOA_OR_IPHONE
+extern CGContextRef wxOSXGetContextFromCurrentNSContext() ;
+extern bool wxOSXLockFocus( WXWidget view) ;
+extern void wxOSXUnlockFocus( WXWidget view) ;
+#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
const CGRect * inBounds,
CGImageRef inImage)
{
-#if defined( __LP64__ ) || defined(__WXCOCOA__)
- // todo flip
- CGContextDrawImage(inContext, *inBounds, inImage );
- return noErr;
-#else
+#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
}
return retval;
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && defined(wxMAC_USE_CORE_TEXT)
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && wxOSX_USE_CORE_TEXT
CTFontRef wxMacCreateCTFont( const wxFont& font )
{
}
else
{
- if ( context->GetLogicalFunction() == wxINVERT || context->GetLogicalFunction() == wxXOR )
- {
- CGContextSetRGBStrokeColor( cg , (CGFloat) 1.0,(CGFloat) 1.0 , (CGFloat) 1.0, (CGFloat) 1.0 );
- }
- else
- CGContextSetStrokeColorWithColor( cg , m_color );
+ CGContextSetStrokeColorWithColor( cg , m_color );
}
}
const wxColour &oColor, const wxColour &cColor )
{
m_gradientFunction = CreateGradientFunction( oColor, cColor );
- m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) xo,(CGFloat) yo), 0,
+ m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake((CGFloat) xo,(CGFloat) yo), 0,
CGPointMake((CGFloat) xc,(CGFloat) yc), (CGFloat) radius, m_gradientFunction, true, true ) ;
m_isShading = true ;
}
// 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 wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
virtual ATSUStyle GetATSUStyle() { return m_macATSUIStyle; }
#endif
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
CTFontRef GetCTFont() 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 wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
ATSUStyle m_macATSUIStyle;
#endif
-#if wxMAC_USE_CORE_TEXT
+#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 wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
m_ctFont.reset( wxMacCreateCTFont( font ) );
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_IPHONE
+ m_uiFont = CreateUIFont(font);
+ wxMacCocoaRetain( m_uiFont );
+#endif
+#if wxOSX_USE_ATSU_TEXT
OSStatus status = noErr;
m_macATSUIStyle = NULL;
wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
#endif
-#if wxMAC_USE_CG_TEXT
-#endif
}
wxMacCoreGraphicsFontData::~wxMacCoreGraphicsFontData()
{
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
if ( m_macATSUIStyle )
{
::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
m_macATSUIStyle = NULL;
}
#endif
-#if wxMAC_USE_CG_TEXT
+#if wxOSX_USE_IPHONE
+ wxMacCocoaRelease( m_uiFont );
#endif
}
// gets the bounding box enclosing all points (possibly including control points)
virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *y) const;
- virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE) const;
+ virtual bool Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle = wxODDEVEN_RULE) const;
private :
CGMutablePathRef m_path;
};
*h = bounds.size.height;
}
-bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, int fillStyle) const
+bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillMode fillStyle) const
{
return CGPathContainsPoint( m_path, NULL, CGPointMake((CGFloat) x,(CGFloat) y), fillStyle == wxODDEVEN_RULE );
}
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 );
virtual void * GetNativeContext();
- bool SetLogicalFunction( int function );
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+
+ virtual bool SetCompositionMode(wxCompositionMode op);
+
+ virtual void BeginLayer(wxDouble opacity);
+
+ virtual void EndLayer();
+
//
// transformation
//
virtual void StrokePath( const wxGraphicsPath &path );
// fills a path with the current brush
- virtual void FillPath( const wxGraphicsPath &path, int fillStyle = wxODDEVEN_RULE );
+ 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, int fillStyle = wxODDEVEN_RULE );
+ virtual void DrawPath( const wxGraphicsPath &path, wxPolygonFillMode fillStyle = wxODDEVEN_RULE );
virtual bool ShouldOffset() const
{
// text
//
- virtual void DrawText( const wxString &str, wxDouble x, wxDouble y );
-
- virtual void DrawText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle );
-
virtual void GetTextExtent( const wxString &text, wxDouble *width, wxDouble *height,
wxDouble *descent, wxDouble *externalLeading ) const;
void SetNativeContext( CGContextRef cg );
- DECLARE_NO_COPY_CLASS(wxMacCoreGraphicsContext)
- DECLARE_DYNAMIC_CLASS(wxMacCoreGraphicsContext)
+ DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacCoreGraphicsContext)
private:
- void EnsureIsValid();
+ 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;
- bool m_releaseContext;
+#else
+ WXWidget m_view;
+#endif
+ bool m_contextSynthesized;
CGAffineTransform m_windowTransform;
wxDouble m_width;
wxDouble m_height;
+ bool m_invisible;
+#if wxOSX_USE_COCOA_OR_CARBON
wxCFRef<HIShapeRef> m_clipRgn;
+#endif
};
//-----------------------------------------------------------------------------
void wxMacCoreGraphicsContext::Init()
{
m_cgContext = NULL;
- m_releaseContext = false;
- m_windowRef = 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;
}
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer)
m_height = height;
}
+#if wxOSX_USE_CARBON
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ): wxGraphicsContext(renderer)
{
Init();
m_windowRef = window;
}
+#endif
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer)
{
Init();
+ wxSize sz = window->GetSize();
+ m_width = sz.x;
+ m_height = sz.y;
+
+#if wxOSX_USE_COCOA_OR_IPHONE
+ m_view = window->GetHandle();
+
+ if ( !((wxWidgetCocoaImpl*) window->GetPeer())->IsFlipped() )
+ {
+ m_windowTransform = CGAffineTransformMakeTranslation( 0 , m_height );
+ m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 );
+ }
+ else
+ {
+ m_windowTransform = CGAffineTransformIdentity;
+ }
+#else
int originX , originY;
originX = originY = 0;
-
Rect bounds = { 0,0,0,0 };
-#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 );
m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 );
m_windowTransform = CGAffineTransformTranslate( m_windowTransform, originX, originY ) ;
+#endif
}
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext(renderer)
CGContextFlush(m_cgContext);
}
-void wxMacCoreGraphicsContext::EnsureIsValid()
+bool wxMacCoreGraphicsContext::EnsureIsValid()
{
if ( !m_cgContext )
{
- OSStatus status =
-#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) )
- QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
-#else
- paramErr;
+ if (m_invisible)
+ return false;
+
+#if wxOSX_USE_COCOA_OR_IPHONE
+ if ( wxOSXLockFocus(m_view) )
+ {
+ m_cgContext = wxOSXGetContextFromCurrentNSContext();
+ wxASSERT_MSG( m_cgContext != NULL, _T("Unable to retrieve drawing context from View"));
+ }
+ else
+ {
+ m_invisible = true;
+ }
#endif
+#if wxOSX_USE_CARBON
+ OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
if ( status != noErr )
{
wxFAIL_MSG("Cannot nest wxDCs on the same window");
}
-
- CGContextConcatCTM( m_cgContext, m_windowTransform );
- CGContextSaveGState( m_cgContext );
- m_releaseContext = true;
- if ( m_clipRgn.get() )
+#endif
+ if ( m_cgContext )
{
- // the clip region is in device coordinates, so we convert this again to user coordinates
- wxCFRef<HIMutableShapeRef> hishape( HIShapeCreateMutableCopy( m_clipRgn ) );
- CGPoint transformedOrigin = CGPointApplyAffineTransform( CGPointZero,m_windowTransform);
- HIShapeOffset( hishape, -transformedOrigin.x, -transformedOrigin.y );
- // if the shape is empty, HIShapeReplacePathInCGContext doesn't work
- if ( HIShapeIsEmpty(hishape))
+ CGContextConcatCTM( m_cgContext, m_windowTransform );
+ CGContextSaveGState( m_cgContext );
+ m_contextSynthesized = true;
+ if ( m_clipRgn.get() )
{
- CGRect empty = CGRectMake( 0,0,0,0 );
- CGContextClipToRect( m_cgContext, empty );
+ // the clip region is in device coordinates, so we convert this again to user coordinates
+ wxCFRef<HIMutableShapeRef> hishape( HIShapeCreateMutableCopy( m_clipRgn ) );
+ CGPoint transformedOrigin = CGPointApplyAffineTransform( CGPointZero,m_windowTransform);
+ HIShapeOffset( hishape, -transformedOrigin.x, -transformedOrigin.y );
+ // if the shape is empty, HIShapeReplacePathInCGContext doesn't work
+ if ( HIShapeIsEmpty(hishape))
+ {
+ CGRect empty = CGRectMake( 0,0,0,0 );
+ CGContextClipToRect( m_cgContext, empty );
+ }
+ else
+ {
+ HIShapeReplacePathInCGContext( hishape, m_cgContext );
+ CGContextClip( m_cgContext );
+ }
}
- else
+ CGContextSaveGState( m_cgContext );
+
+#if 0 // turn on for debugging of clientdc
+ static float color = 0.5 ;
+ static int channel = 0 ;
+ CGRect bounds = CGRectMake(-1000,-1000,2000,2000);
+ CGContextSetRGBFillColor( m_cgContext, channel == 0 ? color : 0.5 ,
+ channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
+ CGContextFillRect( m_cgContext, bounds );
+ color += 0.1 ;
+ if ( color > 0.9 )
{
- HIShapeReplacePathInCGContext( hishape, m_cgContext );
- CGContextClip( m_cgContext );
+ color = 0.5 ;
+ channel++ ;
+ if ( channel == 3 )
+ channel = 0 ;
}
+#endif
}
- CGContextSaveGState( m_cgContext );
}
+ return m_cgContext != NULL;
}
-// TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes)
-
-bool wxMacCoreGraphicsContext::SetLogicalFunction( int function )
+bool wxMacCoreGraphicsContext::SetAntialiasMode(wxAntialiasMode antialias)
{
- if (m_logicalFunction == function)
+ if (EnsureIsValid()==false)
return true;
- EnsureIsValid();
+ if (m_antialias == antialias)
+ return true;
+
+ m_antialias = antialias;
+
+ bool antialiasMode;
+ switch (antialias)
+ {
+ case wxANTIALIAS_DEFAULT:
+ antialiasMode = true;
+ break;
+ case wxANTIALIAS_NONE:
+ antialiasMode = false;
+ break;
+ default:
+ return false;
+ }
+ CGContextSetShouldAntialias(m_cgContext, antialiasMode);
+ return true;
+}
- bool retval = false;
- bool shouldAntiAlias = true;
- CGBlendMode mode = kCGBlendModeNormal;
+bool wxMacCoreGraphicsContext::SetCompositionMode(wxCompositionMode op)
+{
+ if (EnsureIsValid()==false)
+ return true;
-#if defined(__WXMAC__) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 )
- if ( UMAGetSystemVersion() >= 0x1050 )
+ if ( m_composition == op )
+ return true;
+
+ m_composition = op;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return true;
+
+#if wxOSX_USE_COCOA_OR_CARBON
+ if ( UMAGetSystemVersion() < 0x1060 )
{
- retval = true;
- switch ( function )
+ CGCompositeOperation cop = kCGCompositeOperationSourceOver;
+ CGBlendMode mode = kCGBlendModeNormal;
+ switch( op )
{
- // 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;
+ case wxCOMPOSITION_CLEAR:
+ cop = kCGCompositeOperationClear;
+ break;
+ case wxCOMPOSITION_SOURCE:
+ cop = kCGCompositeOperationCopy;
+ break;
+ case wxCOMPOSITION_OVER:
+ mode = kCGBlendModeNormal;
+ break;
+ case wxCOMPOSITION_IN:
+ cop = kCGCompositeOperationSourceIn;
+ break;
+ case wxCOMPOSITION_OUT:
+ cop = kCGCompositeOperationSourceOut;
+ break;
+ case wxCOMPOSITION_ATOP:
+ cop = kCGCompositeOperationSourceAtop;
+ break;
+ case wxCOMPOSITION_DEST_OVER:
+ cop = kCGCompositeOperationDestinationOver;
+ break;
+ case wxCOMPOSITION_DEST_IN:
+ cop = kCGCompositeOperationDestinationIn;
+ break;
+ case wxCOMPOSITION_DEST_OUT:
+ cop = kCGCompositeOperationDestinationOut;
+ break;
+ case wxCOMPOSITION_DEST_ATOP:
+ cop = kCGCompositeOperationDestinationAtop;
+ break;
+ case wxCOMPOSITION_XOR:
+ cop = kCGCompositeOperationXOR;
+ break;
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ case wxCOMPOSITION_ADD:
+ mode = kCGBlendModePlusLighter ;
+ break;
+#endif
+ default:
+ return false;
}
+ if ( cop != kCGCompositeOperationSourceOver )
+ CGContextSetCompositeOperation(m_cgContext, cop);
+ else
+ CGContextSetBlendMode(m_cgContext, mode);
}
- else
#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
+ else
{
- if ( function == wxCOPY )
+ CGBlendMode mode = kCGBlendModeNormal;
+ switch( op )
{
- retval = true;
- }
- else if ( function == wxINVERT || function == wxXOR )
- {
- // change color to white
- mode = kCGBlendModeExclusion;
- shouldAntiAlias = false;
- retval = true;
+ case wxCOMPOSITION_CLEAR:
+ mode = kCGBlendModeClear;
+ break;
+ case wxCOMPOSITION_SOURCE:
+ mode = kCGBlendModeCopy;
+ break;
+ case wxCOMPOSITION_OVER:
+ mode = kCGBlendModeNormal;
+ break;
+ case wxCOMPOSITION_IN:
+ mode = kCGBlendModeSourceIn;
+ break;
+ case wxCOMPOSITION_OUT:
+ mode = kCGBlendModeSourceOut;
+ break;
+ case wxCOMPOSITION_ATOP:
+ mode = kCGBlendModeSourceAtop;
+ break;
+ case wxCOMPOSITION_DEST_OVER:
+ mode = kCGBlendModeDestinationOver;
+ break;
+ case wxCOMPOSITION_DEST_IN:
+ mode = kCGBlendModeDestinationIn;
+ break;
+ case wxCOMPOSITION_DEST_OUT:
+ mode = kCGBlendModeDestinationOut;
+ break;
+ case wxCOMPOSITION_DEST_ATOP:
+ mode = kCGBlendModeDestinationAtop;
+ break;
+ case wxCOMPOSITION_XOR:
+ mode = kCGBlendModeXOR;
+ break;
+
+ case wxCOMPOSITION_ADD:
+ mode = kCGBlendModePlusLighter ;
+ break;
+ default:
+ return false;
}
+ CGContextSetBlendMode(m_cgContext, mode);
}
+#endif
+ return true;
+}
- if (retval)
- {
- m_logicalFunction = function;
- CGContextSetBlendMode( m_cgContext, mode );
- CGContextSetShouldAntialias(m_cgContext, shouldAntiAlias);
- }
- return retval ;
+void wxMacCoreGraphicsContext::BeginLayer(wxDouble opacity)
+{
+ CGContextSaveGState(m_cgContext);
+ CGContextSetAlpha(m_cgContext, opacity);
+ CGContextBeginTransparencyLayer(m_cgContext, 0);
+}
+
+void wxMacCoreGraphicsContext::EndLayer()
+{
+ CGContextEndTransparencyLayer(m_cgContext);
+ CGContextRestoreGState(m_cgContext);
}
void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion )
{
-#ifdef __WXMAC__
+#if wxOSX_USE_COCOA_OR_CARBON
if( m_cgContext )
{
wxCFRef<HIShapeRef> shape = wxCFRefFromGet(region.GetWXHRGN());
HIShapeOffset( mutableShape, transformedOrigin.x, transformedOrigin.y );
m_clipRgn.reset(mutableShape);
}
+#else
+ // allow usage as measuring context
+ // wxASSERT_MSG( m_cgContext != NULL, "Needs a valid context for clipping" );
#endif
}
}
else
{
+#if wxOSX_USE_COCOA_OR_CARBON
// 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.reset(HIShapeCreateWithRect(&r));
+#else
+ // allow usage as measuring context
+ // wxFAIL_MSG( "Needs a valid context for clipping" );
+#endif
}
}
}
else
{
+#if wxOSX_USE_COCOA_OR_CARBON
m_clipRgn.reset();
+#else
+ // allow usage as measuring context
+ // wxFAIL_MSG( "Needs a valid context for clipping" );
+#endif
}
}
if ( m_pen.IsNull() )
return ;
- EnsureIsValid();
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
CGContextStrokePath( m_cgContext );
}
-void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , int fillStyle )
+void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , wxPolygonFillMode fillStyle )
{
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( !m_brush.IsNull() && ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
{
// when using shading, we cannot draw pen and brush at the same time
}
}
- EnsureIsValid();
-
if ( !m_brush.IsNull() )
((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->Apply(this);
if ( !m_pen.IsNull() )
CGContextDrawPath( m_cgContext , mode );
}
-void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , int fillStyle )
+void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , wxPolygonFillMode fillStyle )
{
if ( m_brush.IsNull() )
return;
- EnsureIsValid();
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
{
if ( m_cgContext )
{
- // TODO : when is this necessary - should we add a Flush() method ? CGContextSynchronize( m_cgContext );
CGContextRestoreGState( m_cgContext );
CGContextRestoreGState( m_cgContext );
- if ( m_releaseContext )
+ if ( m_contextSynthesized )
{
-#if ! ( defined( __LP64__ ) || defined(__WXCOCOA__) )
+ // TODO: in case of performance problems, try issuing this not too
+ // frequently (half of refresh rate)
+ CGContextFlush(m_cgContext);
+#if wxOSX_USE_CARBON
QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext);
+#endif
+#if wxOSX_USE_COCOA_OR_IPHONE
+ wxOSXUnlockFocus(m_view);
#endif
}
else
CGContextRelease(m_cgContext);
}
-
m_cgContext = cg;
// FIXME: This check is needed because currently we need to use a DC/GraphicsContext
CGContextSaveGState( m_cgContext );
CGContextSetTextMatrix( m_cgContext, CGAffineTransformIdentity );
CGContextSaveGState( m_cgContext );
- m_releaseContext = false;
+ m_contextSynthesized = false;
}
}
void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
{
- EnsureIsValid();
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
#ifdef __WXMAC__
wxMacCoreGraphicsBitmapData* refdata =static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
CGImageRef image = refdata->GetBitmap();
void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
{
- EnsureIsValid();
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
CGRect r = CGRectMake( (CGFloat) 0.0 , (CGFloat) 0.0 , (CGFloat) w , (CGFloat) h );
CGContextSaveGState( m_cgContext );
CGContextTranslateCTM( m_cgContext,(CGFloat) x ,(CGFloat) (y + h) );
CGContextScaleCTM( m_cgContext, 1, -1 );
-#ifdef __WXMAC__
+#if wxOSX_USE_COCOA_OR_CARBON
PlotIconRefInContext( m_cgContext , &r , kAlignNone , kTransformNone ,
- NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) );
+ NULL , kPlotIconRefNormalFlags , icon.GetHICON() );
#endif
CGContextRestoreGState( m_cgContext );
}
void wxMacCoreGraphicsContext::PushState()
{
- EnsureIsValid();
-
+ if (EnsureIsValid()==false)
+ return;
+
CGContextSaveGState( m_cgContext );
}
void wxMacCoreGraphicsContext::PopState()
{
- EnsureIsValid();
-
+ if (EnsureIsValid()==false)
+ return;
+
CGContextRestoreGState( m_cgContext );
}
-void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y )
+void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDouble y )
{
- if ( m_font.IsNull() )
+ wxCHECK_RET( !m_font.IsNull(), wxT("wxMacCoreGraphicsContext::DrawText - no valid font set") );
+
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
return;
- EnsureIsValid();
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
return;
}
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
{
DrawText(str, x, y, 0.0);
return;
}
#endif
-#if wxMAC_USE_CG_TEXT
- // TODO core graphics text implementation here
+#if wxOSX_USE_IPHONE
+ wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
+
+ CGContextSaveGState(m_cgContext);
+
+ CGColorRef col = wxMacCreateCGColor( fref->GetColour() );
+ CGContextSetTextDrawingMode (m_cgContext, kCGTextFill);
+ CGContextSetFillColorWithColor( m_cgContext, col );
+
+ wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
+ DrawTextInContext( m_cgContext, CGPointMake( x, y ), fref->GetUIFont() , text.AsNSString() );
+
+ CGContextRestoreGState(m_cgContext);
+ CFRelease( col );
#endif
}
-void wxMacCoreGraphicsContext::DrawText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle )
+void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str,
+ wxDouble x, wxDouble y,
+ wxDouble angle)
{
- if ( m_font.IsNull() )
+ wxCHECK_RET( !m_font.IsNull(), wxT("wxMacCoreGraphicsContext::DrawText - no valid font set") );
+
+ if (EnsureIsValid()==false)
+ return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
return;
- EnsureIsValid();
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
// default implementation takes care of rotation and calls non rotated DrawText afterwards
- wxGraphicsContext::DrawText( str, x, y, angle );
+ wxGraphicsContext::DoDrawRotatedText( str, x, y, angle );
return;
}
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
{
OSStatus status = noErr;
ATSUTextLayout atsuLayout;
return;
}
#endif
-#if wxMAC_USE_CG_TEXT
+#if wxOSX_USE_IPHONE
// default implementation takes care of rotation and calls non rotated DrawText afterwards
- wxGraphicsContext::DrawText( str, x, y, angle );
+ wxGraphicsContext::DoDrawRotatedText( str, x, y, angle );
#endif
}
void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
wxDouble *descent, wxDouble *externalLeading ) const
{
- wxCHECK_RET( !m_font.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") );
+ wxCHECK_RET( !m_font.IsNull(), wxT("wxMacCoreGraphicsContext::GetTextExtent - no valid font set") );
if ( width )
*width = 0;
if (str.empty())
return;
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
return;
}
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
{
OSStatus status = noErr;
return;
}
#endif
-#if wxMAC_USE_CG_TEXT
- // TODO core graphics text implementation here
+#if wxOSX_USE_IPHONE
+ wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
+
+ wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
+ CGSize sz = MeasureTextInContext( fref->GetUIFont() , text.AsNSString() );
+
+ if ( height )
+ *height = sz.height;
+ /*
+ if ( descent )
+ *descent = FixedToInt(textDescent);
+ if ( externalLeading )
+ *externalLeading = 0;
+ */
+ if ( width )
+ *width = sz.width;
#endif
}
widths.Empty();
widths.Add(0, text.length());
+ wxCHECK_RET( !m_font.IsNull(), wxT("wxMacCoreGraphicsContext::DrawText - no valid font set") );
+
if (text.empty())
return;
-#if wxMAC_USE_CORE_TEXT
+#if wxOSX_USE_CORE_TEXT
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
CTFontRef font = fref->GetCTFont();
return;
}
#endif
-#if wxMAC_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
{
OSStatus status = noErr;
ATSUTextLayout atsuLayout;
#else
ATSLayoutRecord *layoutRecords = NULL;
ItemCount glyphCount = 0;
-
+
// Get the glyph extents
OSStatus err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(atsuLayout,
0,
&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);
::ATSUDisposeTextLayout(atsuLayout);
}
#endif
-#if wxMAC_USE_CG_TEXT
+#if wxOSX_USE_IPHONE
// TODO core graphics text implementation here
#endif
}
virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc);
virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc);
+#if wxUSE_PRINTING_ARCHITECTURE
virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc);
+#endif
virtual wxGraphicsContext * CreateContextFromNativeContext( void * context );
return &gs_MacCoreGraphicsRenderer;
}
-#ifdef __WXCOCOA__
-extern CGContextRef wxMacGetContextFromCurrentNSContext() ;
-#endif
-
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc )
{
const wxDCImpl* impl = dc.GetImpl();
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 );
+
+ wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext");
+ if (win_impl->GetWindow())
+ cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef());
+
+ if (cgctx != 0)
+ return new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h );
}
return NULL;
}
return NULL;
}
+#if wxUSE_PRINTING_ARCHITECTURE
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxPrinterDC& dc )
{
#ifdef __WXMAC__
#endif
return NULL;
}
+#endif
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeContext( void * context )
{
return new wxMacCoreGraphicsContext(this,(CGContextRef)context);
}
-
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( void * window )
{
+#if wxOSX_USE_CARBON
return new wxMacCoreGraphicsContext(this,(WindowRef)window);
+#else
+ return NULL;
+#endif
}
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( wxWindow* window )