]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/graphics.cpp
cleanup
[wxWidgets.git] / src / mac / carbon / graphics.cpp
old mode 100755 (executable)
new mode 100644 (file)
index b2bcb07..521ea9c
@@ -20,6 +20,7 @@
     #include "wx/dcmemory.h"
     #include "wx/log.h"
     #include "wx/region.h"
+    #include "wx/image.h"
 #endif
 
 #include "wx/mac/uma.h"
@@ -297,7 +298,7 @@ wxMacCoreGraphicsPenData::wxMacCoreGraphicsPenData( wxGraphicsRenderer* renderer
 {
     Init();
 
-    float components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 ,
+    CGFloat components[4] = { pen.GetColour().Red() / 255.0 , pen.GetColour().Green() / 255.0 ,
             pen.GetColour().Blue() / 255.0 , pen.GetColour().Alpha() / 255.0 } ;
     m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ;
 
@@ -478,70 +479,60 @@ void wxMacCoreGraphicsPenData::Apply( wxGraphicsContext* context )
 // Brush
 //
 
-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 wxColour&c1, const wxColour&c2 );
-    void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
-    const wxColour &oColor, const wxColour &cColor );
-
-    virtual bool IsShading() { return m_isShading; }
-    CGShadingRef GetShading() { return m_shading; }
-protected:
-    CGFunctionRef CreateGradientFunction( const wxColour& c1, const wxColour& c2 );
-    static void CalculateShadingValues (void *info, const CGFloat *in, CGFloat *out);
-    virtual void Init();
-
-    wxMacCFRefHolder<CGColorRef> m_color;
-    wxMacCFRefHolder<CGColorSpaceRef> m_colorSpace;
-
-    bool m_isPattern;
-    wxMacCFRefHolder<CGPatternRef> m_pattern;
-    CGFloat* m_patternColorComponents;
-
-    bool m_isShading;
-    CGFunctionRef m_gradientFunction;
-    CGShadingRef m_shading;
-    CGFloat *m_gradientComponents;
+static const char *gs_stripedback_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"4 4 2 1",
+". c #F0F0F0",
+"X c #ECECEC",
+/* pixels */
+"....",
+"....",
+"XXXX",
+"XXXX"
 };
 
-wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer )
+wxBitmap gs_stripedback_bmp( wxImage( (const char* const* ) gs_stripedback_xpm  ), -1 ) ;
+
+wxMacCoreGraphicsColour::~wxMacCoreGraphicsColour()
 {
-    Init();
+    delete[] m_patternColorComponents;
 }
 
-void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
-        const wxColour&c1, const wxColour&c2 )
+void wxMacCoreGraphicsColour::Init()
 {
-    m_gradientFunction = CreateGradientFunction( c1, c2 );
-    m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1,y1), CGPointMake(x2,y2), m_gradientFunction, true, true ) ;
-    m_isShading = true ;
+    m_isPattern = false;
+    m_patternColorComponents = NULL;
 }
 
-void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
-    const wxColour &oColor, const wxColour &cColor )
+void wxMacCoreGraphicsColour::Apply( CGContextRef cgContext )
 {
-    m_gradientFunction = CreateGradientFunction( oColor, cColor );
-    m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo,yo), 0, CGPointMake(xc,yc), radius, m_gradientFunction, true, true ) ;
-    m_isShading = true ;
+    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 );
+    }
 }
 
-wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* renderer, const wxBrush &brush) : wxGraphicsObjectRefData( renderer )
+wxMacCoreGraphicsColour::wxMacCoreGraphicsColour() 
 {
     Init();
+}
 
