]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/dc.cpp
screendc implementation
[wxWidgets.git] / src / mac / carbon / dc.cpp
index 1630fd9c14cc6704ef8d0466ecd84fc33b6e4882..9bc9f204b513a444a17dd5d028ce86cd1e04b7fc 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dc.cpp
+// Name:        src/mac/carbon/dc.cpp
 // Purpose:     wxDC class
 // Author:      Stefan Csomor
 // Modified by:
 #include "wx/dc.h"
 
 #if !wxMAC_USE_CORE_GRAPHICS
-#include "wx/app.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/dcmemory.h"
+    #include "wx/dcprint.h"
+    #include "wx/region.h"
+    #include "wx/image.h"
+#endif
+
 #include "wx/mac/uma.h"
-#include "wx/dcmemory.h"
-#include "wx/dcprint.h"
-#include "wx/region.h"
-#include "wx/image.h"
-#include "wx/log.h"
 
 #ifdef __MSL__
     #if __MSL__ >= 0x6000
 #include <TextEncodingConverter.h>
 #endif
 
+
+// set to 0 if problems arise
+#define wxMAC_EXPERIMENTAL_DC 1
+
+
 IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
 
 //-----------------------------------------------------------------------------
@@ -46,11 +55,6 @@ const double RAD2DEG  = 180.0 / M_PI;
 const short kEmulatedMode = -1 ;
 const short kUnsupportedMode = -2 ;
 
-extern TECObjectRef s_TECNativeCToUnicode ;
-
-// set to 0 if problems arise
-#define wxMAC_EXPERIMENTAL_DC 1
-
 wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) :
     m_ph( (GrafPtr) dc->m_macPort )
 {
@@ -113,7 +117,7 @@ wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) :
         if ( win->GetPeer() )
         {
             int x = 0 , y = 0;
-            win->MacWindowToRootWindow( &x,&y ) ;
+            win->MacWindowToRootWindow( &x, &y ) ;
 
             // get area including focus rect
             CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ;
@@ -147,13 +151,6 @@ wxMacWindowStateSaver::~wxMacWindowStateSaver()
     SetThemeDrawingState( m_themeDrawingState , true ) ;
 }
 
-//-----------------------------------------------------------------------------
-// Local functions
-//-----------------------------------------------------------------------------
-static inline double dmin(double a, double b) { return a < b ? a : b; }
-static inline double dmax(double a, double b) { return a > b ? a : b; }
-static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
-
 //-----------------------------------------------------------------------------
 // wxDC
 //-----------------------------------------------------------------------------
@@ -281,7 +278,6 @@ wxDC::wxDC()
     m_needComputeScaleY = false;
     m_macPort = NULL ;
     m_macMask = NULL ;
-    m_ok = false ;
     m_macFontInstalled = false ;
     m_macBrushInstalled = false ;
     m_macPenInstalled = false ;
@@ -406,8 +402,8 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
      }
      else
      {
-         RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF} ;
-         RGBColor black = { 0, 0, 0} ;
+         RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ;
+         RGBColor black = { 0, 0, 0 } ;
          RGBForeColor( &black ) ;
          RGBBackColor( &white ) ;
      }
@@ -459,7 +455,7 @@ void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
     wxCoord ww = XLOG2DEVREL(w);
     wxCoord hh = YLOG2DEVREL(h);
 
-    Rect r = { yy , xx, yy + hh  , xx + ww } ;
+    Rect r = { yy , xx, yy + hh, xx + ww } ;
     PlotIconRef( &r , kAlignNone , kTransformNone , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ;
 }
 
@@ -479,8 +475,8 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     {
         m_clipX1 = wxMax( m_clipX1 , xx );
         m_clipY1 = wxMax( m_clipY1 , yy );
-        m_clipX2 = wxMin( m_clipX2, (xx + ww));
-        m_clipY2 = wxMin( m_clipY2, (yy + hh));
+        m_clipX2 = wxMin( m_clipX2, (xx + ww) );
+        m_clipY2 = wxMin( m_clipY2, (yy + hh) );
     }
     else
     {
@@ -492,7 +488,7 @@ void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord hei
     }
 }
 
