]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/graphics.cpp
Set the menu itself as event object for EVT_MENU_{OPEN,CLOSED} in wxMSW.
[wxWidgets.git] / src / osx / carbon / graphics.cpp
index d3dd3cb9b72ec62a8193b52c98316589817f1c64..afaec66fa4165ef791b73a499b49ba3244d51b1f 100644 (file)
@@ -113,11 +113,9 @@ extern "C"
 // 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;
 
@@ -165,6 +163,7 @@ CGColorRef wxMacCreateCGColor( const wxColour& col )
     }
 
 #endif
+    wxASSERT(retval != NULL);
     return retval;
 }
 
@@ -1001,17 +1000,6 @@ wxMacCoreGraphicsBitmapData::~wxMacCoreGraphicsBitmapData()
     CGImageRelease( m_bitmap );
 }
 
-#if wxUSE_IMAGE
-
-wxImage wxGraphicsBitmap::ConvertToImage() const
-{
-    wxMacCoreGraphicsBitmapData* const
-        data = static_cast<wxMacCoreGraphicsBitmapData*>(GetRefData());
-
-    return data ? data->ConvertToImage() : wxNullImage;
-}
-
-#endif // wxUSE_IMAGE
 
 //
 // Graphics Matrix
@@ -1519,6 +1507,7 @@ public:
 
 private:
     bool EnsureIsValid();
+    void CheckInvariants() const;
 
     virtual void DoDrawText( const wxString &str, wxDouble x, wxDouble y );
     virtual void DoDrawRotatedText( const wxString &str, wxDouble x, wxDouble y, wxDouble angle );
@@ -1664,6 +1653,13 @@ wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
 }
 
 
+void wxMacCoreGraphicsContext::CheckInvariants() const
+{
+    // check invariants here for debugging ...
+}
+
+
+
 void wxMacCoreGraphicsContext::StartPage( wxDouble width, wxDouble height )
 {
     CGRect r;
@@ -1689,6 +1685,8 @@ void wxMacCoreGraphicsContext::Flush()
 
 bool wxMacCoreGraphicsContext::EnsureIsValid()
 {
+    CheckInvariants();
+    
     if ( !m_cgContext )
     {
         if (m_invisible)
@@ -1762,6 +1760,8 @@ bool wxMacCoreGraphicsContext::EnsureIsValid()
 #endif
         }
     }
+    CheckInvariants();
+
     return m_cgContext != NULL;
 }
 
@@ -1788,6 +1788,7 @@ bool wxMacCoreGraphicsContext::SetAntialiasMode(wxAntialiasMode antialias)
             return false;
     }
     CGContextSetShouldAntialias(m_cgContext, antialiasMode);
+    CheckInvariants();
     return true;
 }
 
@@ -1827,6 +1828,7 @@ bool wxMacCoreGraphicsContext::SetInterpolationQuality(wxInterpolationQuality in
             return false;
     }
     CGContextSetInterpolationQuality(m_cgContext, quality);
+    CheckInvariants();
     return true;
 }
 
@@ -1946,24 +1948,30 @@ bool wxMacCoreGraphicsContext::SetCompositionMode(wxCompositionMode op)
         CGContextSetBlendMode(m_cgContext, mode);
     }
 #endif
+    CheckInvariants();
     return true;
 }
 
 void wxMacCoreGraphicsContext::BeginLayer(wxDouble opacity)
 {
+    CheckInvariants();
     CGContextSaveGState(m_cgContext);
     CGContextSetAlpha(m_cgContext, (CGFloat) opacity);
     CGContextBeginTransparencyLayer(m_cgContext, 0);
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::EndLayer()
 {
+    CheckInvariants();
     CGContextEndTransparencyLayer(m_cgContext);
     CGContextRestoreGState(m_cgContext);
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::Clip( const wxRegion &region )
 {
+    CheckInvariants();
 #if wxOSX_USE_COCOA_OR_CARBON
     if( m_cgContext )
     {
@@ -1994,11 +2002,13 @@ void wxMacCoreGraphicsContext::Clip( const wxRegion &region )
     // allow usage as measuring context
     // wxASSERT_MSG( m_cgContext != NULL, "Needs a valid context for clipping" );
 #endif
+    CheckInvariants();    
 }
 
 // clips drawings to the rect
 void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
 {
+    CheckInvariants();
     CGRect r = CGRectMake( (CGFloat) x , (CGFloat) y , (CGFloat) w , (CGFloat) h );
     if ( m_cgContext )
     {
@@ -2017,6 +2027,7 @@ void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDoubl
     // wxFAIL_MSG( "Needs a valid context for clipping" );
 #endif
     }
+    CheckInvariants();    
 }
 
     // resets the clipping to original extent
@@ -2043,6 +2054,7 @@ void wxMacCoreGraphicsContext::ResetClip()
     // wxFAIL_MSG( "Needs a valid context for clipping" );
 #endif
     }
+    CheckInvariants();    
 }
 
 void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path )