+wxMacCoreGraphicsColour::wxMacCoreGraphicsColour( const wxBrush &brush )
+{
+    Init();
     if ( brush.GetStyle() == wxSOLID )
     {
         if ( brush.MacGetBrushKind() == kwxMacBrushTheme )
         {
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
-            if ( HIThemeBrushCreateCGColor != 0 )
+            if ( UMAGetSystemVersion()  >= 0x1040 )
             {
                 CGColorRef color ;
                 HIThemeBrushCreateCGColor( brush.MacGetTheme(), &color );
@@ -550,17 +541,30 @@ wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* rende
             else
 #endif
             {
-                // as close as we can get, unfortunately < 10.4 things get difficult
-                RGBColor color;
-                GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &color );
-                float components[4] = {  (CGFloat) color.red / 65536,
-                    (CGFloat) color.green / 65536, (CGFloat) color.blue / 65536, 1 } ;
-                m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ;
+                if( brush.MacGetTheme() == kThemeBrushDialogBackgroundActive )
+                {
+                    // striped background is a pattern, we have to emulate it
+                    
+                    m_isPattern = true;
+                    m_patternColorComponents = new CGFloat[1] ;
+                    m_patternColorComponents[0] = 1.0;
+                    m_colorSpace.Set( CGColorSpaceCreatePattern( NULL ) );
+                    m_pattern.Set( *( new ImagePattern( &gs_stripedback_bmp , CGAffineTransformMakeScale( 1,-1 ) ) ) );
+                }
+                else
+                {
+                    // as close as we can get, unfortunately < 10.4 things get difficult
+                    RGBColor color;
+                    GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &color );
+                    CGFloat components[4] = {  (CGFloat) color.red / 65536,
+                        (CGFloat) color.green / 65536, (CGFloat) color.blue / 65536, 1 } ;
+                    m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ;
+                }
             }
         }
         else
         {
-            float components[4] = { brush.GetColour().Red() / 255.0 , brush.GetColour().Green() / 255.0 ,
+            CGFloat components[4] = { brush.GetColour().Red() / 255.0 , brush.GetColour().Green() / 255.0 ,
                 brush.GetColour().Blue() / 255.0 , brush.GetColour().Alpha() / 255.0 } ;
             m_color.Set( CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ) ;
         }
@@ -592,6 +596,62 @@ wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData(wxGraphicsRenderer* rende
     }
 }
 
+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 wxColour&c1, const wxColour&c2 );
+    void CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
+    const wxColour &oColor, const wxColour &cColor );
+
+    virtual bool IsShading() { return m_isShading; }
+    CGShadingRef GetShading() { return m_shading; }
+protected:
+    CGFunctionRef CreateGradientFunction( const wxColour& c1, const wxColour& c2 );
+    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;
+    CGFloat *m_gradientComponents;
+};
+
+wxMacCoreGraphicsBrushData::wxMacCoreGraphicsBrushData( wxGraphicsRenderer* renderer) : wxGraphicsObjectRefData( renderer )
+{
+    Init();
+}
+
+void wxMacCoreGraphicsBrushData::CreateLinearGradientBrush( wxDouble x1, wxDouble y1, wxDouble x2, wxDouble y2,
+        const wxColour&c1, const wxColour&c2 )
+{
+    m_gradientFunction = CreateGradientFunction( c1, c2 );
+    m_shading = CGShadingCreateAxial( wxMacGetGenericRGBColorSpace(), CGPointMake(x1,y1), CGPointMake(x2,y2), m_gradientFunction, true, true ) ;
+    m_isShading = true ;
+}
+
+void wxMacCoreGraphicsBrushData::CreateRadialGradientBrush( wxDouble xo, wxDouble yo, wxDouble xc, wxDouble yc, wxDouble radius,
+    const wxColour &oColor, const wxColour &cColor )
+{
+    m_gradientFunction = CreateGradientFunction( oColor, cColor );
+    m_shading = CGShadingCreateRadial( wxMacGetGenericRGBColorSpace(), CGPointMake(xo,yo), 0, CGPointMake(xc,yc), 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 )
@@ -601,15 +661,12 @@ wxMacCoreGraphicsBrushData::~wxMacCoreGraphicsBrushData()
         CGFunctionRelease(m_gradientFunction);
 
     delete[] m_gradientComponents;
-    delete[] m_patternColorComponents;
 }
 
 void wxMacCoreGraphicsBrushData::Init()
 {
-    m_patternColorComponents = NULL;
     m_gradientFunction = NULL;
     m_shading = NULL;
-    m_isPattern = false;
     m_gradientComponents = NULL;
     m_isShading = false;
 }
@@ -624,17 +681,7 @@ void wxMacCoreGraphicsBrushData::Apply( wxGraphicsContext* context )
     }
     else
     {
-        if ( m_isPattern )
-        {
-            CGAffineTransform matrix = CGContextGetCTM( cg );
-            CGContextSetPatternPhase( cg, CGSizeMake(matrix.tx, matrix.ty) );
-            CGContextSetFillColorSpace( cg , m_colorSpace );
-            CGContextSetFillPattern( cg, m_pattern , m_patternColorComponents );
-        }
-        else
-        {
-            CGContextSetFillColorWithColor( cg, m_color );
-        }
+        m_cgColor.Apply( cg );
     }
 }
 
@@ -985,7 +1032,7 @@ public :
     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) const {}
+    virtual void UnGetNativePath(void *WXUNUSED(p)) const {}
 
     // transforms each point of this path by the matrix
     virtual void Transform( const wxGraphicsMatrixData* matrix );
@@ -1131,7 +1178,7 @@ bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, int fillStyle)
 class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext
 {
 public:
-    wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext );
+    wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 );
 
     wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window );
 
@@ -1145,6 +1192,15 @@ public:
 
     void Init();
 
+    // returns the size of the graphics context in device coordinates
+    virtual void GetSize( wxDouble* width, wxDouble* height);
+
+    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();
 
@@ -1241,6 +1297,8 @@ private:
     WindowRef m_windowRef;
     bool m_releaseContext;
     CGAffineTransform m_windowTransform;
+    wxDouble m_width;
+    wxDouble m_height;
 
     wxMacCFRefHolder<HIShapeRef> m_clipRgn;
 };