-void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region  )
+void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region )
 {
     wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegionAsRegion - invalid DC"));
 
@@ -522,8 +518,8 @@ void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region  )
         {
             m_clipX1 = wxMax( m_clipX1 , xx );
             m_clipY1 = wxMax( m_clipY1 , yy );
-            m_clipX2 = wxMin( m_clipX2, (xx + ww));
-            m_clipY2 = wxMin( m_clipY2, (yy + hh));
+            m_clipX2 = wxMin( m_clipX2, (xx + ww) );
+            m_clipY2 = wxMin( m_clipY2, (yy + hh) );
         }
         else
         {
@@ -750,9 +746,7 @@ bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
     GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour );
 
     // convert from Mac colour to wx
-    col->Set( colour.red   >> 8,
-        colour.green >> 8,
-        colour.blue  >> 8);
+    col->Set( colour.red >> 8, colour.green >> 8, colour.blue >> 8);
 
     return true ;
 }
@@ -767,7 +761,7 @@ void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
     {
         MacInstallPen() ;
         wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 :
-        m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2;
+            m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2;
         wxCoord xx1 = XLOG2DEVMAC(x1) - offset;
         wxCoord yy1 = YLOG2DEVMAC(y1) - offset;
         wxCoord xx2 = XLOG2DEVMAC(x2) - offset;
@@ -862,7 +856,7 @@ void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
 
     double dx = xx1 - xxc;
     double dy = yy1 - yyc;
-    double radius = sqrt((double)(dx*dx+dy*dy));
+    double radius = sqrt((double)(dx * dx + dy * dy));
     wxCoord rad = (wxCoord)radius;
     double radius1, radius2;
 
@@ -879,10 +873,10 @@ void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
     {
         radius1 = (xx1 - xxc == 0) ?
             (yy1 - yyc < 0) ? 90.0 : -90.0 :
-        -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
+        -atan2(double(yy1 - yyc), double(xx1 - xxc)) * RAD2DEG;
         radius2 = (xx2 - xxc == 0) ?
             (yy2 - yyc < 0) ? 90.0 : -90.0 :
-        -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
+        -atan2(double(yy2 - yyc), double(xx2 - xxc)) * RAD2DEG;
     }
 
     wxCoord alpha2 = wxCoord(radius2 - radius1);
@@ -986,11 +980,12 @@ void wxDC::DoDrawLines(int n, wxPoint points[],
     MacInstallPen() ;
     wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 :
     m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2 ;
+
     wxCoord x1, x2 , y1 , y2 ;
     x1 = XLOG2DEVMAC(points[0].x + xoffset);
     y1 = YLOG2DEVMAC(points[0].y + yoffset);
 
-    ::MoveTo(x1 - offset, y1 - offset );
+    ::MoveTo( x1 - offset, y1 - offset );
     for (int i = 0; i < n-1; i++)
     {
         x2 = XLOG2DEVMAC(points[i + 1].x + xoffset);
@@ -1007,7 +1002,7 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[],
 
     if ( m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT )
         return ;
-    
+
     wxMacFastPortSetter helper(this) ;
 
     wxCoord x1, x2 , y1 , y2 ;
@@ -1025,7 +1020,7 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[],
 
     // close the polyline if necessary
     if ( x1 != x2 || y1 != y2 )
-        ::LineTo(x1, y1 ) ;
+        ::LineTo( x1, y1 ) ;
     ClosePoly();
 
     if (m_brush.GetStyle() != wxTRANSPARENT)
@@ -1146,7 +1141,7 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
     // CMB: draw nothing if transformed w or h is 0
     if (ww == 0 || hh == 0)
         return;
-    
+
     // CMB: handle -ve width and/or height
     if (ww < 0)
     {
@@ -1182,7 +1177,7 @@ bool wxDC::CanDrawBitmap(void) const
 
 bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
                    wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
-                   wxCoord xsrcMask,  wxCoord ysrcMask )
+                   wxCoord xsrcMask, wxCoord ysrcMask )
 {
     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit - invalid DC"));
     wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit - invalid source DC"));
@@ -1307,8 +1302,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
         else
         {
             // the modes need this, otherwise we'll end up having really nice colors...
-            RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF} ;
-            RGBColor black = { 0, 0, 0} ;
+            RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ;
+            RGBColor black = { 0, 0, 0 } ;
 
             RGBForeColor( &black ) ;
             RGBBackColor( &white ) ;
@@ -1373,7 +1368,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
                                     GetCPixel( srcPoint.h , srcPoint.v , &srcColor ) ;
                                     SetPort( (GrafPtr) m_macPort ) ;
                                     GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
-                                    wxMacCalculateColour( logical_func , srcColor ,  dstColor ) ;
+                                    wxMacCalculateColour( logical_func , srcColor , dstColor ) ;
                                     SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
                                 }
                             }
@@ -1436,7 +1431,7 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
                                 GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ;
                                 SetPort( (GrafPtr) m_macPort ) ;
                                 GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
-                                wxMacCalculateColour( logical_func , srcColor ,  dstColor ) ;
+                                wxMacCalculateColour( logical_func , srcColor , dstColor ) ;
                                 SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
                             }
                         }
