1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/font.cpp 
   3 // Purpose:     wxFont class 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  17     #include "wx/string.h" 
  20     #include "wx/gdicmn.h" 
  24 #include "wx/fontutil.h" 
  25 #include "wx/graphics.h" 
  27 #include "wx/mac/private.h" 
  30 #include <ATSUnicode.h> 
  34 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
) 
  37 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
 
  39     friend class WXDLLEXPORT wxFont
; 
  49         , m_faceName(wxT("applicationfont")) 
  50         , m_encoding(wxFONTENCODING_DEFAULT
) 
  57         Init(m_pointSize
, m_family
, m_style
, m_weight
, 
  58              m_underlined
, m_faceName
, m_encoding
); 
  61     wxFontRefData(const wxFontRefData
& data
) 
  63         , m_fontId(data
.m_fontId
) 
  64         , m_pointSize(data
.m_pointSize
) 
  65         , m_family(data
.m_family
) 
  66         , m_style(data
.m_style
) 
  67         , m_weight(data
.m_weight
) 
  68         , m_underlined(data
.m_underlined
) 
  69         , m_faceName(data
.m_faceName
) 
  70         , m_encoding(data
.m_encoding
) 
  71         , m_macFontFamily(data
.m_macFontFamily
) 
  72         , m_macFontSize(data
.m_macFontSize
) 
  73         , m_macFontStyle(data
.m_macFontStyle
) 
  75         , m_macATSUFontID(data
.m_macATSUFontID
) 
  77         Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
, 
  78              data
.m_underlined
, data
.m_faceName
, data
.m_encoding
); 
  81     wxFontRefData(int size
, 
  86                   const wxString
& faceName
, 
  87                   wxFontEncoding encoding
) 
  93         , m_underlined(underlined
) 
  94         , m_faceName(faceName
) 
  95         , m_encoding(encoding
) 
 102         Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
); 
 105     virtual ~wxFontRefData(); 
 107     void SetNoAntiAliasing( bool no 
= true ) 
 110     bool GetNoAntiAliasing() const 
 116     // common part of all ctors 
 122               const wxString
& faceName
, 
 123               wxFontEncoding encoding
); 
 125     // font characterstics 
 133     wxFontEncoding  m_encoding
; 
 134     bool            m_noAA
;      // No anti-aliasing 
 137     FMFontFamily    m_macFontFamily
; 
 138     FMFontSize      m_macFontSize
; 
 139     FMFontStyle     m_macFontStyle
; 
 141     // ATSU Font Information 
 143     // this is split into an ATSU font id that may 
 144     // contain some styles (special bold fonts etc) and 
 145     // these are the additional qd styles that are not 
 146     // included in the ATSU font id 
 147     ATSUStyle       m_macATSUStyle 
; 
 148     ATSUFontID      m_macATSUFontID
; 
 149     FMFontStyle     m_macATSUAdditionalQDStyles 
; 
 151     // for true themeing support we must store the correct font 
 152     // information here, as this speeds up and optimizes rendering 
 153     ThemeFontID     m_macThemeFontID 
; 
 155     wxNativeFontInfo  m_info
; 
 158 #define M_FONTDATA ((wxFontRefData*)m_refData) 
 161 // ============================================================================ 
 163 // ============================================================================ 
 165 // ---------------------------------------------------------------------------- 
 167 // ---------------------------------------------------------------------------- 
 169 void wxFontRefData::Init(int pointSize
, 
 174     const wxString
& faceName
, 
 175     wxFontEncoding encoding
) 
 178     m_pointSize 
= pointSize
; 
 182     m_underlined 
= underlined
; 
 183     m_faceName 
= faceName
; 
 184     m_encoding 
= encoding
; 
 186     m_macFontFamily 
= 0 ; 
 190     m_macATSUAdditionalQDStyles 
= 0 ; 
 191     m_macATSUStyle 
= NULL 
; 
 193     m_macThemeFontID 
= kThemeCurrentPortFont 
; 
 197 wxFontRefData::~wxFontRefData() 
 199     if ( m_macATSUStyle 
) 
 201         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
); 
 202         m_macATSUStyle 
= NULL 
; 
 206 void wxFontRefData::MacFindFont() 
 211     if ( m_macThemeFontID 
!= kThemeCurrentPortFont 
) 
 214         GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &m_macFontSize
, &style 
); 
 215         m_macFontStyle 
= style 
; 
 216         m_faceName 
= wxMacMakeStringFromPascal( qdFontName 
); 
 217         if ( m_macFontStyle 
& bold 
) 
 220             m_weight 
= wxNORMAL 
; 
 221         if ( m_macFontStyle 
& italic 
) 
 223         if ( m_macFontStyle 
& underline 
) 
 224             m_underlined 
= true ; 
 225         m_pointSize 
= m_macFontSize 
; 
 227         m_macFontFamily 
= FMGetFontFamilyFromName( qdFontName 
); 
 232         if ( m_faceName
.empty() ) 
 234             if ( m_family 
== wxDEFAULT 
) 
 237                 m_macFontFamily 
