// Modified by:
// Created: 01/02/97
// RCS-ID: $Id$
-// Copyright: (c) Stefan Csomor
+// copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#endif
#if wxOSX_USE_COCOA_OR_IPHONE
-extern CGContextRef wxOSXGetContextFromCurrentNSContext() ;
+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
CTFontRef wxMacCreateCTFont( const wxFont& font )
{
#ifdef __WXMAC__
- return wxCFRetain((CTFontRef) font.MacGetCTFont());
+ return wxCFRetain((CTFontRef) font.OSXGetCTFont());
#else
return CTFontCreateWithName( wxCFStringRef( font.GetFaceName(), wxLocale::GetSystemEncoding() ) , font.GetPointSize() , NULL );
#endif
}
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 );
}
}
virtual ATSUStyle GetATSUStyle() { return m_macATSUIStyle; }
#endif
#if wxOSX_USE_CORE_TEXT
- CTFontRef GetCTFont() const { return m_ctFont ; }
+ CTFontRef OSXGetCTFont() const { return m_ctFont ; }
#endif
wxColour GetColour() const { return m_colour ; }
// we need the scale here ...
- Fixed atsuSize = IntToFixed( int( 1 * font.MacGetFontSize()) );
+ Fixed atsuSize = IntToFixed( int( 1 * font.GetPointSize()) );
RGBColor atsuColor ;
col.GetRGBColor( &atsuColor );
ATSUAttributeTag atsuTags[] =
kATSUSizeTag ,
kATSUColorTag ,
};
- ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
{
sizeof( Fixed ) ,
sizeof( RGBColor ) ,
};
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[WXSIZEOF(atsuTags)] =
{
&atsuSize ,
&atsuColor ,
};
status = ::ATSUSetAttributes(
- m_macATSUIStyle, sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
+ m_macATSUIStyle, WXSIZEOF(atsuTags),
atsuTags, atsuSizes, atsuValues);
wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
virtual void * GetNativeContext();
- bool SetLogicalFunction( wxRasterOperationMode function );
+ virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+
+ virtual bool SetCompositionMode(wxCompositionMode op);
+
+ virtual void BeginLayer(wxDouble opacity);
+
+ virtual void EndLayer();
+
//
// transformation
//
#if wxOSX_USE_COCOA_OR_IPHONE
m_view = window->GetHandle();
- if ( !((wxWidgetCocoaImpl*) window->GetPeer())->IsFlipped() )
+#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;
}
if (m_invisible)
return false;
-#if wxOSX_USE_COCOA_OR_IPHONE
+#if wxOSX_USE_COCOA
if ( wxOSXLockFocus(m_view) )
{
- m_cgContext = wxOSXGetContextFromCurrentNSContext();
- wxASSERT_MSG( m_cgContext != NULL, _T("Unable to retrieve drawing context from View"));
+ m_cgContext = wxOSXGetContextFromCurrentContext();
+ wxASSERT_MSG( m_cgContext != NULL, wxT("Unable to retrieve drawing context from View"));
}
else
{
m_invisible = true;
}
#endif
+#if wxOSX_USE_IPHONE
+ m_cgContext = wxOSXGetContextFromCurrentContext();
+ if ( m_cgContext == NULL )
+ {
+ m_invisible = true;
+ }
+#endif
#if wxOSX_USE_CARBON
OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
if ( status != noErr )
CGContextConcatCTM( m_cgContext, m_windowTransform );
CGContextSaveGState( m_cgContext );
m_contextSynthesized = true;
+#if wxOSX_USE_COCOA_OR_CARBON
if ( m_clipRgn.get() )
{
// the clip region is in device coordinates, so we convert this again to user coordinates
CGContextClip( m_cgContext );
}
}
+#endif
CGContextSaveGState( m_cgContext );
#if 0 // turn on for debugging of clientdc
return m_cgContext != NULL;
}
-// TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes)
-
-bool wxMacCoreGraphicsContext::SetLogicalFunction( wxRasterOperationMode function )
+bool wxMacCoreGraphicsContext::SetAntialiasMode(wxAntialiasMode antialias)
{
- if (m_logicalFunction == function)
+ if (EnsureIsValid()==false)
+ return true;
+
+ 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 wxMacCoreGraphicsContext::SetCompositionMode(wxCompositionMode op)
+{
if (EnsureIsValid()==false)
return true;
-
- bool retval = false;
- bool shouldAntiAlias = true;
- CGBlendMode mode = kCGBlendModeNormal;
-#if defined(__WXMAC__) && ( wxOSX_USE_IPHONE || ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 ) )
-#if wxOSX_USE_IPHONE
- if ( 1 )
-#else
- if ( UMAGetSystemVersion() >= 0x1050 )
-#endif
+ 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, (CGFloat) opacity);
+ CGContextBeginTransparencyLayer(m_cgContext, 0);
+}
+
+void wxMacCoreGraphicsContext::EndLayer()
+{
+ CGContextEndTransparencyLayer(m_cgContext);
+ CGContextRestoreGState(m_cgContext);
}
void wxMacCoreGraphicsContext::Clip( const wxRegion ®ion )
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
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
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() )
{
CGContextSaveGState( m_cgContext );
#if wxOSX_USE_CARBON
QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext);
#endif
-#if wxOSX_USE_COCOA_OR_IPHONE
+#if wxOSX_USE_COCOA
wxOSXUnlockFocus(m_view);
#endif
}
{
if (EnsureIsValid()==false)
return;
+
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
#ifdef __WXMAC__
wxMacCoreGraphicsBitmapData* refdata =static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
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) );
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
- CTFontRef font = fref->GetCTFont();
+ CTFontRef font = fref->OSXGetCTFont();
CGColorRef col = wxMacCreateCGColor( fref->GetColour() );
CTUnderlineStyle ustyle = fref->GetUnderlined() ? kCTUnderlineStyleSingle : kCTUnderlineStyleNone ;
wxCFRef<CFNumberRef> underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) );
y += CTFontGetAscent(font);
CGContextSaveGState(m_cgContext);
- CGContextTranslateCTM(m_cgContext, x, y);
+ CGContextTranslateCTM(m_cgContext, (CGFloat) x, (CGFloat) y);
CGContextScaleCTM(m_cgContext, 1, -1);
CGContextSetTextPosition(m_cgContext, 0, 0);
CTLineDraw( line, m_cgContext );
if (EnsureIsValid()==false)
return;
+ if (m_composition == wxCOMPOSITION_DEST)
+ return;
+
#if wxOSX_USE_CORE_TEXT
if ( UMAGetSystemVersion() >= 0x1050 )
{
{
kATSULineRotationTag ,
};
- ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
{
sizeof( Fixed ) ,
};
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[WXSIZEOF(atsuTags)] =
{
&atsuAngle ,
};
- status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
+ status = ::ATSUSetLayoutControls(atsuLayout , WXSIZEOF(atsuTags),
atsuTags, atsuSizes, atsuValues );
}
{
kATSUCGContextTag ,
};
- ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
{
sizeof( CGContextRef ) ,
};
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[WXSIZEOF(atsuTags)] =
{
&m_cgContext ,
};
- status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
+ status = ::ATSUSetLayoutControls(atsuLayout , WXSIZEOF(atsuTags),
atsuTags, atsuSizes, atsuValues );
}
if ( UMAGetSystemVersion() >= 0x1050 )
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
- CTFontRef font = fref->GetCTFont();
+ CTFontRef font = fref->OSXGetCTFont();
wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
CFStringRef keys[] = { kCTFontAttributeName };
wxCFRef<CFAttributedStringRef> attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) );
wxCFRef<CTLineRef> line( CTLineCreateWithAttributedString(attrtext) );
- CGFloat w, a, d, l;
+ double w;
+ CGFloat a, d, l;
w = CTLineGetTypographicBounds(line, &a, &d, &l) ;
#if wxOSX_USE_CORE_TEXT
{
wxMacCoreGraphicsFontData* fref = (wxMacCoreGraphicsFontData*)m_font.GetRefData();
- CTFontRef font = fref->GetCTFont();
+ CTFontRef font = fref->OSXGetCTFont();
wxCFStringRef t(text, wxLocale::GetSystemEncoding() );
CFStringRef keys[] = { kCTFontAttributeName };
#if wxOSX_USE_CARBON
return new wxMacCoreGraphicsContext(this,(WindowRef)window);
#else
+ wxUnusedVar(window);
return NULL;
#endif
}