@@ -1469,53 +1464,21 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
 void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
                               double angle)
 {
-    // TODO: support text background color (only possible by hand, ATSUI does not support it)
     wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText - invalid DC") );
 
-    if ( str.Length() == 0 )
+    if ( str.empty() )
         return ;
 
     wxMacFastPortSetter helper(this) ;
     MacInstallFont() ;
 
-#if 0
-    if ( 0 )
-    {
-        m_macFormerAliasState = IsAntiAliasedTextEnabled(&m_macFormerAliasSize);
-        SetAntiAliasedTextEnabled(true, SInt16(m_scaleY * m_font.MacGetFontSize()));
-        m_macAliasWasEnabled = true ;
-    }
-#endif
-
     OSStatus status = noErr ;
     ATSUTextLayout atsuLayout ;
-    UniCharCount chars = str.Length() ;
-    UniChar* ubuf = NULL ;
-
-#if SIZEOF_WCHAR_T == 4
-    wxMBConvUTF16 converter ;
-#if wxUSE_UNICODE
-    size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
-    ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
-    converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
-#else
-    const wxWCharBuffer wchar = str.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*) str.wc_str() ;
-#else
-    wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
-    chars = wxWcslen( wchar.data() ) ;
-    ubuf = (UniChar*) wchar.data() ;
-#endif
-#endif
 
-    status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
+    wxMacUniCharBuffer unibuf( str ) ;
+    UniCharCount chars = unibuf.GetChars() ;
+
+    status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 ,
         &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
 
     wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") );
@@ -1530,32 +1493,69 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
     ATSUTextMeasurement textBefore, textAfter ;
     ATSUTextMeasurement ascent, descent ;
 
-    if ( abs(iAngle) > 0 )
+    ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ;
+
+    if (m_font.GetNoAntiAliasing())
     {
-        Fixed atsuAngle = IntToFixed( iAngle ) ;
+        layoutOptions |= kATSLineNoAntiAliasing ;
+    }
 
-        ATSUAttributeTag atsuTags[] =
-        {
-            kATSULineRotationTag ,
-        } ;
-        ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
-        {
-            sizeof( Fixed ) ,
-        } ;
-        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
-        {
-            &atsuAngle ,
-        } ;
+    Fixed atsuAngle = IntToFixed( iAngle ) ;
+
+    ATSUAttributeTag atsuTags[] =
+    {
+        kATSULineLayoutOptionsTag ,
+        kATSULineRotationTag ,
+    } ;
 
-        status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag),
+    ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+    {
+        sizeof( ATSLineLayoutOptions ) ,
+        sizeof( Fixed ) ,
+    } ;
+
+    ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+    {
+        &layoutOptions ,
+        &atsuAngle ,
+    } ;
+
+    status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) - ( abs(iAngle) > 0.001 ? 0 : 1),
             atsuTags, atsuSizes, atsuValues ) ;
-    }
 
     status = ::ATSUMeasureText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
         &textBefore , &textAfter, &ascent , &descent );
