]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/font.cpp
Add EnableHistory support to the OSX WebKit backend.
[wxWidgets.git] / src / osx / carbon / font.cpp
index 9ac75bbfbd7323600f0e463e51b7f52780a589cb..643903040d01d6baeb12013f194f84c369b0188b 100644 (file)
@@ -31,8 +31,6 @@
 #include <map>
 #include <string>
 
-IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
-
 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
 {
 public:
@@ -61,10 +59,6 @@ public:
 
     virtual ~wxFontRefData();
 
-    void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
-
-    bool GetNoAntiAliasing() const { return m_noAA; }
-
     void SetPointSize( int size )
     {
         if( GetPointSize() != size )
@@ -154,7 +148,6 @@ protected:
 #if wxOSX_USE_CORE_TEXT
     // void Init( CTFontRef font );
 #endif
-    bool            m_noAA;      // No anti-aliasing
 public:
     bool            m_fontValid;
 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
@@ -166,6 +159,8 @@ public:
     wxCFRef<CTFontRef> m_ctFont;
 #endif
 #if wxOSX_USE_ATSU_TEXT
+    void CreateATSUFont();
+
     ATSUStyle       m_macATSUStyle ;
 #endif
     wxCFRef<CGFontRef> m_cgFont;
@@ -180,11 +175,10 @@ public:
 
 #define M_FONTDATA ((wxFontRefData*)m_refData)
 
-wxFontRefData::wxFontRefData(const wxFontRefData& data)
+wxFontRefData::wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
 {
     Init();
     m_info = data.m_info;
-    m_noAA = data.m_noAA;
     m_fontValid = data.m_fontValid;
 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
     m_macThemeFontID = data.m_macThemeFontID;
@@ -219,7 +213,6 @@ wxFontRefData::wxFontRefData(const wxFontRefData& data)
 
 void wxFontRefData::Init()
 {
-    m_noAA = false;
 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
     m_macThemeFontID = kThemeCurrentPortFont ;
 #endif
@@ -387,7 +380,80 @@ wxFontRefData::wxFontRefData(wxOSXSystemFont font, int size)
 #if wxOSX_USE_IPHONE
     m_uiFont = wxFont::OSXCreateUIFont( font, &m_info );
 #endif
+    m_info.EnsureValid();
+#if wxOSX_USE_ATSU_TEXT
+    CreateATSUFont();
+#endif
+
+    m_fontValid = true;
+}
+
+#if wxOSX_USE_ATSU_TEXT
+void wxFontRefData::CreateATSUFont()
+{
+    // we try to get as much styles as possible into ATSU
+
+    OSStatus status = ::ATSUCreateStyle(&m_macATSUStyle);
+    wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
+
+    ATSUAttributeTag atsuTags[] =
+    {
+        kATSUFontTag ,
+        kATSUSizeTag ,
+        kATSUVerticalCharacterTag,
+        kATSUQDBoldfaceTag ,
+        kATSUQDItalicTag ,
+        kATSUQDUnderlineTag ,
+        kATSUQDCondensedTag ,
+        kATSUQDExtendedTag ,
+    };
+    ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
+    {
+        sizeof( ATSUFontID ) ,
+        sizeof( Fixed ) ,
+        sizeof( ATSUVerticalCharacterType),
+        sizeof( Boolean ) ,
+        sizeof( Boolean ) ,
+        sizeof( Boolean ) ,
+        sizeof( Boolean ) ,
+        sizeof( Boolean ) ,
+    };
+
+    Boolean kTrue = true ;
+    Boolean kFalse = false ;
+
+    Fixed atsuSize = IntToFixed( m_info.m_pointSize );
+    ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
+    FMFontStyle addQDStyle = m_info.m_atsuAdditionalQDStyles;
+    ATSUAttributeValuePtr    atsuValues[WXSIZEOF(atsuTags)] =
+    {
+        &m_info.m_atsuFontID ,
+        &atsuSize ,
+        &kHorizontal,
+        (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,
+                                 WXSIZEOF(atsuTags),
+                                 atsuTags, atsuSizes, atsuValues);
+
+    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
+
+static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
+static const CGAffineTransform kSlantTransform = CGAffineTransformMake( 1, 0, tan(DegToRad(11)), 1, 0, 0 );
 
 void wxFontRefData::MacFindFont()
 {
@@ -409,79 +475,63 @@ void wxFontRefData::MacFindFont()
             traits |= kCTFontItalicTrait;
 
         // use font caching
-        wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_info.m_faceName.c_str(), traits, m_info.m_pointSize );
+        wxString lookupnameWithSize = wxString::Format( "%s_%u_%d", m_info.m_faceName, traits, m_info.m_pointSize );
 
         static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
         m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
         if ( !m_ctFont )
         {
-            m_ctFont.reset( CTFontCreateWithFontDescriptor( m_info.m_ctFontDescriptor, 0/*m_pointSize */, NULL ) );
+            m_ctFont.reset(CTFontCreateWithName( wxCFStringRef(m_info.m_faceName), m_info.m_pointSize , NULL ));
+            if ( m_ctFont.get() == NULL )
+            {
+                // TODO try fallbacks according to font type
+                m_ctFont.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType, m_info.m_pointSize , NULL ));
+            }
+            else
+            {
+                if ( traits != 0 )
+                {
+                    // attempt native font variant, if not available, fallback to italic emulation mode and remove bold
+                    CTFontRef fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, traits, traits );
+                    if ( fontWithTraits == NULL )
+                    {
+                        CTFontSymbolicTraits remainingTraits = traits;
+                        const CGAffineTransform* remainingTransform = NULL;
+
+                        if( remainingTraits & kCTFontItalicTrait )
+                        {
+                            remainingTraits &= ~kCTFontItalicTrait;
+                            remainingTransform = &kSlantTransform;
+                            if ( remainingTraits & kCTFontBoldTrait )
+                            {
+                                // first try an emulated oblique with an existing bold font
+                                fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, remainingTransform, remainingTraits, remainingTraits );
+                                if ( fontWithTraits == NULL )
+                                {
+                                    // give in on the bold, try native oblique
+                                    fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, kCTFontItalicTrait, kCTFontItalicTrait );
+                                }
+                            }
+                        }
+
+                        if ( fontWithTraits == NULL )
+                        {
+                            fontWithTraits = CTFontCreateWithName( wxCFStringRef(m_info.m_faceName), m_info.m_pointSize, remainingTransform );
+                        }
+
+                    }
+                    if ( fontWithTraits != NULL )
+                        m_ctFont.reset(fontWithTraits);
+                }
+            }
         }
