X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2a0155df7266eff2548304f5aff3fbf6e0a895f4..e773889d7db09182ac5008cb96829b354f22faf0:/src/mac/carbon/font.cpp diff --git a/src/mac/carbon/font.cpp b/src/mac/carbon/font.cpp index 1d4d28e4d6..241ae9a019 100644 --- a/src/mac/carbon/font.cpp +++ b/src/mac/carbon/font.cpp @@ -15,14 +15,16 @@ #ifndef WX_PRECOMP #include "wx/string.h" + #include "wx/utils.h" + #include "wx/intl.h" + #include "wx/gdicmn.h" + #include "wx/log.h" #endif #include "wx/fontutil.h" -#include "wx/gdicmn.h" -#include "wx/utils.h" -#include "wx/fontutil.h" +#include "wx/graphics.h" -#include "wx/mac/private.h" +#include "wx/mac/uma.h" #ifndef __DARWIN__ #include @@ -34,43 +36,16 @@ IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) class WXDLLEXPORT wxFontRefData: public wxGDIRefData { - friend class WXDLLEXPORT wxFont; + friend class wxFont; public: wxFontRefData() - : m_fontId(0) - , m_pointSize(10) - , m_family(wxDEFAULT) - , m_style(wxNORMAL) - , m_weight(wxNORMAL) - , m_underlined(false) - , m_faceName(wxT("applicationfont")) - , m_encoding(wxFONTENCODING_DEFAULT) - , m_macFontFamily(0) - , m_macFontSize(0) - , m_macFontStyle(0) - , m_macATSUStyle(0) - , m_macATSUFontID(0) { - Init(m_pointSize, m_family, m_style, m_weight, - m_underlined, m_faceName, m_encoding); + Init(10, wxDEFAULT, wxNORMAL, wxNORMAL, + false, wxT("applicationfont"), wxFONTENCODING_DEFAULT); } wxFontRefData(const wxFontRefData& data) - : wxGDIRefData() - , m_fontId(data.m_fontId) - , m_pointSize(data.m_pointSize) - , m_family(data.m_family) - , m_style(data.m_style) - , m_weight(data.m_weight) - , m_underlined(data.m_underlined) - , m_faceName(data.m_faceName) - , m_encoding(data.m_encoding) - , m_macFontFamily(data.m_macFontFamily) - , m_macFontSize(data.m_macFontSize) - , m_macFontStyle(data.m_macFontStyle) - , m_macATSUStyle(0) - , m_macATSUFontID(data.m_macATSUFontID) { Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight, data.m_underlined, data.m_faceName, data.m_encoding); @@ -83,19 +58,6 @@ public: bool underlined, const wxString& faceName, wxFontEncoding encoding) - : m_fontId(0) - , m_pointSize(size) - , m_family(family) - , m_style(style) - , m_weight(weight) - , m_underlined(underlined) - , m_faceName(faceName) - , m_encoding(encoding) - , m_macFontFamily(0) - , m_macFontSize(0) - , m_macFontStyle(0) - , m_macATSUStyle(0) - , m_macATSUFontID(0) { Init(size, family, style, weight, underlined, faceName, encoding); } @@ -121,7 +83,6 @@ protected: wxFontEncoding encoding); // font characterstics - int m_fontId; int m_pointSize; int m_family; int m_style; @@ -132,6 +93,7 @@ protected: bool m_noAA; // No anti-aliasing public: +#if wxMAC_USE_ATSU_TEXT FMFontFamily m_macFontFamily; FMFontSize m_macFontSize; FMFontStyle m_macFontStyle; @@ -142,17 +104,23 @@ public: // contain some styles (special bold fonts etc) and // these are the additional qd styles that are not // included in the ATSU font id - ATSUStyle m_macATSUStyle ; ATSUFontID m_macATSUFontID; FMFontStyle m_macATSUAdditionalQDStyles ; // for true themeing support we must store the correct font // information here, as this speeds up and optimizes rendering ThemeFontID m_macThemeFontID ; - + ATSUStyle m_macATSUStyle ; +#endif +#if wxMAC_USE_CORE_TEXT + wxCFRef m_ctFont; + CTFontUIFontType m_macUIFontType; +#endif wxNativeFontInfo m_info; }; +#define M_FONTDATA ((wxFontRefData*)m_refData) + // ============================================================================ // implementation @@ -178,61 +146,121 @@ void wxFontRefData::Init(int pointSize, m_underlined = underlined; m_faceName = faceName; m_encoding = encoding; - + m_noAA = false; +#if wxMAC_USE_CORE_TEXT + m_macUIFontType = kCTFontNoFontType; +#endif +#if wxMAC_USE_ATSU_TEXT m_macFontFamily = 0 ; m_macFontSize = 0; m_macFontStyle = 0; m_macATSUFontID = 0; m_macATSUAdditionalQDStyles = 0 ; - m_macATSUStyle = NULL ; - m_macThemeFontID = kThemeCurrentPortFont ; - m_noAA = false; + m_macATSUStyle = NULL ; +#endif } wxFontRefData::~wxFontRefData() { +#if wxMAC_USE_ATSU_TEXT if ( m_macATSUStyle ) { ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); m_macATSUStyle = NULL ; } +#endif } -void wxFontRefData::MacFindFont() +#if wxMAC_USE_CORE_TEXT + +/* code mixed together from 2 different routines from Core Text Manual Common Operations */ + +static CTFontRef wxMacCreateCTFont(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits, CGFloat iSize ) { - OSStatus status ; + CTFontDescriptorRef descriptor = NULL; + CFMutableDictionaryRef attributes; - Str255 qdFontName ; - if ( m_macThemeFontID != kThemeCurrentPortFont ) - { - Style style ; - GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style ); - 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 ; + 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 and input size. + descriptor = CTFontDescriptorCreateWithAttributes(attributes); + check(descriptor != NULL); - m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); + CFRelease(attributes); } - else + // Return our font descriptor. + CTFontRef font = CTFontCreateWithFontDescriptor( descriptor, iSize, NULL); + CFRelease( descriptor ); + return font ; +} + +#endif + +void wxFontRefData::MacFindFont() +{ + +#if wxMAC_USE_CORE_TEXT + if ( UMAGetSystemVersion() >= 0x1050 ) { - if ( m_faceName.empty() ) + if ( m_faceName.empty() && m_family == wxDEFAULT && m_macUIFontType == kCTFontNoFontType ) + { + m_macUIFontType = kCTFontSystemFontType; + } + + if ( m_macUIFontType != kCTFontNoFontType ) { - if ( m_family == wxDEFAULT ) + m_ctFont.reset(CTFontCreateUIFontForLanguage( m_macUIFontType, 0.0, NULL )); + + wxMacCFStringHolder name( CTFontCopyFamilyName( m_ctFont ) ); + m_faceName = name.AsString(); + if ( CTFontGetSize(m_ctFont) == 0 ) { - m_macFontFamily = GetAppFont(); - FMGetFontFamilyName(m_macFontFamily,qdFontName); - m_faceName = wxMacMakeStringFromPascal( qdFontName ); + m_ctFont.reset(CTFontCreateUIFontForLanguage( m_macUIFontType, 12, NULL )); } - else + + m_pointSize = CTFontGetSize(m_ctFont) ; + // reset this so that future manipulation don't fall back + m_macUIFontType = kCTFontNoFontType; + } + else + { + if ( m_faceName.empty() ) { switch ( m_family ) { @@ -241,96 +269,177 @@ void wxFontRefData::MacFindFont() case wxDECORATIVE : m_faceName = wxT("Times"); break ; - + case wxSWISS : m_faceName = wxT("Lucida Grande"); break ; - + case wxMODERN : + case wxTELETYPE: m_faceName = wxT("Monaco"); break ; - + default: m_faceName = wxT("Times"); break ; } - wxMacStringToPascal( m_faceName , qdFontName ); - m_macFontFamily = FMGetFontFamilyFromName( qdFontName ); } + + wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() ); + CTFontSymbolicTraits traits = 0; + + if (m_weight == wxBOLD) + traits |= kCTFontBoldTrait; + if (m_style == wxITALIC || m_style == wxSLANT) + traits |= kCTFontItalicTrait; + + m_ctFont.reset( wxMacCreateCTFont( cf, traits, m_pointSize ) ); + } + } +#endif +#if wxMAC_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 == wxT("systemfont") ) - m_macFontFamily = GetSysFont(); - else if ( m_faceName == wxT("applicationfont") ) - m_macFontFamily = GetAppFont(); + 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("Lucida Grande"); + break ; + + case wxMODERN : + case wxTELETYPE: + m_faceName = wxT("Monaco"); + 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 { - wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() ); - ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault ); - m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily ); + if ( m_faceName == wxT("systemfont") ) + m_macFontFamily = GetSysFont(); + else if ( m_faceName == wxT("applicationfont") ) + m_macFontFamily = GetAppFont(); + else + { + wxMacCFStringHolder 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 ; } - - 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); - wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ); - - ATSUAttributeTag atsuTags[] = - { - kATSUFontTag , - kATSUSizeTag , - kATSUVerticalCharacterTag, - kATSUQDBoldfaceTag , - kATSUQDItalicTag , - kATSUQDUnderlineTag , - kATSUQDCondensedTag , - kATSUQDExtendedTag , - }; - ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = - { - 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_macFontSize ); - ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; - ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = - { + + // 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); + wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ); + + ATSUAttributeTag atsuTags[] = + { + kATSUFontTag , + kATSUSizeTag , + kATSUVerticalCharacterTag, + kATSUQDBoldfaceTag , + kATSUQDItalicTag , + kATSUQDUnderlineTag , + kATSUQDCondensedTag , + kATSUQDExtendedTag , + }; + ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + 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_macFontSize ); + ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; + ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { &m_macATSUFontID , &atsuSize , &kHorizontal, @@ -339,14 +448,17 @@ void wxFontRefData::MacFindFont() (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse , (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse , (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse , - }; - - status = ::ATSUSetAttributes( - (ATSUStyle)m_macATSUStyle, - sizeof(atsuTags) / sizeof(ATSUAttributeTag) , - atsuTags, atsuSizes, atsuValues); - - wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); + }; + + status = ::ATSUSetAttributes( + (ATSUStyle)m_macATSUStyle, + sizeof(atsuTags) / sizeof(ATSUAttributeTag) , + atsuTags, atsuSizes, atsuValues); + + wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ); + return; + } +#endif } // ---------------------------------------------------------------------------- @@ -386,7 +498,9 @@ bool wxFont::Create(int pointSize, return true; } -bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) +#if wxMAC_USE_CORE_TEXT + +bool wxFont::MacCreateUIFont(wxUint32 ctFontType ) { UnRef(); @@ -394,12 +508,38 @@ bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString, wxFONTENCODING_DEFAULT ); - M_FONTDATA->m_macThemeFontID = themeFontID ; + M_FONTDATA->m_macUIFontType = ctFontType ; RealizeResource(); return true; } +#endif + +bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) +{ +#if wxMAC_USE_CORE_TEXT + if ( UMAGetSystemVersion() >= 0x1050) + { + return MacCreateUIFont(HIThemeGetUIFontType(themeFontID)); + } +#endif +#if wxMAC_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; +} + wxFont::~wxFont() { } @@ -437,6 +577,9 @@ void wxFont::Unshare() void wxFont::SetPointSize(int pointSize) { + if ( M_FONTDATA->m_pointSize == pointSize ) + return; + Unshare(); M_FONTDATA->m_pointSize = pointSize; @@ -471,13 +614,15 @@ void wxFont::SetWeight(int weight) RealizeResource(); } -void wxFont::SetFaceName(const wxString& faceName) +bool wxFont::SetFaceName(const wxString& faceName) { Unshare(); M_FONTDATA->m_faceName = faceName; RealizeResource(); + + return wxFontBase::SetFaceName(faceName); } void wxFont::SetUnderlined(bool underlined) @@ -511,6 +656,21 @@ int wxFont::GetPointSize() const return M_FONTDATA->m_pointSize; } +wxSize wxFont::GetPixelSize() const +{ +#if wxUSE_GRAPHICS_CONTEXT + // TODO: consider caching the value + wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL); + dc->SetFont(*(wxFont *)this,*wxBLACK); + wxDouble width, height = 0; + dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL); + delete dc; + return wxSize((int)width, (int)height); +#else + return wxFontBase::GetPixelSize(); +#endif +} + int wxFont::GetFamily() const { wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); @@ -560,6 +720,8 @@ bool wxFont::GetNoAntiAliasing() const return M_FONTDATA->m_noAA; } +#if wxMAC_USE_ATSU_TEXT + short wxFont::MacGetFontNum() const { wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); @@ -608,6 +770,18 @@ wxUint16 wxFont::MacGetThemeFontID() const return M_FONTDATA->m_macThemeFontID; } +#endif + +#if wxMAC_USE_CORE_TEXT + +const void * wxFont::MacGetCTFont() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return (CTFontRef)(M_FONTDATA->m_ctFont); +} + +#endif const wxNativeFontInfo * wxFont::GetNativeFontInfo() const {