+    wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );
+
+    if ( m_backgroundMode == wxSOLID )
+    {
+        // background painting must be done by hand, cannot be done by ATSUI
+        wxCoord x2 , y2 ;
+        PolyHandle polygon = OpenPoly();
 
-    drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent));
-    drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent));
+        ::MoveTo(drawX, drawY);
+
+        x2 = (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) ;
+        y2 = (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ;
+        ::LineTo(x2, y2);
+
+        x2 = (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ;
+        y2 = (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ;
+        ::LineTo(x2, y2);
+
+        x2 = (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ;
+        y2 = (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ;
+        ::LineTo(x2, y2);
+
+        ::LineTo( drawX, drawY) ;
+        ClosePoly();
+
+        ::ErasePoly( polygon );
+        KillPoly( polygon );
+    }
+
+    drawX += (int)(sin(angle / RAD2DEG) * FixedToInt(ascent));
+    drawY += (int)(cos(angle / RAD2DEG) * FixedToInt(ascent));
     status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
         IntToFixed(drawX) , IntToFixed(drawY) );
 
@@ -1565,90 +1565,16 @@ void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
     status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
         IntToFixed(drawX) , IntToFixed(drawY) , &rect );
     wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );
+
     OffsetRect( &rect , -m_macLocalOrigin.x , -m_macLocalOrigin.y ) ;
     CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) );
     CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) );
     ::ATSUDisposeTextLayout(atsuLayout);
-
-#if SIZEOF_WCHAR_T == 4
-    free( ubuf ) ;
-#endif
 }
 
 void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
 {
-    wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText - invalid DC"));
-
-    wxMacFastPortSetter helper(this) ;
-    long xx = XLOG2DEVMAC(x);
-    long yy = YLOG2DEVMAC(y);
-
-#if TARGET_CARBON
-    bool useDrawThemeText = ( DrawThemeTextBox != (void*) kUnresolvedCFragSymbolAddress ) ;
-    if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || m_font.GetNoAntiAliasing() )
-        useDrawThemeText = false ;
-#endif
-
-    MacInstallFont() ;
-
-    FontInfo fi ;
-    ::GetFontInfo( &fi ) ;
-
-#if TARGET_CARBON
-    if ( !useDrawThemeText )
-        yy += fi.ascent ;
-#else
-    yy += fi.ascent ;
-#endif
-
-    ::TextMode( (m_backgroundMode == wxTRANSPARENT) ? srcOr : srcCopy ) ;
-    ::MoveTo( xx , yy );
-
-    int line = 0 ;
-    {
-        wxString linetext = strtext ;
-
-#if TARGET_CARBON
-        if ( useDrawThemeText )
-        {
-            Rect frame = {
-                yy + line*(fi.descent + fi.ascent + fi.leading), xx ,
-                yy + (line+1)*(fi.descent + fi.ascent + fi.leading) , xx + 10000 } ;
-            wxMacCFStringHolder mString( linetext , m_font.GetEncoding()) ;
-
-            if ( m_backgroundMode != wxTRANSPARENT )
-            {
-                Point bounds = {0, 0} ;
-                Rect background = frame ;
-                SInt16 baseline ;
-                ::GetThemeTextDimensions( mString,
-                    m_font.MacGetThemeFontID() ,
-                    kThemeStateActive,
-                    false,
-                    &bounds,
-                    &baseline );
-                background.right = background.left + bounds.h ;
-                background.bottom = background.top + bounds.v ;
-                ::EraseRect( &background ) ;
-            }
-
-            ::DrawThemeTextBox( mString,
-                m_font.MacGetThemeFontID() ,
-                kThemeStateActive,
-                false,
-                &frame,
-                teJustLeft,
-                NULL );
-        }
-        else
-#endif
-        {
-            wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
-            ::DrawText( text , 0 , strlen(text) ) ;
-         }
-    }
-
-    ::TextMode( srcOr ) ;
+    DoDrawRotatedText( strtext , x , y , 0) ;
 }
 
 bool wxDC::CanGetTextExtent() const
@@ -1658,7 +1584,8 @@ bool wxDC::CanGetTextExtent() const
     return true ;
 }
 
