]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/font.cpp
freeze whole window for TLW
[wxWidgets.git] / src / osx / carbon / font.cpp
index 11fe47b41241ffd52f36c3d61cd2848ef1724aca..f8c6f5f347c8fb3a66d49942e87dbe2a08b01ec0 100644 (file)
 #include "wx/fontutil.h"
 #include "wx/graphics.h"
 #include "wx/settings.h"
+#include "wx/tokenzr.h"
 
 #include "wx/osx/private.h"
 
-#if wxOSX_USE_ATSU_TEXT && !wxOSX_USE_CARBON
-// include themeing support
-#include <Carbon/Carbon.h>
-#endif
-
 #include <map>
 #include <string>
 
 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
 
-
 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
 {
 public:
+
     wxFontRefData()
     {
-        Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
-             false, wxT("applicationfont"), wxFONTENCODING_DEFAULT);
+        Init();
+        m_info.Init(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
+             false, wxEmptyString, wxFONTENCODING_DEFAULT);
     }
 
-    wxFontRefData(const wxFontRefData& data)
-    {
-        Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
-             data.m_underlined, data.m_faceName, data.m_encoding);
-    }
+    wxFontRefData(const wxFontRefData& data);
 
-    wxFontRefData(int size,
-                  int family,
-                  int style,
-                  int weight,
-                  bool underlined,
-                  const wxString& faceName,
-                  wxFontEncoding encoding)
+    wxFontRefData( const wxNativeFontInfo& info ) : m_info(info)
     {
-        Init(size, family, style, weight, underlined, faceName, encoding);
+        Init();
     }
 
+    wxFontRefData(wxOSXSystemFont font, int size);
+
 #if wxOSX_USE_CORE_TEXT
     wxFontRefData( wxUint32 coreTextFontType );
     wxFontRefData( CTFontRef font );
@@ -72,126 +61,147 @@ public:
 
     virtual ~wxFontRefData();
 
-    void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
-
-    bool GetNoAntiAliasing() const { return m_noAA; }
-
     void SetPointSize( int size )
     {
-        m_pointSize = size;
-        MacInvalidateNativeFont();
+        if( GetPointSize() != size )
+        {
+            m_info.SetPointSize(size);
+            Free();
+        }
     }
 
-    int GetPointSize() const { return m_pointSize; }
+    int GetPointSize() const { return m_info.GetPointSize(); }
 
-    void SetFamily( int family )
+    void SetFamily( wxFontFamily family )
     {
-        m_family = family;
-        MacInvalidateNativeFont();
+        if ( m_info.m_family != family )
+        {
+            m_info.SetFamily( family );
+            Free();
+        }
     }
 
+    wxFontFamily GetFamily() const { return m_info.GetFamily(); }
 
-    int GetFamily() const { return m_family; }
-
-    void SetStyle( int style )
+    void SetStyle( wxFontStyle style )
     {
-        m_style = style;
-        MacInvalidateNativeFont();
+        if ( m_info.m_style != style )
+        {
+            m_info.SetStyle( style );
+            Free();
+        }
     }
 
 
-    int GetStyle() const { return m_style; }
+    wxFontStyle GetStyle() const { return m_info.GetStyle(); }
 
-    void SetWeight( int weight )
+    void SetWeight( wxFontWeight weight )
     {
-        m_weight = weight;
-        MacInvalidateNativeFont();
+        if ( m_info.m_weight != weight )
+        {
+            m_info.SetWeight( weight );
+            Free();
+        }
     }
 
 
-    int GetWeight() const { return m_weight; }
+    wxFontWeight GetWeight() const { return m_info.GetWeight(); }
 
     void SetUnderlined( bool u )
     {
-        m_underlined = u;
-        MacInvalidateNativeFont();
+        if ( m_info.m_underlined != u )
+        {
+            m_info.SetUnderlined( u );
+            Free();
+        }
     }
 
-    bool GetUnderlined() const { return m_underlined; }
+    bool GetUnderlined() const { return m_info.GetUnderlined(); }
 
     void SetFaceName( const wxString& facename )
     {
-        m_faceName = facename;
-        MacInvalidateNativeFont();
+        if ( m_info.m_faceName != facename )
+        {
+            m_info.SetFaceName( facename );
+            Free();
+        }
     }
 
-    const wxString& GetFaceName() const { return m_faceName; }
+    wxString GetFaceName() const { return m_info.GetFaceName(); }
 
     void SetEncoding( wxFontEncoding encoding )
     {
-        m_encoding = encoding;
-        MacInvalidateNativeFont();
+        if ( m_info.m_encoding != encoding )
+        {
+            m_info.SetEncoding( encoding );
+            Free();
+        }
     }
 
-    wxFontEncoding GetEncoding() const { return m_encoding; }
+    wxFontEncoding GetEncoding() const { return m_info.GetEncoding(); }
 
-    void MacInvalidateNativeFont();
+    void Free();
 
     void MacFindFont();
 
 protected:
     // common part of all ctors
-    void Init(int size,
-              int family,
-              int style,
-              int weight,
-              bool underlined,
-              const wxString& faceName,
-              wxFontEncoding encoding);
-
+    void Init();
 #if wxOSX_USE_CORE_TEXT
-    void Init( CTFontRef font );
+    // void Init( CTFontRef font );
 #endif
-    // font characterstics
-    int             m_pointSize;
-    int             m_family;
-    int             m_style;
-    int             m_weight;
-    bool            m_underlined;
-    wxString        m_faceName;
-    wxFontEncoding  m_encoding;
-    bool            m_noAA;      // No anti-aliasing
-
 public:
-#if wxOSX_USE_ATSU_TEXT
-    FMFontFamily    m_macFontFamily;
-    FMFontSize      m_macFontSize;
-    FMFontStyle     m_macFontStyle;
-
-    // ATSU Font Information
-
-    // this is split into an ATSU font id that may
-    // contain some styles (special bold fonts etc) and
-    // these are the additional qd styles that are not
-    // included in the ATSU font id
-    ATSUFontID      m_macATSUFontID;
-    FMFontStyle     m_macATSUAdditionalQDStyles ;
-
-    // for true themeing support we must store the correct font
+    bool            m_fontValid;
+#if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
+    // for true theming support we must store the correct font
     // information here, as this speeds up and optimizes rendering
     ThemeFontID     m_macThemeFontID ;
 #endif
 #if wxOSX_USE_CORE_TEXT
     wxCFRef<CTFontRef> m_ctFont;
 #endif
-#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
     ATSUStyle       m_macATSUStyle ;
+#endif
+    wxCFRef<CGFontRef> m_cgFont;
+#if wxOSX_USE_COCOA
+    WX_NSFont       m_nsFont;
+#endif
+#if wxOSX_USE_IPHONE
+    WX_UIFont       m_uiFont;
 #endif
     wxNativeFontInfo  m_info;
 };
 
 #define M_FONTDATA ((wxFontRefData*)m_refData)
 