= GetAppFont(); 
 238                 FMGetFontFamilyName(m_macFontFamily
,qdFontName
); 
 239                 m_faceName 
= wxMacMakeStringFromPascal( qdFontName 
); 
 249                         m_faceName 
= wxT("Times"); 
 253                         m_faceName 
=  wxT("Lucida Grande"); 
 257                         m_faceName 
=  wxT("Monaco"); 
 261                         m_faceName 
=  wxT("Times"); 
 265                 wxMacStringToPascal( m_faceName 
, qdFontName 
); 
 266                 m_macFontFamily 
= FMGetFontFamilyFromName( qdFontName 
); 
 267                 if ( m_macFontFamily 
== kInvalidFontFamily 
) 
 269                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName 
); 
 270                     m_macFontFamily 
= GetAppFont(); 
 278             if ( m_faceName 
== wxT("systemfont") ) 
 279                 m_macFontFamily 
= GetSysFont(); 
 280             else if ( m_faceName 
== wxT("applicationfont") ) 
 281                 m_macFontFamily 
= GetAppFont(); 
 284             if ( m_faceName 
== wxT("systemfont") ) 
 285                 m_faceName 
=  wxT("Lucida Grande"); 
 286             else if ( m_faceName 
== wxT("applicationfont") ) 
 287                 m_faceName 
=  wxT("Lucida Grande"); 
 290                 wxMacCFStringHolder 
cf( m_faceName
, wxLocale::GetSystemEncoding() ); 
 291                 ATSFontFamilyRef atsfamily 
= ATSFontFamilyFindFromName( cf 
, kATSOptionFlagsDefault 
); 
 292                 if ( atsfamily 
== (ATSFontFamilyRef
) -1 ) 
 294                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName 
); 
 295                     m_macFontFamily 
= GetAppFont(); 
 298                     m_macFontFamily 
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily 
); 
 303         if (m_weight 
== wxBOLD
) 
 304              m_macFontStyle 
|= bold
; 
 305         if (m_style 
== wxITALIC 
|| m_style 
== wxSLANT
) 
 306             m_macFontStyle 
|= italic
; 
 308             m_macFontStyle 
|= underline
; 
 309         m_macFontSize 
= m_pointSize 
; 
 312     // we try to get as much styles as possible into ATSU 
 315     // ATSUFontID and FMFont are equivalent 
 316     FMFontStyle intrinsicStyle 
= 0 ; 
 318     status 
= FMGetFontFromFontFamilyInstance( m_macFontFamily 
, m_macFontStyle 
, &m_macATSUFontID 
, &intrinsicStyle
); 
 319     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't get an ATSUFont from font family") ); 
 321     m_macATSUAdditionalQDStyles 
= m_macFontStyle 
& (~intrinsicStyle 
); 
 323     if ( m_macATSUStyle 
) 
 325         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
); 
 326         m_macATSUStyle 
= NULL 
; 
 329     status 
= ::ATSUCreateStyle((ATSUStyle 
*)&m_macATSUStyle
); 
 330     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create ATSU style") ); 
 332     ATSUAttributeTag atsuTags
[] = 
 336         kATSUVerticalCharacterTag
, 
 339         kATSUQDUnderlineTag 
, 
 340         kATSUQDCondensedTag 
, 
 343     ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 345         sizeof( ATSUFontID 
) , 
 347         sizeof( ATSUVerticalCharacterType
), 
 355     Boolean kTrue 
= true ; 
 356     Boolean kFalse 
= false ; 
 358     Fixed atsuSize 
= IntToFixed( m_macFontSize 
); 
 359     ATSUVerticalCharacterType kHorizontal 
= kATSUStronglyHorizontal
; 
 360     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 365             (m_macATSUAdditionalQDStyles 
& bold
) ? &kTrue 
: &kFalse 
, 
 366             (m_macATSUAdditionalQDStyles 
& italic
) ? &kTrue 
: &kFalse 
, 
 367             (m_macATSUAdditionalQDStyles 
& underline
) ? &kTrue 
: &kFalse 
, 
 368             (m_macATSUAdditionalQDStyles 
& condense
) ? &kTrue 
: &kFalse 
, 
 369             (m_macATSUAdditionalQDStyles 
& extend
) ? &kTrue 
: &kFalse 
, 
 372     status 
= ::ATSUSetAttributes( 
 373         (ATSUStyle
)m_macATSUStyle
, 
 374         sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) , 
 375         atsuTags
, atsuSizes
, atsuValues
); 
 377     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ); 
 380 // ---------------------------------------------------------------------------- 
 382 // ---------------------------------------------------------------------------- 
 384 bool wxFont::Create(const wxNativeFontInfo
& info
) 
 387         info
.pointSize
, info
.family
, info
.style
, info
.weight
, 
 388         info
.underlined
, info
.faceName
, info
.encoding 
); 
 391 wxFont::wxFont(const wxString
& fontdesc
) 
 393     wxNativeFontInfo info
; 
 394     if ( info
.FromString(fontdesc
) ) 
 398 bool wxFont::Create(int pointSize
, 
 403     const wxString
& faceName
, 
 404     wxFontEncoding encoding
) 
 408     m_refData 