-void wxDC::DoGetTextExtent( const wxString &strtext, wxCoord *width, wxCoord *height,
+
+void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height,
                             wxCoord *descent, wxCoord *externalLeading ,
                             wxFont *theFont ) const
 {
@@ -1673,51 +1600,63 @@ void wxDC::DoGetTextExtent( const wxString &strtext, wxCoord *width, wxCoord *he
     }
 
     MacInstallFont() ;
-    FontInfo fi ;
-    ::GetFontInfo( &fi ) ;
 
-#if TARGET_CARBON
-    bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
-    if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() )
-        useGetThemeText = false ;
-#endif
+    OSStatus status = noErr ;
+    ATSUTextLayout atsuLayout ;
+
+    wxMacUniCharBuffer unibuf( str ) ;
+    UniCharCount chars = unibuf.GetChars() ;
+
+    status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 ,
+        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+
+    wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") );
+
+    status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ;
+    wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") );
+
+    ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ;
+
+    if (m_font.GetNoAntiAliasing())
+    {
+        layoutOptions |= kATSLineNoAntiAliasing ;
+    }
+
+    ATSUAttributeTag atsuTags[] =
+    {
+        kATSULineLayoutOptionsTag ,
+    } ;
+
+    ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+    {
+        sizeof( ATSLineLayoutOptions ) ,
+    } ;
+
+    ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+    {
+        &layoutOptions ,
+    } ;
+
+    status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
+            atsuTags, atsuSizes, atsuValues ) ;
+
+    ATSUTextMeasurement textBefore, textAfter ;
+    ATSUTextMeasurement textAscent, textDescent ;
+
+    status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
+        &textBefore , &textAfter, &textAscent , &textDescent );
 
     if ( height )
-        *height = YDEV2LOGREL( fi.descent + fi.ascent ) ;
+        *height = YDEV2LOGREL( FixedToInt(textAscent + textDescent) ) ;
     if ( descent )
-        *descent =YDEV2LOGREL( fi.descent );
+        *descent =YDEV2LOGREL( FixedToInt(textDescent) );
     if ( externalLeading )
-        *externalLeading = YDEV2LOGREL( fi.leading ) ;
-
-    int curwidth = 0 ;
+        *externalLeading = 0 ;
     if ( width )
-    {
-        *width = 0 ;
-        wxString linetext = strtext ;
+        *width = XDEV2LOGREL( FixedToInt(textAfter - textBefore) ) ;
 
-        if ( useGetThemeText )
-        {
-            Point bounds = {0, 0} ;
-            SInt16 baseline ;
-            wxMacCFStringHolder mString( linetext , m_font.GetEncoding() ) ;
-            ThemeFontID themeFont = m_font.MacGetThemeFontID() ;
-            ::GetThemeTextDimensions( mString,
-                themeFont ,
-                kThemeStateActive,
-                false,
-                &bounds,
-                &baseline );
-            curwidth = bounds.h ;
-        }
-        else
-        {
-            wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
-            curwidth = ::TextWidth( text , 0 , strlen(text) ) ;
-        }
+    ::ATSUDisposeTextLayout(atsuLayout);
 
-        if ( curwidth > *width )
-            *width = XDEV2LOGREL( curwidth ) ;
-    }
 
     if ( theFont )
     {
@@ -1732,110 +1671,85 @@ bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) con
     wxCHECK_MSG(Ok(), false, wxT("wxDC::DoGetPartialTextExtents - invalid DC"));
 
     widths.Empty();
-    widths.Add(0, text.Length());
+    widths.Add(0, text.length());
 
-    if (text.Length() == 0)
+    if (text.length() == 0)
         return false;
 
     wxMacFastPortSetter helper(this) ;
     MacInstallFont() ;
 
-#if TARGET_CARBON
-    bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
-    if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() )
-        useGetThemeText = false ;
+    OSStatus status = noErr ;
+    ATSUTextLayout atsuLayout ;
 