+wxFontRefData::wxFontRefData(const wxFontRefData& data)
+{
+    Init();
+    m_info = data.m_info;
+    m_fontValid = data.m_fontValid;
+#if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
+    m_macThemeFontID = data.m_macThemeFontID;
+#endif
+#if wxOSX_USE_CORE_TEXT
+    m_ctFont = data.m_ctFont;
+#endif
+    m_cgFont = data.m_cgFont;
+#if wxOSX_USE_ATSU_TEXT
+    if ( data.m_macATSUStyle != NULL )
+    {
+        ATSUCreateStyle(&m_macATSUStyle) ;
+        ATSUCopyAttributes(data.m_macATSUStyle, m_macATSUStyle);
+    }
+#endif
+#if wxOSX_USE_COCOA
+    m_nsFont = (NSFont*) wxMacCocoaRetain(data.m_nsFont);
+#endif
+#if wxOSX_USE_IPHONE
+    m_uiFont = (UIFont*) wxMacCocoaRetain(data.m_uiFont);
+#endif
+
+}
 
 // ============================================================================
 // implementation
@@ -201,444 +211,214 @@ public:
 // wxFontRefData
 // ----------------------------------------------------------------------------
 
-void wxFontRefData::Init(int pointSize,
-    int family,
-    int style,
-    int weight,
-    bool underlined,
-    const wxString& faceName,
-    wxFontEncoding encoding)
+void wxFontRefData::Init()
 {
-    m_style = style;
-    m_pointSize = (pointSize == -1) ? wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize() : pointSize;
-    m_family = family;
-    m_style = style;
-    m_weight = weight;
-    m_underlined = underlined;
-    m_faceName = faceName;
-    m_encoding = encoding;
-    m_noAA = false;
-#if wxOSX_USE_ATSU_TEXT
-    m_macFontFamily = 0 ;
-    m_macFontSize = 0;
-    m_macFontStyle = 0;
-    m_macATSUFontID = 0;
-    m_macATSUAdditionalQDStyles = 0 ;
+#if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
     m_macThemeFontID = kThemeCurrentPortFont ;
 #endif
-#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
+#if wxOSX_USE_ATSU_TEXT
     m_macATSUStyle = NULL ;
 #endif
+#if wxOSX_USE_COCOA
+    m_nsFont = NULL;
+#endif
+#if wxOSX_USE_IPHONE
+    m_uiFont = NULL;
+#endif
+    m_fontValid = false;
 }
 
 wxFontRefData::~wxFontRefData()
 {
-#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
-    if ( m_macATSUStyle )
-    {
-        ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
-        m_macATSUStyle = NULL ;
-    }
-#endif
+    Free();
 }
 
-void wxFontRefData::MacInvalidateNativeFont()
+void wxFontRefData::Free()
 {
 #if wxOSX_USE_CORE_TEXT
     m_ctFont.reset();
 #endif
-#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
+    m_cgFont.reset();
+#if wxOSX_USE_ATSU_TEXT
+#if wxOSX_USE_CARBON
+    m_macThemeFontID = kThemeCurrentPortFont ;
+#endif
     if ( m_macATSUStyle )
     {
         ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
         m_macATSUStyle = NULL ;
     }
 #endif
-}
-
-#if wxOSX_USE_CORE_TEXT
-
-/* from Core Text Manual Common Operations */
-
-static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits )
-{
-    CTFontDescriptorRef descriptor = NULL;
-    CFMutableDictionaryRef attributes;
-
-    assert(iFamilyName != NULL);
-    // Create a mutable dictionary to hold our attributes.
-    attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
-                                           &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    check(attributes != NULL);
-
-    if (attributes != NULL) {
-        // Add a family name to our attributes.
-        CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, iFamilyName);
-
-
-        if ( iTraits ) {
-            CFMutableDictionaryRef traits;
-            CFNumberRef symTraits;
-
-            // Create the traits dictionary.
-            symTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
-                                       &iTraits);
-            check(symTraits != NULL);
-
-            if (symTraits != NULL) {
-                // Create a dictionary to hold our traits values.
-                traits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
-                                                   &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                check(traits != NULL);
-
-                if (traits != NULL) {
-                    // Add the symbolic traits value to the traits dictionary.
-                    CFDictionaryAddValue(traits, kCTFontSymbolicTrait, symTraits);
-
-                    // Add the traits attribute to our attributes.
-                    CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits);
-                    CFRelease(traits);
-                }
-                CFRelease(symTraits);
-            }
-        }
-        // Create the font descriptor with our attributes
-        descriptor = CTFontDescriptorCreateWithAttributes(attributes);
-        check(descriptor != NULL);
-
-        CFRelease(attributes);
+#if wxOSX_USE_COCOA
+    if (m_nsFont != NULL)
+    {
+        wxMacCocoaRelease(m_nsFont);
+        m_nsFont = NULL;
     }
-    // Return our font descriptor.
-    return descriptor ;
-}
-
-wxFontRefData::wxFontRefData( wxUint32 coreTextFontType )
-{
-    CTFontRef font = CTFontCreateUIFontForLanguage( coreTextFontType, 0.0, NULL ) ;
-    if ( CTFontGetSize(font) == 0 )
+#endif
+#if wxOSX_USE_IPHONE
+    if (m_uiFont != NULL)
     {
-        CFRelease(font);
-        font = CTFontCreateUIFontForLanguage( coreTextFontType, 12.0, NULL );
+        wxMacCocoaRelease(m_uiFont);
+        m_uiFont = NULL;
     }
-    Init( font );
+#endif
+    m_fontValid = false;
 }
 
-wxFontRefData::wxFontRefData( CTFontRef font )
+wxFontRefData::wxFontRefData(wxOSXSystemFont font, int size)
 {
-    Init( font );
-}
+    wxASSERT( font != wxOSX_SYSTEM_FONT_NONE );
+    Init();
 
