]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/dccg.cpp
cleaning up, adding support for Quartz / Themeing before 10.3
[wxWidgets.git] / src / mac / carbon / dccg.cpp
index 56c2379701db1cabec6d4eac72fbb3e0d75e7c1b..ee8e6e608eadd04530a10c7b630c79b27f735f8f 100755 (executable)
@@ -105,6 +105,20 @@ wxMacWindowStateSaver::~wxMacWindowStateSaver()
     SetThemeDrawingState( m_themeDrawingState , true ) ;
 }
 
+// minimal implementation only used for appearance drawing < 10.3
+
+wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) :
+    m_ph( (GrafPtr) dc->m_macPort )
+{
+    wxASSERT( dc->Ok() ) ;
+    m_dc = dc ;
+//    dc->MacSetupPort(&m_ph) ;
+}
+wxMacPortSetter::~wxMacPortSetter()
+{
+//    m_dc->MacCleanupPort(&m_ph) ;
+}
+
 //-----------------------------------------------------------------------------
 // Local functions
 //-----------------------------------------------------------------------------
@@ -252,9 +266,10 @@ void wxMacCGContext::FillPath( const wxGraphicPath *p , const wxColor &fillColor
     
 wxGraphicPath* wxMacCGContext::CreatePath() 
 { 
-    CGContextRef cg = GetNativeContext() ;
     // make sure that we now have a real cgref, before doing
     // anything with paths
+    CGContextRef cg = GetNativeContext() ;
+    cg = NULL ;
     return new wxMacCGPath() ; 
 }
 
@@ -563,7 +578,7 @@ wxDC::wxDC()
     m_needComputeScaleY = FALSE;
 
     m_ok = FALSE ;
-
+    m_macPort = 0 ;
     m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
 
     m_pen = *wxBLACK_PEN;
@@ -905,8 +920,17 @@ bool wxDC::DoFloodFill(wxCoord x, wxCoord y,
 bool  wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
 {
     wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel  Invalid DC") );
-    wxFAIL_MSG( wxT("GetPixel not implemented on Core Graphics") ) ;
-    return false ;
+    wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel  Invalid DC") );
+    wxMacPortSaver helper((CGrafPtr)m_macPort) ;
+    RGBColor colour;
+    GetCPixel( 
+        XLOG2DEVMAC(x) + m_macLocalOriginInPort.x - m_macLocalOrigin.x, 
+        YLOG2DEVMAC(y) + m_macLocalOriginInPort.y - m_macLocalOrigin.y, &colour );
+    // Convert from Mac colour to wx
+    col->Set( colour.red   >> 8,
+        colour.green >> 8,
+        colour.blue  >> 8);
+    return true ;
 }
 
 void  wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
@@ -1010,10 +1034,9 @@ void  wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
     if( (xx1 > xx2) || (yy1 > yy2) ) {
         alpha2 *= -1;
     }
-    Rect r = { yyc - rad, xxc - rad, yyc + rad, xxc + rad };
     wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
     CGContextRef ctx = mctx->GetNativeContext() ;
-    AddEllipticArcToPath( ctx , CGPointMake( xxc , yyc ) , rad , rad , 0 , 180 ) ;
+    AddEllipticArcToPath( ctx , CGPointMake( xxc , yyc ) , rad , rad , alpha1 , alpha2 ) ;
     CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
 }
 
@@ -1149,7 +1172,6 @@ void  wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
         hh = -hh;
         yy = yy - hh;
     }
-    Rect rect = { yy , xx , yy + hh , xx + ww } ;
     wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
     CGContextRef ctx = mctx->GetNativeContext() ;
     AddRoundedRectToPath( ctx  , CGRectMake( xx , yy , ww , hh ) , 16 ,16  ) ;
@@ -1220,7 +1242,7 @@ bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     }
 
     wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ;
-    if ( memdc )
+    if ( memdc && logical_func == wxCOPY )
     {
         wxBitmap blit = memdc->GetSelectedObject() ;
         wxASSERT_MSG( blit.Ok() , wxT("Invalid bitmap for blitting") ) ;
@@ -1248,7 +1270,7 @@ bool  wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     }
     else
     {
-        wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
+        return FALSE ; // wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
     }
     return TRUE;
 }
@@ -1355,14 +1377,14 @@ void  wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
             drawX , 
             drawY ) ;
         path->AddLineToPoint( 
-            drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent) , 
-            drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) ) ;
+            (int) (drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent)) , 
+            (int) (drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent)) ) ;
         path->AddLineToPoint( 
-            drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle/RAD2DEG) * FixedToInt(textAfter) ,
-            drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) - sin(angle/RAD2DEG) * FixedToInt(textAfter) ) ;
+            (int) (drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle/RAD2DEG) * FixedToInt(textAfter)) ,
+            (int) (drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) - sin(angle/RAD2DEG) * FixedToInt(textAfter)) ) ;
         path->AddLineToPoint( 
-            drawX + cos(angle/RAD2DEG) * FixedToInt(textAfter) , 
-            drawY - sin(angle/RAD2DEG) * FixedToInt(textAfter) ) ;
+            (int) (drawX + cos(angle/RAD2DEG) * FixedToInt(textAfter)) , 
+            (int) (drawY - sin(angle/RAD2DEG) * FixedToInt(textAfter)) ) ;
             
         m_graphicContext->FillPath( path , m_textBackgroundColour ) ;
         delete path ;