-    if ( useGetThemeText )
+    wxMacUniCharBuffer unibuf( text ) ;
+    UniCharCount chars = unibuf.GetChars() ;
+
+    status = ::ATSUCreateTextLayoutWithTextPtr( unibuf.GetBuffer() , 0 , chars , chars , 1 ,
+        &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+
+    wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") );
+
+    status = ::ATSUSetTransientFontMatching( atsuLayout , true ) ;
+    wxASSERT_MSG( status == noErr , wxT("couldn't setup transient font matching") );
+
+    ATSLineLayoutOptions layoutOptions = kATSLineNoLayoutOptions ;
+
+    if (m_font.GetNoAntiAliasing())
     {
-        // If anybody knows how to do this more efficiently yet still handle
-        // the fractional glyph widths that may be present when using AA
-        // fonts, please change it.  Currently it is measuring from the
-        // begining of the string for each succeding substring, which is much
-        // slower than this should be.
-        for (size_t i=0; i<text.Length(); i++)
-        {
-            wxString str(text.Left(i + 1));
-            Point bounds = {0, 0};
-            SInt16 baseline ;
-            wxMacCFStringHolder mString(str, m_font.GetEncoding());
-
-            ::GetThemeTextDimensions( mString,
-                                      m_font.MacGetThemeFontID(),
-                                      kThemeStateActive,
-                                      false,
-                                      &bounds,
-                                      &baseline );
-            widths[i] = XDEV2LOGREL(bounds.h);
-        }
+        layoutOptions |= kATSLineNoAntiAliasing ;
     }
-    else
-#endif
+
+    ATSUAttributeTag atsuTags[] =
+    {
+        kATSULineLayoutOptionsTag ,
+    } ;
+
+    ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
     {
-        wxCharBuffer buff = text.mb_str(wxConvLocal);
-        size_t len = strlen(buff);
-        short* measurements = new short[len+1];
-        MeasureText(len, buff.data(), measurements);
+        sizeof( ATSLineLayoutOptions ) ,
+    } ;
 
-        // Copy to widths, starting at measurements[1]
-        // NOTE: this doesn't take into account any multi-byte characters
-        // in buff, it probabkly should...
-        for (size_t i=0; i<text.Length(); i++)
-            widths[i] = XDEV2LOGREL(measurements[i + 1]);
+    ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+    {
+        &layoutOptions ,
+    } ;
 
-        delete [] measurements;
+    status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
+            atsuTags, atsuSizes, atsuValues ) ;
+
+    for ( int pos = 0; pos < (int)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 ));
     }
 
+    ::ATSUDisposeTextLayout(atsuLayout);
+
     return true;
 }
 
 wxCoord wxDC::GetCharWidth(void) const
 {
-    wxCHECK_MSG(Ok(), 1, wxT("wxDC::GetCharWidth - invalid DC"));
-
-    wxMacFastPortSetter helper(this) ;
-    int width = 0 ;
-    const char text[] = "g" ;
-
-    MacInstallFont() ;
-
-#if TARGET_CARBON
-    bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
-    if ( UMAGetSystemVersion() < 0x1000 || ((wxFont*)&m_font)->GetNoAntiAliasing() )
-        useGetThemeText = false ;
-
-    if ( useGetThemeText )
-    {
-        Point bounds = {0, 0} ;
-        SInt16 baseline ;
-        CFStringRef mString = CFStringCreateWithBytes( NULL , (UInt8*) text , 1 , CFStringGetSystemEncoding(), false ) ;
-        ::GetThemeTextDimensions( mString,
-            m_font.MacGetThemeFontID(),
-            kThemeStateActive,
-            false,
-            &bounds,
-            &baseline );
-        CFRelease( mString ) ;
-        width = bounds.h ;
-    }
-    else
-#endif
-    {
-        width = ::TextWidth( text , 0 , 1 ) ;
-    }
-
-    return YDEV2LOGREL(width) ;
+    wxCoord width = 0 ;
+    DoGetTextExtent( wxT("g"), &width , NULL , NULL , NULL , NULL ) ;
+    return width ;
 }
 
 wxCoord wxDC::GetCharHeight(void) const
 {
-    wxCHECK_MSG(Ok(), 1, wxT("wxDC::GetCharHeight - invalid DC"));
-
-    wxMacFastPortSetter helper(this) ;
-    MacInstallFont() ;
-    FontInfo fi ;
-    ::GetFontInfo( &fi ) ;
-
-    return YDEV2LOGREL( fi.descent + fi.ascent );
+    wxCoord height ;
+    DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ) ;
+    return height ;
 }
 
 void wxDC::Clear(void)