-wxFontRefData::wxFontRefData( CTFontDescriptorRef fontdescriptor, int size )
-{
-    if ( size == 0 )
+#if wxOSX_USE_CORE_TEXT
+    if (  UMAGetSystemVersion() >= 0x1050 )
     {
-        wxCFRef< CFNumberRef > value( (CFNumberRef) CTFontDescriptorCopyAttribute( fontdescriptor, kCTFontSizeAttribute ) );
-
-        float fsize;
-        if ( CFNumberGetValue( value , kCFNumberFloatType , &fsize ) )
+        CTFontUIFontType uifont = kCTFontSystemFontType;
+        switch( font )
         {
-            size = (int)( fsize + 0.5 );
+            case wxOSX_SYSTEM_FONT_NORMAL:
+                uifont = kCTFontSystemFontType;
+                break;
+            case wxOSX_SYSTEM_FONT_BOLD:
+                uifont = kCTFontEmphasizedSystemFontType;
+                break;
+            case wxOSX_SYSTEM_FONT_SMALL:
+                uifont = kCTFontSmallSystemFontType;
+                break;
+            case wxOSX_SYSTEM_FONT_SMALL_BOLD:
+                uifont = kCTFontSmallEmphasizedSystemFontType;
+                break;
+            case wxOSX_SYSTEM_FONT_MINI:
+                uifont = kCTFontMiniSystemFontType;
+                break;
+           case wxOSX_SYSTEM_FONT_MINI_BOLD:
+                uifont = kCTFontMiniEmphasizedSystemFontType;
+                break;
+            case wxOSX_SYSTEM_FONT_LABELS:
+                uifont = kCTFontLabelFontType;
+                break;
+           case wxOSX_SYSTEM_FONT_VIEWS:
+                uifont = kCTFontViewsFontType;
+                break;
+            default:
+                break;
         }
+        m_ctFont.reset(CTFontCreateUIFontForLanguage( uifont, (CGFloat) size, NULL ));
+        wxCFRef<CTFontDescriptorRef> descr;
+        descr.reset( CTFontCopyFontDescriptor( m_ctFont ) );
+        m_info.Init(descr);
     }
-    Init( CTFontCreateWithFontDescriptor(fontdescriptor, size,NULL)  );
-}
+#endif
+#if wxOSX_USE_ATSU_TEXT
+    {
+#if !wxOSX_USE_CARBON
+        // not needed outside
+        ThemeFontID m_macThemeFontID = kThemeSystemFont;
+#endif
+        switch( font )
+        {
+            case wxOSX_SYSTEM_FONT_NORMAL:
+                m_macThemeFontID = kThemeSystemFont;
+                break;
+            case wxOSX_SYSTEM_FONT_BOLD:
+                m_macThemeFontID = kThemeEmphasizedSystemFont;
+                break;
+            case wxOSX_SYSTEM_FONT_SMALL:
+                m_macThemeFontID = kThemeSmallSystemFont;
+                break;
+            case wxOSX_SYSTEM_FONT_SMALL_BOLD:
+                m_macThemeFontID = kThemeSmallEmphasizedSystemFont;
+                break;
+            case wxOSX_SYSTEM_FONT_MINI:
+                m_macThemeFontID = kThemeMiniSystemFont;
+                break;
+           case wxOSX_SYSTEM_FONT_MINI_BOLD:
+                // bold not available under theming
+                m_macThemeFontID = kThemeMiniSystemFont;
+                break;
+            case wxOSX_SYSTEM_FONT_LABELS:
+                m_macThemeFontID = kThemeLabelFont;
+                break;
+           case wxOSX_SYSTEM_FONT_VIEWS:
+                m_macThemeFontID = kThemeViewsFont;
+                break;
+            default:
+                break;
+        }
+        if ( m_info.m_faceName.empty() )
+        {
+            Style style ;
+            FMFontSize fontSize;
+            Str255 qdFontName ;
 
-void wxFontRefData::Init( CTFontRef font )
-{
-    Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
-         false, wxT("applicationfont"), wxFONTENCODING_DEFAULT);
+            GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &fontSize, &style );
+            if ( size != 0 )
+                fontSize = size;
 
-    m_ctFont.reset( font );
-}
+            wxFontStyle fontstyle = wxFONTSTYLE_NORMAL;
+            wxFontWeight fontweight = wxFONTWEIGHT_NORMAL;
+            bool underlined = false;
 
+            if ( style & bold )
+                fontweight = wxFONTWEIGHT_BOLD ;
+            else
+                fontweight = wxFONTWEIGHT_NORMAL ;
+            if ( style & italic )
+                fontstyle = wxFONTSTYLE_ITALIC ;
+            if ( style & underline )
+                underlined = true ;
+
+            m_info.Init(fontSize,wxFONTFAMILY_DEFAULT,fontstyle,fontweight,underlined,
+                wxMacMakeStringFromPascal( qdFontName ), wxFONTENCODING_DEFAULT);
+         }
+    }
+#endif
+#if wxOSX_USE_COCOA
+    m_nsFont = wxFont::OSXCreateNSFont( font, &m_info );
 #endif