@@ -1263,20 +1321,44 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxMacCoreGraphicsContext, wxGraphicsContext)
 
+class wxQuartzOffsetHelper
+{
+public :
+    wxQuartzOffsetHelper( CGContextRef cg , bool offset )
+    {
+        m_cg = cg;
+        m_offset = offset;
+        if ( m_offset )
+            CGContextTranslateCTM( m_cg, 0.5, 0.5 );
+    }
+    ~wxQuartzOffsetHelper( )
+    {
+        if ( m_offset )
+            CGContextTranslateCTM( m_cg, -0.5, -0.5 );
+    }
+public :
+    CGContextRef m_cg;
+    bool m_offset;
+} ;
+
 void wxMacCoreGraphicsContext::Init()
 {
     m_cgContext = NULL;
     m_releaseContext = false;
     m_windowRef = NULL;
+    m_width = 0;
+    m_height = 0;
 
     HIRect r = CGRectMake(0,0,0,0);
     m_clipRgn.Set(HIShapeCreateWithRect(&r));
 }
 
-wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext ) : wxGraphicsContext(renderer)
+wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer)
 {
     Init();
     SetNativeContext(cgcontext);
+    m_width = width;
+    m_height = height;
 }
 
 wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, WindowRef window ): wxGraphicsContext(renderer)
@@ -1316,11 +1398,46 @@ wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
     SetNativeContext(NULL);
 }
 
+void wxMacCoreGraphicsContext::GetSize( wxDouble* width, wxDouble* height)
+{
+    *width = m_width;
+    *height = m_height;
+}
+
+
+void wxMacCoreGraphicsContext::StartPage( wxDouble width, wxDouble height )
+{
+    CGRect r;
+    if ( width != 0 && height != 0)
+        r = CGRectMake( 0 , 0 , width  , height );
+    else
+        r = CGRectMake( 0 , 0 , m_width  , m_height );
+    
+    CGContextBeginPage(m_cgContext,  &r );
+//    CGContextTranslateCTM( m_cgContext , 0 ,  height == 0 ? m_height : height );
+//    CGContextScaleCTM( m_cgContext , 1 , -1 );
+}
+    
+void wxMacCoreGraphicsContext::EndPage()
+{
+    CGContextEndPage(m_cgContext);
+}
+
+void wxMacCoreGraphicsContext::Flush()
+{
+    CGContextFlush(m_cgContext);
+}
+
 void wxMacCoreGraphicsContext::EnsureIsValid()
 {
     if ( !m_cgContext )
     {
-        OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
+        OSStatus status = 
+#ifndef __LP64__
+            QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
+#else
+            paramErr;
+#endif
         wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") );
 
         CGContextConcatCTM( m_cgContext, m_windowTransform );
@@ -1340,6 +1457,8 @@ void wxMacCoreGraphicsContext::EnsureIsValid()
        }
 }
 
+// TODO test whether the private CGContextSetCompositeOperation works under 10.3 (using NSCompositingModes)
+
 bool wxMacCoreGraphicsContext::SetLogicalFunction( int function )
 {
     if (m_logicalFunction == function)
@@ -1447,16 +1566,11 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path )
 
     EnsureIsValid();
 
-    bool offset = ShouldOffset();
-    if ( offset )
-        CGContextTranslateCTM( m_cgContext, 0.5, 0.5 );
+    wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
 
     ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
     CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() );
     CGContextStrokePath( m_cgContext );
-
-    if ( offset )
-        CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );
 }
 
 void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , int fillStyle )
@@ -1502,16 +1616,10 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , int fillSt
     if ( !m_pen.IsNull() )
         ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
 
-    bool offset = ShouldOffset();
-
-    if ( offset )
-        CGContextTranslateCTM( m_cgContext, 0.5, 0.5 );
+    wxQuartzOffsetHelper helper( m_cgContext , ShouldOffset() );
 
     CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() );
     CGContextDrawPath( m_cgContext , mode );
-
-    if ( offset )
-        CGContextTranslateCTM( m_cgContext, -0.5, -0.5 );
 }
 
 void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , int fillStyle )
@@ -1551,7 +1659,11 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
         CGContextRestoreGState( m_cgContext );
         CGContextRestoreGState( m_cgContext );
         if ( m_releaseContext )
+        {
+#ifndef __LP64__
             QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext);
+#endif
+        }
         else
             CGContextRelease(m_cgContext);
     }
@@ -1786,6 +1898,18 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid
 {
     wxCHECK_RET( !m_font.IsNull(), wxT("wxDC(cg)::DoGetTextExtent - no valid font set") );
 
+    if ( width )
+        *width = 0;
+    if ( height )
+        *height = 0;
+    if ( descent )
+        *descent = 0;
+    if ( externalLeading )
+        *externalLeading = 0;
+        
+    if (str.empty())
+        return;
+
     OSStatus status = noErr;
 
     ATSUTextLayout atsuLayout;