@@ -1859,6 +1773,7 @@ void wxDC::MacInstallFont() const
 
     //    if ( m_macFontInstalled )
     //        return ;
+
     Pattern blackColor ;
     MacSetupBackgroundForCurrentPort(m_backgroundBrush) ;
     if ( m_backgroundMode != wxTRANSPARENT )
@@ -1942,18 +1857,15 @@ void wxDC::MacInstallFont() const
     {
             sizeof( Fixed ) ,
     } ;
-//    Boolean kTrue = true ;
-//    Boolean kFalse = false ;
-
-//    ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
     ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
     {
             &atsuSize ,
     } ;
+
     status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
         atsuTags, atsuSizes, atsuValues);
 
-    wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ;
+    wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ;
 }
 
 Pattern gPatterns[] =
@@ -2007,19 +1919,21 @@ void wxDC::MacInstallPen() const
     //Pattern     blackColor;
     //    if ( m_macPenInstalled )
     //        return ;
+
     RGBColor forecolor = MAC_WXCOLORREF( m_pen.GetColour().GetPixel());
     RGBColor backcolor = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel());
     ::RGBForeColor( &forecolor );
     ::RGBBackColor( &backcolor );
     ::PenNormal() ;
-    int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ; ;
+
     // null means only one pixel, at whatever resolution
+    int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ;
     if ( penWidth == 0 )
         penWidth = 1 ;
     ::PenSize(penWidth, penWidth);
 
-    int penStyle = m_pen.GetStyle();
     Pattern pat;
+    int penStyle = m_pen.GetStyle();
     if (penStyle == wxUSER_DASH)
     {
         // FIXME: there should be exactly 8 items in the dash
@@ -2083,7 +1997,7 @@ void wxDC::MacInstallPen() const
         //        case wxSRC_AND:     // source _bitmap_ AND destination
         break ;
 
-    default;
+    default:
         break ;
     }
 
@@ -2096,6 +2010,7 @@ void wxDC::MacInstallPen() const
 void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background )
 {
     Pattern whiteColor ;
+
     if ( background.Ok() )
     {
         switch ( background.MacGetBrushKind() )
@@ -2108,7 +2023,7 @@ void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background )
             {
                 Rect extent ;
                 ThemeBackgroundKind bg = background.MacGetThemeBackground( &extent ) ;
-                ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ;
+                ::ApplyThemeBackground( bg , &extentkThemeStateActive , wxDisplayDepth() , true ) ;
             }
                 break ;
 
@@ -2140,10 +2055,11 @@ void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background )
 void wxDC::MacInstallBrush() const
 {
     wxCHECK_RET(Ok(), wxT("Invalid DC"));
-    Pattern     blackColor ;
+
     //    if ( m_macBrushInstalled )
     //        return ;
-    // foreground
+
+    Pattern     blackColor ;
     bool backgroundTransparent = (GetBackgroundMode() == wxTRANSPARENT) ;
     ::RGBForeColor( &MAC_WXCOLORREF( m_brush.GetColour().GetPixel()) );
     ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) );
@@ -2151,7 +2067,21 @@ void wxDC::MacInstallBrush() const
     int brushStyle = m_brush.GetStyle();
     if (brushStyle == wxSOLID)
     {
-        ::PenPat(GetQDGlobalsBlack(&blackColor));
+        switch ( m_brush.MacGetBrushKind() )
+        {
+            case kwxMacBrushTheme :
+                {
+                    Pattern whiteColor ;
+                    ::BackPat(GetQDGlobalsWhite(&whiteColor));
+                    ::SetThemePen( m_brush.MacGetTheme() , wxDisplayDepth() , true ) ;
+                }
+            break ;
+
+            default :
+                ::PenPat(GetQDGlobalsBlack(&blackColor));
+                break ;
+
+        }
     }
     else if (m_brush.IsHatch())
     {
@@ -2196,7 +2126,7 @@ void wxDC::MacInstallBrush() const
 
             for ( int i = 0 ; i < 8 ; ++i )
             {
-                pat.pat[i] = gwbits[i*alignment+0] ;
+                pat.pat[i] = gwbits[i * alignment + 0] ;
             }
 
             UnlockPixels( GetGWorldPixMap( gw ) ) ;