diff --git a/src/osx/carbon/font.cpp b/src/osx/carbon/font.cpp index c46f774724..f53c0138ca 100644 --- a/src/osx/carbon/font.cpp +++ b/src/osx/carbon/font.cpp @@ -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 ) { - m_ctFont.reset(CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, traits, traits )); + // 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); + } } } @@ -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 */ diff --git a/src/osx/carbon/utilscocoa.mm b/src/osx/carbon/utilscocoa.mm index 7a306737f3..ae7df72070 100644 --- a/src/osx/carbon/utilscocoa.mm +++ b/src/osx/carbon/utilscocoa.mm @@ -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;