X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3bf5a59b5e058bebffcf9d87f03550b4ecf93e73..76e36d433484b94cb5b7c3668fbce85ceebe508c:/src/mac/carbon/font.cpp diff --git a/src/mac/carbon/font.cpp b/src/mac/carbon/font.cpp index bb1c2b4939..517f232e70 100644 --- a/src/mac/carbon/font.cpp +++ b/src/mac/carbon/font.cpp @@ -9,29 +9,29 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "font.h" -#endif +#include "wx/wxprec.h" -#include "wx/defs.h" #include "wx/string.h" #include "wx/font.h" #include "wx/fontutil.h" #include "wx/gdicmn.h" #include "wx/utils.h" - #include "wx/fontutil.h" #include "wx/mac/private.h" -#include "ATSUnicode.h" -#if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) +#ifndef __DARWIN__ +#include #endif + +IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) + + class WXDLLEXPORT wxFontRefData: public wxGDIRefData { friend class WXDLLEXPORT wxFont; + public: wxFontRefData() : m_fontId(0) @@ -40,15 +40,16 @@ public: , m_style(wxNORMAL) , m_weight(wxNORMAL) , m_underlined(FALSE) - , m_faceName(wxT("Geneva")) + , m_faceName(wxT("applicationfont")) , m_encoding(wxFONTENCODING_DEFAULT) , m_macFontNum(0) , m_macFontSize(0) , m_macFontStyle(0) - , m_macATSUFontID() + , m_macATSUStyle(0) + , m_macATSUFontID(0) { - Init(10, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE, - wxT("Geneva"), wxFONTENCODING_DEFAULT); + Init(m_pointSize, m_family, m_style, m_weight, + m_underlined, m_faceName, m_encoding); } wxFontRefData(const wxFontRefData& data) @@ -64,6 +65,7 @@ public: , m_macFontNum(data.m_macFontNum) , 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, @@ -88,15 +90,22 @@ public: , m_macFontNum(0) , m_macFontSize(0) , m_macFontStyle(0) + , m_macATSUStyle(0) , m_macATSUFontID(0) { Init(size, family, style, weight, underlined, faceName, encoding); } virtual ~wxFontRefData(); - void SetNoAntiAliasing( bool no = TRUE ) { m_noAA = no; } - bool GetNoAntiAliasing() { return m_noAA; } - + + void SetNoAntiAliasing( bool no = true ) + { m_noAA = no; } + + bool GetNoAntiAliasing() const + { return m_noAA; } + + void MacFindFont() ; + protected: // common part of all ctors void Init(int size, @@ -108,27 +117,39 @@ protected: wxFontEncoding encoding); // font characterstics - int m_fontId; - int m_pointSize; - int m_family; - int m_style; - int m_weight; - bool m_underlined; - wxString m_faceName; - wxFontEncoding m_encoding; + int m_fontId; + int m_pointSize; + int m_family; + int m_style; + int m_weight; + bool m_underlined; + wxString m_faceName; + wxFontEncoding m_encoding; bool m_noAA; // No anti-aliasing - + public: - short m_macFontNum; - short m_macFontSize; - unsigned char m_macFontStyle; - wxUint32 m_macATSUFontID; + short m_macFontNum; + short m_macFontSize; + Style m_macFontStyle; - wxNativeFontInfo m_info; + // ATSU Font Information -public: - void MacFindFont() ; + // this is split into an ATSU font id that may + // 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; + Style m_macATSUAdditionalQDStyles ; + + // for true themeing support we must store the correct font + // information here, as this speeds up and optimizes rendering + ThemeFontID m_macThemeFontID ; + + wxNativeFontInfo m_info; }; + + // ============================================================================ // implementation // ============================================================================ @@ -138,12 +159,12 @@ public: // ---------------------------------------------------------------------------- void wxFontRefData::Init(int pointSize, - int family, - int style, - int weight, - bool underlined, - const wxString& faceName, - wxFontEncoding encoding) + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding) { m_style = style; m_pointSize = pointSize; @@ -157,78 +178,194 @@ void wxFontRefData::Init(int pointSize, m_macFontNum = 0 ; m_macFontSize = 0; m_macFontStyle = 0; - m_fontId = 0; - m_noAA = FALSE; + m_macATSUFontID = 0; + m_macATSUAdditionalQDStyles = 0 ; + m_macATSUStyle = NULL ; + + m_macThemeFontID = kThemeCurrentPortFont ; + m_noAA = false; } wxFontRefData::~wxFontRefData() { + if ( m_macATSUStyle ) + { + ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); + m_macATSUStyle = NULL ; + } } void wxFontRefData::MacFindFont() { - if( m_faceName.Length() == 0 ) + if ( m_macThemeFontID != kThemeCurrentPortFont ) + { + Str255 fontName ; + + GetThemeFont( m_macThemeFontID, GetApplicationScript(), fontName, &m_macFontSize, &m_macFontStyle ); + m_faceName = wxMacMakeStringFromPascal( fontName ) ; + 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 ; + ::GetFNum( fontName, &m_macFontNum ); + m_pointSize = m_macFontSize ; + } + else { - switch( m_family ) + if ( m_faceName.Length() == 0 ) + { + switch ( m_family ) + { + case wxDEFAULT : + m_macFontNum = ::GetAppFont(); + break ; + + case wxSCRIPT : + case wxROMAN : + case wxDECORATIVE : + ::GetFNum( "\pTimes", &m_macFontNum ); + break ; + + case wxSWISS : +#ifdef __WXMAC_OSX__ + ::GetFNum( "\pLucida Grande", &m_macFontNum ); +#else + ::GetFNum( "\pGeneva", &m_macFontNum ); +#endif + break ; + + case wxMODERN : + ::GetFNum( "\pMonaco", &m_macFontNum ); + break ; + + default: + break ; + } + + Str255 name ; + ::GetFontName( m_macFontNum , name ) ; + m_faceName = wxMacMakeStringFromPascal( name ) ; + } + else { - case wxDEFAULT : + if ( m_faceName == wxT("systemfont") ) + m_macFontNum = ::GetSysFont() ; + else if ( m_faceName == wxT("applicationfont") ) m_macFontNum = ::GetAppFont() ; - break ; - case wxDECORATIVE : - ::GetFNum( "\pTimes" , &m_macFontNum) ; - break ; - case wxROMAN : - ::GetFNum( "\pTimes" , &m_macFontNum) ; - break ; - case wxSCRIPT : - ::GetFNum( "\pTimes" , &m_macFontNum) ; - break ; - case wxSWISS : - ::GetFNum( "\pGeneva" , &m_macFontNum) ; - break ; - case wxMODERN : - ::GetFNum( "\pMonaco" , &m_macFontNum) ; - break ; + else + { + Str255 fontname ; + wxMacStringToPascal( m_faceName , fontname ) ; + ::GetFNum( fontname, &m_macFontNum); + } } - Str255 name ; - GetFontName( m_macFontNum , name ) ; - m_faceName = wxMacMakeStringFromPascal( name ) ; + + 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 ; } - else + + // we try to get as much styles as possible into ATSU + + Fixed atsuSize = IntToFixed( m_macFontSize ) ; + + Style atsuStyle = normal ; + verify_noerr(::ATSUFONDtoFontID(m_macFontNum, atsuStyle , (UInt32*)&m_macATSUFontID) ); + if ( m_macFontStyle & bold ) { - if ( m_faceName == wxT("systemfont") ) - m_macFontNum = ::GetSysFont() ; - else if ( m_faceName == wxT("applicationfont") ) - m_macFontNum = ::GetAppFont() ; - else + ATSUFontID test ; + if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | bold , &test) == noErr ) { - Str255 fontname ; - wxMacStringToPascal( m_faceName , fontname ) ; - ::GetFNum( fontname, &m_macFontNum); + atsuStyle |= bold ; + m_macATSUFontID = test ; } } - 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 ; - - //TODO:if we supply the style as an additional parameter we must make a testing - //sequence in order to degrade gracefully while trying to maintain most of the style - //information, meanwhile we just take the normal font and apply the features after -#ifdef __WXDEBUG__ - OSStatus status = -#endif // __WXDEBUG__ - ::ATSUFONDtoFontID(m_macFontNum, normal /*qdStyle*/, (UInt32*)&m_macATSUFontID); - /* - status = ATSUFindFontFromName ( (Ptr) m_faceName , strlen( m_faceName ) , - kFontFullName, kFontMacintoshPlatform, kFontRomanScript , kFontNoLanguage , (UInt32*)&m_macATSUFontID ) ; - */ - wxASSERT_MSG( status == noErr , wxT("couldn't retrieve font identifier") ) ; + if ( m_macFontStyle & italic ) + { + ATSUFontID test ; + if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | italic , &test) == noErr ) + { + atsuStyle |= italic ; + m_macATSUFontID = test ; + } + } + + if ( m_macFontStyle & underline ) + { + ATSUFontID test ; + if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | underline , &test) == noErr ) + { + atsuStyle |= underline ; + m_macATSUFontID = test ; + } + } + + m_macATSUAdditionalQDStyles = m_macFontStyle & (~atsuStyle ) ; + + if ( m_macATSUStyle ) + { + ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle); + m_macATSUStyle = NULL ; + } + + OSStatus 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 ; + + ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal; + ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] = + { + &m_macATSUFontID , + &atsuSize , + &kHorizontal, + (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse , + (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse , + (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") ) ; } // ---------------------------------------------------------------------------- @@ -241,8 +378,9 @@ void wxFont::Init() bool wxFont::Create(const wxNativeFontInfo& info) { - return Create(info.pointSize, info.family, info.style, info.weight, - info.underlined, info.faceName, info.encoding); + return Create( + info.pointSize, info.family, info.style, info.weight, + info.underlined, info.faceName, info.encoding ); } wxFont::wxFont(const wxString& fontdesc) @@ -253,20 +391,36 @@ wxFont::wxFont(const wxString& fontdesc) } bool wxFont::Create(int pointSize, - int family, - int style, - int weight, - bool underlined, - const wxString& faceName, - wxFontEncoding encoding) + int family, + int style, + int weight, + bool underlined, + const wxString& faceName, + wxFontEncoding encoding) { UnRef(); - m_refData = new wxFontRefData(pointSize, family, style, weight, - underlined, faceName, encoding); + + m_refData = new wxFontRefData( + pointSize, family, style, weight, + underlined, faceName, encoding); RealizeResource(); - return TRUE; + return true; +} + +bool wxFont::MacCreateThemeFont(wxUint16 themeFontID) +{ + UnRef(); + + m_refData = new wxFontRefData( + 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, + false, wxEmptyString, wxFONTENCODING_DEFAULT ); + + M_FONTDATA->m_macThemeFontID = themeFontID ; + RealizeResource(); + + return true; } wxFont::~wxFont() @@ -276,7 +430,8 @@ wxFont::~wxFont() bool wxFont::RealizeResource() { M_FONTDATA->MacFindFont() ; - return TRUE; + + return true; } void wxFont::SetEncoding(wxFontEncoding encoding) @@ -370,51 +525,116 @@ void wxFont::SetNoAntiAliasing( bool no ) // accessors // ---------------------------------------------------------------------------- +// TODO: insert checks everywhere for M_FONTDATA == NULL! + int wxFont::GetPointSize() const { + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + return M_FONTDATA->m_pointSize; } int wxFont::GetFamily() const { + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + return M_FONTDATA->m_family; } int wxFont::GetStyle() const { + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + return M_FONTDATA->m_style; } int wxFont::GetWeight() const { + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + return M_FONTDATA->m_weight; } bool wxFont::GetUnderlined() const { + wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") ); + return M_FONTDATA->m_underlined; } wxString wxFont::GetFaceName() const { - wxString str; - if ( M_FONTDATA ) - str = M_FONTDATA->m_faceName ; - return str; + wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") ); + + return M_FONTDATA->m_faceName; } wxFontEncoding wxFont::GetEncoding() const { + wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") ); + return M_FONTDATA->m_encoding; } -bool wxFont::GetNoAntiAliasing() +bool wxFont::GetNoAntiAliasing() const { + wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") ); + return M_FONTDATA->m_noAA; } -const wxNativeFontInfo *wxFont::GetNativeFontInfo() const +short wxFont::MacGetFontNum() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontNum; +} + +short wxFont::MacGetFontSize() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontSize; +} + +wxByte wxFont::MacGetFontStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macFontStyle; +} + +wxUint32 wxFont::MacGetATSUFontID() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUFontID; +} + +void * wxFont::MacGetATSUStyle() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUStyle; +} + +wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macATSUAdditionalQDStyles; +} + +wxUint16 wxFont::MacGetThemeFontID() const +{ + wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") ); + + return M_FONTDATA->m_macThemeFontID; +} + +const wxNativeFontInfo * wxFont::GetNativeFontInfo() const { + wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") ); wxCHECK_MSG( Ok(), NULL, wxT("invalid font") ); M_FONTDATA->m_info.InitFromFont(*this);