+
         m_cgFont.reset(CTFontCopyGraphicsFont(m_ctFont, NULL));
     }
 
 #endif
 #if wxOSX_USE_ATSU_TEXT
-    {
-        // we try to get as much styles as possible into ATSU
-
-        OSStatus status = ::ATSUCreateStyle(&m_macATSUStyle);
-        wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
-
-        ATSUAttributeTag atsuTags[] =
-        {
-            kATSUFontTag ,
-            kATSUSizeTag ,
-            kATSUVerticalCharacterTag,
-            kATSUQDBoldfaceTag ,
-            kATSUQDItalicTag ,
-            kATSUQDUnderlineTag ,
-            kATSUQDCondensedTag ,
-            kATSUQDExtendedTag ,
-        };
-        ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
-        {
-            sizeof( ATSUFontID ) ,
-            sizeof( Fixed ) ,
-            sizeof( ATSUVerticalCharacterType),
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-            sizeof( Boolean ) ,
-        };
-
-        Boolean kTrue = true ;
-        Boolean kFalse = false ;
-
-        Fixed atsuSize = IntToFixed( m_info.m_pointSize );
-        ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
-        FMFontStyle addQDStyle = m_info.m_atsuAdditionalQDStyles;
-        ATSUAttributeValuePtr    atsuValues[WXSIZEOF(atsuTags)] =
-        {
-            &m_info.m_atsuFontID ,
-            &atsuSize ,
-            &kHorizontal,
-            (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,
-                                     WXSIZEOF(atsuTags),
-                                     atsuTags, atsuSizes, atsuValues);
-
-        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 ) );
-        }
-    }
+    CreateATSUFont();
 #endif
 #if wxOSX_USE_COCOA
     m_nsFont = wxFont::OSXCreateNSFont( &m_info );
@@ -506,6 +556,11 @@ bool wxFont::Create(const wxNativeFontInfo& info)
     return true;
 }
 
+wxFont::wxFont(wxOSXSystemFont font)
+{
+    m_refData = new wxFontRefData( font, 0 );
+}
+
 wxFont::wxFont(const wxString& fontdesc)
 {
     wxNativeFontInfo info;
@@ -564,15 +619,6 @@ bool wxFont::Create(int pointSize,
     return true;
 }
 
-bool wxFont::CreateSystemFont(wxOSXSystemFont font)
-{
-    UnRef();
-
-    m_refData = new wxFontRefData( font, 0 );
-
-    return true;
-}
-
 wxFont::~wxFont()
 {
 }
@@ -656,13 +702,6 @@ void wxFont::SetUnderlined(bool underlined)
     M_FONTDATA->SetUnderlined( underlined );
 }
 
-void wxFont::SetNoAntiAliasing( bool no )
-{
-    AllocExclusive();
-
-    M_FONTDATA->SetNoAntiAliasing( no );
-}
-
 // ----------------------------------------------------------------------------
 // accessors
 // ----------------------------------------------------------------------------
@@ -691,10 +730,8 @@ wxSize wxFont::GetPixelSize() const
 #endif
 }
 