@@ -1495,9 +1517,54 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con
     if (text.Length() == 0)
         return false;
     
-    wxFAIL_MSG( wxT("Unimplemented for Core Graphics") ) ;
-    
-    return false;
+    ATSUTextLayout atsuLayout ;
+    UniCharCount chars = text.Length() ;
+    UniChar* ubuf = NULL ;
+#if SIZEOF_WCHAR_T == 4
+    wxMBConvUTF16BE converter ;
+#if wxUSE_UNICODE
+    size_t unicharlen = converter.WC2MB( NULL , text.wc_str() , 0 ) ;
+    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+    converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 ) ;
+#else
+    const wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
+    size_t unicharlen = converter.WC2MB( NULL , wchar.data()  , 0 ) ;
+    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+    converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
+#endif
+    chars = unicharlen / 2 ;
+#else
+#if wxUSE_UNICODE
+    ubuf = (UniChar*) text.wc_str() ;
+#else
+    wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
+    chars = wxWcslen( wchar.data() ) ;
+    ubuf = (UniChar*) wchar.data() ;
+#endif
+#endif
+
+       OSStatus status;
+    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
+        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+        
+       for ( int pos = 0; pos < chars; pos ++ ) {
+                       unsigned long actualNumberOfBounds = 0;
+                       ATSTrapezoid glyphBounds;
+
+                       // We get a single bound, since the text should only require one. If it requires more, there is an issue
+                       OSStatus result; 
+                       result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds );
+                       if (result != noErr || actualNumberOfBounds != 1 )
+                       {
+                               return false;
+                       }
+
+                       widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
+                       //unsigned char uch = s[i];
+                       
+       }
+    ::ATSUDisposeTextLayout(atsuLayout);
+    return true;
 }
 
 wxCoord   wxDC::GetCharWidth(void) const
@@ -1521,39 +1588,63 @@ void  wxDC::Clear(void)
     if ( m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT)
     {      
         HIRect rect = CGRectMake( -10000 , -10000 , 20000 , 20000 ) ;
+        CGContextRef cg = dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ;
         switch( m_backgroundBrush.MacGetBrushKind() )
         {
             case kwxMacBrushTheme :
                 {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+                    if ( HIThemeSetFill != 0 )
+                    {
+                        HIThemeSetFill( m_backgroundBrush.MacGetTheme() , cg ) ;
+                        CGContextFillRect(cg, rect);
+
+                    }
+                    else
+#endif
+                    {
+                                       RGBColor        color;
+                                       GetThemeBrushAsColor( m_backgroundBrush.MacGetTheme() , 32, true, &color );
+                                       CGContextSetRGBFillColor( cg , (float) color.red / 65536,
+                                                       (float) color.green / 65536, (float) color.blue / 65536, 1 );
+                                       CGContextFillRect( cg, rect );
+                    }
+                    // reset to normal value
+                    RGBColor col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
+                    CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
                 }
             break ;
             case kwxMacBrushThemeBackground :
                 {
+                    wxFAIL_MSG( wxT("There shouldn't be theme backgrounds under Quartz") ) ;
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
-                    if ( HIThemeDrawBackground )
+                    if ( HIThemeDrawBackground != 0 )
                     {
                         HIThemeBackgroundDrawInfo drawInfo ;
                         drawInfo.version = 0 ;
                         drawInfo.state = kThemeStateActive ;
                         drawInfo.kind = m_backgroundBrush.MacGetThemeBackground(NULL) ;
                         if ( drawInfo.kind == kThemeBackgroundMetal )
-                            HIThemeDrawBackground( &rect , &drawInfo, dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ,
+                            HIThemeDrawBackground( &rect , &drawInfo, cg ,
                                 kHIThemeOrientationNormal) ;
-                            HIThemeApplyBackground( &rect , &drawInfo, dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() ,
+                            HIThemeApplyBackground( &rect , &drawInfo, cg ,
                                 kHIThemeOrientationNormal) ;
                     }
+                    else
 #endif
+                    {
+                    }
                 }
             break ;
             case kwxMacBrushColour :
             {
                 RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ;
-                CGContextSetRGBFillColor( dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
-                CGContextFillRect(dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext(), rect);
+                CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+                CGContextFillRect(cg, rect);
 
                 // reset to normal value
                 col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
-                CGContextSetRGBFillColor( dynamic_cast<wxMacCGContext*>(m_graphicContext)->GetNativeContext() , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+                CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
             }
             break ;
         }