+#if wxOSX_USE_IPHONE
+    m_uiFont = wxFont::OSXCreateUIFont( font, &m_info );
+#endif
+}
 
 void wxFontRefData::MacFindFont()
 {
+    if ( m_fontValid )
+        return;
+
+    wxCHECK_RET( m_info.m_pointSize > 0, wxT("Point size should not be zero.") );
+
+    m_info.EnsureValid();
 
 #if wxOSX_USE_CORE_TEXT
     if (  UMAGetSystemVersion() >= 0x1050 )
     {
-        if ( m_faceName.empty() && m_family == wxDEFAULT )
-        {
-            m_ctFont.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType, 0.0, NULL ));
-        }
-
-        if ( m_ctFont )
-        {
-            wxCFStringRef name( CTFontCopyFamilyName( m_ctFont ) );
-            m_faceName = name.AsString();
-            m_pointSize = CTFontGetSize(m_ctFont) ;
-            CTFontSymbolicTraits traits = CTFontGetSymbolicTraits( m_ctFont );
-            if ( traits & kCTFontItalicTrait )
-                m_style = wxITALIC;
-            if (  traits & kCTFontBoldTrait )
-                m_weight = wxBOLD ;
-        }
-        else
-        {
-            if ( m_faceName.empty() )
-            {
-                switch ( m_family )
-                {
-                    case wxSCRIPT :
-                    case wxROMAN :
-                    case wxDECORATIVE :
-                        m_faceName = wxT("Times");
-                        break ;
-
-                    case wxSWISS :
-                        m_faceName =  wxT("Helvetica");
-                        break ;
-
-                    case wxMODERN :
-                    case wxTELETYPE:
-                        m_faceName =  wxT("Courier");
-                        if ( m_style == wxITALIC && m_weight == wxNORMAL )
-                        {
-                            m_style = wxITALIC;
-                        }
-                        break ;
-
-                    default:
-                        m_faceName =  wxT("Times");
-                        break ;
-                }
-            }
-
-            
-            CTFontSymbolicTraits traits = 0;
-
-            if (m_weight == wxBOLD)
-                traits |= kCTFontBoldTrait;
-            if (m_style == wxITALIC || m_style == wxSLANT)
-                traits |= kCTFontItalicTrait;
-     
-            // use font caching
-            wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize );
-            
-            static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
-            m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
-            if ( !m_ctFont )
-            {
-                // QD selection algorithm is the fastest by orders of magnitude on 10.5
-                if ( m_faceName.IsAscii() )
-                {
-                    uint8 qdstyle = 0;
-                    if (m_weight == wxBOLD)
-                        qdstyle |= bold;
-                    if (m_style == wxITALIC || m_style == wxSLANT)
-                        qdstyle |= italic;
-                    
-                    Str255 qdFontName ;
-                    wxMacStringToPascal( m_faceName , qdFontName );
-                    m_ctFont.reset( CTFontCreateWithQuickdrawInstance(qdFontName, 0 , qdstyle, m_pointSize) );
-                }
-                else
-                {
-
-                    static std::map< std::wstring , wxCFRef< CTFontDescriptorRef > > fontdescriptorcache ;
-                    wxString lookupname = wxString::Format( "%s_%ld", m_faceName.c_str(), traits );
-                    // descriptor caching
-                    wxCFRef< CTFontDescriptorRef > descriptor = fontdescriptorcache[ std::wstring(lookupname.wc_str()) ];
-                    if ( !descriptor )
-                    {
-                        wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
-                        descriptor.reset( wxMacCreateCTFontDescriptor( cf, traits ) );
-                        fontdescriptorcache[ std::wstring(lookupname.wc_str()) ] = descriptor;
-                    }
-                    m_ctFont.reset( CTFontCreateWithFontDescriptor( descriptor, m_pointSize, NULL ) );
-                    CTFontSymbolicTraits received = CTFontGetSymbolicTraits( m_ctFont ) & 0x03;
-                    if ( traits != received )
-                    {
-                        // TODO further fallbacks, synthesizing bold and italic, trying direct PostScript names etc
-                    }
-                }
-                
-                fontcache[ std::wstring(lookupnameWithSize.wc_str()) ] = m_ctFont;
-#if 1 // debugging coretext font matching
-                CTFontSymbolicTraits received = CTFontGetSymbolicTraits( m_ctFont ) & 0x03;
-                if ( received != traits )
-                {
-                    float angle = CTFontGetSlantAngle( m_ctFont );
-                    CFDictionaryRef dict = CTFontCopyTraits( m_ctFont );
-                    CFNumberRef number = (CFNumberRef) CFDictionaryGetValue(dict, kCTFontWeightTrait );
-                    float floatnumber;
-                    CFNumberGetValue( number, kCFNumberFloatType, &floatnumber );
-                    {
-                        wxString msg = wxString::Format( "font %s expected %d but got %d traits, %f angle \n" ,
-                                                         m_faceName.c_str(), traits, received, angle );
-                        printf( msg.c_str() );
-                    }
-                    CFShow( dict );
-                    CFRelease( dict );
-                }
-#endif  
-            }
+         CTFontSymbolicTraits traits = 0;
 
-        }
-#if wxOSX_USE_ATSU_TEXT
-        OSStatus status = noErr;
-        ATSFontRef atsfont = CTFontGetPlatformFont( m_ctFont, NULL );
-        FMFont fmfont = FMGetFontFromATSFontRef( atsfont );
-        ATSUAttributeTag atsuTags[] =
-        {
-            kATSUFontTag ,
-            kATSUSizeTag ,
-            kATSUVerticalCharacterTag,
-            kATSUQDBoldfaceTag ,
-            kATSUQDItalicTag ,
-            kATSUQDUnderlineTag ,
-        };
-        ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
-        {
-            sizeof( ATSUFontID ) ,
-            sizeof( Fixed ) ,
-            sizeof( ATSUVerticalCharacterType),
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-        };
-        Boolean kTrue = true ;
-        Boolean kFalse = false ;
+        if (m_info.m_weight == wxFONTWEIGHT_BOLD)
+            traits |= kCTFontBoldTrait;
+        if (m_info.m_style == wxFONTSTYLE_ITALIC || m_info.m_style == wxFONTSTYLE_SLANT)
+            traits |= kCTFontItalicTrait;
 
-        Fixed atsuSize = IntToFixed( m_pointSize );
-        ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
-        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
-        {
-            &fmfont ,
-            &atsuSize ,
-            &kHorizontal,
-            (m_weight == wxBOLD) ? &kTrue : &kFalse ,
-            (m_style == wxITALIC || m_style == wxSLANT) ? &kTrue : &kFalse ,
-            (m_underlined) ? &kTrue : &kFalse ,
-        };
+        // use font caching
+        wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_info.m_faceName.c_str(), traits, m_info.m_pointSize );
 
-        if ( m_macATSUStyle )
+        static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
+        m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
+        if ( !m_ctFont )
         {
-            ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
-            m_macATSUStyle = NULL ;
+            m_ctFont.reset( CTFontCreateWithFontDescriptor( m_info.m_ctFontDescriptor, 0/*m_pointSize */, NULL ) );
         }
-        status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
-        wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
-        status = ::ATSUSetAttributes(
-                                     (ATSUStyle)m_macATSUStyle,
-                                     sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
-                                     atsuTags, atsuSizes, atsuValues);
-#endif
+        m_cgFont.reset(CTFontCopyGraphicsFont(m_ctFont, NULL));
     }
+
 #endif
 #if wxOSX_USE_ATSU_TEXT
     {
-        OSStatus status = noErr;
-        Str255 qdFontName ;
-        if ( m_macThemeFontID != kThemeCurrentPortFont )
-        {
-            Style style ;
-            GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style );
-            if ( m_macFontSize == 0 )
-                m_macFontSize = 12;
-            m_macFontStyle = style ;
-            m_faceName = wxMacMakeStringFromPascal( qdFontName );
-            if ( m_macFontStyle & bold )
-                m_weight = wxBOLD ;
-            else
-                m_weight = wxNORMAL ;
-            if ( m_macFontStyle & italic )
-                m_style = wxITALIC ;
-            if ( m_macFontStyle & underline )
-                m_underlined = true ;
-            m_pointSize = m_macFontSize ;
-            m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
-        }
-        else
-        {
-            if ( m_faceName.empty() )
-            {
-                if ( m_family == wxDEFAULT )
-                {
-                    m_macFontFamily = GetAppFont();
-                    FMGetFontFamilyName(m_macFontFamily,qdFontName);
-                    m_faceName = wxMacMakeStringFromPascal( qdFontName );
-                }
-                else
-                {
-                    switch ( m_family )
-                    {
-                        case wxSCRIPT :
-                        case wxROMAN :
-                        case wxDECORATIVE :
-                            m_faceName = wxT("Times");
-                            break ;
-
-                        case wxSWISS :
-                            m_faceName =  wxT("Helvetica");
-                            break ;
-
-                        case wxMODERN :
-                        case wxTELETYPE:
-                            m_faceName =  wxT("Courier");
-                            break ;
-
-                        default:
-                            m_faceName =  wxT("Times");
-                            break ;
-                    }
-                    wxMacStringToPascal( m_faceName , qdFontName );
-                    m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
-                    if ( m_macFontFamily == kInvalidFontFamily )
-                    {
-                        wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName.c_str() );
-                        m_macFontFamily = GetAppFont();
-                    }
-                }
-            }
-            else
-            {
-                if ( m_faceName == wxT("systemfont") )
-                    m_macFontFamily = GetSysFont();
-                else if ( m_faceName == wxT("applicationfont") )
-                    m_macFontFamily = GetAppFont();
-                else
-                {
-                    wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
-                    ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
-                    if ( atsfamily == (ATSFontFamilyRef) -1 )
-                    {
-                        wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
-                        m_macFontFamily = GetAppFont();
-                    }
-                    else
-                        m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
-                }
-            }
-
-            m_macFontStyle = 0;
-            if (m_weight == wxBOLD)
-                m_macFontStyle |= bold;
-            if (m_style == wxITALIC || m_style == wxSLANT)
-                m_macFontStyle |= italic;
-            if (m_underlined)
-                m_macFontStyle |= underline;
-            m_macFontSize = m_pointSize ;
-        }
-
         // we try to get as much styles as possible into ATSU
 
