X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0a84f928e9a273248a4843f6282507a39212d2d1..bb996f289574defb0ae4339ae8e46ff3cf6fa54c:/src/osx/carbon/font.cpp diff --git a/src/osx/carbon/font.cpp b/src/osx/carbon/font.cpp index da83253eaa..634453ec6a 100644 --- a/src/osx/carbon/font.cpp +++ b/src/osx/carbon/font.cpp @@ -31,8 +31,6 @@ #include #include -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 ) @@ -143,6 +137,8 @@ public: } wxFontEncoding GetEncoding() const { return m_info.GetEncoding(); } + + bool IsFixedWidth() const; void Free(); @@ -154,7 +150,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 +161,8 @@ public: wxCFRef m_ctFont; #endif #if wxOSX_USE_ATSU_TEXT + void CreateATSUFont(); + ATSUStyle m_macATSUStyle ; #endif wxCFRef m_cgFont; @@ -180,11 +177,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 +215,6 @@ wxFontRefData::wxFontRefData(const wxFontRefData& data) void wxFontRefData::Init() { - m_noAA = false; #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT m_macThemeFontID = kThemeCurrentPortFont ; #endif @@ -279,7 +274,6 @@ wxFontRefData::wxFontRefData(wxOSXSystemFont font, int size) Init(); #if wxOSX_USE_CORE_TEXT - if ( UMAGetSystemVersion() >= 0x1050 ) { CTFontUIFontType uifont = kCTFontSystemFontType; switch( font ) @@ -387,17 +381,91 @@ 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() { 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 ) { CTFontSymbolicTraits traits = 0; @@ -407,78 +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 , wxT("couldn't modify ATSU style") ); - 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 ); @@ -489,6 +542,16 @@ void wxFontRefData::MacFindFont() m_fontValid = true; } +bool wxFontRefData::IsFixedWidth() const +{ +#if wxOSX_USE_CORE_TEXT + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(m_ctFont); + return (traits & kCTFontMonoSpaceTrait) != 0; +#else + return false; +#endif +} + // ---------------------------------------------------------------------------- // wxFont // ---------------------------------------------------------------------------- @@ -503,6 +566,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; @@ -561,15 +629,6 @@ bool wxFont::Create(int pointSize, return true; } -bool wxFont::CreateSystemFont(wxOSXSystemFont font) -{ - UnRef(); - - m_refData = new wxFontRefData( font, 0 ); - - return true; -} - wxFont::~wxFont() { } @@ -608,7 +667,7 @@ wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const void wxFont::SetPointSize(int pointSize) { - if ( M_FONTDATA->GetPointSize() == pointSize ) + if ( M_FONTDATA != NULL && M_FONTDATA->GetPointSize() == pointSize ) return; AllocExclusive(); @@ -653,13 +712,6 @@ void wxFont::SetUnderlined(bool underlined) M_FONTDATA->SetUnderlined( underlined ); } -void wxFont::SetNoAntiAliasing( bool no ) -{ - AllocExclusive(); - - M_FONTDATA->SetNoAntiAliasing( no ); -} - // ---------------------------------------------------------------------------- // accessors // ---------------------------------------------------------------------------- @@ -688,10 +740,18 @@ wxSize wxFont::GetPixelSize() const #endif } -wxFontFamily wxFont::GetFamily() const +bool wxFont::IsFixedWidth() const { - wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") ); + wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") ); + + // cast away constness otherwise lazy font resolution is not possible + const_cast(this)->RealizeResource(); + return M_FONTDATA->IsFixedWidth(); +} + +wxFontFamily wxFont::DoGetFamily() const +{ return M_FONTDATA->GetFamily(); } @@ -730,13 +790,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 @@ -779,7 +832,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") ); @@ -801,8 +853,6 @@ wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const } #endif -#endif - #if wxOSX_USE_CORE_TEXT CTFontRef wxFont::OSXGetCTFont() const @@ -846,10 +896,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(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(this)->RealizeResource(); @@ -863,7 +927,7 @@ const wxNativeFontInfo * wxFont::GetNativeFontInfo() const // wxNativeFontInfo // ---------------------------------------------------------------------------- -#if wxOSX_USE_CORE_TEXT +#if 0 // wxOSX_USE_CORE_TEXT /* from Core Text Manual Common Operations */ @@ -923,9 +987,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; @@ -934,9 +995,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; @@ -952,14 +1010,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) ) { @@ -969,7 +1026,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 @@ -979,46 +1036,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 ) { @@ -1060,13 +1077,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; } @@ -1074,9 +1084,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 ; @@ -1085,9 +1092,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; @@ -1122,18 +1126,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; } @@ -1241,6 +1237,12 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const return m_encoding; } +bool wxNativeFontInfo::GetStrikethrough() const +{ + return false; +} + + // changing the font descriptor void wxNativeFontInfo::SetPointSize(int pointsize) @@ -1305,3 +1307,9 @@ void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_) m_encoding = encoding_; // not reflected in native descriptors } + +void wxNativeFontInfo::SetStrikethrough(bool WXUNUSED(strikethrough)) +{ +} + +