-wxFontFamily wxFont::GetFamily() const
+wxFontFamily wxFont::DoGetFamily() const
 {
-    wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
-
     return M_FONTDATA->GetFamily();
 }
 
@@ -733,13 +770,6 @@ wxFontEncoding wxFont::GetEncoding() const
     return M_FONTDATA->GetEncoding() ;
 }
 
-bool wxFont::GetNoAntiAliasing() const
-{
-    wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
-
-    return M_FONTDATA->GetNoAntiAliasing();
-}
-
 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
 
 short wxFont::MacGetFontNum() const
@@ -782,7 +812,6 @@ void * wxFont::MacGetATSUStyle() const
     return M_FONTDATA->m_macATSUStyle;
 }
 
-#if WXWIN_COMPATIBILITY_2_8
 wxUint32 wxFont::MacGetATSUFontID() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL, 0, wxT("invalid font") );
@@ -804,8 +833,6 @@ wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
 }
 #endif
 
-#endif
-
 #if wxOSX_USE_CORE_TEXT
 
 CTFontRef wxFont::OSXGetCTFont() const
@@ -849,10 +876,24 @@ NSFont* wxFont::OSXGetNSFont() const
 
 #endif
 
+#if wxOSX_USE_IPHONE
+
+UIFont* wxFont::OSXGetUIFont() const
+{
+    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_uiFont);
+}
+
+#endif
+
 const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
 {
     wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
-    wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
+    wxCHECK_MSG( IsOk(), NULL, wxT("invalid font") );
 
     // cast away constness otherwise lazy font resolution is not possible
     const_cast<wxFont *>(this)->RealizeResource();
@@ -866,7 +907,7 @@ const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
 // wxNativeFontInfo
 // ----------------------------------------------------------------------------
 
-#if wxOSX_USE_CORE_TEXT
+#if 0 // wxOSX_USE_CORE_TEXT
 
 /* from Core Text Manual Common Operations */
 
@@ -926,9 +967,6 @@ static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName,
 
 void wxNativeFontInfo::Init()
 {
-#if wxOSX_USE_CORE_TEXT
-    m_ctFontDescriptor = NULL;
-#endif
 #if wxOSX_USE_ATSU_TEXT
     m_atsuFontID = 0 ;
     m_atsuAdditionalQDStyles = 0;
@@ -937,9 +975,6 @@ void wxNativeFontInfo::Init()
     m_qdFontStyle = 0;
     m_qdFontFamily = 0;
 #endif
-#endif
-#if wxOSX_USE_COCOA
-    m_nsFontDescriptor = NULL;
 #endif
     m_pointSize = 0;
     m_family = wxFONTFAMILY_DEFAULT;
@@ -955,14 +990,13 @@ void wxNativeFontInfo::Init()
 void wxNativeFontInfo::Init(CTFontDescriptorRef descr)
 {
     Init();
-    m_ctFontDescriptor = wxCFRetain(descr);
 
-    wxCFRef< CFNumberRef > sizevalue( (CFNumberRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontSizeAttribute ) );
+    wxCFRef< CFNumberRef > sizevalue( (CFNumberRef) CTFontDescriptorCopyAttribute( descr, kCTFontSizeAttribute ) );
     float fsize;
     if ( CFNumberGetValue( sizevalue , kCFNumberFloatType , &fsize ) )
         m_pointSize = (int)( fsize + 0.5 );
 
-    wxCFRef< CFDictionaryRef > traitsvalue( (CFDictionaryRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontTraitsAttribute ) );
+    wxCFRef< CFDictionaryRef > traitsvalue( (CFDictionaryRef) CTFontDescriptorCopyAttribute( descr, kCTFontTraitsAttribute ) );
     CTFontSymbolicTraits traits;
     if ( CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(traitsvalue,kCTFontSymbolicTrait),kCFNumberIntType,&traits) )
     {
@@ -972,7 +1006,7 @@ void wxNativeFontInfo::Init(CTFontDescriptorRef descr)
             m_weight = wxFONTWEIGHT_BOLD ;
     }
 
-    wxCFStringRef familyName( (CFStringRef) CTFontDescriptorCopyAttribute(m_ctFontDescriptor, kCTFontFamilyNameAttribute));
+    wxCFStringRef familyName( (CFStringRef) CTFontDescriptorCopyAttribute(descr, kCTFontFamilyNameAttribute));
     m_faceName = familyName.AsString();
 }
 #endif
@@ -982,46 +1016,6 @@ 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 )
     {
@@ -1063,13 +1057,6 @@ void wxNativeFontInfo::EnsureValid()
         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;
 }
@@ -1077,9 +1064,6 @@ void wxNativeFontInfo::EnsureValid()
 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 ;
@@ -1088,9 +1072,6 @@ void wxNativeFontInfo::Init(const wxNativeFontInfo& info)
     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;
@@ -1125,18 +1106,10 @@ void wxNativeFontInfo::Init(int size,
 
 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;
 }