-
-        // ATSUFontID and FMFont are equivalent
-        FMFontStyle intrinsicStyle = 0 ;
-        status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle);
-        wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
-        m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle );
-
-        if ( m_macATSUStyle )
-        {
-            ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
-            m_macATSUStyle = NULL ;
-        }
-
-        status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
+        OSStatus status = ::ATSUCreateStyle(&m_macATSUStyle);
         wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
 
         ATSUAttributeTag atsuTags[] =
@@ -652,7 +432,7 @@ void wxFontRefData::MacFindFont()
             kATSUQDCondensedTag ,
             kATSUQDExtendedTag ,
         };
-        ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+        ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
         {
             sizeof( ATSUFontID ) ,
             sizeof( Fixed ) ,
@@ -667,29 +447,42 @@ void wxFontRefData::MacFindFont()
         Boolean kTrue = true ;
         Boolean kFalse = false ;
 
-        Fixed atsuSize = IntToFixed( m_macFontSize );
+        Fixed atsuSize = IntToFixed( m_info.m_pointSize );
         ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
-        ATSUAttributeValuePtr    atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
+        FMFontStyle addQDStyle = m_info.m_atsuAdditionalQDStyles;
+        ATSUAttributeValuePtr    atsuValues[WXSIZEOF(atsuTags)] =
         {
-            &m_macATSUFontID ,
+            &m_info.m_atsuFontID ,
             &atsuSize ,
             &kHorizontal,
-            (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
-            (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
-            (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
-            (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
-            (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
+            (addQDStyle & bold) ? &kTrue : &kFalse ,
+            (addQDStyle & italic) ? &kTrue : &kFalse ,
+            (addQDStyle & underline) ? &kTrue : &kFalse ,
+            (addQDStyle & condense) ? &kTrue : &kFalse ,
+            (addQDStyle & extend) ? &kTrue : &kFalse ,
         };
 
         status = ::ATSUSetAttributes(
                                      (ATSUStyle)m_macATSUStyle,
-                                     sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
+                                     WXSIZEOF(atsuTags),
                                      atsuTags, atsuSizes, atsuValues);
 
-        wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
-        return;
+        wxASSERT_MSG( status == noErr , wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status).c_str() );
+
+        if ( m_cgFont.get() == NULL )
+        {
+            ATSFontRef fontRef = FMGetATSFontRefFromFont(m_info.m_atsuFontID);
+            m_cgFont.reset( CGFontCreateWithPlatformFont( &fontRef ) );
+        }
     }
 #endif
+#if wxOSX_USE_COCOA
+    m_nsFont = wxFont::OSXCreateNSFont( &m_info );
+#endif
+#if wxOSX_USE_IPHONE
+    m_uiFont = wxFont::OSXCreateUIFont( &m_info );
+#endif
+    m_fontValid = true;
 }
 
 // ----------------------------------------------------------------------------
@@ -698,9 +491,12 @@ void wxFontRefData::MacFindFont()
 
 bool wxFont::Create(const wxNativeFontInfo& info)
 {
-    return Create(
-        info.pointSize, info.family, info.style, info.weight,
-        info.underlined, info.faceName, info.encoding );
+    UnRef();
+
+    m_refData = new wxFontRefData( info );
+    RealizeResource();
+
+    return true;
 }
 
 wxFont::wxFont(const wxString& fontdesc)
@@ -711,80 +507,78 @@ wxFont::wxFont(const wxString& fontdesc)
 }
 
 bool wxFont::Create(int pointSize,
-    int family,
-    int style,
-    int weight,
-    bool underlined,
-    const wxString& faceName,
-    wxFontEncoding encoding)
+                    wxFontFamily family,
+                    wxFontStyle style,
+                    wxFontWeight weight,
+                    bool underlined,
+                    const wxString& faceNameParam,
+                    wxFontEncoding encoding)
 {
     UnRef();
 
-    m_refData = new wxFontRefData(
-        pointSize, family, style, weight,
+    wxString faceName = faceNameParam;
+
+    if ( faceName.empty() )
+    {
+        switch ( family )
+        {
+            case wxFONTFAMILY_DEFAULT :
+                faceName = wxT("Lucida Grande");
+                break;
+
+            case wxFONTFAMILY_SCRIPT :
+            case wxFONTFAMILY_ROMAN :
+            case wxFONTFAMILY_DECORATIVE :
+                faceName = wxT("Times");
+                break ;
+
+            case wxFONTFAMILY_SWISS :
+                faceName =  wxT("Helvetica");
+                break ;
+
+            case wxFONTFAMILY_MODERN :
+            case wxFONTFAMILY_TELETYPE:
+                faceName =  wxT("Courier");
+                 break ;
+
+            default:
+                faceName =  wxT("Times");
+                break ;
+        }
+    }
+
+    wxNativeFontInfo info;
+
+    info.Init(pointSize, family, style, weight,
         underlined, faceName, encoding);
 
-    RealizeResource();
+    m_refData = new wxFontRefData(info);
 
     return true;
 }
 
-#if wxOSX_USE_CORE_TEXT
-
-bool wxFont::MacCreateFromUIFont(wxUint32 ctFontType )
+bool wxFont::CreateSystemFont(wxOSXSystemFont font)
 {
     UnRef();
 
-    m_refData = new wxFontRefData(ctFontType);
-    RealizeResource();
+    m_refData = new wxFontRefData( font, 0 );
 
     return true;
 }
 
-bool wxFont::MacCreateFromCTFontDescriptor( const void * ctFontDescriptor , int size )
+wxFont::~wxFont()
 {
-    UnRef();
+}
 
-    m_refData = new wxFontRefData((CTFontDescriptorRef)ctFontDescriptor, size);;
-    RealizeResource();
+void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
+{
+    UnRef();
 
-    return true;
+    m_refData = new wxFontRefData( info);
 }
 
 
-#endif
-
-#if wxOSX_USE_CARBON
-bool wxFont::MacCreateFromThemeFont(wxUint16 themeFontID)
-{
-#if wxOSX_USE_CORE_TEXT
-    if ( UMAGetSystemVersion() >= 0x1050)
-    {
-        return MacCreateFromUIFont(HIThemeGetUIFontType(themeFontID));
-    }
-#endif
-#if wxOSX_USE_ATSU_TEXT
-    {
-        UnRef();
-
-        m_refData = new wxFontRefData(
-                                      12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
-                                      false, wxEmptyString, wxFONTENCODING_DEFAULT );
-
-        M_FONTDATA->m_macThemeFontID = themeFontID ;
-        RealizeResource();
-        return true;
-    }
-#endif
-    return false;
-}
-#endif
-
-wxFont::~wxFont()
-{
-}
-
-bool wxFont::RealizeResource()
+bool wxFont::RealizeResource()
 {
     M_FONTDATA->MacFindFont();
 
@@ -793,26 +587,9 @@ bool wxFont::RealizeResource()
 
 void wxFont::SetEncoding(wxFontEncoding encoding)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetEncoding( encoding );
-
-    RealizeResource();
-}
-
-void wxFont::Unshare()
-{
-    // Don't change shared data
-    if (!m_refData)
-    {
-        m_refData = new wxFontRefData();
-    }
-    else
-    {
-        wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
-        UnRef();
-        m_refData = ref;
-    }
 }
 
 wxGDIRefData *wxFont::CreateGDIRefData() const
@@ -822,7 +599,7 @@ wxGDIRefData *wxFont::CreateGDIRefData() const
 
 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
 {
-    return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data));
+    return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
 }
 
 void wxFont::SetPointSize(int pointSize)