= new wxFontRefData( 
 409         pointSize
, family
, style
, weight
, 
 410         underlined
, faceName
, encoding
); 
 417 bool wxFont::MacCreateThemeFont(wxUint16 themeFontID
) 
 421     m_refData 
= new wxFontRefData( 
 422         12, wxDEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
, 
 423         false, wxEmptyString
, wxFONTENCODING_DEFAULT 
); 
 425     M_FONTDATA
->m_macThemeFontID 
= themeFontID 
; 
 435 bool wxFont::RealizeResource() 
 437     M_FONTDATA
->MacFindFont(); 
 442 void wxFont::SetEncoding(wxFontEncoding encoding
) 
 446     M_FONTDATA
->m_encoding 
= encoding
; 
 451 void wxFont::Unshare() 
 453     // Don't change shared data 
 456         m_refData 
= new wxFontRefData(); 
 460         wxFontRefData
* ref 
= new wxFontRefData(*(wxFontRefData
*)m_refData
); 
 466 void wxFont::SetPointSize(int pointSize
) 
 470     M_FONTDATA
->m_pointSize 
= pointSize
; 
 475 void wxFont::SetFamily(int family
) 
 479     M_FONTDATA
->m_family 
= family
; 
 484 void wxFont::SetStyle(int style
) 
 488     M_FONTDATA
->m_style 
= style
; 
 493 void wxFont::SetWeight(int weight
) 
 497     M_FONTDATA
->m_weight 
= weight
; 
 502 bool wxFont::SetFaceName(const wxString
& faceName
) 
 506     M_FONTDATA
->m_faceName 
= faceName
; 
 510     return wxFontBase::SetFaceName(faceName
); 
 513 void wxFont::SetUnderlined(bool underlined
) 
 517     M_FONTDATA
->m_underlined 
= underlined
; 
 522 void wxFont::SetNoAntiAliasing( bool no 
) 
 526     M_FONTDATA
->SetNoAntiAliasing( no 
); 
 531 // ---------------------------------------------------------------------------- 
 533 // ---------------------------------------------------------------------------- 
 535 // TODO: insert checks everywhere for M_FONTDATA == NULL! 
 537 int wxFont::GetPointSize() const 
 539     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 541     return M_FONTDATA
->m_pointSize
; 
 544 wxSize 
wxFont::GetPixelSize() const 
 546 #if wxUSE_GRAPHICS_CONTEXT 
 547     // TODO: consider caching the value 
 548     wxGraphicsContext
* dc 
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
); 
 549     dc
->SetFont(*(wxFont 
*)this,*wxBLACK
); 
 550     wxDouble width
, height 
= 0; 
 551     dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
); 
 552     return wxSize((int)width
, (int)height
); 
 554     wxFontBase::GetPixelSize(); 
 558 int wxFont::GetFamily() const 
 560     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 562     return M_FONTDATA
->m_family
; 
 565 int wxFont::GetStyle() const 
 567     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 569     return M_FONTDATA
->m_style
; 
 572 int wxFont::GetWeight() const 
 574     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 576     return M_FONTDATA
->m_weight
; 
 579 bool wxFont::GetUnderlined() const 
 581     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 583     return M_FONTDATA
->m_underlined
; 
 586 wxString 
wxFont::GetFaceName() const 
 588     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxEmptyString 
, wxT("invalid font") ); 
 590     return M_FONTDATA
->m_faceName
; 
 593 wxFontEncoding 
wxFont::GetEncoding() const 
 595     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxFONTENCODING_DEFAULT 
, wxT("invalid font") ); 
 597     return M_FONTDATA
->m_encoding
; 
 600 bool wxFont::GetNoAntiAliasing() const 
 602     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 604     return M_FONTDATA
->m_noAA
; 
 607 short wxFont::MacGetFontNum() const 
 609     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 611     return M_FONTDATA
->m_macFontFamily
; 
 614 short wxFont::MacGetFontSize() const 
 616     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 618     return M_FONTDATA
->m_macFontSize
; 
 621 wxByte 
wxFont::MacGetFontStyle() const 
 623     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 625     return M_FONTDATA
->m_macFontStyle
; 
 628 wxUint32 
wxFont::MacGetATSUFontID() const 
 630     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 632     return M_FONTDATA
->m_macATSUFontID
; 
 635 void * wxFont::MacGetATSUStyle() const 
 637     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 639     return M_FONTDATA
->m_macATSUStyle
; 
 642 wxUint32 
wxFont::MacGetATSUAdditionalQDStyles() const 
 644     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 646     return M_FONTDATA
->m_macATSUAdditionalQDStyles
; 
 649 wxUint16 
wxFont::MacGetThemeFontID() const 
 651     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 653     return M_FONTDATA
->m_macThemeFontID
; 
 656 const wxNativeFontInfo 
* wxFont::GetNativeFontInfo() const 
 658     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 659     wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") ); 
 661     M_FONTDATA
->m_info
.InitFromFont(*this); 
 663     return &(M_FONTDATA
->m_info
);