]> git.saurik.com Git - wxWidgets.git/commitdiff
adding fallbacks for non-native font variants, fixes #11938
authorStefan Csomor <csomor@advancedconcepts.ch>
Tue, 13 Apr 2010 12:08:51 +0000 (12:08 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Tue, 13 Apr 2010 12:08:51 +0000 (12:08 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63963 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/osx/carbon/font.cpp
src/osx/carbon/utilscocoa.mm

index c46f7747246fedfc2b382a7185980f535ae1245a..f53c0138caa0777ca6f728c09ccdb168b5dcc236 100644 (file)
@@ -454,6 +454,9 @@ void wxFontRefData::CreateATSUFont()
 }
 #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()
 {
     if ( m_fontValid )
@@ -481,9 +484,47 @@ void wxFontRefData::MacFindFont()
         if ( !m_ctFont )
         {
             m_ctFont.reset(CTFontCreateWithName( wxCFStringRef(m_info.m_faceName), m_info.m_pointSize , NULL ));
-            if ( traits != 0 )
+            if ( m_ctFont.get() == NULL )
+            {
+                // TODO try fallbacks according to font type
+                m_ctFont.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType, m_info.m_pointSize , NULL ));
+            }
+            else
             {
-                m_ctFont.reset(CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, traits, traits ));
+                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);
+                }
             }
         }
         
@@ -859,7 +900,7 @@ const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
 // wxNativeFontInfo
 // ----------------------------------------------------------------------------
 
-#if wxOSX_USE_CORE_TEXT
+#if 0 // wxOSX_USE_CORE_TEXT
 
 /* from Core Text Manual Common Operations */
 
index 7a306737f37c2e094c1ca194ff77906fccc00c93..ae7df72070e87cbe758a977bfce6d301c5f0dead 100644 (file)
@@ -188,6 +188,9 @@ WX_NSFont wxFont::OSXCreateNSFont(wxOSXSystemFont font, wxNativeFontInfo* info)
     return nsfont;
 }
 
+static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
+static const NSAffineTransformStruct kSlantNSTransformStruct = { 1, 0, tan(DegToRad(11)), 1, 0, 0  };
+
 WX_NSFont wxFont::OSXCreateNSFont(const wxNativeFontInfo* info)
 {
     NSFont* nsFont;
@@ -206,7 +209,62 @@ WX_NSFont wxFont::OSXCreateNSFont(const wxNativeFontInfo* info)
     
     nsFont = [[NSFontManager sharedFontManager] fontWithFamily:wxCFStringRef(info->m_faceName).AsNSString() 
         traits:traits weight:weight size:info->m_pointSize];
-
+    
+    if ( nsFont == nil )
+    {
+        NSFontTraitMask remainingTraits = traits;
+        nsFont = [[NSFontManager sharedFontManager] fontWithFamily:wxCFStringRef(info->m_faceName).AsNSString() 
+                                                            traits:0 weight:5 size:info->m_pointSize];
+        if ( nsFont == nil )
+        {
+            if ( info->m_weight == wxFONTWEIGHT_BOLD )
+            {
+                nsFont = [NSFont boldSystemFontOfSize:info->m_pointSize];
+                remainingTraits &= ~NSBoldFontMask;
+            }
+            else
+                nsFont = [NSFont systemFontOfSize:info->m_pointSize];
+        }
+        
+        // fallback - if in doubt, let go of the bold attribute
+        if ( nsFont && (remainingTraits & NSItalicFontMask) )
+        {
+            NSFont* nsFontWithTraits = nil;
+            if ( remainingTraits & NSBoldFontMask)
+            {
+                nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
+                if ( nsFontWithTraits == nil )
+                {
+                    nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
+                    if ( nsFontWithTraits != nil )
+                        remainingTraits &= ~NSItalicFontMask;
+                }
+                else
+                {
+                    remainingTraits &= ~NSBoldFontMask;
+                }
+            }
+            if ( remainingTraits & NSItalicFontMask)
+            {
+                if ( nsFontWithTraits == nil )
+                    nsFontWithTraits = nsFont;
+                
+                NSAffineTransform* transform = [NSAffineTransform transform];
+                [transform setTransformStruct:kSlantNSTransformStruct];
+                [transform scaleBy:info->m_pointSize];
+                NSFontDescriptor* italicDesc = [[nsFontWithTraits fontDescriptor] fontDescriptorWithMatrix:transform];
+                if ( italicDesc != nil )
+                {
+                    NSFont* f = [NSFont fontWithDescriptor:italicDesc size:(CGFloat)(info->m_pointSize)];
+                    if ( f != nil )
+                        nsFontWithTraits = f;
+                }
+            }
+            if ( nsFontWithTraits != nil )
+                nsFont = nsFontWithTraits;
+        }
+    }
+            
     wxASSERT_MSG(nsFont != nil,wxT("Couldn't create nsFont")) ;
     wxMacCocoaRetain(nsFont);
     return nsFont;