@@ -830,67 +607,46 @@ void wxFont::SetPointSize(int pointSize)
     if ( M_FONTDATA->GetPointSize() == pointSize )
         return;
 
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetPointSize( pointSize );
-
-    RealizeResource();
 }
 
-void wxFont::SetFamily(int family)
+void wxFont::SetFamily(wxFontFamily family)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetFamily( family );
-
-    RealizeResource();
 }
 
-void wxFont::SetStyle(int style)
+void wxFont::SetStyle(wxFontStyle style)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetStyle( style );
-
-    RealizeResource();
 }
 
-void wxFont::SetWeight(int weight)
+void wxFont::SetWeight(wxFontWeight weight)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetWeight( weight );
-
-    RealizeResource();
 }
 
 bool wxFont::SetFaceName(const wxString& faceName)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetFaceName( faceName );
 
-    RealizeResource();
-
     return wxFontBase::SetFaceName(faceName);
 }
 
 void wxFont::SetUnderlined(bool underlined)
 {
-    Unshare();
+    AllocExclusive();
 
     M_FONTDATA->SetUnderlined( underlined );
-
-    RealizeResource();
-}
-
-void wxFont::SetNoAntiAliasing( bool no )
-{
-    Unshare();
-
-    M_FONTDATA->SetNoAntiAliasing( no );
-
-    RealizeResource();
 }
 
 // ----------------------------------------------------------------------------
@@ -921,23 +677,23 @@ wxSize wxFont::GetPixelSize() const
 #endif
 }
 
-int wxFont::GetFamily() const
+wxFontFamily wxFont::GetFamily() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
 
     return M_FONTDATA->GetFamily();
 }
 
-int wxFont::GetStyle() const
+wxFontStyle wxFont::GetStyle() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , wxFONTSTYLE_MAX, wxT("invalid font") );
 
     return M_FONTDATA->GetStyle() ;
 }
 
-int wxFont::GetWeight() const
+wxFontWeight wxFont::GetWeight() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , wxFONTWEIGHT_MAX, wxT("invalid font") );
 
     return M_FONTDATA->GetWeight();
 }
@@ -963,74 +719,111 @@ wxFontEncoding wxFont::GetEncoding() const
     return M_FONTDATA->GetEncoding() ;
 }
 
-bool wxFont::GetNoAntiAliasing() const
+#if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
+
+short wxFont::MacGetFontNum() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return M_FONTDATA->GetNoAntiAliasing();
-}
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
 
-#if wxOSX_USE_ATSU_TEXT
+    return M_FONTDATA->m_info.m_qdFontFamily;
+}
 
-short wxFont::MacGetFontNum() const
+wxByte wxFont::MacGetFontStyle() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return M_FONTDATA->m_macFontFamily;
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    return M_FONTDATA->m_info.m_qdFontStyle;
 }
 
-short wxFont::MacGetFontSize() const
+wxUint16 wxFont::MacGetThemeFontID() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return M_FONTDATA->m_macFontSize;
+    return M_FONTDATA->m_macThemeFontID;
 }
 
-wxByte wxFont::MacGetFontStyle() const
+#endif
+
+#if wxOSX_USE_ATSU_TEXT
+void * wxFont::MacGetATSUStyle() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
+
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
 
-    return M_FONTDATA->m_macFontStyle;
+    return M_FONTDATA->m_macATSUStyle;
 }
 
+#if WXWIN_COMPATIBILITY_2_8
 wxUint32 wxFont::MacGetATSUFontID() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL, 0, wxT("invalid font") );
 
-    return M_FONTDATA->m_macATSUFontID;
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    return M_FONTDATA->m_info.m_atsuFontID;
 }
 
 wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL, 0, wxT("invalid font") );
+
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
 
-    return M_FONTDATA->m_macATSUAdditionalQDStyles;
+    return M_FONTDATA->m_info.m_atsuAdditionalQDStyles;
 }
+#endif
 
-wxUint16 wxFont::MacGetThemeFontID() const
+#endif
+
+#if wxOSX_USE_CORE_TEXT
+
+CTFontRef wxFont::OSXGetCTFont() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return M_FONTDATA->m_macThemeFontID;
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    return (CTFontRef)(M_FONTDATA->m_ctFont);
 }
+
 #endif
 
-#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
-void * wxFont::MacGetATSUStyle() const
+#if wxOSX_USE_COCOA_OR_CARBON
+
+CGFontRef wxFont::OSXGetCGFont() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
+    wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return M_FONTDATA->m_macATSUStyle;
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    return (M_FONTDATA->m_cgFont);
 }
+
 #endif
 
-#if wxOSX_USE_CORE_TEXT
 
-const void * wxFont::MacGetCTFont() const
+#if wxOSX_USE_COCOA
+
+NSFont* wxFont::OSXGetNSFont() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
 