@@ -2061,6 +2073,8 @@ void wxMacCoreGraphicsContext::StrokePath( const wxGraphicsPath &path )
     ((wxMacCoreGraphicsPenData*)m_pen.GetRefData())->Apply(this);
     CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() );
     CGContextStrokePath( m_cgContext );
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , wxPolygonFillMode fillStyle )
@@ -2114,6 +2128,8 @@ void wxMacCoreGraphicsContext::DrawPath( const wxGraphicsPath &path , wxPolygonF
 
     CGContextAddPath( m_cgContext , (CGPathRef) path.GetNativePath() );
     CGContextDrawPath( m_cgContext , mode );
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , wxPolygonFillMode fillStyle )
@@ -2144,6 +2160,8 @@ void wxMacCoreGraphicsContext::FillPath( const wxGraphicsPath &path , wxPolygonF
         else
             CGContextFillPath( m_cgContext );
     }
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
@@ -2153,6 +2171,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
 
     if ( m_cgContext )
     {
+        CheckInvariants();
         CGContextRestoreGState( m_cgContext );
         CGContextRestoreGState( m_cgContext );
         if ( m_contextSynthesized )
@@ -2257,6 +2276,8 @@ void wxMacCoreGraphicsContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble
         wxMacDrawCGImage( m_cgContext , &r , image );
     }
 #endif
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
@@ -2276,6 +2297,8 @@ void wxMacCoreGraphicsContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDoubl
         NULL , kPlotIconRefNormalFlags , icon.GetHICON() );
 #endif
     CGContextRestoreGState( m_cgContext );
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::PushState()
@@ -2311,10 +2334,16 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo
         wxCFStringRef text(str, wxLocale::GetSystemEncoding() );
         CTFontRef font = fref->OSXGetCTFont();
         CGColorRef col = wxMacCreateCGColor( fref->GetColour() );
+#if 0
+        // right now there's no way to get continuous underlines, only words, so we emulate it
         CTUnderlineStyle ustyle = fref->GetUnderlined() ? kCTUnderlineStyleSingle : kCTUnderlineStyleNone ;
         wxCFRef<CFNumberRef> underlined( CFNumberCreate(NULL, kCFNumberSInt32Type, &ustyle) );
          CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName, kCTUnderlineStyleAttributeName };
         CFTypeRef values[] = { font, col, underlined };
+#else
+        CFStringRef keys[] = { kCTFontAttributeName , kCTForegroundColorAttributeName };
+        CFTypeRef values[] = { font, col };
+#endif
         wxCFRef<CFDictionaryRef> attributes( CFDictionaryCreate(kCFAllocatorDefault, (const void**) &keys, (const void**) &values,
                                                         WXSIZEOF( keys ), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks) );
         wxCFRef<CFAttributedStringRef> attrtext( CFAttributedStringCreate(kCFAllocatorDefault, text, attributes) );
@@ -2323,12 +2352,30 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo
         y += CTFontGetAscent(font);
 
         CGContextSaveGState(m_cgContext);
+        CGAffineTransform textMatrix = CGContextGetTextMatrix(m_cgContext);
+        
         CGContextTranslateCTM(m_cgContext, (CGFloat) x, (CGFloat) y);
         CGContextScaleCTM(m_cgContext, 1, -1);
