X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c0f6cd192451e0d0ab7d1382b95a6f9e155d6c44..ae901b234c4a0aa7c1777b3bd181dd7f8517ad21:/src/osx/carbon/graphics.cpp diff --git a/src/osx/carbon/graphics.cpp b/src/osx/carbon/graphics.cpp index 4e1fac0d53..4a1e139f31 100644 --- a/src/osx/carbon/graphics.cpp +++ b/src/osx/carbon/graphics.cpp @@ -5,7 +5,7 @@ // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Stefan Csomor +// copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -72,11 +72,42 @@ int UMAGetSystemVersion() #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 @@ -142,7 +173,7 @@ CGColorRef wxMacCreateCGColor( const wxColour& col ) 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 @@ -534,12 +565,7 @@ void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context ) } 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 ); } } @@ -791,7 +817,7 @@ public: 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 ; } @@ -835,7 +861,7 @@ wxMacCoreGraphicsFontData::wxMacCoreGraphicsFontData(wxGraphicsRenderer* rendere // 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[] = @@ -1316,7 +1342,14 @@ public: 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 // @@ -1488,12 +1521,14 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer #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; } @@ -1563,10 +1598,10 @@ bool wxMacCoreGraphicsContext::EnsureIsValid() if (m_invisible) return false; -#if wxOSX_USE_COCOA_OR_IPHONE +#if wxOSX_USE_COCOA if ( wxOSXLockFocus(m_view) ) { - m_cgContext = wxOSXGetContextFromCurrentNSContext(); + m_cgContext = wxOSXGetContextFromCurrentContext(); wxASSERT_MSG( m_cgContext != NULL, _T("Unable to retrieve drawing context from View")); } else @@ -1574,6 +1609,13 @@ bool wxMacCoreGraphicsContext::EnsureIsValid() 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 ) @@ -1586,6 +1628,7 @@ bool wxMacCoreGraphicsContext::EnsureIsValid() 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 @@ -1604,6 +1647,7 @@ bool wxMacCoreGraphicsContext::EnsureIsValid() CGContextClip( m_cgContext ); } } +#endif CGContextSaveGState( m_cgContext ); #if 0 // turn on for debugging of clientdc @@ -1627,69 +1671,162 @@ bool wxMacCoreGraphicsContext::EnsureIsValid() 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 ) @@ -1782,6 +1919,9 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path ) if (EnsureIsValid()==false) return; + if (m_composition == wxCOMPOSITION_DEST) + return; + wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() ); ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this); @@ -1794,6 +1934,9 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , wxPolygonF 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 @@ -1847,6 +1990,9 @@ void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , wxPolygonF if (EnsureIsValid()==false) return; + if (m_composition == wxCOMPOSITION_DEST) + return; + if ( ((wxMacCoreGraphicsBrushData*)m_brush.GetRefData())->IsShading() ) { CGContextSaveGState( m_cgContext ); @@ -1883,7 +2029,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg ) #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 } @@ -1944,6 +2090,9 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble { if (EnsureIsValid()==false) return; + + if (m_composition == wxCOMPOSITION_DEST) + return; #ifdef __WXMAC__ wxMacCoreGraphicsBitmapData* refdata =static_cast(bmp.GetRefData()); @@ -1984,6 +2133,9 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl 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) ); @@ -2018,12 +2170,15 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo 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 underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) ); @@ -2037,7 +2192,7 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo 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 ); @@ -2078,6 +2233,9 @@ void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str, if (EnsureIsValid()==false) return; + if (m_composition == wxCOMPOSITION_DEST) + return; + #if wxOSX_USE_CORE_TEXT if ( UMAGetSystemVersion() >= 0x1050 ) { @@ -2197,7 +2355,7 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid 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 }; @@ -2207,7 +2365,8 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid wxCFRef attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) ); wxCFRef line( CTLineCreateWithAttributedString(attrtext) ); - CGFloat w, a, d, l; + double w; + CGFloat a, d, l; w = CTLineGetTypographicBounds(line, &a, &d, &l) ; @@ -2291,7 +2450,7 @@ void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString& text, wxArr #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 }; @@ -2558,6 +2717,7 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContextFromNativeWindow( vo #if wxOSX_USE_CARBON return new wxMacCoreGraphicsContext(this,(WindowRef)window); #else + wxUnusedVar(window); return NULL; #endif }