-    return (CTFontRef)(M_FONTDATA->m_ctFont);
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    return (M_FONTDATA->m_nsFont);
 }
 
 #endif
@@ -1040,7 +833,457 @@ const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
     wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
     wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
 
-    M_FONTDATA->m_info.InitFromFont(*this);
+    // cast away constness otherwise lazy font resolution is not possible
+    const_cast<wxFont *>(this)->RealizeResource();
+
+    // M_FONTDATA->m_info.InitFromFont(*this);
 
     return &(M_FONTDATA->m_info);
 }
+
+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
+
+#if wxOSX_USE_CORE_TEXT
+
+/* from Core Text Manual Common Operations */
+
+static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits )
+{
+    CTFontDescriptorRef descriptor = NULL;
+    CFMutableDictionaryRef attributes;
+
+    wxASSERT(iFamilyName != NULL);
+    // Create a mutable dictionary to hold our attributes.
+    attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                           &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    wxASSERT(attributes != NULL);
+
+    if (attributes != NULL) {
+        // Add a family name to our attributes.
+        CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, iFamilyName);
+
+
+        if ( iTraits ) {
+            CFMutableDictionaryRef traits;
+            CFNumberRef symTraits;
+
+            // Create the traits dictionary.
+            symTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
+                                       &iTraits);
+            wxASSERT(symTraits != NULL);
+
+            if (symTraits != NULL) {
+                // Create a dictionary to hold our traits values.
+                traits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                   &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                wxASSERT(traits != NULL);
+
+                if (traits != NULL) {
+                    // Add the symbolic traits value to the traits dictionary.
+                    CFDictionaryAddValue(traits, kCTFontSymbolicTrait, symTraits);
+
+                    // Add the traits attribute to our attributes.
+                    CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits);
+                    CFRelease(traits);
+                }
+                CFRelease(symTraits);
+            }
+        }
+        // Create the font descriptor with our attributes
+        descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+        wxASSERT(descriptor != NULL);
+
+        CFRelease(attributes);
+    }
+    // Return our font descriptor.
+    return descriptor ;
+}
+
+#endif
+
+void wxNativeFontInfo::Init()
+{
+#if wxOSX_USE_CORE_TEXT
+    m_ctFontDescriptor = NULL;
+#endif
+#if wxOSX_USE_ATSU_TEXT
+    m_atsuFontID = 0 ;
+    m_atsuAdditionalQDStyles = 0;
+    m_atsuFontValid = false;
+#if wxOSX_USE_CARBON
+    m_qdFontStyle = 0;
+    m_qdFontFamily = 0;
+#endif
+#endif
+#if wxOSX_USE_COCOA
+    m_nsFontDescriptor = NULL;
+#endif
+    m_pointSize = 0;
+    m_family = wxFONTFAMILY_DEFAULT;
+    m_style = wxFONTSTYLE_NORMAL;
+    m_weight = wxFONTWEIGHT_NORMAL;
+    m_underlined = false;
+    m_faceName.clear();
+    m_encoding = wxFont::GetDefaultEncoding();
+    m_descriptorValid = false;
+}
+
+#if wxOSX_USE_CORE_TEXT
+void wxNativeFontInfo::Init(CTFontDescriptorRef descr)
+{
+    Init();
+    m_ctFontDescriptor = wxCFRetain(descr);
+
+    wxCFRef< CFNumberRef > sizevalue( (CFNumberRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontSizeAttribute ) );
+    float fsize;
+    if ( CFNumberGetValue( sizevalue , kCFNumberFloatType , &fsize ) )
+        m_pointSize = (int)( fsize + 0.5 );
+
+    wxCFRef< CFDictionaryRef > traitsvalue( (CFDictionaryRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontTraitsAttribute ) );
+    CTFontSymbolicTraits traits;
+    if ( CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(traitsvalue,kCTFontSymbolicTrait),kCFNumberIntType,&traits) )
+    {
+        if ( traits & kCTFontItalicTrait )
+            m_style = wxFONTSTYLE_ITALIC;
+        if (  traits & kCTFontBoldTrait )
+            m_weight = wxFONTWEIGHT_BOLD ;
+    }
+
+    wxCFStringRef familyName( (CFStringRef) CTFontDescriptorCopyAttribute(m_ctFontDescriptor, kCTFontFamilyNameAttribute));
+    m_faceName = familyName.AsString();
+}
+#endif
+
+void wxNativeFontInfo::EnsureValid()
+{
+    if ( m_descriptorValid )
+        return;
+
+#if wxOSX_USE_CORE_TEXT
+    if ( m_ctFontDescriptor == NULL && UMAGetSystemVersion() >= 0x1050 )
+    {
+        CTFontSymbolicTraits traits = 0;
+
+        if (m_weight == wxFONTWEIGHT_BOLD)
+            traits |= kCTFontBoldTrait;
+        if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
+            traits |= kCTFontItalicTrait;
+
+        // use font caching
+        wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize );
+
+        static std::map< std::wstring , wxCFRef< CTFontDescriptorRef > > fontdescriptorcache ;
+        m_ctFontDescriptor = wxCFRetain((CTFontDescriptorRef)fontdescriptorcache[ std::wstring(lookupnameWithSize.wc_str()) ]);
+        if ( !m_ctFontDescriptor )
+        {
+            // QD selection algorithm is the fastest by orders of magnitude on 10.5
+            if ( m_faceName.IsAscii() )
+            {
+                uint8_t qdstyle = 0;
+                if (m_weight == wxFONTWEIGHT_BOLD)
+                    qdstyle |= bold;
+                if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
+                    qdstyle |= italic;
+
+                Str255 qdFontName ;
+                wxMacStringToPascal( m_faceName , qdFontName );
+                wxCFRef< CTFontRef > font;
+                font.reset( CTFontCreateWithQuickdrawInstance(qdFontName, 0 , qdstyle, m_pointSize) );
+                m_ctFontDescriptor = CTFontCopyFontDescriptor(font);
+            }
+            else
+            {
+                m_ctFontDescriptor = wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName),traits );
+            }
+            fontdescriptorcache[ std::wstring(lookupnameWithSize.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor));
+        }
+    }
+#endif
+#if wxOSX_USE_ATSU_TEXT
+    if ( !m_atsuFontValid )
+    {
+#if !wxOSX_USE_CARBON
+        // not needed outside
+        wxInt16 m_qdFontFamily;
+        wxInt16 m_qdFontStyle;
+#endif
+        wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
+        ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
+        if ( atsfamily == (ATSFontFamilyRef) -1 )
+        {
+            wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
+            m_qdFontFamily = GetAppFont();
+        }
+        else
+        {
+            m_qdFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
+        }
+
+        m_qdFontStyle = 0;
+        if (m_weight == wxFONTWEIGHT_BOLD)
+            m_qdFontStyle |= bold;
+        if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
+            m_qdFontStyle |= italic;
+        if (m_underlined)
+            m_qdFontStyle |= underline;
+
+
+        // we try to get as much styles as possible into ATSU
+
+        // ATSUFontID and FMFont are equivalent
+        FMFontStyle intrinsicStyle = 0 ;
+        OSStatus status = FMGetFontFromFontFamilyInstance( m_qdFontFamily , m_qdFontStyle , (FMFont*)&m_atsuFontID , &intrinsicStyle);
+        if ( status != noErr )
+        {
+            wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
+        }
+        m_atsuAdditionalQDStyles = m_qdFontStyle & (~intrinsicStyle );
+        m_atsuFontValid = true;
+    }
+#endif
+#if wxOSX_USE_COCOA
+    if ( m_nsFontDescriptor == NULL )
+        OSXValidateNSFontDescriptor();
+#endif
+#if wxOSX_USE_IPHONE
+    // TODO
+#endif
+    m_descriptorValid = true;
+}
+
+void wxNativeFontInfo::Init(const wxNativeFontInfo& info)
+{
+    Init();
+#if wxOSX_USE_CORE_TEXT
+    m_ctFontDescriptor = wxCFRetain(info.m_ctFontDescriptor);
+#endif
+#if wxOSX_USE_ATSU_TEXT
+    m_atsuFontValid = info.m_atsuFontValid;
+    m_atsuFontID = info.m_atsuFontID ;
+    m_atsuAdditionalQDStyles = info.m_atsuAdditionalQDStyles;
+#if wxOSX_USE_CARBON
+    m_qdFontFamily = info.m_qdFontFamily;
+    m_qdFontStyle = info.m_qdFontStyle;
+#endif
+#endif
+#if wxOSX_USE_COCOA
+    m_nsFontDescriptor = (NSFontDescriptor*) wxMacCocoaRetain(info.m_nsFontDescriptor);
+#endif
+    m_pointSize = info.m_pointSize;
+    m_family = info.m_family;
+    m_style = info.m_style;
+    m_weight = info.m_weight;
+    m_underlined = info.m_underlined;
+    m_faceName = info.m_faceName;
+    m_encoding = info.m_encoding;
+    m_descriptorValid = info.m_descriptorValid;
+}
+
+void wxNativeFontInfo::Init(int size,
+                  wxFontFamily family,
+                  wxFontStyle style,
+                  wxFontWeight weight,
+                  bool underlined,
+                  const wxString& faceName,
+                  wxFontEncoding encoding)
+{
+    Init();
+    m_pointSize = size;
+    m_family = family;
+    m_style = style;
+    m_weight = weight;
+    m_underlined = underlined;
+    m_faceName = faceName;
+    if ( encoding == wxFONTENCODING_DEFAULT )
+        encoding = wxFont::GetDefaultEncoding();
+    m_encoding = encoding;
+
+}
+
+void wxNativeFontInfo::Free()
+{
+#if wxOSX_USE_CORE_TEXT
+    wxCFRelease(m_ctFontDescriptor);
+    m_ctFontDescriptor = NULL;
+#endif
+#if wxOSX_USE_ATSU_TEXT
+    m_atsuFontID = 0 ;
+    m_atsuAdditionalQDStyles = 0;
+    m_atsuFontValid = false;
+#endif
+#if wxOSX_USE_COCOA
+    wxMacCocoaRelease(m_nsFontDescriptor);
+    m_nsFontDescriptor = NULL;
+#endif
+    m_descriptorValid = false;
+}
+
+bool wxNativeFontInfo::FromString(const wxString& s)
+{
+    long l;
+
+    wxStringTokenizer tokenizer(s, wxT(";"));
+
+    wxString token = tokenizer.GetNextToken();
+    //
+    //  Ignore the version for now
+    //
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_pointSize = (int)l;
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_family = (wxFontFamily)l;
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_style = (wxFontStyle)l;
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_weight = (wxFontWeight)l;
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_underlined = l != 0;
+
+    m_faceName = tokenizer.GetNextToken();
+
+#ifndef __WXMAC__
+    if( !faceName )
+        return false;
+#endif
+
+    token = tokenizer.GetNextToken();
+    if ( !token.ToLong(&l) )
+        return false;
+    m_encoding = (wxFontEncoding)l;
+
+    return true;
+}
+
+wxString wxNativeFontInfo::ToString() const
+{
+    wxString s;
+
+    s.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
+             0,                                 // version
+             m_pointSize,
+             m_family,
+             (int)m_style,
+             (int)m_weight,
+             m_underlined,
+             m_faceName.GetData(),
+             (int)m_encoding);
+
+    return s;
+}
+
+int wxNativeFontInfo::GetPointSize() const
+{
+    return m_pointSize;
+}
+
+wxFontStyle wxNativeFontInfo::GetStyle() const
+{
+    return m_style;
+}
+
+wxFontWeight wxNativeFontInfo::GetWeight() const
+{
+    return m_weight;
+}
+
+bool wxNativeFontInfo::GetUnderlined() const
+{
+    return m_underlined;
+}
+
+wxString wxNativeFontInfo::GetFaceName() const
+{
+    return m_faceName;
+}
+
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+    return m_family;
+}
+
+wxFontEncoding wxNativeFontInfo::GetEncoding() const
+{
+    return m_encoding;
+}
+
+// changing the font descriptor
+
+void wxNativeFontInfo::SetPointSize(int pointsize)
+{
+    if ( m_pointSize != pointsize )
+    {
+        m_pointSize = pointsize;
+        Free();
+    }
+}
+
+void wxNativeFontInfo::SetStyle(wxFontStyle style_)
+{
+    if ( m_style != style_ )
+    {
+        m_style = style_;
+        Free();
+    }
+}
+
+void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
+{
+    if ( m_weight != weight_ )
+    {
+        m_weight = weight_;
+        Free();
+    }
+}
+
+void wxNativeFontInfo::SetUnderlined(bool underlined_)
+{
+    if ( m_underlined != underlined_ )
+    {
+        m_underlined = underlined_;
+        Free();
+    }
+}
+
+bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
+{
+    if ( m_faceName != facename_ )
+    {
+        m_faceName = facename_;
+        Free();
+    }
+    return true;
+}
+
+void wxNativeFontInfo::SetFamily(wxFontFamily family_)
+{
+    if ( m_family != family_ )
+    {
+        m_family = family_;
+        Free();
+    }
+}
+
+void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
+{
+    if ( encoding_ == wxFONTENCODING_DEFAULT )
+        encoding_ = wxFont::GetDefaultEncoding();
+    m_encoding = encoding_;
+    // not reflected in native descriptors
+}