-        CGContextSetTextPosition(m_cgContext, 0, 0);
+        CGContextSetTextMatrix(m_cgContext, CGAffineTransformIdentity);
+        
         CTLineDraw( line, m_cgContext );
+        
+        if ( fref->GetUnderlined() ) {
+            //AKT: draw horizontal line 1 pixel thick and with 1 pixel gap under baseline
+            CGFloat width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
+
+            CGPoint points[] = { {0.0, -2.0},  {width, -2.0} };
+            
+            CGContextSetStrokeColorWithColor(m_cgContext, col);
+            CGContextSetShouldAntialias(m_cgContext, false);
+            CGContextSetLineWidth(m_cgContext, 1.0);
+            CGContextStrokeLineSegments(m_cgContext, points, 2);
+        }
+        
         CGContextRestoreGState(m_cgContext);
+        CGContextSetTextMatrix(m_cgContext, textMatrix);
         CFRelease( col );
+        CheckInvariants();
         return;
     }
 #endif
@@ -2353,6 +2400,8 @@ void wxMacCoreGraphicsContext::DoDrawText( const wxString &str, wxDouble x, wxDo
     CGContextRestoreGState(m_cgContext);
     CFRelease( col );
 #endif
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str,
@@ -2455,6 +2504,7 @@ void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str,
         CGContextRestoreGState(m_cgContext);
 
         ::ATSUDisposeTextLayout(atsuLayout);
+        CheckInvariants();
 
         return;
     }
@@ -2463,6 +2513,8 @@ void wxMacCoreGraphicsContext::DoDrawRotatedText(const wxString &str,
     // default implementation takes care of rotation and calls non rotated DrawText afterwards
     wxGraphicsContext::DoDrawRotatedText( str, x, y, angle );
 #endif
+    
+    CheckInvariants();
 }
 
 void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height,
@@ -2564,6 +2616,8 @@ void wxMacCoreGraphicsContext::GetTextExtent( const wxString &str, wxDouble *wid
     if ( width )
         *width = sz.width;
 #endif
+    
+    CheckInvariants();    
 }
 
 void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const
@@ -2662,6 +2716,8 @@ void wxMacCoreGraphicsContext::GetPartialTextExtents(const wxString& text, wxArr
 #if wxOSX_USE_IPHONE
     // TODO core graphics text implementation here
 #endif
+    
+    CheckInvariants();
 }
 
 void * wxMacCoreGraphicsContext::GetNativeContext()
@@ -2702,6 +2758,7 @@ void wxMacCoreGraphicsContext::ConcatTransform( const wxGraphicsMatrix& matrix )
 // sets the transform of this context
 void wxMacCoreGraphicsContext::SetTransform( const wxGraphicsMatrix& matrix )
 {
+    CheckInvariants();
     if ( m_cgContext )
     {
         CGAffineTransform transform = CGContextGetCTM( m_cgContext );
@@ -2713,6 +2770,7 @@ void wxMacCoreGraphicsContext::SetTransform( const wxGraphicsMatrix& matrix )
     {
         m_windowTransform = *(CGAffineTransform*) matrix.GetNativeMatrix();
     }
+    CheckInvariants();
 }
 
 // gets the matrix of this context
@@ -2839,6 +2897,7 @@ public :
 
 #if wxUSE_IMAGE
     virtual wxGraphicsBitmap CreateBitmapFromImage(const wxImage& image);
+    virtual wxImage CreateImageFromBitmap(const wxGraphicsBitmap& bmp);
 #endif // wxUSE_IMAGE
 
     // create a graphics bitmap from a native bitmap
@@ -3030,6 +3089,14 @@ wxMacCoreGraphicsRenderer::CreateBitmapFromImage(const wxImage& image)
     return CreateBitmap(wxBitmap(image));
 }
 
+wxImage wxMacCoreGraphicsRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp)
+{
+    wxMacCoreGraphicsBitmapData* const
+        data = static_cast<wxMacCoreGraphicsBitmapData*>(bmp.GetRefData());
+
+    return data ? data->ConvertToImage() : wxNullImage;
+}
+
 #endif // wxUSE_IMAGE
 
 wxGraphicsBitmap wxMacCoreGraphicsRenderer::CreateBitmapFromNativeBitmap( void* bitmap )